From 49096b1959d54dacbea9baf6528c0132bc0b307a Mon Sep 17 00:00:00 2001 From: Evyatar Date: Sat, 14 May 2022 00:13:16 +0300 Subject: [PATCH] patch(vest): replace Cursor with IsolateCursor (#869) --- packages/shared/src/cursor.ts | 53 -------------- packages/vest/src/core/ctx/ctx.ts | 19 ++--- packages/vest/src/core/ctx/testCursor.ts | 27 -------- .../vest/src/core/isolate/IsolateTypes.ts | 8 +++ packages/vest/src/core/isolate/isolate.ts | 69 +++++++++++++++---- .../vest/src/core/isolate/isolateCursor.ts | 29 ++++++++ packages/vest/src/core/test/key.ts | 4 +- .../src/core/test/lib/registerPrevRunTest.ts | 13 ++-- .../vest/src/core/test/lib/useTestAtCursor.ts | 12 ++-- packages/vest/src/core/test/test.memo.ts | 4 +- tsconfig.json | 3 +- 11 files changed, 114 insertions(+), 127 deletions(-) delete mode 100644 packages/shared/src/cursor.ts delete mode 100644 packages/vest/src/core/ctx/testCursor.ts create mode 100644 packages/vest/src/core/isolate/isolateCursor.ts diff --git a/packages/shared/src/cursor.ts b/packages/shared/src/cursor.ts deleted file mode 100644 index 6cfe68bd8..000000000 --- a/packages/shared/src/cursor.ts +++ /dev/null @@ -1,53 +0,0 @@ -import asArray from 'asArray'; -import last from 'last'; - -export function createCursor(): Cursor { - const storage: { cursor: number[] } = { - cursor: [], - }; - - function addLevel(): void { - storage.cursor.push(0); - } - - function removeLevel(): void { - storage.cursor.pop(); - } - - function cursorAt(): number { - return last(storage.cursor); - } - - function getCursor(): number[] { - return asArray(storage.cursor); - } - - function next(): number { - storage.cursor[storage.cursor.length - 1]++; - return last(storage.cursor); - } - - function reset(): void { - storage.cursor = [0]; - } - - reset(); - - return { - addLevel, - cursorAt, - getCursor, - next, - removeLevel, - reset, - }; -} - -export type Cursor = { - addLevel: () => void; - cursorAt: () => number; - getCursor: () => number[]; - next: () => number; - removeLevel: () => void; - reset: () => void; -}; diff --git a/packages/vest/src/core/ctx/ctx.ts b/packages/vest/src/core/ctx/ctx.ts index c6dbedb4a..81d41dab6 100644 --- a/packages/vest/src/core/ctx/ctx.ts +++ b/packages/vest/src/core/ctx/ctx.ts @@ -1,13 +1,13 @@ import assign from 'assign'; import { createContext } from 'context'; -import { createCursor, Cursor } from 'cursor'; import { CB } from 'utilityTypes'; -import { IsolateKeys, IsolateTypes } from 'IsolateTypes'; +import { Isolate, IsolateTypes } from 'IsolateTypes'; import { Modes } from 'Modes'; import VestTest from 'VestTest'; import type { StateRef } from 'createStateRef'; import { SuiteSummary } from 'genTestsSummary'; +import { generateIsolate } from 'isolate'; export default createContext((ctxRef, parentContext) => parentContext @@ -20,26 +20,15 @@ export default createContext((ctxRef, parentContext) => groups: {}, }, inclusion: {}, - isolate: { - type: IsolateTypes.DEFAULT, - keys: { - current: {}, - prev: {}, - }, - }, + isolate: generateIsolate(IsolateTypes.DEFAULT), mode: [Modes.ALL], - testCursor: createCursor(), }, ctxRef ) ); type CTXType = { - isolate: { - type: IsolateTypes; - keys: IsolateKeys; - }; - testCursor: Cursor; + isolate: Isolate; stateRef?: StateRef; exclusion: { tests: Record; diff --git a/packages/vest/src/core/ctx/testCursor.ts b/packages/vest/src/core/ctx/testCursor.ts deleted file mode 100644 index 52f56737c..000000000 --- a/packages/vest/src/core/ctx/testCursor.ts +++ /dev/null @@ -1,27 +0,0 @@ -import ctx from 'ctx'; - -export function usePath(): number[] { - const context = ctx.useX(); - return context.testCursor.getCursor(); -} - -export function useCursorAt(): number { - const context = ctx.useX(); - return context.testCursor.cursorAt(); -} - -export function moveForward(): number { - const context = ctx.useX(); - - return context.testCursor.next(); -} - -export function addLevel(): void { - const context = ctx.useX(); - context.testCursor.addLevel(); -} - -export function removeLevel(): void { - const context = ctx.useX(); - context.testCursor.removeLevel(); -} diff --git a/packages/vest/src/core/isolate/IsolateTypes.ts b/packages/vest/src/core/isolate/IsolateTypes.ts index 1171e2032..0a92f7292 100644 --- a/packages/vest/src/core/isolate/IsolateTypes.ts +++ b/packages/vest/src/core/isolate/IsolateTypes.ts @@ -1,4 +1,5 @@ import VestTest from 'VestTest'; +import { IsolateCursor } from 'isolateCursor'; export enum IsolateTypes { DEFAULT, @@ -13,3 +14,10 @@ export type IsolateKeys = { current: Record; prev: Record; }; + +export type Isolate = { + type: IsolateTypes; + keys: IsolateKeys; + path: number[]; + cursor: IsolateCursor; +}; diff --git a/packages/vest/src/core/isolate/isolate.ts b/packages/vest/src/core/isolate/isolate.ts index bc79b4116..148225146 100644 --- a/packages/vest/src/core/isolate/isolate.ts +++ b/packages/vest/src/core/isolate/isolate.ts @@ -2,12 +2,13 @@ import invariant from 'invariant'; import isFunction from 'isFunction'; import * as nestedArray from 'nestedArray'; -import { IsolateKeys, IsolateTypes } from 'IsolateTypes'; +import { createIsolateCursor, IsolateCursor } from './isolateCursor'; + +import { Isolate, IsolateTypes } from 'IsolateTypes'; import VestTest from 'VestTest'; import ctx from 'ctx'; import { usePrevKeys } from 'key'; import { useSetTests } from 'stateHooks'; -import * as testCursor from 'testCursor'; export function isolate( { type = IsolateTypes.DEFAULT }: { type?: IsolateTypes }, @@ -15,26 +16,64 @@ export function isolate( ): VestTest[] | void { invariant(isFunction(callback)); - const keys: IsolateKeys = { - current: {}, - prev: {}, - }; - - const path = testCursor.usePath(); - return ctx.run({ isolate: { type, keys } }, () => { - testCursor.addLevel(); + // Generate a new Isolate layer, with its own cursor + const isolate = generateIsolate(type, useCurrentPath()); - keys.prev = usePrevKeys(); + const output = ctx.run({ isolate }, () => { + isolate.keys.prev = usePrevKeys(); - useSetTests(tests => nestedArray.setValueAtPath(tests, path, [])); + useSetTests(tests => nestedArray.setValueAtPath(tests, isolate.path, [])); const res = callback(); - testCursor.removeLevel(); - testCursor.moveForward(); return res; }); + + // Move the parent cursor forward once we're done + useCursor().next(); + + return output; +} + +/** + * @returns {Isolate} The current isolate layer + */ +export function useIsolate(): Isolate { + return ctx.useX().isolate; } -export function shouldAllowReorder() { +/** + * @returns {boolean} Whether or not the current isolate allows tests to be reordered + */ +export function shouldAllowReorder(): boolean { return ctx.useX().isolate.type === IsolateTypes.EACH; } + +/** + * @returns {number[]} The current cursor path of the isolate tree + */ +export function useCurrentPath(): number[] { + const isolate = useIsolate(); + return isolate.path.concat(isolate.cursor.current()); +} + +/** + * @returns {IsolateCursor} The cursor object for the current isolate + */ +export function useCursor(): IsolateCursor { + return useIsolate().cursor; +} + +export function generateIsolate( + type: IsolateTypes, + path: number[] = [] +): Isolate { + return { + cursor: createIsolateCursor(), + keys: { + current: {}, + prev: {}, + }, + path, + type, + }; +} diff --git a/packages/vest/src/core/isolate/isolateCursor.ts b/packages/vest/src/core/isolate/isolateCursor.ts new file mode 100644 index 000000000..996958590 --- /dev/null +++ b/packages/vest/src/core/isolate/isolateCursor.ts @@ -0,0 +1,29 @@ +export function createIsolateCursor(): IsolateCursor { + const cursor = { + value: 0, + }; + + return { + current, + next, + }; + + /** + * @returns {number} The current value of the cursor + */ + function current(): number { + return cursor.value; + } + + /** + * Moves the isolate cursor forward by 1 + */ + function next(): void { + cursor.value++; + } +} + +export type IsolateCursor = { + current: () => number; + next: () => void; +}; diff --git a/packages/vest/src/core/test/key.ts b/packages/vest/src/core/test/key.ts index 6118ceaf4..50f260486 100644 --- a/packages/vest/src/core/test/key.ts +++ b/packages/vest/src/core/test/key.ts @@ -5,13 +5,13 @@ import { deferThrow } from 'throwError'; import VestTest from 'VestTest'; import ctx from 'ctx'; +import { useCurrentPath } from 'isolate'; import { useTestObjects } from 'stateHooks'; -import * as testCursor from 'testCursor'; export function usePrevKeys(): Record { const [{ prev }] = useTestObjects(); - return asArray(nestedArray.getCurrent(prev, testCursor.usePath())).reduce( + return asArray(nestedArray.getCurrent(prev, useCurrentPath())).reduce( (prevKeys, testObject) => { if (!(testObject instanceof VestTest)) { return prevKeys; diff --git a/packages/vest/src/core/test/lib/registerPrevRunTest.ts b/packages/vest/src/core/test/lib/registerPrevRunTest.ts index fb0cb67bb..00bac2127 100644 --- a/packages/vest/src/core/test/lib/registerPrevRunTest.ts +++ b/packages/vest/src/core/test/lib/registerPrevRunTest.ts @@ -3,20 +3,23 @@ import isPromise from 'isPromise'; import VestTest from 'VestTest'; import cancelOverriddenPendingTest from 'cancelOverriddenPendingTest'; import { isExcluded } from 'exclusive'; +import { useCursor } from 'isolate'; import { shouldSkipBasedOnMode } from 'mode'; import { isOmitted } from 'omitWhen'; import registerTest from 'registerTest'; import runAsyncTest from 'runAsyncTest'; import { isExcludedIndividually } from 'skipWhen'; -import * as testCursor from 'testCursor'; import { useTestAtCursor, useSetTestAtCursor } from 'useTestAtCursor'; // eslint-disable-next-line max-statements export default function registerPrevRunTest(testObject: VestTest): VestTest { + const cursor = useCursor(); + if (shouldSkipBasedOnMode(testObject)) { testObject.skip(); useTestAtCursor(testObject); - testCursor.moveForward(); + + cursor.next(); return testObject; } @@ -24,7 +27,7 @@ export default function registerPrevRunTest(testObject: VestTest): VestTest { if (isOmitted()) { prevRunTest.omit(); - testCursor.moveForward(); + cursor.next(); return prevRunTest; } @@ -34,16 +37,16 @@ export default function registerPrevRunTest(testObject: VestTest): VestTest { // This mostly means that we're probably giving // up on this async test intentionally. prevRunTest.skip(isExcludedIndividually()); - testCursor.moveForward(); + cursor.next(); return prevRunTest; } cancelOverriddenPendingTest(prevRunTest, testObject); useSetTestAtCursor(testObject); - testCursor.moveForward(); registerTestObjectByTier(testObject); + cursor.next(); return testObject; } diff --git a/packages/vest/src/core/test/lib/useTestAtCursor.ts b/packages/vest/src/core/test/lib/useTestAtCursor.ts index 54a0d411c..ba2ca2d38 100644 --- a/packages/vest/src/core/test/lib/useTestAtCursor.ts +++ b/packages/vest/src/core/test/lib/useTestAtCursor.ts @@ -7,10 +7,9 @@ import { deferThrow } from 'throwError'; import VestTest from 'VestTest'; import isSameProfileTest from 'isSameProfileTest'; -import { shouldAllowReorder } from 'isolate'; +import { shouldAllowReorder, useCurrentPath, useCursor } from 'isolate'; import { usePrevTestByKey, useRetainTestKey } from 'key'; import { useTestObjects, useSetTests } from 'stateHooks'; -import * as testCursor from 'testCursor'; /** * This module serves as the "collision detection" mechanism for Vest. @@ -59,8 +58,9 @@ function removeAllNextTestsInIsolate() { const [testObjects, setTestObjects] = useTestObjects(); const prevTests = testObjects.prev; - const current = nestedArray.getCurrent(prevTests, testCursor.usePath()); - const cursorAt = testCursor.useCursorAt(); + const current = nestedArray.getCurrent(prevTests, useCurrentPath()); + const cursorAt = useCursor().current(); + current.splice(cursorAt); // We actually don't mind mutating the state directly (as can be seen above). There is no harm in it // since we're only touching the "prev" state. The reason we still use the setter function is @@ -72,7 +72,7 @@ function removeAllNextTestsInIsolate() { } export function useSetTestAtCursor(testObject: VestTest): void { - const cursorPath = testCursor.usePath(); + const cursorPath = useCurrentPath(); useSetTests(tests => nestedArray.setValueAtPath(tests, cursorPath, testObject) @@ -80,7 +80,7 @@ export function useSetTestAtCursor(testObject: VestTest): void { } function useGetTestAtCursor(tests: NestedArray): VestTest { - const cursorPath = testCursor.usePath(); + const cursorPath = useCurrentPath(); return nestedArray.valueAtPath(tests, cursorPath) as VestTest; } diff --git a/packages/vest/src/core/test/test.memo.ts b/packages/vest/src/core/test/test.memo.ts index 0f0ba9a7a..013aa1483 100644 --- a/packages/vest/src/core/test/test.memo.ts +++ b/packages/vest/src/core/test/test.memo.ts @@ -3,10 +3,10 @@ import createCache from 'cache'; import { isNull } from 'isNull'; import VestTest, { TestFn } from 'VestTest'; +import { useCursor } from 'isolate'; import registerPrevRunTest from 'registerPrevRunTest'; import { useSuiteId } from 'stateHooks'; import type { TestBase } from 'test'; -import * as testCursor from 'testCursor'; // eslint-disable-next-line max-lines-per-function export default function bindTestMemo(test: TestBase): { (fieldName: string, test: TestFn, deps: unknown[]): VestTest; @@ -32,7 +32,7 @@ export default function bindTestMemo(test: TestBase): { | [message: string, test: TestFn, deps: unknown[]] | [test: TestFn, deps: unknown[]] ): VestTest { - const cursorAt = testCursor.useCursorAt(); + const cursorAt = useCursor().current(); const [deps, testFn, msg] = args.reverse() as [any[], TestFn, string]; diff --git a/tsconfig.json b/tsconfig.json index 5f570f30e..f1639bda7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -97,7 +97,6 @@ "bus": ["./packages/shared/src/bus.ts"], "cache": ["./packages/shared/src/cache.ts"], "callEach": ["./packages/shared/src/callEach.ts"], - "cursor": ["./packages/shared/src/cursor.ts"], "defaultTo": ["./packages/shared/src/defaultTo.ts"], "either": ["./packages/shared/src/either.ts"], "genId": ["./packages/shared/src/genId.ts"], @@ -120,8 +119,8 @@ "utilityTypes": ["./packages/shared/src/utilityTypes.ts"], "vast": ["./packages/vast/src/vast.ts"], "ctx": ["./packages/vest/src/core/ctx/ctx.ts"], - "testCursor": ["./packages/vest/src/core/ctx/testCursor.ts"], "isolate": ["./packages/vest/src/core/isolate/isolate.ts"], + "isolateCursor": ["./packages/vest/src/core/isolate/isolateCursor.ts"], "each": ["./packages/vest/src/core/isolate/isolates/each.ts"], "group": ["./packages/vest/src/core/isolate/isolates/group.ts"], "omitWhen": ["./packages/vest/src/core/isolate/isolates/omitWhen.ts"],