Skip to content

Commit

Permalink
feat: Suite Serialization (#1055)
Browse files Browse the repository at this point in the history
  • Loading branch information
ealush committed Aug 2, 2023
1 parent bcfa1f2 commit eee4905
Show file tree
Hide file tree
Showing 35 changed files with 433 additions and 130 deletions.
1 change: 1 addition & 0 deletions packages/vest/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ tsconfig.json
!enforce@compounds/
!enforce@compose/
!classnames/
!SuiteSerializer/

# Manual Section. Edit at will.
30 changes: 30 additions & 0 deletions packages/vest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,36 @@
"vestjs-runtime": "^0.0.1"
},
"exports": {
"./suiteSerializer": {
"production": {
"types": "./types/suiteSerializer.d.ts",
"browser": "./dist/es/suiteSerializer.production.js",
"umd": "./dist/umd/suiteSerializer.production.js",
"import": "./dist/es/suiteSerializer.production.js",
"require": "./dist/cjs/suiteSerializer.production.js",
"node": "./dist/cjs/suiteSerializer.production.js",
"module": "./dist/es/suiteSerializer.production.js",
"default": "./dist/cjs/suiteSerializer.production.js"
},
"development": {
"types": "./types/suiteSerializer.d.ts",
"browser": "./dist/es/suiteSerializer.development.js",
"umd": "./dist/umd/suiteSerializer.development.js",
"import": "./dist/es/suiteSerializer.development.js",
"require": "./dist/cjs/suiteSerializer.development.js",
"node": "./dist/cjs/suiteSerializer.development.js",
"module": "./dist/es/suiteSerializer.development.js",
"default": "./dist/cjs/suiteSerializer.development.js"
},
"types": "./types/suiteSerializer.d.ts",
"browser": "./dist/es/suiteSerializer.production.js",
"umd": "./dist/umd/suiteSerializer.production.js",
"import": "./dist/es/suiteSerializer.production.js",
"require": "./dist/cjs/suiteSerializer.production.js",
"node": "./dist/cjs/suiteSerializer.production.js",
"module": "./dist/es/suiteSerializer.production.js",
"default": "./dist/cjs/suiteSerializer.production.js"
},
"./promisify": {
"production": {
"types": "./types/promisify.d.ts",
Expand Down
3 changes: 2 additions & 1 deletion packages/vest/src/core/Runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from 'vest-utils';
import { IRecociler, VestRuntime } from 'vestjs-runtime';

import { TIsolateSuite } from 'IsolateSuite';
import {
SuiteName,
SuiteResult,
Expand Down Expand Up @@ -93,7 +94,7 @@ export function useResetSuite() {
VestRuntime.reset();
}

export function useLoadSuite(rootNode: Record<string, any>): void {
export function useLoadSuite(rootNode: TIsolateSuite): void {
VestRuntime.useLoadRootNode(rootNode);
useExpireSuiteResultCache();
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ErrorStrings } from 'ErrorStrings';
import { Maybe, deferThrow, text } from 'vest-utils';
import { IsolateInspector, Reconciler } from 'vestjs-runtime';
import type { TIsolate } from 'vestjs-runtime';

import { ErrorStrings } from 'ErrorStrings';
import type { TIsolateTest } from 'IsolateTest';
import { VestTest } from 'VestTest';
import cancelOverriddenPendingTest from 'cancelOverriddenPendingTest';
Expand Down
6 changes: 3 additions & 3 deletions packages/vest/src/core/test/__tests__/test.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { faker } from '@faker-js/faker';
import { VestTest } from 'VestTest';
import { text } from 'vest-utils';
import { IsolateInspector } from 'vestjs-runtime';
import { IsolateSerializer } from 'vestjs-runtime';

import { TestPromise } from '../../../testUtils/testPromise';

Expand Down Expand Up @@ -192,8 +192,8 @@ describe("Test Vest's `test` function", () => {
expect(testObject.data.fieldName).toBe('field_name');
expect(testObject.key).toBe('keyboardcat');
expect(testObject.data.message).toBe('failure message');
expect(IsolateInspector.dump(testObject)).toMatchInlineSnapshot(
`"{"$type":"Test","data":{"severity":"error","status":"PASSING","fieldName":"field_name","message":"failure message"},"key":"keyboardcat"}"`
expect(IsolateSerializer.serialize(testObject)).toMatchInlineSnapshot(
`"{"$":"Test","D":{"severity":"error","status":"PASSING","fieldName":"field_name","message":"failure message"},"k":"keyboardcat"}"`
);
});

Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/core/test/test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { ErrorStrings } from 'ErrorStrings';
import { assign, invariant, isFunction, isStringValue, text } from 'vest-utils';
import { Bus, IsolateKey } from 'vestjs-runtime';

import { Events } from 'BusEvents';
import { ErrorStrings } from 'ErrorStrings';
import { IsolateTest, TIsolateTest } from 'IsolateTest';
import { useGroupName } from 'SuiteContext';
import { TFieldName } from 'SuiteResultTypes';
Expand Down
6 changes: 3 additions & 3 deletions packages/vest/src/core/test/testLevelFlowControl/runTest.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ErrorStrings } from 'ErrorStrings';
import {
isPromise,
isStringValue,
BusType,
text,
deferThrow,
} from 'vest-utils';
import { Bus, IsolateInspector, VestRuntime } from 'vestjs-runtime';
import { Bus, VestRuntime } from 'vestjs-runtime';

import { Events } from 'BusEvents';
import { ErrorStrings } from 'ErrorStrings';
import { TIsolateTest } from 'IsolateTest';
import { SuiteContext } from 'SuiteContext';
import { TestResult } from 'TestTypes';
Expand All @@ -30,7 +30,7 @@ export function useAttemptRunTest(testObject: TIsolateTest) {
/* istanbul ignore next */
deferThrow(
text(ErrorStrings.UNEXPECTED_TEST_REGISTRATION_ERROR, {
testObject: IsolateInspector.dump(testObject),
testObject: JSON.stringify(testObject),
})
);
}
Expand Down
26 changes: 26 additions & 0 deletions packages/vest/src/exports/SuiteSerializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { IsolateSerializer } from 'vestjs-runtime';

import { TIsolateSuite } from 'IsolateSuite';
import { TFieldName, TGroupName } from 'SuiteResultTypes';
import { Suite } from 'SuiteTypes';

export class SuiteSerializer {
static serialize(suite: Suite<TFieldName, TGroupName>) {
return IsolateSerializer.serialize(suite.dump());
}

static deserialize(
serialized: string | TIsolateSuite | Record<string, any>
): TIsolateSuite {
return IsolateSerializer.deserialize(serialized) as TIsolateSuite;
}

static resume(
suite: Suite<TFieldName, TGroupName>,
root: string | TIsolateSuite | Record<string, any>
): void {
const suiteRoot = SuiteSerializer.deserialize(root);

suite.resume(suiteRoot);
}
}
66 changes: 66 additions & 0 deletions packages/vest/src/exports/__tests__/SuiteSerializer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { SuiteSerializer } from 'SuiteSerializer';
import * as vest from 'vest';

describe('SuiteSerializer', () => {
it('Should produce a valid serialized dump', () => {
const suite = vest.create('suite_serialize_test', () => {
vest.only('field_1');

vest.test('field_1', 'field_1_message', () => false);
vest.test('field_2', 'field_2_message', () => false);

vest.group('group_1', () => {
vest.test('field_3', 'field_3_message_1', () => false);
vest.test('field_3', 'field_3_message_2', () => false);
vest.test('field_4', 'field_4_message', () => false);
});

vest.skipWhen(false, () => {
vest.test('field_5', 'field_5_message', () => false);
});
});
suite();

const serialized = SuiteSerializer.serialize(suite);
expect(serialized).toMatchSnapshot();
});
});

describe('suite.resume', () => {
it('Should resume a suite from a serialized dump', () => {
const suite = vest.create(() => {
vest.only('field_1');

vest.test('field_1', 'field_1_message', () => false);
vest.test('field_2', 'field_2_message', () => false);

vest.group('group_1', () => {
vest.test('field_3', 'field_3_message_1', () => false);
vest.test('field_3', 'field_3_message_2', () => false);
vest.test('field_4', 'field_4_message', () => false);
});

vest.skipWhen(false, () => {
vest.test('field_5', 'field_5_message', () => false);
});
});

suite();
suite.get();

const serialized = SuiteSerializer.serialize(suite);

const suite2 = vest.create(() => {});

suite2();

expect(suite.get()).not.toEqual(suite2.get());

SuiteSerializer.resume(suite2, serialized);

expect(suite.get()).isDeepCopyOf(suite2.get());

suite2();
expect(suite.get()).not.toEqual(suite2.get());
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`SuiteSerializer Should produce a valid serialized dump 1`] = `"{"children":[{"$":"Focused","D":{"focusMode":0,"match":["field_1"],"matchAll":false}},{"$":"Test","D":{"severity":"error","status":"FAILED","fieldName":"field_1","message":"field_1_message"}},{"$":"Test","D":{"severity":"error","status":"SKIPPED","fieldName":"field_2","message":"field_2_message"}},{"children":[{"$":"Test","D":{"severity":"error","status":"SKIPPED","fieldName":"field_3","groupName":"group_1","message":"field_3_message_1"}},{"$":"Test","D":{"severity":"error","status":"SKIPPED","fieldName":"field_3","groupName":"group_1","message":"field_3_message_2"}},{"$":"Test","D":{"severity":"error","status":"SKIPPED","fieldName":"field_4","groupName":"group_1","message":"field_4_message"}}],"$":"Group","D":{}},{"children":[{"$":"Test","D":{"severity":"error","status":"SKIPPED","fieldName":"field_5","message":"field_5_message"}}],"$":"SkipWhen","D":{}}],"$":"Suite","D":{"optional":{}},"output":{"errorCount":1,"warnCount":0,"testCount":1,"errors":[{"fieldName":"field_1","message":"field_1_message"}],"warnings":[],"groups":{"group_1":{"field_3":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false},"field_4":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false}}},"tests":{"field_1":{"errorCount":1,"warnCount":0,"testCount":1,"errors":["field_1_message"],"warnings":[],"valid":false},"field_2":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false},"field_3":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false},"field_4":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false},"field_5":{"errorCount":0,"warnCount":0,"testCount":0,"errors":[],"warnings":[],"valid":false}},"valid":false,"suiteName":"suite_serialize_test"}}"`;
2 changes: 1 addition & 1 deletion packages/vest/src/exports/parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ErrorStrings } from 'ErrorStrings';
import { suiteSelectors } from 'vest';
import { hasOwnProperty, invariant, isNullish, isPositive } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import { SuiteSummary, TFieldName, TGroupName } from 'SuiteResultTypes';

export function parse<F extends TFieldName, G extends TGroupName>(
Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/exports/promisify.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorStrings } from 'ErrorStrings';
import { invariant, isFunction } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import {
SuiteResult,
SuiteRunResult,
Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/hooks/include.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorStrings } from 'ErrorStrings';
import { isStringValue, invariant, optionalFunctionValue } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import { TIsolateTest } from 'IsolateTest';
import { useInclusion } from 'SuiteContext';
import { TFieldName, TGroupName } from 'SuiteResultTypes';
Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/hooks/warn.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorStrings } from 'ErrorStrings';
import { invariant } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import { useCurrentTest } from 'SuiteContext';
import { VestTest } from 'VestTest';

Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/isolates/each.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorStrings } from 'ErrorStrings';
import { invariant, isFunction } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import { IsolateEach } from 'IsolateEach';

/**
Expand Down
5 changes: 3 additions & 2 deletions packages/vest/src/suite/SuiteTypes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CB } from 'vest-utils';

import { TIsolateSuite } from 'IsolateSuite';
import {
SuiteResult,
SuiteRunResult,
Expand All @@ -16,11 +17,11 @@ export type Suite<
> = ((...args: Parameters<T>) => SuiteRunResult<F, G>) & SuiteMethods<F, G>;

export type SuiteMethods<F extends TFieldName, G extends TGroupName> = {
dump: CB<TIsolateSuite>;
get: CB<SuiteResult<F, G>>;
resume: CB<void, [Record<string, any>]>;
resume: CB<void, [TIsolateSuite]>;
reset: CB<void>;
remove: CB<void, [fieldName: F]>;
resetField: CB<void, [fieldName: F]>;
serialize: CB<string>;
} & TTypedMethods<F, G> &
SuiteSelectors<F, G>;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as vest from 'vest';

describe('suite.serialize', () => {
describe('SuiteSerializer', () => {
it('Should produce a valid serialized dump', () => {
const suite = vest.create('suite_serialize_test', () => {
vest.only('field_1');
Expand All @@ -20,8 +20,8 @@ describe('suite.serialize', () => {
});
suite();

const serialized = suite.serialize();
expect(serialized).toMatchSnapshot();
const dump = suite.dump();
expect(dump).toMatchSnapshot();
});
});

Expand All @@ -47,15 +47,16 @@ describe('suite.resume', () => {
suite();
suite.get();

const serialized = suite.serialize();
const dump = suite.dump();

const suite2 = vest.create(() => {});

suite2();

expect(suite.get()).not.toEqual(suite2.get());

suite2.resume(serialized);
suite2.resume(dump);

expect(suite.get()).isDeepCopyOf(suite2.get());

suite2();
Expand Down
6 changes: 4 additions & 2 deletions packages/vest/src/suite/createSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { assign, CB } from 'vest-utils';
import { Bus, VestRuntime } from 'vestjs-runtime';

import { Events } from 'BusEvents';
import { IsolateSuite } from 'IsolateSuite';
import { IsolateSuite, TIsolateSuite } from 'IsolateSuite';
import { useCreateVestState, useLoadSuite } from 'Runtime';
import { SuiteContext } from 'SuiteContext';
import {
Expand Down Expand Up @@ -72,12 +72,14 @@ function createSuite<
// can access the stateRef when it's called.
VestRuntime.persist(suite),
{
dump: VestRuntime.persist(
() => VestRuntime.useHistoryRoot()[0] 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),
serialize: VestRuntime.persist(VestRuntime.useSerializeHistoryRoot),
...bindSuiteSelectors<F, G>(VestRuntime.persist(useCreateSuiteResult)),
...getTypedMethods<F, G>(),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ErrorStrings } from 'ErrorStrings';
import { CB, invariant, isFunction } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';



export function validateSuiteCallback<T extends CB>(
Expand Down
2 changes: 1 addition & 1 deletion packages/vest/src/testUtils/asVestTest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ErrorStrings } from 'ErrorStrings';
import { invariant } from 'vest-utils';

import { ErrorStrings } from 'ErrorStrings';
import { TIsolateTest } from 'IsolateTest';
import { isIsolateTest } from 'isIsolateTest';

Expand Down
1 change: 1 addition & 0 deletions packages/vest/tsconfig.json

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

1 change: 1 addition & 0 deletions packages/vestjs-runtime/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ src
!dist/
tsconfig.json
!test-utils/
!IsolateSerializer/

# Manual Section. Edit at will.
Loading

2 comments on commit eee4905

@vercel
Copy link

@vercel vercel bot commented on eee4905 Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

vest – ./website

vestjs.dev
vest-ealush.vercel.app
vest-git-latest-ealush.vercel.app
vest.vercel.app
www.vestjs.dev

@vercel
Copy link

@vercel vercel bot commented on eee4905 Aug 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

vest-next – ./website

vest-next-git-latest-ealush.vercel.app
vest-next-ealush.vercel.app
vest-website.vercel.app
vest-next.vercel.app

Please sign in to comment.