diff --git a/packages/vest-utils/src/freezeAssign.ts b/packages/vest-utils/src/freezeAssign.ts new file mode 100644 index 000000000..7bf3db39a --- /dev/null +++ b/packages/vest-utils/src/freezeAssign.ts @@ -0,0 +1,5 @@ +import assign from 'assign'; + +export function freezeAssign(...args: Partial[]): T { + return Object.freeze(assign({}, ...args)); +} diff --git a/packages/vest-utils/src/vest-utils.ts b/packages/vest-utils/src/vest-utils.ts index c612309ab..1037e62f0 100644 --- a/packages/vest-utils/src/vest-utils.ts +++ b/packages/vest-utils/src/vest-utils.ts @@ -41,6 +41,7 @@ export * as tinyState from 'tinyState'; export { StringObject } from 'StringObject'; export { noop } from 'noop'; export * as Predicates from 'Predicates'; +export { freezeAssign } from 'freezeAssign'; export type { DropFirst, diff --git a/packages/vest-utils/tsconfig.json b/packages/vest-utils/tsconfig.json index 6a9181eb1..dd8b8f85a 100644 --- a/packages/vest-utils/tsconfig.json +++ b/packages/vest-utils/tsconfig.json @@ -35,6 +35,7 @@ "hasOwnProperty": ["./src/hasOwnProperty.ts"], "greaterThan": ["./src/greaterThan.ts"], "globals.d": ["./src/globals.d.ts"], + "freezeAssign": ["./src/freezeAssign.ts"], "either": ["./src/either.ts"], "deferThrow": ["./src/deferThrow.ts"], "defaultTo": ["./src/defaultTo.ts"], diff --git a/packages/vest/src/exports/debounce.ts b/packages/vest/src/exports/debounce.ts index 85e82abd2..b185d1721 100644 --- a/packages/vest/src/exports/debounce.ts +++ b/packages/vest/src/exports/debounce.ts @@ -1,8 +1,8 @@ -import { registerReconciler } from 'vest'; import { CB, isPromise, Nullable } from 'vest-utils'; import { Isolate, TIsolate, IsolateSelectors } from 'vestjs-runtime'; import { TestFn, TestFnPayload } from 'TestTypes'; +import { registerReconciler } from 'vest'; const isolateType = 'Debounce'; diff --git a/packages/vest/src/exports/parser.ts b/packages/vest/src/exports/parser.ts index 5a0b90e0d..f31e52093 100644 --- a/packages/vest/src/exports/parser.ts +++ b/packages/vest/src/exports/parser.ts @@ -1,15 +1,15 @@ -import { suiteSelectors } from 'vest'; import { hasOwnProperty, invariant, isNullish, isPositive } from 'vest-utils'; import { ErrorStrings } from 'ErrorStrings'; import { SuiteSummary, TFieldName, TGroupName } from 'SuiteResultTypes'; +import { suiteSelectors } from 'vest'; export function parse( - summary: SuiteSummary + summary: SuiteSummary, ): ParsedVestObject { invariant( summary && hasOwnProperty(summary, 'valid'), - ErrorStrings.PARSER_EXPECT_RESULT_OBJECT + ErrorStrings.PARSER_EXPECT_RESULT_OBJECT, ); const sel = suiteSelectors(summary); diff --git a/packages/vest/src/suite/__tests__/staticSuite.test.ts b/packages/vest/src/suite/__tests__/staticSuite.test.ts index 4102af189..bb9f5766f 100644 --- a/packages/vest/src/suite/__tests__/staticSuite.test.ts +++ b/packages/vest/src/suite/__tests__/staticSuite.test.ts @@ -1,3 +1,5 @@ +import wait from 'wait'; + import { SuiteSerializer } from 'SuiteSerializer'; import { VestIsolateType } from 'VestIsolateType'; import * as vest from 'vest'; @@ -139,4 +141,35 @@ describe('runStatic', () => { expect(suite2.hasErrors('t3')).toBe(false); expect(suite2.hasErrors('t4')).toBe(false); }); + + describe('runStatic.resolve', () => { + it("Should resolve with the suite's result", async () => { + const suite = vest.create(() => { + vest.test('t1', async () => { + await wait(100); + throw new Error(); + }); + }); + + const res = suite.runStatic(); + expect(res.errorCount).toBe(0); + expect(res).toHaveProperty('resolve'); + const result = await res.resolve(); + expect(result.errorCount).toBe(1); + }); + + it("Should have a dump method on the resolved suite's result", async () => { + const suite = vest.create(() => { + vest.test('t1', async () => { + await wait(100); + throw new Error(); + }); + }); + + const res = suite.runStatic(); + const result = await res.resolve(); + expect(result).toHaveProperty('dump'); + expect(result.dump()).toHaveProperty('$type', VestIsolateType.Suite); + }); + }); }); diff --git a/packages/vest/src/suite/createSuite.ts b/packages/vest/src/suite/createSuite.ts index 5c1a1fd5b..5dba9842f 100644 --- a/packages/vest/src/suite/createSuite.ts +++ b/packages/vest/src/suite/createSuite.ts @@ -1,4 +1,4 @@ -import { assign, CB } from 'vest-utils'; +import { assign, CB, freezeAssign } from 'vest-utils'; import { Bus, VestRuntime } from 'vestjs-runtime'; import { TTypedMethods, getTypedMethods } from './getTypedMethods'; @@ -9,6 +9,7 @@ import { useCreateVestState, useLoadSuite } from 'Runtime'; import { SuiteContext } from 'SuiteContext'; import { SuiteName, + SuiteResult, SuiteRunResult, TFieldName, TGroupName, @@ -154,14 +155,22 @@ function staticSuite< const result = suite(...args); - return Object.freeze( - assign( - { - dump: suite.dump, - }, - result, - ), - ) as StaticSuiteRunResult; + const resolve = new Promise>(resolve => { + result.done(res => { + resolve(withDump(res) as SuiteWithDump); + }); + }); + + return freezeAssign>( + withDump({ + resolve: () => resolve, + }), + result, + ); + + function withDump(o: any) { + return freezeAssign({ dump: suite.dump }, o); + } }, { ...getTypedMethods(), @@ -178,8 +187,15 @@ export type StaticSuite< export type StaticSuiteRunResult< F extends TFieldName = string, G extends TGroupName = string, -> = SuiteRunResult & { - dump: CB; -} & TTypedMethods; +> = WithDump< + SuiteRunResult & { + resolve: () => Promise>; + } & TTypedMethods +>; + +type WithDump = T & { dump: CB }; +type SuiteWithDump = WithDump< + SuiteResult +>; export { createSuite, staticSuite }; diff --git a/packages/vest/src/suiteResult/suiteResult.ts b/packages/vest/src/suiteResult/suiteResult.ts index 906a89081..76086110d 100644 --- a/packages/vest/src/suiteResult/suiteResult.ts +++ b/packages/vest/src/suiteResult/suiteResult.ts @@ -1,4 +1,4 @@ -import { assign } from 'vest-utils'; +import { freezeAssign } from 'vest-utils'; import { useSuiteName, useSuiteResultCache } from 'Runtime'; import { SuiteResult, TFieldName, TGroupName } from 'SuiteResultTypes'; @@ -7,7 +7,7 @@ import { useProduceSuiteSummary } from 'useProduceSuiteSummary'; export function useCreateSuiteResult< F extends TFieldName, - G extends TGroupName + G extends TGroupName, >(): SuiteResult { return useSuiteResultCache(() => { // @vx-allow use-use @@ -15,10 +15,12 @@ export function useCreateSuiteResult< // @vx-allow use-use const suiteName = useSuiteName(); - return Object.freeze( - assign(summary, suiteSelectors(summary), { + return freezeAssign>( + summary, + suiteSelectors(summary), + { suiteName, - }) + }, ) as SuiteResult; }); } diff --git a/packages/vest/src/suiteResult/suiteRunResult.ts b/packages/vest/src/suiteResult/suiteRunResult.ts index 393350e4d..e60a18566 100644 --- a/packages/vest/src/suiteResult/suiteRunResult.ts +++ b/packages/vest/src/suiteResult/suiteRunResult.ts @@ -1,4 +1,4 @@ -import { assign } from 'vest-utils'; +import { freezeAssign } from 'vest-utils'; import { VestRuntime } from 'vestjs-runtime'; import { @@ -14,15 +14,13 @@ import { useCreateSuiteResult } from 'suiteResult'; export function useSuiteRunResult< F extends TFieldName, - G extends TGroupName + G extends TGroupName, >(): SuiteRunResult { - return Object.freeze( - assign( - { - done: VestRuntime.persist(done), - }, - useCreateSuiteResult() - ) + return freezeAssign>( + { + done: VestRuntime.persist(done) as Done, + }, + useCreateSuiteResult(), ); } @@ -36,7 +34,7 @@ function done( ): SuiteRunResult { const [callback, fieldName] = args.reverse() as [ (res: SuiteResult) => void, - F + F, ]; const output = useSuiteRunResult(); if (shouldSkipDoneRegistration(callback, fieldName, output)) {