reactant-module
Version:
A module model for Reactant
332 lines (313 loc) • 7.65 kB
text/typescript
import { Middleware } from 'redux';
import {
injectable,
createContainer,
createStore,
state,
action,
PluginModule,
actionIdentifier,
} from '../..';
describe('createStore', () => {
test('basic parameters', () => {
()
class Counter {
count = 0;
}
const ServiceIdentifiers = new Map();
const modules = [Counter];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
container.get(Counter);
const store = createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: [],
},
});
expect(Object.values(store.getState())).toEqual([{ count: 0 }]);
});
test('preloadedState', () => {
({
name: 'counter',
})
class Counter {
count = 0;
}
const ServiceIdentifiers = new Map();
const modules = [Counter];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
container.get(Counter);
const store = createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: [],
},
preloadedState: {
counter: { count: 18 },
},
});
expect(Object.values(store.getState())).toEqual([{ count: 18 }]);
});
test('middleware module', () => {
({
name: 'counter',
})
class Counter {
count = 0;
increase() {
this.count += 1;
}
}
const actionFn = jest.fn();
class Logger extends PluginModule {
middleware: Middleware = (store) => (next) => (_action) => {
actionFn(_action);
const result = next(_action);
actionFn(store.getState());
return result;
};
}
const ServiceIdentifiers = new Map();
const modules = [Counter, Logger];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
const counter = container.get(Counter);
createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: [],
},
});
counter.increase();
expect(actionFn.mock.calls.length).toBe(2);
expect(actionFn.mock.calls[0]).toEqual([
{
_reactant: actionIdentifier,
method: 'increase',
params: [],
state: {
counter: { count: 1 },
},
type: 'counter',
},
]);
expect(actionFn.mock.calls[1]).toEqual([{ counter: { count: 1 } }]);
});
test('providers', () => {
const Provider = () => null;
()
class CounterPlugin extends PluginModule {
provider = Provider;
}
()
class Counter {
constructor(public counterPlugin: CounterPlugin) {}
state = {
count: 0,
};
}
const ServiceIdentifiers = new Map();
const modules = [Counter];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
container.get(Counter);
const providers: React.FunctionComponent[] = [];
const store = createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: providers,
},
});
expect(providers.length).toBe(1);
expect(providers[0]({}) === null).toBeTruthy();
});
test('providers - be depended on', () => {
const fooProvider = () => null;
const barProvider = () => null;
()
class FooPlugin extends PluginModule {
provider = fooProvider;
}
()
class BarPlugin extends PluginModule {
provider = barProvider;
}
()
class Counter {}
const ServiceIdentifiers = new Map();
const modules = [Counter, FooPlugin, BarPlugin];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
container.get(Counter);
const providers: React.FunctionComponent[] = [];
const store = createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: providers,
},
});
expect(providers.map(({ name }) => name)).toEqual(
[fooProvider, barProvider].map(({ name }) => `bound ${name}`)
);
});
test('devOptions', () => {
({
name: 'counter',
})
class Counter {
count = 0;
sum = { count: 0 };
increase() {
this.sum.count += 1;
}
increase1() {
this.sum.count += 1;
}
increase2() {
this.count += 1;
}
}
const ServiceIdentifiers = new Map();
const modules = [Counter];
const container = createContainer({
ServiceIdentifiers,
modules,
options: {
defaultScope: 'Singleton',
},
});
const counter = container.get(Counter);
const store = createStore({
modules,
container,
ServiceIdentifiers,
loadedModules: new Set(),
load: (...args: any[]) => {
//
},
dynamicModules: new Map(),
pluginHooks: {
middleware: [],
beforeCombineRootReducers: [],
afterCombineRootReducers: [],
enhancer: [],
preloadedStateHandler: [],
afterCreateStore: [],
provider: [],
},
devOptions: { autoFreeze: true },
});
expect(() => {
store.getState().counter.sum.count = 1;
}).toThrowError(/Cannot assign to read only property/);
counter.increase();
for (const fn of [
() => {
store.getState().counter.sum.count = 1;
},
() => counter.increase1(),
() => counter.increase2(),
]) {
expect(fn).toThrowError(/Cannot assign to read only property/);
}
});
});