diff --git a/src/testing/mocks/middleware/store.ts b/src/testing/mocks/middleware/store.ts new file mode 100644 index 000000000..b40ad4481 --- /dev/null +++ b/src/testing/mocks/middleware/store.ts @@ -0,0 +1,55 @@ +import { create, destroy, invalidator } from '../../../core/vdom'; +import injector from '../../../core/middleware/injector'; +import { createStoreMiddleware } from '../../../core/middleware/store'; +import Store, { StatePaths } from '../../../stores/Store'; +import { MiddlewareResult } from '../../../core/interfaces'; +import { PatchOperation } from '../../../stores/state/Patch'; +import { Process } from '../../../stores/process'; + +const factory = create({ destroy, invalidator, injector }); + +export function createMockStoreMiddleware(processes: [Process, any][] = []) { + const store = createStoreMiddleware(); + const storeMock = new Store(); + const processMockMap = new Map(processes); + const injectorStub = { + get: (): any => { + return storeMock; + }, + subscribe: (): any => {} + }; + const mockStoreMiddleware = factory(({ properties, middleware: { destroy, invalidator }, children, id }) => { + const { callback } = store(); + const mock = callback({ + id, + middleware: { destroy, invalidator, injector: injectorStub }, + properties, + children + }); + return { + get: mock.get.bind(mock), + path: mock.path.bind(mock), + executor: >(process: T): ReturnType => { + const mock = processMockMap.get(process); + if (mock) { + return mock; + } + return (() => {}) as any; + }, + at: mock.at.bind(mock) + }; + }); + + function mockStore(): MiddlewareResult; + function mockStore(operations: (path: StatePaths) => PatchOperation[]): void; + function mockStore(operations?: (path: any) => PatchOperation[]): void | MiddlewareResult { + if (operations) { + storeMock.apply(operations(storeMock.path), true); + } else { + return mockStoreMiddleware(); + } + } + return mockStore; +} + +export default createMockStoreMiddleware; diff --git a/tests/testing/unit/mocks/middleware/all.ts b/tests/testing/unit/mocks/middleware/all.ts index a9ec3498e..374565367 100644 --- a/tests/testing/unit/mocks/middleware/all.ts +++ b/tests/testing/unit/mocks/middleware/all.ts @@ -1,3 +1,4 @@ import './intersection'; import './node'; import './resize'; +import './store'; diff --git a/tests/testing/unit/mocks/middleware/store.tsx b/tests/testing/unit/mocks/middleware/store.tsx new file mode 100644 index 000000000..7ad0ebd94 --- /dev/null +++ b/tests/testing/unit/mocks/middleware/store.tsx @@ -0,0 +1,87 @@ +const { it, describe } = intern.getInterface('bdd'); +const { assert } = intern.getPlugin('chai'); +import createStoreMock from '../../../../../src/testing/mocks/middleware/store'; +import { createStoreMiddleware } from '../../../../../src/core/middleware/store'; +import { tsx, create } from '../../../../../src/core/vdom'; +import harness from '../../../../../src/testing/harness'; +import { createProcess } from '../../../../../src/stores/process'; +import { stub } from 'sinon'; +import { replace } from '../../../../../src/stores/state/operations'; + +interface State { + foo: string; + bar: { + qux: number; + }; +} + +const store = createStoreMiddleware(); + +const myProcess = createProcess('test', [() => {}]); +const otherProcess = createProcess('other', [() => {}]); + +describe('store mock', () => { + it('should mock store middleware', () => { + const processStub = stub(); + const storeMock = createStoreMock([[myProcess, processStub]]); + const factory = create({ store }); + const App = factory(({ middleware: { store } }) => { + const { get, path, executor } = store; + const foo = get(path('foo')); + const qux = get(path('bar', 'qux')); + return ( +
+
+ ); + }); + const h = harness(() => , { middleware: [[store, storeMock]] }); + h.expect(() => { + return ( +
+
+ ); + }); + assert.isTrue(processStub.notCalled); + h.trigger('@button', 'onclick'); + h.trigger('@other', 'onclick'); + assert.isTrue(processStub.calledOnce); + storeMock((path) => [replace(path('foo'), 'foo')]); + h.expect(() => { + return ( +
+
+ ); + }); + storeMock((path) => [replace(path('bar'), { qux: 1 })]); + h.expect(() => { + return ( +
+
+ ); + }); + }); +});