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
Section titled “Import”import { createTestRuntime } from '@triggery/testing';
const rt = createTestRuntime();
await rt.flushMicrotasks();Signature
Section titled “Signature”flushMicrotasks(): Promise<void>;Parameters
Section titled “Parameters”None.
Returns
Section titled “Returns”A Promise<void> that resolves after two microtask ticks.
Examples
Section titled “Examples”Async fire, then assert
Section titled “Async fire, then assert”import { createTrigger function 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). } from '@triggery/core';
import { createTestRuntime function createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing';
import { expect const expect: ExpectStatic , it const it: TestAPIDefines a test case with a given name and test function. The test function can optionally be configured with test options. , vi const vi: VitestUtils } from 'vitest';
it it<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. ('completes a microtask-scheduled handler', async () => {
const rt const rt: TestRuntime = createTestRuntime function 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). <{
events events: {
tick: void;
}
: { tick tick: void : void };
actions actions: {
log: void;
}
: { log log: void : void };
}>(
{ id id: string : 'demo', events events: readonly "tick"[] : ['tick'], handler handler: TriggerHandler<{
events: {
tick: void;
};
actions: {
log: void;
};
}, never>
({ actions actions: ActionsCtx<{
log: void;
}>
}) { actions actions: ActionsCtx<{
log: void;
}>
.log log?: (() => void) | undefined ?.(); } },
rt const rt: TestRuntime ,
);
const log const log: Mock<Procedure> = vi const vi: VitestUtils .fn VitestUtils.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. ();
rt const 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', log const log: Mock<Procedure> );
rt const rt: TestRuntime .fire function fire(eventName: string, payload?: unknown): voidFire an event asynchronously (through the scheduler). ('tick');
expect expect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload) (log const log: Mock<Procedure> ).not not: Assertion<Mock<Procedure>> .toHaveBeenCalled JestAssertion<Mock<Procedure>>.toHaveBeenCalled: () => voidEnsures that a mock function is called.
Also under the alias `expect.toBeCalled`. (); // handler not run yet
await rt const rt: TestRuntime .flushMicrotasks function 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. ();
expect expect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload) (log const log: Mock<Procedure> ).toHaveBeenCalledOnce Assertion<Mock<Procedure>>.toHaveBeenCalledOnce: () => voidAsserts that a mock function was called exactly once. ();
});Async handler chain
Section titled “Async handler chain”import { createTrigger function 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). } from '@triggery/core';
import { createTestRuntime function createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing';
import { expect const expect: ExpectStatic , it const it: TestAPIDefines a test case with a given name and test function. The test function can optionally be configured with test options. , vi const vi: VitestUtils } from 'vitest';
it it<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. ('awaits an async action chain', async () => {
const rt const rt: TestRuntime = createTestRuntime function 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). <{
events events: {
fetch: string;
}
: { fetch fetch: string : string };
actions actions: {
setData: {
value: string;
};
}
: { setData setData: {
value: string;
}
: { value value: string : string } };
}>(
{
id id: string : 'demo',
events events: 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 value const value: string = await Promise var Promise: PromiseConstructorRepresents the completion of an asynchronous operation .resolve PromiseConstructor.resolve<string>(value: string): Promise<string> (+2 overloads)Creates a new resolved promise for the provided value. (`got-${event event: {
readonly name: "fetch";
readonly payload: string;
}
.payload payload: string }`);
actions actions: ActionsCtx<{
setData: {
value: string;
};
}>
.setData setData?: ((payload: {
value: string;
}) => void) | undefined
?.({ value value: string });
},
},
rt const rt: TestRuntime ,
);
const setData const setData: Mock<Procedure> = vi const vi: VitestUtils .fn VitestUtils.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. ();
rt const 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', setData const setData: Mock<Procedure> );
rt const rt: TestRuntime .fire function fire(eventName: string, payload?: unknown): voidFire an event asynchronously (through the scheduler). ('fetch', 'x');
await rt const rt: TestRuntime .flushMicrotasks function 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. ();
expect expect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload) (setData const 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`. ({ value value: string : 'got-x' });
});Multiple fires, single flush
Section titled “Multiple fires, single flush”import { createTrigger function 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). } from '@triggery/core';
import { createTestRuntime function createTestRuntime(options?: TestRuntimeOptions): TestRuntime } from '@triggery/testing';
import { expect const expect: ExpectStatic , it const it: TestAPIDefines a test case with a given name and test function. The test function can optionally be configured with test options. , vi const vi: VitestUtils } from 'vitest';
it it<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. ('drains all queued runs together', async () => {
const rt const rt: TestRuntime = createTestRuntime function 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). <{
events events: {
tick: number;
}
: { tick tick: number : number };
actions actions: {
log: number;
}
: { log log: number : number };
}>(
{ id id: string : 'demo', events events: 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;
}>
.log log?: ((payload: number) => void) | undefined ?.(event event: {
readonly name: "tick";
readonly payload: number;
}
.payload payload: number ); } },
rt const rt: TestRuntime ,
);
const log const log: Mock<Procedure> = vi const vi: VitestUtils .fn VitestUtils.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. ();
rt const 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', log const log: Mock<Procedure> );
rt const rt: TestRuntime .fire function fire(eventName: string, payload?: unknown): voidFire an event asynchronously (through the scheduler). ('tick', 1);
rt const rt: TestRuntime .fire function fire(eventName: string, payload?: unknown): voidFire an event asynchronously (through the scheduler). ('tick', 2);
rt const rt: TestRuntime .fire function fire(eventName: string, payload?: unknown): voidFire an event asynchronously (through the scheduler). ('tick', 3);
await rt const rt: TestRuntime .flushMicrotasks function 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. ();
expect expect<Mock<Procedure>>(actual: Mock<Procedure>, message?: string): Assertion<Mock<Procedure>> (+1 overload) (log const log: Mock<Procedure> ).toHaveBeenCalledTimes JestAssertion<Mock<Procedure>>.toHaveBeenCalledTimes: (times: number) => voidEnsures that a mock function is called an exact number of times.
Also under the alias `expect.toBeCalledTimes`. (3);
});Related
Section titled “Related” createTestRuntime The runtime that exposes this method.
createFakeScheduler Virtual clock for timer-based handlers.
createScheduler The microtask scheduler being drained.
Testing guide Async test patterns.