Skip to content

Commit

Permalink
minor(vest): suite.runStatic
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed Feb 19, 2024
1 parent eaa1f4d commit b3a4e72
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 77 deletions.
11 changes: 8 additions & 3 deletions packages/vest/src/suite/SuiteTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@ import { SuiteSelectors } from 'suiteSelectors';
export type Suite<
F extends TFieldName,
G extends TGroupName,
T extends CB = CB
> = ((...args: Parameters<T>) => SuiteRunResult<F, G>) & SuiteMethods<F, G>;
T extends CB = CB,
> = ((...args: Parameters<T>) => SuiteRunResult<F, G>) & SuiteMethods<F, G, T>;

export type SuiteMethods<F extends TFieldName, G extends TGroupName> = {
export type SuiteMethods<
F extends TFieldName,
G extends TGroupName,
T extends CB,
> = {
dump: CB<TIsolateSuite>;
get: CB<SuiteResult<F, G>>;
resume: CB<void, [TIsolateSuite]>;
reset: CB<void>;
remove: CB<void, [fieldName: F]>;
resetField: CB<void, [fieldName: F]>;
runStatic: CB<SuiteRunResult<F, G>, Parameters<T>>;
subscribe: (cb: CB) => CB<void>;
} & TTypedMethods<F, G> &
SuiteSelectors<F, G>;
21 changes: 18 additions & 3 deletions packages/vest/src/suite/__tests__/staticSuite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,33 @@ describe('staticSuite', () => {
expect(res.dump().children).toHaveLength(3);
expect(res.dump().children?.[0]).toHaveProperty(
'$type',
VestIsolateType.Test
VestIsolateType.Test,
);
expect(res.dump().children?.[1]).toHaveProperty(
'$type',
VestIsolateType.Test
VestIsolateType.Test,
);
expect(res.dump().children?.[2]).toHaveProperty(
'$type',
VestIsolateType.Group
VestIsolateType.Group,
);

expect(res.dump()).toMatchSnapshot();
});
});
});

describe('runStatic', () => {
it('Should run a static suite', () => {
const suite = vest.create(() => {
vest.test('t1', () => false);
vest.test('t2', () => false);
});

const res = suite.runStatic();
expect(suite.runStatic()).not.toBe(suite.runStatic());

expect(res.hasErrors('t1')).toBe(true);
expect(res.hasErrors('t2')).toBe(true);
});
});
77 changes: 67 additions & 10 deletions packages/vest/src/suite/createSuite.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { assign, CB } from 'vest-utils';
import { Bus, VestRuntime } from 'vestjs-runtime';

import { TTypedMethods, getTypedMethods } from './getTypedMethods';

import { Events } from 'BusEvents';
import { IsolateSuite, TIsolateSuite } from 'IsolateSuite';
import { useCreateVestState, useLoadSuite } from 'Runtime';
Expand All @@ -14,7 +16,6 @@ import {
import { Suite } from 'SuiteTypes';
import { useInitVestBus } from 'VestBus';
import { VestReconciler } from 'VestReconciler';
import { getTypedMethods } from 'getTypedMethods';
import { useCreateSuiteResult } from 'suiteResult';
import { useSuiteRunResult } from 'suiteRunResult';
import { bindSuiteSelectors } from 'suiteSelectors';
Expand All @@ -23,18 +24,19 @@ import { validateSuiteCallback } from 'validateSuiteParams';
function createSuite<
F extends TFieldName = string,
G extends TGroupName = string,
T extends CB = CB
T extends CB = CB,
>(suiteName: SuiteName, suiteCallback: T): Suite<F, G, T>;
function createSuite<
F extends TFieldName = string,
G extends TGroupName = string,
T extends CB = CB
T extends CB = CB,
>(suiteCallback: T): Suite<F, G, T>;
// @vx-allow use-use
// eslint-disable-next-line max-lines-per-function
function createSuite<
F extends TFieldName = string,
G extends TGroupName = string,
T extends CB = CB
T extends CB = CB,
>(
...args: [suiteName: SuiteName, suiteCallback: T] | [suiteCallback: T]
): Suite<F, G, T> {
Expand All @@ -55,12 +57,14 @@ function createSuite<
Bus.useEmit(Events.SUITE_RUN_STARTED);

return IsolateSuite(
useRunSuiteCallback<T, F, G>(suiteCallback, ...args)
useRunSuiteCallback<T, F, G>(suiteCallback, ...args),
);
}
},
).output;
}

const mountedStatic = staticSuite<F, G, T>(...(args as [T]));

// Assign methods to the suite
// We do this within the VestRuntime so that the suite methods
// will be bound to the suite's stateRef and be able to access it.
Expand All @@ -74,25 +78,26 @@ function createSuite<
VestRuntime.persist(suite),
{
dump: VestRuntime.persist(
() => VestRuntime.useAvailableRoot() as TIsolateSuite
() => VestRuntime.useAvailableRoot() as TIsolateSuite,
),
get: VestRuntime.persist(useCreateSuiteResult),
remove: Bus.usePrepareEmitter<string>(Events.REMOVE_FIELD),
reset: Bus.usePrepareEmitter(Events.RESET_SUITE),
resetField: Bus.usePrepareEmitter<string>(Events.RESET_FIELD),
resume: VestRuntime.persist(useLoadSuite),
runStatic: (...args: Parameters<T>): SuiteRunResult<F, G> => mountedStatic(...args) as SuiteRunResult<F, G>,
subscribe: VestBus.subscribe,
...bindSuiteSelectors<F, G>(VestRuntime.persist(useCreateSuiteResult)),
...getTypedMethods<F, G>(),
}
},
);
});
}

function useRunSuiteCallback<
T extends CB,
F extends TFieldName,
G extends TGroupName
G extends TGroupName,
>(suiteCallback: T, ...args: Parameters<T>): CB<SuiteRunResult<F, G>> {
const emit = Bus.useEmit();

Expand All @@ -103,4 +108,56 @@ function useRunSuiteCallback<
};
}

export { createSuite };
/**
* Creates a static suite for server-side validation.
*
* @param {Function} validationFn - The validation function that defines the suite's tests.
* @returns {Function} - A function that runs the validations defined in the suite.
*
* @example
* import { staticSuite, test, enforce } from 'vest';
*
* const suite = staticSuite(data => {
* test('username', 'username is required', () => {
* enforce(data.username).isNotEmpty();
* });
* });
*
* suite(data);
*/
function staticSuite<
F extends TFieldName = string,
G extends TGroupName = string,
T extends CB = CB,
>(suiteCallback: T): StaticSuite<F, G, T> {
return assign(
(...args: Parameters<T>) => {
const suite = createSuite<F, G, T>(suiteCallback);

const result = suite(...args);

return Object.freeze(
assign(
{
dump: suite.dump,
},
result,
),
);
},
{
...getTypedMethods<F, G>(),
},
);
}

export type StaticSuite<
F extends TFieldName = string,
G extends TGroupName = string,
T extends CB = CB,
> = ((...args: Parameters<T>) => SuiteRunResult<F, G> & {
dump: CB<TIsolateSuite>;
}) &
TTypedMethods<F, G>;

export { createSuite, staticSuite };
58 changes: 0 additions & 58 deletions packages/vest/src/suite/staticSuite.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/vest/src/vest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ import type {
SuiteSummary,
} from 'SuiteResultTypes';
import type { Suite } from 'SuiteTypes';
import { createSuite } from 'createSuite';
import { createSuite, staticSuite, StaticSuite } from 'createSuite';
import { each } from 'each';
import { skip, only } from 'focused';
import { group } from 'group';
import { include } from 'include';
import { mode } from 'mode';
import { omitWhen } from 'omitWhen';
import { skipWhen } from 'skipWhen';
import { staticSuite, StaticSuite } from 'staticSuite';
import { suiteSelectors } from 'suiteSelectors';
import { test } from 'test';
import { warn } from 'warn';
Expand Down
1 change: 0 additions & 1 deletion packages/vest/tsconfig.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit b3a4e72

Please sign in to comment.