Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add resetCache, with more tests (#4)
* Add resetCache * More tests
- Loading branch information
Showing
9 changed files
with
222 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { createDynamicSelector } from '../src'; | ||
import DebugInfoCheckUtil from './util/debugInfoCheckUtil'; | ||
|
||
describe('freeze result', () => { | ||
test('sorted array', () => { | ||
const sortedArraySelector = createDynamicSelector((getState) => { | ||
const rawArray = getState('list'); | ||
return [...rawArray].sort((a, b) => a - b); | ||
}); | ||
const checkSortedArraySelector = new DebugInfoCheckUtil(sortedArraySelector); | ||
|
||
let state = { list: [1, 4, 7, 3, 2, 6, 9, 8, 5] }; | ||
|
||
const result1 = sortedArraySelector(state); | ||
expect(result1).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); | ||
checkSortedArraySelector.expectInvoked('run'); | ||
|
||
// Same state, really, but this will cause a rerun | ||
state = { list: [1, 4, 7, 3, 2, 6, 9, 8, 5] }; | ||
|
||
const result2 = sortedArraySelector(state); | ||
expect(result2).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); | ||
expect(result2).toStrictEqual(result1); | ||
checkSortedArraySelector.expectInvoked('phantom'); | ||
|
||
// Once more, with a genuinely different input | ||
state = { list: [6, 9, 1, 4, 7, 3, 8, 5, 2] }; | ||
|
||
const result3 = sortedArraySelector(state); | ||
expect(result3).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); | ||
expect(result3).toStrictEqual(result1); | ||
checkSortedArraySelector.expectInvoked('phantom'); | ||
}); | ||
|
||
test('recovery after exception', () => { | ||
const sortedArraySelector = createDynamicSelector( | ||
(getState) => { | ||
const rawArray = getState('list'); | ||
return [...rawArray].sort((a, b) => a - b); | ||
}, | ||
{ | ||
onError: () => [], | ||
}, | ||
); | ||
const checkSortedArraySelector = new DebugInfoCheckUtil(sortedArraySelector); | ||
|
||
let state: any = { list: [] }; | ||
|
||
const result1 = sortedArraySelector(state); | ||
expect(result1).toEqual([]); | ||
checkSortedArraySelector.expectInvoked('run'); | ||
|
||
// Oops, we can't sort a nonexistent value | ||
state = {}; | ||
|
||
// But it's ok: onError recovers with an empty array, which is still detected as a phantom run | ||
const result2 = sortedArraySelector(state); | ||
expect(result2).toEqual([]); | ||
expect(result2).toStrictEqual(result1); | ||
checkSortedArraySelector.expectInvoked('aborted'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { createDynamicSelector, DynamicSelectorFn } from '../src'; | ||
import DebugInfoCheckUtil from './util/debugInfoCheckUtil'; | ||
|
||
describe('recursion', () => { | ||
test('Fibonacci(3)', () => { | ||
const fibonacciSelector: DynamicSelectorFn = createDynamicSelector((_getState, num: number) => { | ||
if (num < 1) { | ||
return 0; | ||
} else if (num === 1) { | ||
return 1; | ||
} | ||
return fibonacciSelector(num - 1) + fibonacciSelector(num - 2); | ||
}); | ||
|
||
const fibonacciSelectorCheck1 = new DebugInfoCheckUtil(fibonacciSelector, 1); | ||
const fibonacciSelectorCheck2 = new DebugInfoCheckUtil(fibonacciSelector, 2); | ||
const fibonacciSelectorCheck3 = new DebugInfoCheckUtil(fibonacciSelector, 3); | ||
|
||
let state = {}; | ||
|
||
expect(fibonacciSelector(state, 3)).toEqual(2); | ||
|
||
fibonacciSelectorCheck3.expectInvoked('run'); | ||
fibonacciSelectorCheck2.expectInvoked('run'); | ||
fibonacciSelectorCheck1.expectMultiple([ | ||
['invoked', 'run'], | ||
['invoked', 'skipped'], | ||
]); | ||
}); | ||
|
||
test('Fibonacci(6)', () => { | ||
const fibonacciSelector: DynamicSelectorFn = createDynamicSelector((_getState, num: number) => { | ||
if (num < 1) { | ||
return 0; | ||
} else if (num === 1) { | ||
return 1; | ||
} | ||
return fibonacciSelector(num - 1) + fibonacciSelector(num - 2); | ||
}); | ||
|
||
const fibonacciSelectorCheck1 = new DebugInfoCheckUtil(fibonacciSelector, 1); | ||
const fibonacciSelectorCheck2 = new DebugInfoCheckUtil(fibonacciSelector, 2); | ||
const fibonacciSelectorCheck3 = new DebugInfoCheckUtil(fibonacciSelector, 3); | ||
const fibonacciSelectorCheck4 = new DebugInfoCheckUtil(fibonacciSelector, 4); | ||
const fibonacciSelectorCheck5 = new DebugInfoCheckUtil(fibonacciSelector, 5); | ||
const fibonacciSelectorCheck6 = new DebugInfoCheckUtil(fibonacciSelector, 6); | ||
|
||
let state = {}; | ||
|
||
expect(fibonacciSelector(state, 6)).toEqual(8); | ||
|
||
// Because of the caching, none will be called more than twice | ||
fibonacciSelectorCheck6.expectInvoked('run'); | ||
fibonacciSelectorCheck5.expectInvoked('run'); | ||
fibonacciSelectorCheck4.expectMultiple([ | ||
['invoked', 'run'], | ||
['invoked', 'skipped'], | ||
]); | ||
fibonacciSelectorCheck3.expectMultiple([ | ||
['invoked', 'run'], | ||
['invoked', 'skipped'], | ||
]); | ||
fibonacciSelectorCheck2.expectMultiple([ | ||
['invoked', 'run'], | ||
['invoked', 'skipped'], | ||
]); | ||
fibonacciSelectorCheck1.expectMultiple([ | ||
['invoked', 'run'], | ||
['invoked', 'skipped'], | ||
]); | ||
}); | ||
}); |