or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

cli-interface.mdconfiguration.mdexception-execution.mdindex.mdtest-assertions.mdtest-control.mdtest-creation.md
tile.json

exception-execution.mddocs/

Exception and Execution Testing

Testing for exceptions, promise rejections, and execution outcomes with detailed error matching.

Capabilities

Exception Testing

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"
  );
});

Exception with Native Errors

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"
  );
});

Execution Testing

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");
});

Error Pattern Matching

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) => boolean

Usage 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"
  );
});

Async Exception Handling

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");
});

Integration with Test Flow

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
});