CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jasmine-core

Simple JavaScript testing framework for browsers and 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-utilities.mddocs/

Test Utilities

Additional testing utilities including asymmetric equality testers, clock mocking, and helper functions for complex testing scenarios. These tools help handle edge cases and create more flexible test assertions.

Capabilities

Asymmetric Equality Testers

Special matcher objects that provide flexible matching for complex assertions.

/**
 * Match any instance of the given constructor
 * @param constructor - Constructor function to match against
 * @returns AsymmetricEqualityTester
 */
jasmine.any(constructor: Function): AsymmetricEqualityTester;

/**
 * Match any non-null, non-undefined value
 * @returns AsymmetricEqualityTester
 */
jasmine.anything(): AsymmetricEqualityTester;

/**
 * Match objects that contain at least the provided properties
 * @param sample - Object with properties to match
 * @returns AsymmetricEqualityTester
 */
jasmine.objectContaining(sample: object): AsymmetricEqualityTester;

/**
 * Match arrays that contain at least the provided elements
 * @param sample - Array with elements to match
 * @returns AsymmetricEqualityTester
 */
jasmine.arrayContaining(sample: any[]): AsymmetricEqualityTester;

/**
 * Match arrays with exactly the provided contents (order independent)
 * @param sample - Array with exact contents to match
 * @returns AsymmetricEqualityTester
 */
jasmine.arrayWithExactContents(sample: any[]): AsymmetricEqualityTester;

/**
 * Match Set objects that contain at least the provided values
 * @param sample - Set with values to match
 * @returns AsymmetricEqualityTester
 */
jasmine.setContaining(sample: Set<any>): AsymmetricEqualityTester;

/**
 * Match Map objects that contain at least the provided key-value pairs
 * @param sample - Map with entries to match
 * @returns AsymmetricEqualityTester
 */
jasmine.mapContaining(sample: Map<any, any>): AsymmetricEqualityTester;

Usage Examples:

// Match any string
expect('hello world').toEqual(jasmine.any(String));
expect(42).not.toEqual(jasmine.any(String));

// Match any number
expect(123).toEqual(jasmine.any(Number));
expect(new Date()).toEqual(jasmine.any(Date));

// Match anything non-null/undefined
expect('anything').toEqual(jasmine.anything());
expect(0).toEqual(jasmine.anything());
expect(false).toEqual(jasmine.anything());
expect(null).not.toEqual(jasmine.anything());

// Partial object matching
expect({
  id: 123,
  name: 'Alice',
  email: 'alice@example.com',
  metadata: { created: '2023-01-01' }
}).toEqual(jasmine.objectContaining({
  name: 'Alice',
  metadata: jasmine.objectContaining({ created: jasmine.any(String) })
}));

// Partial array matching
expect(['apple', 'banana', 'cherry', 'date']).toEqual(
  jasmine.arrayContaining(['banana', 'cherry'])
);

// Exact array contents (order doesn't matter)
expect([3, 1, 2]).toEqual(jasmine.arrayWithExactContents([1, 2, 3]));

// Set matching
const userRoles = new Set(['admin', 'user', 'moderator']);
expect(userRoles).toEqual(jasmine.setContaining(new Set(['admin', 'user'])));

// Map matching
const userPrefs = new Map([
  ['theme', 'dark'],
  ['language', 'en'],
  ['notifications', true]
]);
expect(userPrefs).toEqual(jasmine.mapContaining(new Map([
  ['theme', 'dark'],
  ['notifications', jasmine.any(Boolean)]
])));

String Matching Utilities

Asymmetric equality testers for string pattern matching.

/**
 * Match strings that match the given pattern
 * @param pattern - RegExp or string pattern to match
 * @returns AsymmetricEqualityTester
 */
jasmine.stringMatching(pattern: string | RegExp): AsymmetricEqualityTester;

/**
 * Match strings that contain the given substring
 * @param substring - Substring to search for
 * @returns AsymmetricEqualityTester
 */
jasmine.stringContaining(substring: string): AsymmetricEqualityTester;

Usage Examples:

// Pattern matching
expect('hello@example.com').toEqual(jasmine.stringMatching(/\S+@\S+\.\S+/));
expect('user123').toEqual(jasmine.stringMatching(/user\d+/));
expect('Product ABC-123').toEqual(jasmine.stringMatching('ABC'));

// Substring matching
expect('The quick brown fox').toEqual(jasmine.stringContaining('quick'));
expect('Error: File not found').toEqual(jasmine.stringContaining('Error:'));

// In object matching
expect({
  id: 'user-456',
  email: 'bob@company.com',
  message: 'Welcome to our service!'
}).toEqual({
  id: jasmine.stringMatching(/user-\d+/),
  email: jasmine.stringContaining('@company.com'),
  message: jasmine.stringContaining('Welcome')
});

Truthiness and Collection Utilities

Asymmetric equality testers for common value patterns.

/**
 * Match any truthy value
 * @returns AsymmetricEqualityTester
 */
jasmine.truthy(): AsymmetricEqualityTester;

/**
 * Match any falsy value
 * @returns AsymmetricEqualityTester
 */
jasmine.falsy(): AsymmetricEqualityTester;

/**
 * Match empty collections or strings
 * @returns AsymmetricEqualityTester
 */
jasmine.empty(): AsymmetricEqualityTester;

/**
 * Match non-empty collections or strings
 * @returns AsymmetricEqualityTester
 */
jasmine.notEmpty(): AsymmetricEqualityTester;

/**
 * Match using reference equality (===)
 * @param expected - Value to compare by reference
 * @returns AsymmetricEqualityTester
 */
jasmine.is(expected: any): AsymmetricEqualityTester;

Usage Examples:

// Truthiness matching
expect(1).toEqual(jasmine.truthy());
expect('hello').toEqual(jasmine.truthy());
expect(true).toEqual(jasmine.truthy());
expect(0).not.toEqual(jasmine.truthy());

expect(false).toEqual(jasmine.falsy());
expect(0).toEqual(jasmine.falsy());
expect('').toEqual(jasmine.falsy());
expect(null).toEqual(jasmine.falsy());

// Collection matching
expect([]).toEqual(jasmine.empty());
expect('').toEqual(jasmine.empty());
expect(new Set()).toEqual(jasmine.empty());

expect([1, 2, 3]).toEqual(jasmine.notEmpty());
expect('hello').toEqual(jasmine.notEmpty());
expect(new Map([['key', 'value']])).toEqual(jasmine.notEmpty());

// Reference equality
const obj = { name: 'test' };
expect(obj).toEqual(jasmine.is(obj));
expect({ name: 'test' }).not.toEqual(jasmine.is(obj)); // Different objects

Clock Mocking

Functions for mocking JavaScript's timer functions and Date constructor.

/**
 * Get the mock clock instance
 * @returns Clock instance for time manipulation
 */
jasmine.clock(): Clock;

interface Clock {
  /**
   * Install the mock clock, replacing native timer functions
   */
  install(): void;
  
  /**
   * Uninstall the mock clock, restoring native timer functions
   */
  uninstall(): void;
  
  /**
   * Advance the mock clock by the specified number of milliseconds
   * @param milliseconds - Time to advance
   */
  tick(milliseconds: number): void;
  
  /**
   * Set the mock current date
   * @param date - Date to set as current time
   */
  mockDate(date?: Date): void;
  
  /**
   * Get the current mock time
   * @returns Current mock time as Date
   */
  mockDate(): Date;
}

Usage Examples:

describe('Timer functions', () => {
  beforeEach(() => {
    jasmine.clock().install();
  });
  
  afterEach(() => {
    jasmine.clock().uninstall();
  });
  
  it('should handle setTimeout', () => {
    let callback = jasmine.createSpy('callback');
    
    setTimeout(callback, 1000);
    expect(callback).not.toHaveBeenCalled();
    
    jasmine.clock().tick(1000);
    expect(callback).toHaveBeenCalled();
  });
  
  it('should handle setInterval', () => {
    let callback = jasmine.createSpy('callback');
    
    setInterval(callback, 500);
    
    jasmine.clock().tick(1500);
    expect(callback).toHaveBeenCalledTimes(3);
  });
  
  it('should mock Date', () => {
    const mockDate = new Date(2023, 0, 1); // January 1, 2023
    jasmine.clock().mockDate(mockDate);
    
    expect(new Date()).toEqual(mockDate);
    expect(Date.now()).toBe(mockDate.getTime());
    
    // Advance time
    jasmine.clock().tick(60000); // 1 minute
    expect(new Date().getTime()).toBe(mockDate.getTime() + 60000);
  });
  
  it('should handle async operations with timers', async () => {
    const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
    
    const startTime = Date.now();
    const promise = delay(2000).then(() => Date.now() - startTime);
    
    jasmine.clock().tick(2000);
    const elapsed = await promise;
    
    expect(elapsed).toBe(2000);
  });
});

Pretty Printing Utilities

Functions for formatting objects in test output and error messages.

/**
 * Pretty print any value for display in test output
 * @param object - Value to format
 * @returns Formatted string representation
 */
jasmine.pp(object: any): string;

/**
 * Check if a value is undefined
 * @param obj - Value to check
 * @returns Whether value is undefined
 */
jasmine.isUndefined(obj: any): boolean;

/**
 * Create a shallow clone of an object or array
 * @param obj - Object or array to clone
 * @returns Shallow copy of the input
 */
jasmine.clone(obj: any): any;

/**
 * Clone function arguments into a regular array
 * @param args - Arguments object to clone
 * @returns Array containing the arguments
 */
jasmine.cloneArgs(args: IArguments): any[];

Usage Examples:

// Pretty printing for custom error messages
const complexObject = {
  users: [{ name: 'Alice' }, { name: 'Bob' }],
  settings: { theme: 'dark', notifications: true }
};

console.log(jasmine.pp(complexObject));
// Output: Object({ users: [ Object({ name: 'Alice' }), Object({ name: 'Bob' }) ], settings: Object({ theme: 'dark', notifications: true }) })

// Utility functions
expect(jasmine.isUndefined(undefined)).toBe(true);
expect(jasmine.isUndefined(null)).toBe(false);

const original = { a: 1, b: [2, 3] };
const cloned = jasmine.clone(original);
cloned.a = 99;
expect(original.a).toBe(1); // Original unchanged

function testFunction() {
  const argsArray = jasmine.cloneArgs(arguments);
  expect(Array.isArray(argsArray)).toBe(true);
  expect(argsArray).toEqual(['arg1', 'arg2']);
}
testFunction('arg1', 'arg2');

Utility Helper Functions

Additional utility functions for testing scenarios.

/**
 * Get property descriptor from object or its prototype chain
 * @param obj - Object to inspect
 * @param prop - Property name
 * @returns Property descriptor or undefined
 */
jasmine.getPropertyDescriptor(obj: any, prop: string): PropertyDescriptor | undefined;

/**
 * Create a matcher that always fails (useful for testing)
 * @param message - Optional failure message
 * @returns Failed matcher result
 */
jasmine.createSpy.isSpy(obj: any): boolean;

Usage Examples:

// Property descriptor inspection
const obj = {
  get name() { return this._name; },
  set name(value) { this._name = value; }
};

const descriptor = jasmine.getPropertyDescriptor(obj, 'name');
expect(descriptor.get).toBeDefined();
expect(descriptor.set).toBeDefined();

// Spy detection
const regularFunction = () => {};
const spy = jasmine.createSpy('testSpy');

expect(jasmine.createSpy.isSpy(regularFunction)).toBe(false);
expect(jasmine.createSpy.isSpy(spy)).toBe(true);

// This is useful for conditional spy setup
function maybeSpyOn(obj, method) {
  if (!jasmine.createSpy.isSpy(obj[method])) {
    spyOn(obj, method);
  }
}

Error Handling Utilities

Utilities for working with errors and exceptions in tests.

/**
 * Create an error with a specific message and stack trace
 * Used internally by Jasmine for consistent error formatting
 */
jasmine.createError(message: string, stack?: string): Error;

/**
 * Format error messages consistently
 * Used by matchers for error reporting
 */
jasmine.formatErrorMsg(domain: string, usage: string): (msg: string) => string;

Usage Examples:

// In custom matchers or test utilities
function validateInput(input) {
  if (!input) {
    throw jasmine.createError('Input is required');
  }
  return input.toUpperCase();
}

// Custom matcher using error formatting
jasmine.addMatchers({
  toBeValidConfig: (util) => {
    return {
      compare: (actual) => {
        const formatter = jasmine.formatErrorMsg('ConfigValidator', 'toBeValidConfig()');
        
        if (typeof actual !== 'object') {
          return {
            pass: false,
            message: formatter('Expected an object')
          };
        }
        
        return { pass: true };
      }
    };
  }
});

Debug and Development Utilities

Utilities for debugging tests and working with Jasmine's internal functionality.

/**
 * Log a debug message that will be included in spec results if the spec fails
 * @param message - Message to log for debugging
 */
jasmine.debugLog(message: string): void;

/**
 * Check if a function is a Jasmine spy
 * @param putativeSpy - Function to check
 * @returns Whether the function is a spy
 */
jasmine.isSpy(putativeSpy: any): boolean;

/**
 * Replace global error handling with a spy for testing uncaught exceptions
 * @param fn - Async function to run with global error spy active
 * @returns Promise that resolves when the function completes
 */
jasmine.spyOnGlobalErrorsAsync(fn: (globalErrorSpy: Spy) => Promise<void>): Promise<void>;

Usage Examples:

describe('Debug utilities', () => {
  it('should log debug messages on failure', () => {
    jasmine.debugLog('Setting up test data');
    const testData = { id: 1, name: 'test' };
    
    jasmine.debugLog('Performing validation');
    expect(testData.id).toBe(2); // This will fail
    
    // Debug messages will appear in the failure output
  });

  it('should detect spies correctly', () => {
    const regularFunction = () => 'result';
    const spyFunction = jasmine.createSpy('testSpy');
    
    expect(jasmine.isSpy(regularFunction)).toBe(false);
    expect(jasmine.isSpy(spyFunction)).toBe(true);
    
    // Useful for conditional logic
    if (!jasmine.isSpy(regularFunction)) {
      console.log('This is not a spy');
    }
  });

  it('should spy on global errors', async () => {
    await jasmine.spyOnGlobalErrorsAsync(async (globalErrorSpy) => {
      // Trigger an uncaught exception
      setTimeout(() => {
        throw new Error('Test error');
      }, 0);
      
      // Wait for the error to be thrown
      await new Promise(resolve => setTimeout(resolve, 10));
      
      // Verify the error was caught by the spy
      expect(globalErrorSpy).toHaveBeenCalledWith(jasmine.any(Error));
      expect(globalErrorSpy.calls.argsFor(0)[0].message).toBe('Test error');
    });
  });
});

Types

interface AsymmetricEqualityTester {
  asymmetricMatch(other: any, customTesters: EqualityTester[]): boolean;
  jasmineToString(): string;
}

interface Clock {
  install(): void;
  uninstall(): void;
  tick(milliseconds: number): void;
  mockDate(date?: Date): void | Date;
}

interface EqualityTester {
  (first: any, second: any): boolean | undefined;
}

docs

custom-extensions.md

environment-config.md

expectations-matchers.md

index.md

spy-system.md

test-organization.md

test-utilities.md

tile.json