Procházet zdrojové kódy

Added actionCreatorFactory and tests

Hugo Häggmark před 6 roky
rodič
revize
62341ffe56

+ 53 - 0
public/app/core/redux/actionCreatorFactory.test.ts

@@ -0,0 +1,53 @@
+import { actionCreatorFactory, resetAllActionCreatorTypes } from './actionCreatorFactory';
+
+interface Dummy {
+  n: number;
+  s: string;
+  o: {
+    n: number;
+    s: string;
+    b: boolean;
+  };
+  b: boolean;
+}
+
+const setup = payload => {
+  resetAllActionCreatorTypes();
+  const actionCreator = actionCreatorFactory<Dummy>('dummy').create();
+  const result = actionCreator(payload);
+
+  return {
+    actionCreator,
+    result,
+  };
+};
+
+describe('actionCreatorFactory', () => {
+  describe('when calling create', () => {
+    it('then it should create correct type string', () => {
+      const payload = { n: 1, b: true, s: 'dummy', o: { n: 1, b: true, s: 'dummy' } };
+      const { actionCreator, result } = setup(payload);
+
+      expect(actionCreator.type).toEqual('dummy');
+      expect(result.type).toEqual('dummy');
+    });
+
+    it('then it should create correct payload', () => {
+      const payload = { n: 1, b: true, s: 'dummy', o: { n: 1, b: true, s: 'dummy' } };
+      const { result } = setup(payload);
+
+      expect(result.payload).toEqual(payload);
+    });
+  });
+
+  describe('when calling create with existing type', () => {
+    it('then it should throw error', () => {
+      const payload = { n: 1, b: true, s: 'dummy', o: { n: 1, b: true, s: 'dummy' } };
+      setup(payload);
+
+      expect(() => {
+        actionCreatorFactory<Dummy>('dummy').create();
+      }).toThrow();
+    });
+  });
+});

+ 33 - 0
public/app/core/redux/actionCreatorFactory.ts

@@ -0,0 +1,33 @@
+import { Action } from 'redux';
+
+const allActionCreators: string[] = [];
+
+export interface GrafanaAction<Payload> extends Action {
+  readonly type: string;
+  readonly payload: Payload;
+}
+
+export interface GrafanaActionCreator<Payload> {
+  readonly type: string;
+  (payload: Payload): GrafanaAction<Payload>;
+}
+
+export interface ActionCreatorFactory<Payload> {
+  create: () => GrafanaActionCreator<Payload>;
+}
+
+export const actionCreatorFactory = <Payload>(type: string): ActionCreatorFactory<Payload> => {
+  const create = (): GrafanaActionCreator<Payload> => {
+    return Object.assign((payload: Payload): GrafanaAction<Payload> => ({ type, payload }), { type });
+  };
+
+  if (allActionCreators.some(t => type === type)) {
+    throw new Error(`There is already an actionCreator defined with the type ${type}`);
+  }
+
+  allActionCreators.push(type);
+
+  return { create };
+};
+
+export const resetAllActionCreatorTypes = () => (allActionCreators.length = 0);