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

spy-system.mddocs/

Spy System

Jasmine's comprehensive mocking and spying functionality for testing object interactions, method calls, and return values. Includes spy creation, behavior configuration, call tracking, and verification.

Capabilities

Spy Creation Functions

Functions for creating spies on existing objects and methods.

/**
 * Install a spy on an existing object method
 * @param obj - Object containing the method to spy on
 * @param methodName - Name of the method to spy on
 * @returns Spy object for configuration and verification
 */
function spyOn(obj: object, methodName: string): Spy;

/**
 * Install a spy on an object property getter or setter
 * @param obj - Object containing the property to spy on
 * @param propertyName - Name of the property to spy on
 * @param accessType - Type of access to spy on ('get', 'set', or both)
 * @returns PropertySpy object
 */
function spyOnProperty(obj: object, propertyName: string, accessType?: 'get' | 'set'): PropertySpy;

/**
 * Install spies on all functions of an object
 * @param obj - Object to spy on all functions
 * @param includeNonEnumerable - Whether to include non-enumerable functions
 * @returns Object with all function names as keys and spies as values
 */
function spyOnAllFunctions(obj: object, includeNonEnumerable?: boolean): { [key: string]: Spy };

Usage Examples:

const calculator = {
  add: (a, b) => a + b,
  multiply: (a, b) => a * b
};

// Spy on existing method
const addSpy = spyOn(calculator, 'add');
calculator.add(2, 3);
expect(addSpy).toHaveBeenCalledWith(2, 3);

// Spy on property
const obj = {
  get value() { return this._value; },
  set value(val) { this._value = val; }
};

spyOnProperty(obj, 'value', 'get');
const val = obj.value;
expect(obj.value).toHaveBeenCalled();

// Spy on all functions
const mathUtils = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  helper: () => 'helper'
};

spyOnAllFunctions(mathUtils);
mathUtils.add(1, 2);
mathUtils.subtract(5, 3);
expect(mathUtils.add).toHaveBeenCalled();
expect(mathUtils.subtract).toHaveBeenCalled();

Jasmine Spy Factory Functions

Functions for creating standalone spies and spy objects.

/**
 * Create a standalone spy function
 * @param name - Optional name for the spy (for better error messages)
 * @param originalFn - Optional original function to wrap
 * @returns Spy function
 */
jasmine.createSpy(name?: string, originalFn?: Function): Spy;

/**
 * Create an object with multiple spy methods
 * @param baseName - Base name for the spy object
 * @param methodNames - Array of method names or object with method configurations
 * @param propertyNames - Optional array of property names or object with property configurations
 * @returns Object with spy methods and properties
 */
jasmine.createSpyObj(
  baseName: string,
  methodNames: string[] | { [methodName: string]: any },
  propertyNames?: string[] | { [propertyName: string]: any }
): any;

Usage Examples:

// Create standalone spy
const callback = jasmine.createSpy('callback');
callback('arg1', 'arg2');
expect(callback).toHaveBeenCalledWith('arg1', 'arg2');

// Create spy with original function
const originalFn = (x) => x * 2;
const spy = jasmine.createSpy('doubler', originalFn);

// Create spy object with methods
const userService = jasmine.createSpyObj('UserService', [
  'getUser',
  'saveUser',
  'deleteUser'
]);

userService.getUser.and.returnValue({ id: 1, name: 'John' });
const user = userService.getUser(1);
expect(user.name).toBe('John');

// Create spy object with methods and properties
const apiClient = jasmine.createSpyObj(
  'ApiClient',
  ['get', 'post'],
  ['baseUrl', 'timeout']
);

apiClient.baseUrl = 'https://api.example.com';
apiClient.get.and.returnValue(Promise.resolve({ data: 'response' }));

Spy Behavior Configuration

Methods for configuring how spies behave when called.

interface SpyStrategy {
  /**
   * Make spy return a specific value
   * @param value - Value to return when spy is called
   * @returns The spy for chaining
   */
  returnValue(value: any): Spy;
  
  /**
   * Make spy return different values on successive calls
   * @param ...values - Values to return in order
   * @returns The spy for chaining
   */
  returnValues(...values: any[]): Spy;
  
  /**
   * Make spy call a fake function instead of original
   * @param fn - Function to call instead
   * @returns The spy for chaining
   */
  callFake(fn: Function): Spy;
  
  /**
   * Make spy call through to the original function
   * @returns The spy for chaining
   */
  callThrough(): Spy;
  
  /**
   * Make spy throw an error when called
   * @param msg - Error message or Error object to throw
   * @returns The spy for chaining
   */
  throwError(msg?: string | Error): Spy;
  
  /**
   * Make spy do nothing when called (default behavior)
   * @returns The spy for chaining
   */
  stub(): Spy;
  
  /**
   * Make spy return a resolved promise
   * @param value - Value to resolve with
   * @returns The spy for chaining
   */
  resolveTo(value?: any): Spy;
  
  /**
   * Make spy return a rejected promise
   * @param value - Value to reject with
   * @returns The spy for chaining
   */
  rejectWith(value?: any): Spy;
}

Usage Examples:

const spy = jasmine.createSpy('testSpy');

// Return specific value
spy.and.returnValue(42);
expect(spy()).toBe(42);

// Return different values
spy.and.returnValues(1, 2, 3);
expect(spy()).toBe(1);
expect(spy()).toBe(2);
expect(spy()).toBe(3);

// Call fake function
spy.and.callFake((x, y) => x + y);
expect(spy(5, 3)).toBe(8);

// Throw error
spy.and.throwError('Something went wrong');
expect(() => spy()).toThrowError('Something went wrong');

// Return promises
const asyncSpy = jasmine.createSpy('asyncSpy');
asyncSpy.and.resolveTo('success');
await expectAsync(asyncSpy()).toBeResolvedTo('success');

asyncSpy.and.rejectWith('error');
await expectAsync(asyncSpy()).toBeRejectedWith('error');

// Call through to original
const obj = { method: (x) => x * 2 };
spyOn(obj, 'method').and.callThrough();
expect(obj.method(5)).toBe(10); // calls original
expect(obj.method).toHaveBeenCalledWith(5);

Call Tracking and Verification

Methods for tracking and verifying spy calls.

interface CallTracker {
  /**
   * Get the number of times the spy was called
   * @returns Number of calls
   */
  count(): number;
  
  /**
   * Get arguments for a specific call
   * @param index - Index of the call (0-based)
   * @returns Array of arguments for that call
   */
  argsFor(index: number): any[];
  
  /**
   * Get all arguments for all calls
   * @returns Array of argument arrays
   */
  allArgs(): any[][];
  
  /**
   * Get all call objects with full details
   * @returns Array of call objects
   */
  all(): CallInfo[];
  
  /**
   * Get the most recent call object
   * @returns Most recent call object or undefined
   */
  mostRecent(): CallInfo | undefined;
  
  /**
   * Get the first call object
   * @returns First call object or undefined
   */
  first(): CallInfo | undefined;
  
  /**
   * Reset the spy's call history
   */
  reset(): void;
}

interface CallInfo {
  object: any;
  args: any[];
  returnValue: any;
}

Usage Examples:

const spy = jasmine.createSpy('testSpy');

spy('first', 'call');
spy('second', 'call');
spy('third', 'call');

// Check call count
expect(spy.calls.count()).toBe(3);

// Check specific call arguments
expect(spy.calls.argsFor(0)).toEqual(['first', 'call']);
expect(spy.calls.argsFor(1)).toEqual(['second', 'call']);

// Get all arguments
expect(spy.calls.allArgs()).toEqual([
  ['first', 'call'],
  ['second', 'call'],
  ['third', 'call']
]);

// Get call details
const firstCall = spy.calls.first();
expect(firstCall.args).toEqual(['first', 'call']);

const lastCall = spy.calls.mostRecent();
expect(lastCall.args).toEqual(['third', 'call']);

// Reset call history
spy.calls.reset();
expect(spy.calls.count()).toBe(0);

Spy Object Interface

The complete spy object interface showing all available properties and methods.

interface Spy extends Function {
  /** Strategy object for configuring spy behavior */
  and: SpyStrategy;
  
  /** Call tracker for verifying calls */
  calls: CallTracker;
  
  /** Original function identity (internal) */
  identity: string;
}

interface PropertySpy {
  /** Strategy object for configuring property spy behavior */
  and: SpyStrategy;
  
  /** Call tracker for verifying property access */
  calls: CallTracker;
}

Advanced Spy Features

Additional spy functionality for complex testing scenarios.

/**
 * Add a custom spy strategy that can be used by any spy
 * @param name - Name of the strategy
 * @param factory - Function that creates the strategy
 */
jasmine.addSpyStrategy(name: string, factory: (spy: Spy) => Function): void;

/**
 * Set the default spy strategy for all new spies
 * @param defaultStrategyFn - Function that returns default strategy
 */
jasmine.setDefaultSpyStrategy(defaultStrategyFn: (name: string, originalFn?: Function) => Function): void;

Usage Examples:

// Add custom spy strategy
jasmine.addSpyStrategy('returnRandomValue', (spy) => {
  return () => Math.random();
});

const spy = jasmine.createSpy('randomSpy');
spy.and.returnRandomValue();
const result = spy();
expect(typeof result).toBe('number');

// Set default spy strategy
jasmine.setDefaultSpyStrategy((name, originalFn) => {
  return function() {
    console.log(`Spy ${name} was called`);
    return originalFn ? originalFn.apply(this, arguments) : undefined;
  };
});

Spy Restoration

Methods for restoring original functionality after spying.

/**
 * Restore all spies to their original functions
 * Usually called in afterEach hooks
 */
function restoreAllSpies(): void;

Usage Examples:

describe('Test suite with spies', () => {
  let originalConsoleLog;
  
  beforeEach(() => {
    originalConsoleLog = console.log;
    spyOn(console, 'log');
  });
  
  afterEach(() => {
    // Restore all spies after each test
    restoreAllSpies();
  });
  
  it('should spy on console.log', () => {
    console.log('test message');
    expect(console.log).toHaveBeenCalledWith('test message');
  });
  
  it('should have clean slate', () => {
    // console.log spy is restored to original
    expect(console.log).toBe(originalConsoleLog);
  });
});

Types

interface Spy extends Function {
  and: SpyStrategy;
  calls: CallTracker;
  identity: string;
}

interface SpyStrategy {
  returnValue(value: any): Spy;
  returnValues(...values: any[]): Spy;
  callFake(fn: Function): Spy;
  callThrough(): Spy;
  throwError(msg?: string | Error): Spy;
  stub(): Spy;
  resolveTo(value?: any): Spy;
  rejectWith(value?: any): Spy;
}

interface CallTracker {
  count(): number;
  argsFor(index: number): any[];
  allArgs(): any[][];
  all(): CallInfo[];
  mostRecent(): CallInfo | undefined;
  first(): CallInfo | undefined;
  reset(): void;
}

interface CallInfo {
  object: any;
  args: any[];
  returnValue: any;
}

interface PropertySpy {
  and: SpyStrategy;
  calls: CallTracker;
}

docs

custom-extensions.md

environment-config.md

expectations-matchers.md

index.md

spy-system.md

test-organization.md

test-utilities.md

tile.json