Skip to content
GitHubXDiscord

flushMicrotasks

Stable · since 0.1.0

A method on the TestRuntime. Awaits twice to drain the pending microtask queue — first the queue you know about, then any follow-up microtasks queued by handlers that already ran.

Use this after rt.fire(...) when the trigger’s schedule is 'microtask' (the default) and the test needs the handler to complete before the next assertion. fireSync does not need it — it runs handlers in the caller’s stack.

import { createTestRuntime } from '@triggery/testing';

const rt = createTestRuntime();
await rt.flushMicrotasks();
flushMicrotasks(): Promise<void>;

None.

A Promise<void> that resolves after two microtask ticks.

import { createTriggerfunction createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
import { createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing'; import { expectconst expect: ExpectStatic, itconst it: TestAPI
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
, viconst vi: VitestUtils } from 'vitest';
itit<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
('completes a microtask-scheduled handler', async () => {
const rtconst rt: TestRuntime = createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime(); const t
const t: Trigger<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>
= createTrigger
createTrigger<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>(config: CreateTriggerConfig<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    tick: void;
}
: { ticktick: void: void };
actions
actions: {
    log: void;
}
: { loglog: void: void };
}>( { idid: string: 'demo', eventsevents: readonly "tick"[]: ['tick'], handler
handler: TriggerHandler<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}, never>
({ actions
actions: ActionsCtx<{
    log: void;
}>
}) { actions
actions: ActionsCtx<{
    log: void;
}>
.loglog?: (() => void) | undefined?.(); } },
rtconst rt: TestRuntime, ); const logconst log: Mock<Procedure> = viconst vi: VitestUtils.fnVitestUtils.fn: <Procedure>(originalImplementation?: Procedure | undefined) => Mock<Procedure>
Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock). If no function is given, mock will return `undefined`, when invoked.
@example```ts const getApples = vi.fn(() => 0) getApples() expect(getApples).toHaveBeenCalled() expect(getApples).toHaveReturnedWith(0) getApples.mockReturnValueOnce(5) expect(getApples()).toBe(5) expect(getApples).toHaveNthReturnedWith(2, 5) ```
();
rtconst rt: TestRuntime.mockAction
mockAction<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}, "log">(trigger: Trigger<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>, name: "log", handler: () => void): RegistrationToken
Register an action handler — typically a `vi.fn()`.
(t
const t: Trigger<{
    events: {
        tick: void;
    };
    actions: {
        log: void;
    };
}>
, 'log', logconst log: Mock<Procedure>);
rtconst rt: TestRuntime.firefunction fire(eventName: string, payload?: unknown): void
Fire an event asynchronously (through the scheduler).
('tick');
expectexpect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload)(logconst log: Mock<Procedure>).notnot: Assertion<Mock<Procedure>>.toHaveBeenCalledJestAssertion<Mock<Procedure>>.toHaveBeenCalled: () => void
Ensures that a mock function is called. Also under the alias `expect.toBeCalled`.
@exampleexpect(mockFunc).toHaveBeenCalled();
(); // handler not run yet
await rtconst rt: TestRuntime.flushMicrotasksfunction flushMicrotasks(): Promise<void>
Flush pending microtasks. The default scheduler uses `queueMicrotask` — after `rt.fire(...)` you await `flushMicrotasks()` before asserting. `fireSync` does not need this: it runs handlers immediately.
();
expectexpect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload)(logconst log: Mock<Procedure>).toHaveBeenCalledOnceAssertion<Mock<Procedure>>.toHaveBeenCalledOnce: () => void
Asserts that a mock function was called exactly once.
@exampleexpect(mockFunc).toHaveBeenCalledOnce();
();
});
import { createTriggerfunction createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
import { createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing'; import { expectconst expect: ExpectStatic, itconst it: TestAPI
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
, viconst vi: VitestUtils } from 'vitest';
itit<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
('awaits an async action chain', async () => {
const rtconst rt: TestRuntime = createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime(); const t
const t: Trigger<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>
= createTrigger
createTrigger<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>(config: CreateTriggerConfig<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    fetch: string;
}
: { fetchfetch: string: string };
actions
actions: {
    setData: {
        value: string;
    };
}
: { setData
setData: {
    value: string;
}
: { valuevalue: string: string } };
}>( { idid: string: 'demo', eventsevents: readonly "fetch"[]: ['fetch'], async handler
handler: TriggerHandler<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}, never>
({ event
event: {
    readonly name: "fetch";
    readonly payload: string;
}
, actions
actions: ActionsCtx<{
    setData: {
        value: string;
    };
}>
}) {
const valueconst value: string = await Promisevar Promise: PromiseConstructor
Represents the completion of an asynchronous operation
.resolvePromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)
Creates a new resolved promise for the provided value.
@paramvalue A promise.@returnsA promise whose internal state matches the provided promise.
(`got-${event
event: {
    readonly name: "fetch";
    readonly payload: string;
}
.payloadpayload: string}`);
actions
actions: ActionsCtx<{
    setData: {
        value: string;
    };
}>
.setData
setData?: ((payload: {
    value: string;
}) => void) | undefined
?.({ valuevalue: string });
}, }, rtconst rt: TestRuntime, ); const setDataconst setData: Mock<Procedure> = viconst vi: VitestUtils.fnVitestUtils.fn: <Procedure>(originalImplementation?: Procedure | undefined) => Mock<Procedure>
Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock). If no function is given, mock will return `undefined`, when invoked.
@example```ts const getApples = vi.fn(() => 0) getApples() expect(getApples).toHaveBeenCalled() expect(getApples).toHaveReturnedWith(0) getApples.mockReturnValueOnce(5) expect(getApples()).toBe(5) expect(getApples).toHaveNthReturnedWith(2, 5) ```
();
rtconst rt: TestRuntime.mockAction
mockAction<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}, "setData">(trigger: Trigger<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>, name: "setData", handler: (payload: {
    value: string;
}) => void): RegistrationToken
Register an action handler — typically a `vi.fn()`.
(t
const t: Trigger<{
    events: {
        fetch: string;
    };
    actions: {
        setData: {
            value: string;
        };
    };
}>
, 'setData', setDataconst setData: Mock<Procedure>);
rtconst rt: TestRuntime.firefunction fire(eventName: string, payload?: unknown): void
Fire an event asynchronously (through the scheduler).
('fetch', 'x');
await rtconst rt: TestRuntime.flushMicrotasksfunction flushMicrotasks(): Promise<void>
Flush pending microtasks. The default scheduler uses `queueMicrotask` — after `rt.fire(...)` you await `flushMicrotasks()` before asserting. `fireSync` does not need this: it runs handlers immediately.
();
expectexpect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload)(setDataconst setData: Mock<Procedure>).toHaveBeenCalledWith
JestAssertion<Mock<Procedure>>.toHaveBeenCalledWith: <[{
    value: string;
}]>(args_0: {
    value: string;
}) => void
Ensure that a mock function is called with specific arguments. Also under the alias `expect.toBeCalledWith`.
@exampleexpect(mockFunc).toHaveBeenCalledWith('arg1', 42);
({ valuevalue: string: 'got-x' });
});
import { createTriggerfunction createTrigger<S extends TriggerSchema>(config: CreateTriggerConfig<S>, runtime?: Runtime): Trigger<S>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
} from '@triggery/core';
import { createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing'; import { expectconst expect: ExpectStatic, itconst it: TestAPI
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
, viconst vi: VitestUtils } from 'vitest';
itit<object>(name: string | Function, fn?: TestFunction<object> | undefined, options?: number): void (+1 overload)
Defines a test case with a given name and test function. The test function can optionally be configured with test options.
@paramname - The name of the test or a function that will be used as a test name.@paramoptionsOrFn - Optional. The test options or the test function if no explicit name is provided.@paramoptionsOrTest - Optional. The test function or options, depending on the previous parameters.@throws{Error} If called inside another test function.@example```ts // Define a simple test it('adds two numbers', () => { expect(add(1, 2)).toBe(3); }); ```@example```ts // Define a test with options it('subtracts two numbers', { retry: 3 }, () => { expect(subtract(5, 2)).toBe(3); }); ```
('drains all queued runs together', async () => {
const rtconst rt: TestRuntime = createTestRuntimefunction createTestRuntime(options?: TestRuntimeOptions): TestRuntime(); const t
const t: Trigger<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>
= createTrigger
createTrigger<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>(config: CreateTriggerConfig<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>, runtime?: Runtime): Trigger<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>
Create a trigger and register it in a runtime (the default runtime if none is passed).
@example```ts const messageTrigger = createTrigger<{ events: { 'new-message': { author: string; text: string } }; conditions: { user: { id: string }; settings: { sound: boolean } }; actions: { showToast: { title: string }; playSound: void }; }>({ id: 'message-received', events: ['new-message'], required: ['user', 'settings'], handler({ event, conditions, actions, check }) { if (!conditions.user || !conditions.settings) return; // V1: manual narrowing if (check.is('settings', (s) => s.sound)) actions.playSound?.(); actions.showToast?.({ title: event.payload.author }); }, }); ```
<{
events
events: {
    tick: number;
}
: { ticktick: number: number };
actions
actions: {
    log: number;
}
: { loglog: number: number };
}>( { idid: string: 'demo', eventsevents: readonly "tick"[]: ['tick'], handler
handler: TriggerHandler<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}, never>
({ event
event: {
    readonly name: "tick";
    readonly payload: number;
}
, actions
actions: ActionsCtx<{
    log: number;
}>
}) { actions
actions: ActionsCtx<{
    log: number;
}>
.loglog?: ((payload: number) => void) | undefined?.(event
event: {
    readonly name: "tick";
    readonly payload: number;
}
.payloadpayload: number); } },
rtconst rt: TestRuntime, ); const logconst log: Mock<Procedure> = viconst vi: VitestUtils.fnVitestUtils.fn: <Procedure>(originalImplementation?: Procedure | undefined) => Mock<Procedure>
Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](https://vitest.dev/api/mock). If no function is given, mock will return `undefined`, when invoked.
@example```ts const getApples = vi.fn(() => 0) getApples() expect(getApples).toHaveBeenCalled() expect(getApples).toHaveReturnedWith(0) getApples.mockReturnValueOnce(5) expect(getApples()).toBe(5) expect(getApples).toHaveNthReturnedWith(2, 5) ```
();
rtconst rt: TestRuntime.mockAction
mockAction<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}, "log">(trigger: Trigger<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>, name: "log", handler: (payload: number) => void): RegistrationToken
Register an action handler — typically a `vi.fn()`.
(t
const t: Trigger<{
    events: {
        tick: number;
    };
    actions: {
        log: number;
    };
}>
, 'log', logconst log: Mock<Procedure>);
rtconst rt: TestRuntime.firefunction fire(eventName: string, payload?: unknown): void
Fire an event asynchronously (through the scheduler).
('tick', 1);
rtconst rt: TestRuntime.firefunction fire(eventName: string, payload?: unknown): void
Fire an event asynchronously (through the scheduler).
('tick', 2);
rtconst rt: TestRuntime.firefunction fire(eventName: string, payload?: unknown): void
Fire an event asynchronously (through the scheduler).
('tick', 3);
await rtconst rt: TestRuntime.flushMicrotasksfunction flushMicrotasks(): Promise<void>
Flush pending microtasks. The default scheduler uses `queueMicrotask` — after `rt.fire(...)` you await `flushMicrotasks()` before asserting. `fireSync` does not need this: it runs handlers immediately.
();
expectexpect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload)(logconst log: Mock<Procedure>).toHaveBeenCalledTimesJestAssertion<Mock<Procedure>>.toHaveBeenCalledTimes: (times: number) => void
Ensures that a mock function is called an exact number of times. Also under the alias `expect.toBeCalledTimes`.
@exampleexpect(mockFunc).toHaveBeenCalledTimes(2);
(3);
});