@lifeart/gxt
Version:
<img align="right" width="95" height="95" alt="Philosopher’s stone, logo of PostCSS" src="./public/logo.png">
139 lines (137 loc) • 4.22 kB
TypeScript
import { Window } from 'happy-dom';
import { Cell } from '../reactive';
import { DOMApi } from '../dom-api';
import { Root } from '../dom';
/**
* Creates a function that tracks how many times it was called.
* Use this instead of vi.fn() when you only need to verify call counts.
*
* @example
* const { fn, getCallCount } = createCallTracker(() => 42);
* fn();
* expect(getCallCount()).toBe(1);
*/
export declare function createCallTracker<T, Args extends unknown[] = []>(implementation: (...args: Args) => T): {
fn: (...args: Args) => T;
getCallCount: () => number;
getLastArgs: () => Args | undefined;
getAllCalls: () => Args[];
reset: () => void;
};
/**
* Creates a getter function that tracks accesses.
* Useful for testing reactive getter unwrapping.
*
* @example
* const { getter, getAccessCount } = createTrackedGetter(() => 'value');
* const result = getter();
* expect(result).toBe('value');
* expect(getAccessCount()).toBe(1);
*/
export declare function createTrackedGetter<T>(getValue: () => T): {
getter: () => T;
getAccessCount: () => number;
reset: () => void;
};
/**
* Creates a test Cell with tracking capabilities.
* Use this when you need a real reactive Cell but want to track updates.
*
* @example
* const { testCell, getUpdateCount } = createTrackedCell(0);
* testCell.update(1);
* expect(getUpdateCount()).toBe(1);
* expect(testCell.value).toBe(1);
*/
export declare function createTrackedCell<T>(initial: T): {
testCell: Cell<T>;
getUpdateCount: () => number;
reset: () => void;
};
/**
* Creates a regular function (with prototype) for testing.
* Unlike arrow functions, these should NOT be unwrapped by helpers.
*
* @example
* const callback = createRegularFunction(() => 'result');
* expect(callback.prototype).toBeDefined(); // Has prototype
*/
export declare function createRegularFunction<T>(implementation: () => T): () => T;
/**
* Creates a class-based callback for testing.
* Classes always have prototypes and should not be called as getters.
*/
export declare function createClassCallback<T>(returnValue: T): {
new (): {};
getValue(): T;
};
/**
* Waits for a condition to be true, with timeout.
* Useful for testing async reactive updates.
*
* @example
* await waitFor(() => element.textContent === 'loaded');
*/
export declare function waitFor(condition: () => boolean, timeout?: number, interval?: number): Promise<void>;
/**
* Creates a deferred promise for testing async scenarios.
*
* @example
* const { promise, resolve } = createDeferred<string>();
* // Later...
* resolve('done');
* await promise; // 'done'
*/
export declare function createDeferred<T>(): {
promise: Promise<T>;
resolve: (value: T) => void;
reject: (error: Error) => void;
};
/**
* Flushes microtask queue.
* Useful for testing reactive updates that use queueMicrotask.
*/
export declare function flushMicrotasks(): Promise<void>;
/**
* Flushes all pending timers and microtasks.
*/
export declare function flushAll(): Promise<void>;
export interface DOMFixture {
window: Window;
document: Document;
api: DOMApi;
root: Root;
container: HTMLElement;
cleanup: () => void;
}
/**
* Creates a complete DOM fixture for tests that need happy-dom.
* Replaces the duplicated beforeEach/afterEach pattern across test files.
*
* @param customApi - Optional custom DOMApi to use instead of HTMLBrowserDOMApi
*
* @example
* let fixture: DOMFixture;
* beforeEach(() => { fixture = createDOMFixture(); });
* afterEach(() => { fixture.cleanup(); });
*/
export declare function createDOMFixture(customApi?: DOMApi): DOMFixture;
/**
* Creates a test suspense context that tracks start/end calls.
* Use this instead of vi.fn() for suspense protocol tests.
*
* @example
* const { ctx, getStartCount, getEndCount } = createTestSuspenseContext();
* provideContext(component, SUSPENSE_CONTEXT, ctx);
* // ... trigger followPromise ...
* expect(getStartCount()).toBe(1);
*/
export declare function createTestSuspenseContext(): {
ctx: {
start(): void;
end(): void;
};
getStartCount: () => number;
getEndCount: () => number;
reset(): void;
};