Testing for exceptions, promise rejections, and execution outcomes with detailed error matching.
Assert that functions throw exceptions or promises reject with optional error matching.
/**
* Assert that function throws or promise rejects
* @param functionOrPromise - Function to call or promise to await
* @param expectedError - Optional error pattern to match against
* @param message - Optional assertion message (default: "should throw" or "should reject")
* @returns Promise that resolves when assertion completes
*/
exception(functionOrPromise: Function | Promise, expectedError?: any, message?: string): Promise<void>;
/**
* Assert that function throws or promise rejects (including native errors)
* @param functionOrPromise - Function to call or promise to await
* @param expectedError - Optional error pattern to match against
* @param message - Optional assertion message
* @returns Promise that resolves when assertion completes
*/
exception.all(functionOrPromise: Function | Promise, expectedError?: any, message?: string): Promise<void>;Usage Examples:
test("exception testing", async (t) => {
// Basic exception testing
await t.exception(() => {
throw new Error("Something went wrong");
}, "function should throw");
// Promise rejection
await t.exception(
Promise.reject(new Error("Async error")),
"promise should reject"
);
// Exception with error matching
await t.exception(
() => { throw new TypeError("Invalid type"); },
{ name: "TypeError", message: "Invalid type" },
"should throw TypeError with specific message"
);
// String pattern matching
await t.exception(
() => { throw new Error("File not found: config.json"); },
/File not found/,
"should throw error matching pattern"
);
// Class-based matching
await t.exception(
() => { throw new TypeError("Bad type"); },
TypeError,
"should throw TypeError instance"
);
});By default, exception() does not catch native JavaScript errors (SyntaxError, ReferenceError, TypeError, EvalError, RangeError) as these usually indicate programming errors. Use exception.all() to catch these as well.
test("native error handling", async (t) => {
// This would not be caught by regular exception()
await t.exception.all(
() => eval("invalid syntax {"),
SyntaxError,
"should catch syntax error"
);
// This would not be caught by regular exception()
await t.exception.all(
() => undefinedVariable.property,
ReferenceError,
"should catch reference error"
);
});Assert that functions execute successfully or promises resolve, with execution timing.
/**
* Assert that function executes successfully or promise resolves
* @param functionOrPromise - Function to call or promise to await
* @param message - Optional assertion message (default: "should return" or "should resolve")
* @returns Promise<number> - Execution time in milliseconds
*/
execution(functionOrPromise: Function | Promise, message?: string): Promise<number>;Usage Examples:
test("execution testing", async (t) => {
// Function execution
const time1 = await t.execution(() => {
return "success";
}, "function should execute");
t.comment(`Function executed in ${time1}ms`);
// Promise resolution
const time2 = await t.execution(
Promise.resolve("async success"),
"promise should resolve"
);
t.comment(`Promise resolved in ${time2}ms`);
// Async function execution
const time3 = await t.execution(async () => {
await new Promise(resolve => setTimeout(resolve, 100));
return "delayed result";
}, "async function should complete");
t.ok(time3 >= 100, "should take at least 100ms");
});The expectedError parameter supports various matching patterns:
// Error matching patterns:
// - Error instance: new Error("message")
// - Error class: Error, TypeError, etc.
// - Object pattern: { name: "Error", message: "text" }
// - String pattern: "error message"
// - Regular expression: /pattern/
// - Function: (error) => booleanUsage Examples:
test("error pattern matching", async (t) => {
// Exact error instance
const expectedError = new Error("Specific error");
await t.exception(
() => { throw expectedError; },
expectedError,
"exact error instance"
);
// Error class
await t.exception(
() => { throw new TypeError("Bad type"); },
TypeError,
"error class matching"
);
// Object pattern
await t.exception(
() => { throw new Error("Not found"); },
{ name: "Error", message: "Not found" },
"object pattern matching"
);
// Regular expression
await t.exception(
() => { throw new Error("File not found: config.json"); },
/File not found: \w+\.json/,
"regex pattern matching"
);
// Custom function
await t.exception(
() => { throw new Error("HTTP 404: Page not found"); },
(error) => error.message.includes("404"),
"custom function matching"
);
});Both exception and execution methods properly handle async functions and promises:
test("async error handling", async (t) => {
// Async function that throws
await t.exception(async () => {
await new Promise(resolve => setTimeout(resolve, 10));
throw new Error("Async error");
}, "async function should throw");
// Promise that rejects
await t.exception(
new Promise((_, reject) => {
setTimeout(() => reject(new Error("Delayed rejection")), 10);
}),
"promise should reject"
);
// Async function that succeeds
const time = await t.execution(async () => {
await new Promise(resolve => setTimeout(resolve, 50));
return "success";
}, "async function should succeed");
t.ok(time >= 50, "should measure execution time correctly");
});Exception and execution tests integrate seamlessly with other test features:
test("integrated exception testing", async (t) => {
t.plan(3);
// This counts toward the plan
await t.exception(() => {
throw new Error("Expected error");
});
// This also counts
const time = await t.execution(() => "success");
// Regular assertion
t.ok(time >= 0, "execution time should be non-negative");
// Plan automatically completes when all 3 assertions are done
});