UNPKG

overmind

Version:
1 lines 15.5 kB
{"version":3,"file":"derived.test.js","sourceRoot":"","sources":["../src/derived.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { PROXY_TREE } from 'proxy-state-tree'\n\nimport { EventType, Overmind, derived, IContext } from './'\n\ndescribe('Derived', () => {\n test('should instantiate app with derived state', () => {\n type State = {\n foo: string\n upperFoo: string\n }\n const state: State = {\n foo: 'bar',\n upperFoo: derived((state: State) => state.foo.toUpperCase()),\n }\n const config = {\n state,\n }\n\n const app = new Overmind(config)\n\n expect(app.state.upperFoo).toEqual('BAR')\n })\n\n test('should dynamically remove derived', async () => {\n let dirtyCount = 0\n const removeDerived = ({ state }: Context) => {\n state.upperFoo = null as any\n }\n const changeFoo = ({ state }: Context, count: number) => {\n state.foo = 'bar' + count\n }\n type State = {\n foo: string\n upperFoo: string\n }\n const state: State = {\n foo: 'bar',\n upperFoo: derived((state: State) => state.foo.toUpperCase()),\n }\n const actions = {\n changeFoo,\n removeDerived,\n }\n const config = {\n state,\n actions,\n }\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n\n const app = new Overmind(config)\n const trackStateTree = app.getTrackStateTree()\n const onTrack = () => {}\n function render() {\n trackStateTree.track(onTrack)\n app.state.upperFoo\n }\n app.eventHub.on(EventType.DERIVED_DIRTY, () => {\n dirtyCount++\n })\n render()\n expect(app.state.upperFoo).toBe('BAR')\n app.actions.changeFoo(2)\n expect(app.state.upperFoo).toBe('BAR2')\n app.actions.removeDerived()\n app.actions.changeFoo(3)\n // The dirty event is async\n await new Promise((resolve) => setTimeout(resolve, 0))\n expect(dirtyCount).toBe(1)\n })\n\n test('should dynamically add derived', () => {\n const addDerived = ({ state }: Context) => {\n state.upperFoo = derived((state: State) => state.foo.toUpperCase())\n }\n const changeFoo = ({ state }: Context) => {\n state.foo = 'bar2'\n }\n type State = {\n foo: string\n upperFoo: string | null\n }\n const state: State = {\n foo: 'bar',\n upperFoo: null,\n }\n const actions = {\n changeFoo,\n addDerived,\n }\n\n const config = {\n state,\n actions,\n }\n\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n\n const app = new Overmind(config)\n const trackStateTree = app.getTrackStateTree()\n const onTrack = () => {}\n function render() {\n trackStateTree.track(onTrack)\n app.state.upperFoo\n }\n render()\n app.actions.addDerived()\n expect(app.state.upperFoo).toBe('BAR')\n app.actions.changeFoo()\n expect(app.state.upperFoo).toBe('BAR2')\n })\n\n test('should allow access to proxy state tree to continue tracking with derived function', () => {\n let renderCount = 0\n const changeFoo = ({ state }: Context) => {\n state.foo = 'bar2'\n }\n type State = {\n foo: string\n upperFoo: () => string\n }\n const state: State = {\n foo: 'bar',\n upperFoo: derived(\n () =>\n function() {\n const state = this[PROXY_TREE].state\n\n return state.foo.toUpperCase()\n }\n ),\n }\n const actions = {\n changeFoo,\n }\n\n const config = {\n state,\n actions,\n }\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n\n const app = new Overmind(config)\n const trackStateTree = app.getTrackStateTree()\n const onTrack = () => {\n renderCount++\n }\n function render() {\n trackStateTree.track(onTrack)\n app.state.upperFoo()\n }\n render()\n app.actions.changeFoo()\n expect(renderCount).toBe(1)\n })\n\n test('should track derived state', () => {\n let renderCount = 0\n const changeFoo = ({ state }: Context) => {\n state.foo = 'bar2'\n }\n type State = {\n foo: string\n upperFoo: string\n }\n const state: State = {\n foo: 'bar',\n upperFoo: derived((state: State) => state.foo.toUpperCase()),\n }\n const actions = {\n changeFoo,\n }\n const config = {\n state,\n actions,\n }\n\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n\n const app = new Overmind(config)\n const trackStateTree = app.getTrackStateTree()\n const onTrack = () => {\n renderCount++\n }\n function render() {\n trackStateTree.track(onTrack)\n app.state.upperFoo\n }\n render()\n app.actions.changeFoo()\n expect(app.state.upperFoo).toBe('BAR2')\n expect(renderCount).toBe(1)\n })\n\n test('should not require flush to flag as dirty', () => {\n expect.assertions(1)\n type State = {\n foo: string\n upperFoo: string\n }\n const state: State = {\n foo: 'bar',\n upperFoo: derived((state: State) => state.foo.toUpperCase()),\n }\n const changeFoo = ({ state }: Context) => {\n state.foo = 'bar2'\n expect(state.upperFoo).toBe('BAR2')\n }\n const actions = {\n changeFoo,\n }\n const config = {\n state,\n actions,\n }\n\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n const app = new Overmind(config)\n\n app.actions.changeFoo()\n })\n test('should pass parent as second argument', () => {\n expect.assertions(1)\n const changeFoo = ({ state }: Context) => {\n state.foo = 'bar2'\n expect(state.upperFoo).toBe('BAR2')\n }\n\n type State = {\n foo: string\n upperFoo: string\n }\n\n const state: State = {\n foo: 'bar',\n upperFoo: derived((_, parent: State) => parent.foo.toUpperCase()),\n }\n const actions = {\n changeFoo,\n }\n const config = {\n state,\n actions,\n }\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n const app = new Overmind(config)\n\n app.actions.changeFoo()\n })\n test('should track nested derived correctly', () => {\n expect.assertions(4)\n let runCount = 0\n const changeFoo = ({ state }: Context) => {\n state.nestedDerived.foo = 'bar2'\n expect(state.nestedDerived.upperFoo).toBe('BAR2')\n }\n\n type State = {\n nestedDerived: {\n foo: string\n upperFoo: string\n }\n }\n\n const state: State = {\n nestedDerived: {\n foo: 'bar',\n upperFoo: derived((parent: State['nestedDerived']) =>\n parent.foo.toUpperCase()\n ),\n },\n }\n const actions = {\n changeFoo,\n }\n const config = {\n state,\n actions,\n }\n type Context = IContext<{\n state: typeof state\n actions: typeof actions\n }>\n const app = new Overmind(config)\n\n const trackStateTree = app.getTrackStateTree()\n\n function render() {\n runCount++\n if (runCount === 1) {\n expect(trackStateTree.state.nestedDerived.upperFoo).toBe('BAR')\n } else {\n expect(trackStateTree.state.nestedDerived.upperFoo).toBe('BAR2')\n }\n trackStateTree.stopTracking()\n }\n\n trackStateTree.track(render)\n\n render()\n\n app.actions.changeFoo()\n\n expect(runCount).toBe(2)\n })\n test('should be able to add derived to class instances', () => {\n class SomeClass {\n foo = derived((state: SomeClass) => state.bar + '!')\n bar = 'foo'\n }\n type State = {\n class: SomeClass\n }\n const state: State = {\n class: new SomeClass(),\n }\n const config = {\n state,\n }\n\n const app = new Overmind(config)\n\n expect(app.state.class.foo).toEqual('foo!')\n })\n})\n"]}