CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jasmine-node

DOM-less simple JavaScript BDD testing framework for Node.js

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

test-writing.mddocs/

Test Writing

Core BDD functions for writing test suites and specifications with jasmine-node. Includes support for test organization, setup/teardown, assertions, spies, and asynchronous testing.

Capabilities

Test Suite Definition

Define test suites using the describe function to group related specifications.

/**
 * Define a test suite with a descriptive name and specification functions
 * @param description - Descriptive name for the test suite
 * @param specDefinitions - Function containing it() calls and setup
 */
function describe(description: string, specDefinitions: () => void): void;

/**
 * Skip/disable a test suite (will not be executed)
 * @param description - Descriptive name for the skipped test suite
 * @param specDefinitions - Function containing it() calls and setup
 */
function xdescribe(description: string, specDefinitions: () => void): void;

Usage Examples:

describe("User Authentication", function() {
  // Test specifications go here
  it("should validate user credentials", function() {
    // Test implementation
  });

  describe("Password Reset", function() {
    // Nested describe blocks for sub-functionality
    it("should send reset email", function() {
      // Test implementation
    });
  });
});

// Skip entire test suite during development/debugging
xdescribe("Feature Under Development", function() {
  it("should work eventually", function() {
    // This won't run
  });
});

Test Specification

Define individual test specifications within describe blocks.

/**
 * Define a test specification with optional timeout
 * @param description - Descriptive name for the test
 * @param specFunction - Test function, optionally accepting done callback
 * @param timeout - Optional timeout in milliseconds (default: 5000)
 */
function it(description: string, specFunction: (done?: () => void) => void, timeout?: number): void;

/**
 * Skip/disable a test specification (will not be executed)
 * @param description - Descriptive name for the skipped test
 * @param specFunction - Test function that won't be executed
 */
function xit(description: string, specFunction: () => void): void;

Usage Examples:

describe("Calculator", function() {
  it("should add two numbers", function() {
    const result = add(2, 3);
    expect(result).toEqual(5);
  });

  it("should handle async operations", function(done) {
    setTimeout(function() {
      expect(true).toBe(true);
      done();
    }, 100);
  });

  it("should timeout after custom duration", function(done) {
    // This test will timeout after 1 second instead of default 5 seconds
    setTimeout(done, 500);
  }, 1000);

  it("should handle async errors", function(done) {
    setTimeout(function() {
      try {
        expect(false).toBe(true);
        done();
      } catch (error) {
        done(error); // Pass error to done() to fail the test
      }
    }, 100);
  });

  // Skip this test during development
  xit("should handle edge case", function() {
    // This won't run
  });
});

Setup and Teardown

Functions to run setup and teardown code before and after each test specification.

/**
 * Run setup function before each test specification in the suite
 * @param setupFunction - Function to run before each test, optionally accepting done callback
 * @param timeout - Optional timeout in milliseconds for async setup
 */
function beforeEach(setupFunction: (done?: () => void) => void, timeout?: number): void;

/**
 * Run teardown function after each test specification in the suite
 * @param teardownFunction - Function to run after each test, optionally accepting done callback
 * @param timeout - Optional timeout in milliseconds for async teardown
 */
function afterEach(teardownFunction: (done?: () => void) => void, timeout?: number): void;

Usage Examples:

describe("Database Operations", function() {
  let database;

  beforeEach(function() {
    database = new MockDatabase();
    database.connect();
  });

  afterEach(function() {
    database.disconnect();
    database = null;
  });

  // Async setup and teardown
  beforeEach(function(done) {
    initializeTestData(function() {
      done();
    });
  });

  afterEach(function(done) {
    cleanupTestData(function() {
      done();
    });
  });

  it("should save user data", function() {
    const user = { name: "John", email: "john@example.com" };
    const result = database.save(user);
    expect(result.success).toBe(true);
  });
});

Expectations and Matchers

Create expectations and assertions using the expect function and built-in matchers.

/**
 * Create an expectation for testing actual values
 * @param actual - The actual value to test
 * @returns Matchers object with assertion methods
 */
function expect(actual: any): jasmine.Matchers;

interface jasmine.Matchers {
  /** Assert strict equality (===) */
  toBe(expected: any): boolean;
  /** Assert deep equality for objects and arrays */
  toEqual(expected: any): boolean;
  /** Assert string or regex match */
  toMatch(expected: string | RegExp): boolean;
  /** Assert value is null */
  toBeNull(): boolean;
  /** Assert value is undefined */
  toBeUndefined(): boolean;
  /** Assert value is truthy */
  toBeTruthy(): boolean;
  /** Assert value is falsy */
  toBeFalsy(): boolean;
  /** Assert array/string contains value */
  toContain(expected: any): boolean;
  /** Assert numeric greater than */
  toBeGreaterThan(expected: number): boolean;
  /** Assert numeric less than */
  toBeLessThan(expected: number): boolean;
  /** Assert function throws exception */
  toThrow(expected?: any): boolean;
  /** Assert spy was called (from jasmine-reporters) */
  toHaveBeenCalled(): boolean;
  /** Assert spy was called with specific arguments (from jasmine-reporters) */
  toHaveBeenCalledWith(...args: any[]): boolean;
  /** Negate any matcher */
  not: jasmine.Matchers;
}

Usage Examples:

describe("Matchers", function() {
  it("should demonstrate basic matchers", function() {
    expect(5).toBe(5);                    // Strict equality
    expect({name: "John"}).toEqual({name: "John"}); // Deep equality
    expect("hello world").toMatch(/world/); // Regex match
    expect(null).toBeNull();              // Null check
    expect(undefined).toBeUndefined();    // Undefined check
    expect("truthy").toBeTruthy();        // Truthy check
    expect(0).toBeFalsy();                // Falsy check
    expect([1, 2, 3]).toContain(2);       // Array contains
    expect(10).toBeGreaterThan(5);        // Numeric comparison
    expect(3).toBeLessThan(10);           // Numeric comparison
  });

  it("should demonstrate negation", function() {
    expect(5).not.toBe(10);
    expect("hello").not.toMatch(/goodbye/);
  });

  it("should test exceptions", function() {
    expect(function() {
      throw new Error("Something went wrong");
    }).toThrow();

    expect(function() {
      throw new Error("Specific error");
    }).toThrow("Specific error");
  });
});

Spies and Mocking

Create spies for testing function calls, arguments, and return values.

/**
 * Create a spy on an object method to track calls and control behavior
 * @param object - Object containing the method to spy on
 * @param method - Method name to spy on
 * @returns Spy object with tracking and stubbing methods
 */
function spyOn(object: any, method: string): jasmine.Spy;

interface jasmine.Spy {
  /** Make spy return specific value */
  andReturn(value: any): jasmine.Spy;
  /** Make spy throw specific exception */
  andThrow(exception: any): jasmine.Spy;
  /** Make spy call through to original method */
  andCallThrough(): jasmine.Spy;
  /** Make spy call fake function instead */
  andCallFake(fakeFunction: Function): jasmine.Spy;
  /** Array of all call objects */
  calls: any[];
  /** Most recent call object with args */
  mostRecentCall: { args: any[] };
  /** Array of argument arrays for each call */
  argsForCall: any[][];
  /** Number of times spy was called */
  callCount: number;
}

Usage Examples:

describe("User Service", function() {
  let userService, httpClient;

  beforeEach(function() {
    httpClient = {
      get: function() {},
      post: function() {}
    };
    userService = new UserService(httpClient);
  });

  it("should call HTTP client with correct URL", function() {
    spyOn(httpClient, 'get').andReturn({id: 1, name: "John"});
    
    const user = userService.getUser(123);
    
    expect(httpClient.get).toHaveBeenCalled();
    expect(httpClient.get).toHaveBeenCalledWith('/users/123');
    expect(httpClient.get.callCount).toBe(1);
    expect(user.name).toBe("John");
  });

  it("should handle errors from HTTP client", function() {
    spyOn(httpClient, 'get').andThrow(new Error("Network error"));
    
    expect(function() {
      userService.getUser(123);
    }).toThrow("Network error");
  });

  it("should use fake implementation", function() {
    spyOn(httpClient, 'post').andCallFake(function(url, data) {
      return { success: true, id: 999 };
    });
    
    const result = userService.createUser({name: "Jane"});
    expect(result.id).toBe(999);
  });
});

Asynchronous Testing

jasmine-node provides multiple patterns for handling asynchronous operations in tests. The primary approach uses the done callback pattern, with additional support for waits, waitsFor, and runs.

/**
 * Wait for asynchronous condition to become true
 * @param latchFunction - Function that returns true when condition is met
 * @param timeoutMessage - Message to display if timeout occurs
 * @param timeout - Timeout in milliseconds (default: 5000)
 */
function waitsFor(latchFunction: () => boolean, timeoutMessage?: string, timeout?: number): void;

/**
 * Wait for specified duration
 * @param timeout - Time to wait in milliseconds
 */
function waits(timeout: number): void;

/**
 * Execute function in test context (used with waits/waitsFor)
 * @param asyncMethod - Function to execute
 */
function runs(asyncMethod: () => void): void;

Done Callback Pattern

jasmine-node enhances the standard Jasmine framework with automatic detection of asynchronous specs. When a test function accepts a parameter (typically named done), jasmine-node automatically treats it as an asynchronous test and provides a callback function that must be called to complete the test.

The async callback implementation wraps the original test function and:

  • Detects when a function parameter is present (indicating async)
  • Provides a done() callback that marks the test as complete
  • Automatically fails the test if done() is not called within the timeout period
  • Supports error handling by passing an error to done(error)

Usage Examples:

describe("Async Operations", function() {
  it("should handle async with done callback", function(done) {
    setTimeout(function() {
      expect(true).toBe(true);
      done();
    }, 100);
  });

  it("should use waitsFor pattern", function() {
    let completed = false;
    
    runs(function() {
      setTimeout(function() {
        completed = true;
      }, 100);
    });
    
    waitsFor(function() {
      return completed;
    }, "operation to complete", 1000);
    
    runs(function() {
      expect(completed).toBe(true);
    });
  });

  it("should use waits pattern", function() {
    let value = 0;
    
    runs(function() {
      setTimeout(function() {
        value = 42;
      }, 50);
    });
    
    waits(100);
    
    runs(function() {
      expect(value).toBe(42);
    });
  });
});

Global Environment Access

/**
 * Get current Jasmine environment for configuration
 * @returns Jasmine environment object
 */
function jasmine.getEnv(): jasmine.Env;

interface jasmine.Env {
  /** Default timeout for async operations in milliseconds */
  defaultTimeoutInterval: number;
  /** Execute all registered specs */
  execute(): void;
  /** Add reporter to environment */
  addReporter(reporter: any): void;
}

Usage Examples:

// Set default timeout for all async tests
jasmine.getEnv().defaultTimeoutInterval = 10000;

// Add custom reporter
jasmine.getEnv().addReporter(new CustomReporter());

docs

advanced-features.md

cli-usage.md

index.md

reporters.md

test-writing.md

tile.json