Skip to main content
Module

x/opine/test/utils.ts

Fast, minimalist web framework for Deno ported from ExpressJS.
Very Popular
Go to Latest
File
import { expect } from "./deps.ts";/** * Test timeout. */export const TEST_TIMEOUT = 3000;
/** * A no-op _describe_ method. * * @param name * @param fn */export function describe(_name: string, fn: () => void | Promise<void>) { return fn();}
export type Done = (err?: unknown) => void;
/** * An stub to remove a test. * * @param name * @param fn */export function nit( _name: string, _fn: (done: Done) => void | Promise<void>, _options?: Partial<Deno.TestDefinition>,) {}
/** * An _it_ wrapper around `Deno.test`. * * @param name * @param fn */export function it( name: string, fn: (done: Done) => void | Promise<void>, options?: Partial<Deno.TestDefinition>,) { Deno.test({ ...options, name, fn: async () => { let testError: unknown;
let done: Done = (err?: unknown) => { if (err) { testError = err; } };
let race: Promise<unknown> = Promise.resolve(); let timeoutId: number;
if (fn.length === 1) { let resolve: (value?: unknown) => void; const donePromise = new Promise((r) => { resolve = r; });
race = Promise.race([ new Promise((_, reject) => timeoutId = setTimeout(() => { clearTimeout(timeoutId);
reject( new Error( `test "${name}" failed to complete by calling "done" within ${TEST_TIMEOUT}ms.`, ), ); }, TEST_TIMEOUT) ), donePromise, ]);
done = (err?: unknown) => { clearTimeout(timeoutId); resolve();
if (err) { testError = err; } }; }
await fn(done); await race;
if (timeoutId!) { clearTimeout(timeoutId); }
// REF: https://github.com/denoland/deno/blob/987716798fb3bddc9abc7e12c25a043447be5280/ext/timers/01_timers.js#L353 await new Promise((resolve) => setTimeout(resolve, 20));
if (testError) { throw testError; } }, });}
export const after = (count: number, done: Done) => { let _count = 0;
return (err?: unknown) => { _count++;
if (err) { done(err); } else if (_count >= count) { done(); } };};
/** * Returns an object subset of `obj`, whose properties are in `keys`. * * @param obj * @param props */export function pick< T extends Record<string, unknown>, K extends keyof T,>(obj: T, keys: K[]): Pick<T, K> { const output = {} as Pick<T, K>;
for (const key of keys) { output[key] = obj[key]; }
return output;}
/** * Returns an object subset of `obj`, whose properties are not in `keys`. * @param obj * @param keys */export function omit<T extends Record<string, unknown>, K extends keyof T>( obj: T, keys: K[],): Omit<T, K> { const copy = Object.create(Object.getPrototypeOf(obj)); Object.defineProperties(copy, Object.getOwnPropertyDescriptors(obj));
for (const key of keys) { delete copy[key]; }
return copy as Omit<T, K>;}
export const shouldNotHaveHeader = (field: string) => (res: any) => { expect(res.header[field.toLowerCase()]).toBeFalsy(); };
export const shouldHaveBody = (buf: any) => (res: any) => { const body = res.body || res.text; expect(body).toBeTruthy(); expect(body.toString("hex")).toEqual(buf.toString("hex")); };
export const shouldNotHaveBody = () => (res: any) => { expect(res.text === "" || res.text === undefined || res.text === null) .toBeTruthy(); };