Skip to content

Commit

Permalink
patch(vest): add cache invalidation for canceled tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed Nov 10, 2021
1 parent 4cb2c6c commit 8730e25
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
packages/*/types/
packages/vest/classnames/
packages/vest/promisify/
packages/vest/parser/
packages/anyone/all/
packages/anyone/any/
packages/anyone/none/
Expand Down
10 changes: 10 additions & 0 deletions packages/shared/src/__tests__/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,14 @@ describe('lib: cache', () => {
});
});
});

describe('cache.invalidate', () => {
it('Should remove cached item from cache storage by its dependcies', () => {
const deps = [1, 2, 3];
c(deps, Math.random);
expect(c.get(deps)).not.toBeNull();
c.invalidate(deps);
expect(c.get(deps)).toBeNull();
});
});
});
24 changes: 13 additions & 11 deletions packages/shared/src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ import { lengthEquals } from 'lengthEquals';
export default function createCache(maxSize = 10): {
<T>(deps: unknown[], cacheAction: (...args: unknown[]) => T): T;
get(deps: unknown[]): any;
invalidate(item: any): void;
} {
const cacheStorage: Array<[unknown[], any]> = [];

/**
* @param {any[]} deps dependency array.
* @param {Function} cache action function.
*/
const cache = <T>(
deps: unknown[],
cacheAction: (...args: unknown[]) => T
Expand All @@ -24,17 +21,22 @@ export default function createCache(maxSize = 10): {
const result = cacheAction();
cacheStorage.unshift([deps.concat(), result]);

if (cacheStorage.length > maxSize) {
cacheStorage.length = maxSize;
}
if (cacheStorage.length > maxSize) cacheStorage.length = maxSize;

return result;
};

/**
* Retrieves an item from the cache.
* @param {deps} deps Dependency array
*/
// invalidate an item in the cache by its dependencies
cache.invalidate = (deps: any[]): void => {
const index = cacheStorage.findIndex(
([cachedDeps]) =>
lengthEquals(deps, cachedDeps.length) &&
deps.every((dep, i) => dep === cachedDeps[i])
);
if (index > -1) cacheStorage.splice(index, 1);
};

// Retrieves an item from the cache.
cache.get = (deps: unknown[]): [unknown[], any] | null =>
cacheStorage[
cacheStorage.findIndex(
Expand Down
7 changes: 7 additions & 0 deletions packages/vest/parser/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"main": "../dist/cjs/parser.js",
"module": "../dist/es/parser.production.js",
"name": "parser",
"types": "../types/parser.d.ts",
"private": true
}
31 changes: 31 additions & 0 deletions packages/vest/src/core/test/__tests__/memo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,37 @@ describe('test.memo', () => {
}
});
});

describe('Test is canceled', () => {
it('Should refresh', async () => {
let count = 0;
const tests = [];
const suite = vest.create(() => {
count++;

tests.push(
vestTest.memo(
'f1',
async () => {
await wait(10);
},
[true]
)
);

if (count === 1) {
tests[0].cancel();
}
});

suite();
suite();
suite();

expect(tests[0]).not.toBe(tests[1]);
expect(tests[1]).toBe(tests[2]);
});
});
});

describe('cache miss', () => {
Expand Down
11 changes: 8 additions & 3 deletions packages/vest/src/core/test/test.memo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ export default function bindTestMemo(test: TTestBase): {
} {
const cache = createCache(100); // arbitrary cache size

/**
* Caches, or returns an already cached test call
*/
// Caches, or returns an already cached test call
function memo(
fieldName: string,
...args: [test: TTestFn, deps: unknown[]]
Expand All @@ -28,6 +26,7 @@ export default function bindTestMemo(test: TTestBase): {
fieldName: string,
...args: [message: string, test: TTestFn, deps: unknown[]]
): VestTest;
// eslint-disable-next-line max-statements
function memo(
fieldName: string,
...args:
Expand All @@ -49,6 +48,12 @@ export default function bindTestMemo(test: TTestBase): {
return cache(dependencies, () => test(fieldName, msg, testFn));
}

if (cached[1].isCanceled()) {
// cache hit, but test is canceled
cache.invalidate(dependencies);
return cache(dependencies, () => test(fieldName, msg, testFn));
}

return registerPrevRunTest(cached[1]);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/hooks/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import context from 'ctx';
/**
* Runs a group callback.
*/
export default function group(groupName: string, tests: () => any): void {
export default function group(groupName: string, tests: () => void): void {
if (!isStringValue(groupName)) {
throwGroupError('name must be a string');
}
Expand Down

0 comments on commit 8730e25

Please sign in to comment.