From fb6c5ff7f2496511273a9881c230a65bb0a7ffeb Mon Sep 17 00:00:00 2001 From: REllEK-IO Date: Fri, 20 Oct 2023 08:03:37 -0700 Subject: [PATCH] Constistency, debounce fires most recent action after duration. --- ActionStrategy.md | 6 +- package.json | 2 +- src/concepts/experiment/experiment.concept.ts | 4 +- ...erateIdThenReceiveInMethod.quality copy.ts | 42 +++++++ ...ateIdThenReceiveInMethod.quality copy 2.ts | 52 +++++++++ ...nceIterateIdThenReceiveInMethod.quality.ts | 46 ++++++++ .../iterateIdThenReceiveInMethod.quality.ts | 37 +++++++ .../asyncIterateIdThenAddToData.strategy.ts | 17 +++ ...nceAsyncIterateIdThenAddToData.strategy.ts | 17 +++ ...nceIterateIdThenAddToData.strategy copy.ts | 17 +++ .../iterateIdThenAddToData.strategy.ts | 17 +++ src/model/actionStrategy.ts | 5 +- src/model/actionStrategyData.ts | 21 ++-- src/model/method.ts | 11 +- src/test/debounceMethods.test.ts | 103 +++++++++++++++++- src/test/methodHelpers.test.ts | 66 ++++++++++- 16 files changed, 437 insertions(+), 26 deletions(-) create mode 100644 src/concepts/experiment/qualities/asyncIterateIdThenReceiveInMethod.quality copy.ts create mode 100644 src/concepts/experiment/qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2.ts create mode 100644 src/concepts/experiment/qualities/debounceIterateIdThenReceiveInMethod.quality.ts create mode 100644 src/concepts/experiment/qualities/iterateIdThenReceiveInMethod.quality.ts create mode 100644 src/concepts/experiment/strategies/asyncIterateIdThenAddToData.strategy.ts create mode 100644 src/concepts/experiment/strategies/debounceAsyncIterateIdThenAddToData.strategy.ts create mode 100644 src/concepts/experiment/strategies/debounceIterateIdThenAddToData.strategy copy.ts create mode 100644 src/concepts/experiment/strategies/iterateIdThenAddToData.strategy.ts diff --git a/ActionStrategy.md b/ActionStrategy.md index f8e8983..dd53581 100644 --- a/ActionStrategy.md +++ b/ActionStrategy.md @@ -130,7 +130,7 @@ This was a purposeful design choice, if you find yourself doing such. Known this export const createMethod = (method: (action: Action) => Action): [Method, Subject] => {} export const createMethodWithConcepts = - (method: (action: Action) => Action, concepts$: UnifiedSubject): [Method, Subject] => {} + (method: (action: Action, concepts: Concept[]) => Action, concepts$: UnifiedSubject): [Method, Subject] => {} export const createAsyncMethod = (asyncMethod: (controller: ActionController, action: Action) => void): [Method, Subject] => {} export const createAsyncMethodWithConcepts = @@ -153,7 +153,7 @@ export const createAsyncMethodDebounceWithConcepts = * createAsyncMethodWithConcepts - Will also have access to the most recent concepts. *Note if you are implementing your own debounceAction, pay attention to how these method helpers work. They are handling a passed conclude from debounceAction within their map/switchMap* -* createMethodDebounce - After the first action, this will filter actions within the duration to be set to the conclude action. +* createMethodDebounce - Will fire after the set duration with the most recent action, and filter previous actions within the duration to be set to the conclude action. * createMethodDebounceWithConcepts - Will filter actions within the duration while providing access to the most recent concepts. -* createAsyncMethodDebounce - Will not disengage the initial ActionController, but will allow debounced actions to pass through when filtered as conclude actions. And will fire the first action upon its own conditions are met asynchronously. +* createAsyncMethodDebounce - Will not disengage the initial ActionController, but will allow debounced actions to pass through when filtered as conclude actions. And will fire the most recent action upon its own conditions are met asynchronously after the set duration. * createAsyncMethodDebounceWithConcepts - Filters and then first the first action once conditions are met, and provides access to the most recent concepts. \ No newline at end of file diff --git a/package.json b/package.json index 491ec05..b92566a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@phuire/strx", - "version": "0.0.39", + "version": "0.0.40", "description": "Unified Turing Machine", "main": "dist/index.js", "module": "dist/index.mjs", diff --git a/src/concepts/experiment/experiment.concept.ts b/src/concepts/experiment/experiment.concept.ts index 705e8a5..7696288 100644 --- a/src/concepts/experiment/experiment.concept.ts +++ b/src/concepts/experiment/experiment.concept.ts @@ -5,6 +5,7 @@ import { PrincipleFunction } from '../../model/principle'; export type ExperimentState = { actionQue: Action[], mock: boolean, + id: number } export const experimentName = 'experiment'; @@ -12,7 +13,8 @@ export const experimentName = 'experiment'; export const createExperimentState = (): ExperimentState => { return { actionQue: [], - mock: false + mock: false, + id: 0, }; }; diff --git a/src/concepts/experiment/qualities/asyncIterateIdThenReceiveInMethod.quality copy.ts b/src/concepts/experiment/qualities/asyncIterateIdThenReceiveInMethod.quality copy.ts new file mode 100644 index 0000000..68bb2ad --- /dev/null +++ b/src/concepts/experiment/qualities/asyncIterateIdThenReceiveInMethod.quality copy.ts @@ -0,0 +1,42 @@ +import { MethodCreator, defaultMethodCreator, defaultReducer } from '../../../model/concept'; +import { Action, prepareActionCreator } from '../../../model/action'; +import { createQuality } from '../../../model/concept'; +import { ExperimentState, experimentName } from '../experiment.concept'; +import { UnifiedSubject } from '../../../model/stagePlanner'; +import { createAsyncMethodWithConcepts, createMethodWithConcepts } from '../../../model/method'; +import { selectState } from '../../../model/selector'; +import { strategySuccess } from '../../../model/actionStrategy'; +import { strategyData_unifyData } from '../../../model/actionStrategyData'; + +export const experimentAsyncIterateIdThenReceiveInMethodType + = 'Experiment asynchronously iterate ID then receive in Method via Concept select'; + +export const experimentAsyncIterateIdThenReceiveInMethod = prepareActionCreator(experimentAsyncIterateIdThenReceiveInMethodType); + +const experimentAsyncIterateIdThenReceiveInMethodCreator: MethodCreator = (concepts$?: UnifiedSubject) => + createAsyncMethodWithConcepts((controller, action, concepts) => { + console.log('HIT'); + setTimeout(() => { + const experimentState = selectState(concepts, experimentName); + if (action.strategy) { + const data = strategyData_unifyData(action.strategy, {id: experimentState.id}); + const strategy = strategySuccess(action.strategy, data); + console.log('FIRE'); + controller.fire(strategy); + } + controller.fire(action); + }, 50); + }, concepts$ as UnifiedSubject); + +function experimentAsyncIterateIdThenReceiveInMethodReducer(state: ExperimentState, _: Action): ExperimentState { + return { + ...state, + id: state.id + 1 + }; +} + +export const experimentAsyncIterateIdThenReceiveInMethodQuality = createQuality( + experimentAsyncIterateIdThenReceiveInMethodType, + experimentAsyncIterateIdThenReceiveInMethodReducer, + experimentAsyncIterateIdThenReceiveInMethodCreator +); diff --git a/src/concepts/experiment/qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2.ts b/src/concepts/experiment/qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2.ts new file mode 100644 index 0000000..b61356e --- /dev/null +++ b/src/concepts/experiment/qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2.ts @@ -0,0 +1,52 @@ +import { MethodCreator } from '../../../model/concept'; +import { Action, prepareActionWithPayloadCreator } from '../../../model/action'; +import { createQuality } from '../../../model/concept'; +import { ExperimentState, experimentName } from '../experiment.concept'; +import { UnifiedSubject } from '../../../model/stagePlanner'; +import { createAsyncMethodDebounceWithConcepts } from '../../../model/method'; +import { selectPayload, selectState } from '../../../model/selector'; +import { strategySuccess } from '../../../model/actionStrategy'; +import { strategyData_unifyData } from '../../../model/actionStrategyData'; + +export type DebounceAsyncIterateIdThenReceiveInMethodPayload = { + setId: number; +} +export const experimentDebounceAsyncIterateIdThenReceiveInMethodType + = 'Experiment asynchronously iterate ID then receive in Method via Concept select'; +export const experimentDebounceAsyncIterateIdThenReceiveInMethod + = prepareActionWithPayloadCreator( + experimentDebounceAsyncIterateIdThenReceiveInMethodType + ); + +const experimentDebounceAsyncIterateIdThenReceiveInMethodCreator: MethodCreator = (concepts$?: UnifiedSubject) => + createAsyncMethodDebounceWithConcepts((controller, action, concepts) => { + setTimeout(() => { + const payload = selectPayload(action); + const experimentState = selectState(concepts, experimentName); + if (action.strategy) { + const data = strategyData_unifyData( + action.strategy, + { + id: experimentState.id, + setId: payload.setId + } + ); + const strategy = strategySuccess(action.strategy, data); + controller.fire(strategy); + } + controller.fire(action); + }, 50); + }, concepts$ as UnifiedSubject, 500); + +function experimentDebounceAsyncIterateIdThenReceiveInMethodReducer(state: ExperimentState, _: Action): ExperimentState { + return { + ...state, + id: state.id + 1 + }; +} + +export const experimentDebounceAsyncIterateIdThenReceiveInMethodQuality = createQuality( + experimentDebounceAsyncIterateIdThenReceiveInMethodType, + experimentDebounceAsyncIterateIdThenReceiveInMethodReducer, + experimentDebounceAsyncIterateIdThenReceiveInMethodCreator +); diff --git a/src/concepts/experiment/qualities/debounceIterateIdThenReceiveInMethod.quality.ts b/src/concepts/experiment/qualities/debounceIterateIdThenReceiveInMethod.quality.ts new file mode 100644 index 0000000..70b9dcf --- /dev/null +++ b/src/concepts/experiment/qualities/debounceIterateIdThenReceiveInMethod.quality.ts @@ -0,0 +1,46 @@ +import { MethodCreator, defaultMethodCreator, defaultReducer } from '../../../model/concept'; +import { Action, prepareActionCreator, prepareActionWithPayloadCreator } from '../../../model/action'; +import { createQuality } from '../../../model/concept'; +import { ExperimentState, experimentName } from '../experiment.concept'; +import { UnifiedSubject } from '../../../model/stagePlanner'; +import { createMethodDebounceWithConcepts, createMethodWithConcepts } from '../../../model/method'; +import { selectPayload, selectState } from '../../../model/selector'; +import { strategySuccess } from '../../../model/actionStrategy'; +import { strategyData_unifyData } from '../../../model/actionStrategyData'; + +export type DebounceIterateIdThenReceiveInMethodPayload = { + setId: number; +} +export const experimentDebounceIterateIdThenReceiveInMethodType = + 'Experiment debounce iterate ID then receive in Method via Concept select'; + +export const experimentDebounceIterateIdThenReceiveInMethod = + prepareActionWithPayloadCreator(experimentDebounceIterateIdThenReceiveInMethodType); + +const experimentDebounceIterateIdThenReceiveInMethodCreator: MethodCreator = (concepts$?: UnifiedSubject) => + createMethodDebounceWithConcepts((action, concepts) => { + const payload = selectPayload(action); + const experimentState = selectState(concepts, experimentName); + if (action.strategy) { + const data = strategyData_unifyData(action.strategy, { + id: experimentState.id, + setId: payload.setId + }); + const strategy = strategySuccess(action.strategy, data); + return strategy; + } + return action; + }, concepts$ as UnifiedSubject, 500); + +function experimentDebounceIterateIdThenReceiveInMethodReducer(state: ExperimentState, _: Action): ExperimentState { + return { + ...state, + id: state.id + 1 + }; +} + +export const experimentDebounceIterateIdThenReceiveInMethodQuality = createQuality( + experimentDebounceIterateIdThenReceiveInMethodType, + experimentDebounceIterateIdThenReceiveInMethodReducer, + experimentDebounceIterateIdThenReceiveInMethodCreator +); diff --git a/src/concepts/experiment/qualities/iterateIdThenReceiveInMethod.quality.ts b/src/concepts/experiment/qualities/iterateIdThenReceiveInMethod.quality.ts new file mode 100644 index 0000000..f295e97 --- /dev/null +++ b/src/concepts/experiment/qualities/iterateIdThenReceiveInMethod.quality.ts @@ -0,0 +1,37 @@ +import { MethodCreator, defaultMethodCreator, defaultReducer } from '../../../model/concept'; +import { Action, prepareActionCreator } from '../../../model/action'; +import { createQuality } from '../../../model/concept'; +import { ExperimentState, experimentName } from '../experiment.concept'; +import { UnifiedSubject } from '../../../model/stagePlanner'; +import { createMethodWithConcepts } from '../../../model/method'; +import { selectState } from '../../../model/selector'; +import { strategySuccess } from '../../../model/actionStrategy'; +import { strategyData_unifyData } from '../../../model/actionStrategyData'; + +export const experimentIterateIdThenReceiveInMethodType = 'Experiment iterate ID then receive in Method via Concept select'; + +export const experimentIterateIdThenReceiveInMethod = prepareActionCreator(experimentIterateIdThenReceiveInMethodType); + +const experimentIterateIdThenReceiveInMethodCreator: MethodCreator = (concepts$?: UnifiedSubject) => + createMethodWithConcepts((action, concepts) => { + const experimentState = selectState(concepts, experimentName); + if (action.strategy) { + const data = strategyData_unifyData(action.strategy, {id: experimentState.id}); + const strategy = strategySuccess(action.strategy, data); + return strategy; + } + return action; + }, concepts$ as UnifiedSubject); + +function experimentIterateIdThenReceiveInMethodReducer(state: ExperimentState, _: Action): ExperimentState { + return { + ...state, + id: state.id + 1 + }; +} + +export const experimentIterateIdThenReceiveInMethodQuality = createQuality( + experimentIterateIdThenReceiveInMethodType, + experimentIterateIdThenReceiveInMethodReducer, + experimentIterateIdThenReceiveInMethodCreator +); diff --git a/src/concepts/experiment/strategies/asyncIterateIdThenAddToData.strategy.ts b/src/concepts/experiment/strategies/asyncIterateIdThenAddToData.strategy.ts new file mode 100644 index 0000000..72ff377 --- /dev/null +++ b/src/concepts/experiment/strategies/asyncIterateIdThenAddToData.strategy.ts @@ -0,0 +1,17 @@ +import { ActionStrategy, ActionStrategyParameters, createActionNode, createStrategy } from '../../../model/actionStrategy'; +import { experimentAsyncIterateIdThenReceiveInMethod } from '../qualities/asyncIterateIdThenReceiveInMethod.quality copy'; + +export const asyncIterateIdThenAddToDataTopic = 'Async iterate experiment ID then add to strategy data'; +export function asyncIterateIdThenAddToData(): ActionStrategy { + const stepOne = createActionNode(experimentAsyncIterateIdThenReceiveInMethod(), { + successNode: null, + failureNode: null, + }); + + const params: ActionStrategyParameters = { + topic: asyncIterateIdThenAddToDataTopic, + initialNode: stepOne, + }; + + return createStrategy(params); +} \ No newline at end of file diff --git a/src/concepts/experiment/strategies/debounceAsyncIterateIdThenAddToData.strategy.ts b/src/concepts/experiment/strategies/debounceAsyncIterateIdThenAddToData.strategy.ts new file mode 100644 index 0000000..d2f9a71 --- /dev/null +++ b/src/concepts/experiment/strategies/debounceAsyncIterateIdThenAddToData.strategy.ts @@ -0,0 +1,17 @@ +import { ActionStrategy, ActionStrategyParameters, createActionNode, createStrategy } from '../../../model/actionStrategy'; +import { experimentDebounceAsyncIterateIdThenReceiveInMethod } from '../qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2'; + +export const debounceAsyncIterateIdThenAddToDataTopic = 'Debounce async iterate experiment ID then add to strategy data'; +export function debounceAsyncIterateIdThenAddToData(setId: number): ActionStrategy { + const stepOne = createActionNode(experimentDebounceAsyncIterateIdThenReceiveInMethod({setId}), { + successNode: null, + failureNode: null, + }); + + const params: ActionStrategyParameters = { + topic: debounceAsyncIterateIdThenAddToDataTopic, + initialNode: stepOne, + }; + + return createStrategy(params); +} \ No newline at end of file diff --git a/src/concepts/experiment/strategies/debounceIterateIdThenAddToData.strategy copy.ts b/src/concepts/experiment/strategies/debounceIterateIdThenAddToData.strategy copy.ts new file mode 100644 index 0000000..1eb5c28 --- /dev/null +++ b/src/concepts/experiment/strategies/debounceIterateIdThenAddToData.strategy copy.ts @@ -0,0 +1,17 @@ +import { ActionStrategy, ActionStrategyParameters, createActionNode, createStrategy } from '../../../model/actionStrategy'; +import { experimentDebounceIterateIdThenReceiveInMethod } from '../qualities/debounceIterateIdThenReceiveInMethod.quality'; + +export const debounceIterateIdThenAddToDataTopic = 'Debounce iterate experiment ID then add to strategy data'; +export function debounceIterateIdThenAddToData(setId: number): ActionStrategy { + const stepOne = createActionNode(experimentDebounceIterateIdThenReceiveInMethod({setId}), { + successNode: null, + failureNode: null, + }); + + const params: ActionStrategyParameters = { + topic: debounceIterateIdThenAddToDataTopic, + initialNode: stepOne, + }; + + return createStrategy(params); +} \ No newline at end of file diff --git a/src/concepts/experiment/strategies/iterateIdThenAddToData.strategy.ts b/src/concepts/experiment/strategies/iterateIdThenAddToData.strategy.ts new file mode 100644 index 0000000..74443c4 --- /dev/null +++ b/src/concepts/experiment/strategies/iterateIdThenAddToData.strategy.ts @@ -0,0 +1,17 @@ +import { ActionStrategy, ActionStrategyParameters, createActionNode, createStrategy } from '../../../model/actionStrategy'; +import { experimentIterateIdThenReceiveInMethod } from '../qualities/iterateIdThenReceiveInMethod.quality'; + +export const iterateIdThenAddToDataTopic = 'Iterate experiment ID then add to strategy data'; +export function iterateIdThenAddToData(): ActionStrategy { + const stepOne = createActionNode(experimentIterateIdThenReceiveInMethod(), { + successNode: null, + failureNode: null, + }); + + const params: ActionStrategyParameters = { + topic: iterateIdThenAddToDataTopic, + initialNode: stepOne, + }; + + return createStrategy(params); +} \ No newline at end of file diff --git a/src/model/actionStrategy.ts b/src/model/actionStrategy.ts index 7be0008..a0fc022 100644 --- a/src/model/actionStrategy.ts +++ b/src/model/actionStrategy.ts @@ -240,6 +240,7 @@ export const strategySuccess = (_strategy: ActionStrategy, data?: Record) { const strategy = {..._strategy}; let nextAction: Action; const actionListEntry = createSentence( @@ -310,6 +311,7 @@ export function strategyFailed(_strategy: ActionStrategy, data?: unknown) { conclude.action.strategy = { ...strategy, currentNode: conclude, + data: data ? data : strategy.data }; return conclude.action; } @@ -388,6 +390,7 @@ export const strategyDecide = ( conclude.action.strategy = { ...strategy, currentNode: conclude, + data: data ? data : strategy.data }; return conclude.action; }; diff --git a/src/model/actionStrategyData.ts b/src/model/actionStrategyData.ts index 4cf85a4..e46f670 100644 --- a/src/model/actionStrategyData.ts +++ b/src/model/actionStrategyData.ts @@ -59,13 +59,14 @@ export const strategyData_select = (strategy: ActionStrategy): T | undefined } }; -export const strategyData_unifyData = (strategy: ActionStrategy, data: Record): Record => { - if (strategy.data) { - return { - ...strategy.data, - ...data - }; - } else { - return {...data}; - } -}; \ No newline at end of file +export const strategyData_unifyData = + >(strategy: ActionStrategy, data: Record | T): Record => { + if (strategy.data) { + return { + ...strategy.data, + ...data + }; + } else { + return {...data}; + } + }; \ No newline at end of file diff --git a/src/model/method.ts b/src/model/method.ts index e732745..9c06bec 100644 --- a/src/model/method.ts +++ b/src/model/method.ts @@ -38,12 +38,12 @@ export const createMethod = return [defaultMethod, defaultSubject]; }; export const createMethodWithConcepts = - (method: (action: Action) => Action, concepts$: UnifiedSubject): [Method, Subject] => { + (methodWithConcepts: (action: Action, concepts: Concept[]) => Action, concepts$: UnifiedSubject): [Method, Subject] => { const defaultSubject = new Subject(); const defaultMethod: Method = defaultSubject.pipe( withLatestFrom(concepts$ as UnifiedSubject), map(([act, concepts] : [Action, Concept[]]) => { - const methodAction = method(act); + const methodAction = methodWithConcepts(act, concepts); if (methodAction.strategy) { return methodAction; } @@ -71,10 +71,9 @@ export const createAsyncMethodWithConcepts = const defaultSubject = new Subject(); const defaultMethod: Method = defaultSubject.pipe( withLatestFrom(concepts$ as UnifiedSubject), - switchMap(([act, concepts] : [Action, Concept[]]) => - createActionController$(act, (controller: ActionController, action: Action) => { - asyncMethodWithConcepts(controller, action, concepts); - })), + switchMap(([act, concepts] : [Action, Concept[]]) => createActionController$(act, (controller: ActionController, action: Action) => { + asyncMethodWithConcepts(controller, action, concepts); + })), ); return [defaultMethod, defaultSubject]; }; diff --git a/src/test/debounceMethods.test.ts b/src/test/debounceMethods.test.ts index 3a0318d..b9f1cee 100644 --- a/src/test/debounceMethods.test.ts +++ b/src/test/debounceMethods.test.ts @@ -1,13 +1,18 @@ +import { axiumSelectLastStrategy, axiumSelectLastStrategyData } from '../concepts/axium/axium.selector'; import { axiumKick } from '../concepts/axium/qualities/kick.quality'; import { Counter, counterName, createCounterConcept } from '../concepts/counter/counter.concept'; -import { createExperimentConcept, createExperimentState } from '../concepts/experiment/experiment.concept'; +import { ExperimentState, createExperimentConcept, createExperimentState, experimentName } from '../concepts/experiment/experiment.concept'; +import { experimentDebounceAsyncIterateIdThenReceiveInMethodQuality } from '../concepts/experiment/qualities/debounceAsyncIterateIdThenReceiveInMethod.quality copy 2'; import { asyncDebounceNextActionNodeQuality } from '../concepts/experiment/qualities/debounceAsyncNextActionNode.quality'; +import { DebounceIterateIdThenReceiveInMethodPayload, experimentDebounceIterateIdThenReceiveInMethodQuality } from '../concepts/experiment/qualities/debounceIterateIdThenReceiveInMethod.quality'; import { debounceNextActionNodeQuality } from '../concepts/experiment/qualities/debounceNextActionNode.quality'; import { experimentAsyncDebounceAddOneStrategy } from '../concepts/experiment/strategies/asyncDebounceAddOne.strategy'; import { experimentDebounceAddOneStrategy } from '../concepts/experiment/strategies/debounceAddOne.strategy'; +import { debounceAsyncIterateIdThenAddToData, debounceAsyncIterateIdThenAddToDataTopic } from '../concepts/experiment/strategies/debounceAsyncIterateIdThenAddToData.strategy'; +import { debounceIterateIdThenAddToData, debounceIterateIdThenAddToDataTopic } from '../concepts/experiment/strategies/debounceIterateIdThenAddToData.strategy copy'; import { strategyBegin } from '../model/actionStrategy'; import { createAxium } from '../model/axium'; -import { selectState } from '../model/selector'; +import { selectSlice, selectState } from '../model/selector'; test('Debounce method prevent excess count', (done) => { const experiment = createExperimentConcept(createExperimentState(), [debounceNextActionNodeQuality]); @@ -104,4 +109,98 @@ test('Async debounce method prevent excess count', (done) => { // Downside of halting quality. axium.dispatch(axiumKick()); }, 1000); +}); + +test('Debounce Method Test with Concepts id comparison', (done) => { + const experiment = createExperimentConcept(createExperimentState(), [experimentDebounceIterateIdThenReceiveInMethodQuality]); + const axium = createAxium('Experiment observe how concepts updates via reducer and method', [experiment]); + const plan = axium.stage('Debounce Iterate id with concepts', [ + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + dispatch(strategyBegin(debounceIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Debounce: ', experimentState.id, lastStrategy, data); + dispatch(strategyBegin(debounceIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Debounce: ', experimentState.id, lastStrategy, data); + dispatch(strategyBegin(debounceIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, _) => { + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const experimentState = selectState(concepts, experimentName); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Debounce: ', experimentState.id, lastStrategy, data); + if (lastStrategy === debounceIterateIdThenAddToDataTopic) { + if (data) { + console.log('Strategy Data: ', data, 'Experiment State ID: ', experimentState.id); + expect(data.id).toBe(3); + expect(data.setId).toBe(2); + expect(experimentState.id).toBe(3); + plan.conclude(); + done(); + } + } + } + ]); +}); + +test('Debounce Async Method Test with Concepts id comparison', (done) => { + const experiment = createExperimentConcept(createExperimentState(), [experimentDebounceAsyncIterateIdThenReceiveInMethodQuality]); + const axium = createAxium('Experiment observe how concepts updates via reducer and method', [experiment]); + const plan = axium.stage('Debounce Async Iterate id with concepts', [ + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + dispatch(strategyBegin(debounceAsyncIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Async Debounce: ', experimentState.id, lastStrategy, data); + dispatch(strategyBegin(debounceAsyncIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, dispatch) => { + const experimentState = selectState(concepts, experimentName); + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Async Debounce: ', experimentState.id, lastStrategy, data); + dispatch(strategyBegin(debounceAsyncIterateIdThenAddToData(experimentState.id)), { + iterateStage: true + }); + }, + (concepts, _) => { + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const experimentState = selectState(concepts, experimentName); + const data = selectSlice(concepts, axiumSelectLastStrategyData); + console.log('Async Debounce: ', experimentState.id, lastStrategy, data); + if (lastStrategy === debounceAsyncIterateIdThenAddToDataTopic) { + if (data) { + console.log('Strategy Data: ', data, 'Experiment State ID: ', experimentState.id); + expect(data.id).toBe(3); + expect(data.setId).toBe(2); + expect(experimentState.id).toBe(3); + plan.conclude(); + done(); + } + } + } + ]); }); \ No newline at end of file diff --git a/src/test/methodHelpers.test.ts b/src/test/methodHelpers.test.ts index 07b5caa..b2794b9 100644 --- a/src/test/methodHelpers.test.ts +++ b/src/test/methodHelpers.test.ts @@ -1,8 +1,17 @@ import { axiumSelectLastStrategy, axiumSelectLastStrategyData } from '../concepts/axium/axium.selector'; import { ExperimentState, createExperimentConcept, createExperimentState, experimentName } from '../concepts/experiment/experiment.concept'; +import { + experimentAsyncIterateIdThenReceiveInMethodQuality +} from '../concepts/experiment/qualities/asyncIterateIdThenReceiveInMethod.quality copy'; +import { experimentIterateIdThenReceiveInMethodQuality } from '../concepts/experiment/qualities/iterateIdThenReceiveInMethod.quality'; import { mockToTrueQuality } from '../concepts/experiment/qualities/mockTrue.quality'; import { timerEmitActionQuality } from '../concepts/experiment/qualities/timerEmitAction.quality'; import { timerEmitActionWithConceptsQuality } from '../concepts/experiment/qualities/timerEmitActionWithConcepts.quality'; +import { + asyncIterateIdThenAddToData, + asyncIterateIdThenAddToDataTopic +} from '../concepts/experiment/strategies/asyncIterateIdThenAddToData.strategy'; +import { iterateIdThenAddToData, iterateIdThenAddToDataTopic } from '../concepts/experiment/strategies/iterateIdThenAddToData.strategy'; import { timedMockToTrue } from '../concepts/experiment/strategies/timedMockToTrue.strategy'; import { timedMockToTrueWithConcepts, @@ -12,7 +21,7 @@ import { strategyBegin } from '../model/actionStrategy'; import { createAxium } from '../model/axium'; import { selectSlice, selectState } from '../model/selector'; -test('ActionController async Method Test', (done) => { +test('Async Method Test', (done) => { const experiment = createExperimentConcept(createExperimentState(), [timerEmitActionQuality, mockToTrueQuality]); const axium = createAxium('Experiment async method creator', [experiment]); const plan = axium.stage('timed mock to true', [ @@ -32,7 +41,7 @@ test('ActionController async Method Test', (done) => { ]); }); -test('ActionController async Method Test with Concepts', (done) => { +test('Async Method with Concepts Test', (done) => { const experiment = createExperimentConcept(createExperimentState(), [timerEmitActionWithConceptsQuality, mockToTrueQuality]); const axium = createAxium('Experiment async method creator with Concepts', [experiment]); const plan = axium.stage('timed mock to true', [ @@ -56,3 +65,56 @@ test('ActionController async Method Test with Concepts', (done) => { } ]); }); + +test('Method Test with Concepts id comparison', (done) => { + const experiment = createExperimentConcept(createExperimentState(), [experimentIterateIdThenReceiveInMethodQuality]); + const axium = createAxium('Experiment observe how concepts updates via reducer and method', [experiment]); + const plan = axium.stage('Iterate id', [ + (_, dispatch) => { + dispatch(strategyBegin(iterateIdThenAddToData()), { + iterateStage: true + }); + }, + (concepts, _) => { + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const experimentState = selectState(concepts, experimentName); + if (lastStrategy === iterateIdThenAddToDataTopic) { + const data = selectSlice(concepts, axiumSelectLastStrategyData); + if (data) { + console.log('Strategy Data: ', data.id, 'Experiment State ID: ', experimentState.id); + expect(data.id).toBe(0); + expect(experimentState.id).toBe(1); + plan.conclude(); + done(); + } + } + } + ]); +}); + +test('Async Method Test with Concepts id comparison', (done) => { + const experiment = createExperimentConcept(createExperimentState(), [experimentAsyncIterateIdThenReceiveInMethodQuality]); + const axium = createAxium('Experiment observe how concepts updates via reducer and method', [experiment]); + const plan = axium.stage('Iterate id', [ + (_, dispatch) => { + dispatch(strategyBegin(asyncIterateIdThenAddToData()), { + iterateStage: true + }); + }, + (concepts, _) => { + const lastStrategy = selectSlice(concepts, axiumSelectLastStrategy); + const experimentState = selectState(concepts, experimentName); + console.log('PING', experimentState); + if (lastStrategy === asyncIterateIdThenAddToDataTopic) { + const data = selectSlice(concepts, axiumSelectLastStrategyData); + if (data) { + console.log('Async Strategy Data: ', data.id, 'Experiment State ID: ', experimentState.id); + expect(data.id).toBe(1); + expect(experimentState.id).toBe(1); + plan.conclude(); + done(); + } + } + } + ]); +}); \ No newline at end of file