Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minor(vest): Add subscribe to specific events #1154

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions packages/vest/src/core/VestBus/BusEvents.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
export enum Events {
TEST_RUN_STARTED = 'test_run_started',
TEST_COMPLETED = 'test_completed',
ALL_RUNNING_TESTS_FINISHED = 'all_running_tests_finished',
REMOVE_FIELD = 'remove_field',
RESET_FIELD = 'reset_field',
RESET_SUITE = 'reset_suite',
SUITE_RUN_STARTED = 'suite_run_started',
SUITE_CALLBACK_RUN_FINISHED = 'SUITE_CALLBACK_RUN_FINISHED',
DONE_TEST_OMISSION_PASS = 'DONE_TEST_OMISSION_PASS',
}
export type Events =
| 'TEST_RUN_STARTED'
| 'TEST_COMPLETED'
| 'ALL_RUNNING_TESTS_FINISHED'
| 'REMOVE_FIELD'
| 'RESET_FIELD'
| 'RESET_SUITE'
| 'SUITE_RUN_STARTED'
| 'SUITE_CALLBACK_RUN_FINISHED'
| 'DONE_TEST_OMISSION_PASS';
36 changes: 22 additions & 14 deletions packages/vest/src/core/VestBus/VestBus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ import { useRunDoneCallbacks, useRunFieldCallbacks } from 'runCallbacks';
export function useInitVestBus() {
const VestBus = Bus.useBus();

on(Events.TEST_COMPLETED, () => {});
// on(Events.TEST_RUN_STARTED, () => {});
on('TEST_COMPLETED', () => {});
// on("TEST_RUN_STARTED", () => {});

VestBus.on(RuntimeEvents.ISOLATE_PENDING, (isolate: TIsolate) => {
if (VestTest.is(isolate)) {
Expand All @@ -33,7 +33,7 @@ export function useInitVestBus() {

VestBus.on(RuntimeEvents.ISOLATE_DONE, (isolate: TIsolate) => {
if (VestTest.is(isolate)) {
VestBus.emit(Events.TEST_COMPLETED, isolate);
VestBus.emit('TEST_COMPLETED', isolate);
}

VestIsolate.setDone(isolate);
Expand All @@ -50,16 +50,16 @@ export function useInitVestBus() {

if (!SuiteWalker.useHasPending()) {
// When no more async tests are running, emit the done event
VestBus.emit(Events.ALL_RUNNING_TESTS_FINISHED);
VestBus.emit('ALL_RUNNING_TESTS_FINISHED');
}
});

on(Events.DONE_TEST_OMISSION_PASS, () => {
on('DONE_TEST_OMISSION_PASS', () => {
/* We NEED to refresh the cache here. Don't ask */
});

// Called when all the tests, including async, are done running
VestBus.on(Events.ALL_RUNNING_TESTS_FINISHED, () => {
VestBus.on('ALL_RUNNING_TESTS_FINISHED', () => {
// Small optimization. We don't need to run this if there are no async tests
// The reason is that we run this function immediately after the suite callback
// is run, so if the suite is only comprised of sync tests, we don't need to
Expand All @@ -70,37 +70,40 @@ export function useInitVestBus() {
useRunDoneCallbacks();
});

on(Events.RESET_FIELD, (fieldName: TFieldName) => {
on('RESET_FIELD', (fieldName: TFieldName) => {
TestWalker.resetField(fieldName);
});

on(Events.SUITE_RUN_STARTED, () => {
on('SUITE_RUN_STARTED', () => {
useResetCallbacks();
});

on(Events.SUITE_CALLBACK_RUN_FINISHED, () => {
on('SUITE_CALLBACK_RUN_FINISHED', () => {
if (!SuiteWalker.useHasPending()) {
// When no more async tests are running, emit the done event
VestBus.emit(Events.ALL_RUNNING_TESTS_FINISHED);
VestBus.emit('ALL_RUNNING_TESTS_FINISHED');
}

useOmitOptionalFields();
});

on(Events.REMOVE_FIELD, (fieldName: TFieldName) => {
on('REMOVE_FIELD', (fieldName: TFieldName) => {
TestWalker.removeTestByFieldName(fieldName);
});

on(Events.RESET_SUITE, () => {
on('RESET_SUITE', () => {
useResetSuite();
});

return {
subscribe,
};

function subscribe(cb: CB) {
return VestBus.on('*', () => {
function subscribe(event: Events, cb: CB): CB<void>;
function subscribe(cb: CB): CB<void>;
function subscribe(...args: [event: Events, cb: CB] | [cb: CB]): CB<void> {
const [cb, event] = args.reverse() as [CB, Events];
return VestBus.on(event ?? '*', () => {
cb();
}).off;
}
Expand All @@ -116,3 +119,8 @@ export function useInitVestBus() {
}

type VestEvents = Events | ValueOf<typeof RuntimeEvents> | '*';

export type Subscribe = {
(event: Events, cb: CB): CB<void>;
(cb: CB): CB<void>;
};
3 changes: 1 addition & 2 deletions packages/vest/src/core/test/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
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';
Expand Down Expand Up @@ -47,7 +46,7 @@ function vestTest<F extends TFieldName>(
const testObjectInput = { fieldName, groupName, message, testFn };

// This invalidates the suite cache.
Bus.useEmit(Events.TEST_RUN_STARTED);
Bus.useEmit('TEST_RUN_STARTED');

return IsolateTest(useAttemptRunTest, testObjectInput, key);
}
Expand Down
3 changes: 1 addition & 2 deletions packages/vest/src/hooks/optional/omitOptionalFields.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { isEmpty, optionalFunctionValue } from 'vest-utils';
import { Bus, VestRuntime } from 'vestjs-runtime';

import { Events } from 'BusEvents';
import { SuiteOptionalFields, TIsolateSuite } from 'IsolateSuite';
import { TIsolateTest } from 'IsolateTest';
import { TestWalker } from 'TestWalker';
Expand Down Expand Up @@ -44,7 +43,7 @@ export function useOmitOptionalFields(): void {
}
});

Bus.useEmit(Events.DONE_TEST_OMISSION_PASS);
Bus.useEmit('DONE_TEST_OMISSION_PASS');

function verifyAndOmit(testObject: TIsolateTest) {
const { fieldName } = VestTest.getData(testObject);
Expand Down
3 changes: 2 additions & 1 deletion packages/vest/src/suite/SuiteTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TFieldName,
TGroupName,
} from 'SuiteResultTypes';
import { Subscribe } from 'VestBus';
import { StaticSuiteRunResult } from 'createSuite';
import { TTypedMethods } from 'getTypedMethods';
import { SuiteSelectors } from 'suiteSelectors';
Expand All @@ -29,6 +30,6 @@ export type SuiteMethods<
remove: CB<void, [fieldName: F]>;
resetField: CB<void, [fieldName: F]>;
runStatic: CB<StaticSuiteRunResult<F, G>, Parameters<T>>;
subscribe: (cb: CB) => CB<void>;
subscribe: Subscribe;
} & TTypedMethods<F, G> &
SuiteSelectors<F, G>;
28 changes: 27 additions & 1 deletion packages/vest/src/suite/__tests__/subscribe.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { SuiteSerializer } from 'SuiteSerializer';
import { enforce } from 'n4s';
import { describe, it, expect, vi } from 'vitest';
import wait from 'wait';

import { SuiteSerializer } from 'SuiteSerializer';
import * as vest from 'vest';

describe('suite.subscribe', () => {
Expand Down Expand Up @@ -52,6 +52,32 @@ describe('suite.subscribe', () => {
expect(cb.mock.calls.length).toBeGreaterThan(callCount);
});

describe('Subscribe with event name', () => {
it('Should only call the callback on the specified event', () => {
const cbAllDone = vi.fn();
const testDone = vi.fn();
const testStarted = vi.fn();
const suiteStart = vi.fn();

const suite = vest.create('suite', () => {
vest.test('field1', () => false);
vest.test('field2', () => true);
vest.test('field3', () => false);
});

suite.subscribe('ALL_RUNNING_TESTS_FINISHED', cbAllDone);
suite.subscribe('TEST_COMPLETED', testDone);
suite.subscribe('TEST_RUN_STARTED', testStarted);
suite.subscribe('SUITE_RUN_STARTED', suiteStart);

suite();
expect(cbAllDone).toHaveBeenCalledTimes(1);
expect(testDone).toHaveBeenCalledTimes(3);
expect(testStarted).toHaveBeenCalledTimes(3);
expect(suiteStart).toHaveBeenCalledTimes(1);
});
});

describe('unsubscribe', () => {
it('Should unsubscribe future events', () => {
const cb = vi.fn();
Expand Down
11 changes: 5 additions & 6 deletions packages/vest/src/suite/createSuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ 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';
import { SuiteContext } from 'SuiteContext';
Expand Down Expand Up @@ -55,7 +54,7 @@ function createSuite<
suiteParams: args,
},
() => {
Bus.useEmit(Events.SUITE_RUN_STARTED);
Bus.useEmit('SUITE_RUN_STARTED');

return IsolateSuite(
useRunSuiteCallback<T, F, G>(suiteCallback, ...args),
Expand All @@ -82,9 +81,9 @@ function createSuite<
() => 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),
remove: Bus.usePrepareEmitter<string>('REMOVE_FIELD'),
reset: Bus.usePrepareEmitter('RESET_SUITE'),
resetField: Bus.usePrepareEmitter<string>('RESET_FIELD'),
resume: VestRuntime.persist(useLoadSuite),
runStatic: (...args: Parameters<T>): StaticSuiteRunResult<F, G> =>
mountedStatic(...args) as StaticSuiteRunResult<F, G>,
Expand All @@ -105,7 +104,7 @@ function useRunSuiteCallback<

return () => {
suiteCallback(...args);
emit(Events.SUITE_CALLBACK_RUN_FINISHED);
emit('SUITE_CALLBACK_RUN_FINISHED');
return useSuiteRunResult<F, G>();
};
}
Expand Down
Loading