npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@grzpab/ts-spymaster

v0.0.4

Published

A spymaster library for TypeScript projects

Downloads

10

Readme

ts-spymaster

A spymaster library for TypeScript projects.

Context

During testing, developers usually want to know that a particular function:

  • was called a predefined number of times,
  • was called with predefined attributes,
  • returned predefined values.

Most coders achieve that using spies, which has been a standard practice for some time now. What the TS community misses, in the opinion of the creator of this library, is:

  • a component that manages all the spies,
  • a straightforward way to exchange spies in tests,
  • a simple way to reset all spies after a test has passed.

This library provided this and much more.

Library

As a spymaster is someone running a spy ring, the ts-spymaster library allows developers to control the lifecycles of spy objects during testing.

The library is agnostic towards test frameworks, meaning you can use virtually any framework or library with it. It contains bindings for Sinon spies, though.

Abstract Components

SpyProxy

The SpyProxy interface serves as a blueprint for a spy proxy. A spy proxy holds the following spies:

  • the default spy (you construct the proxy with it),
  • the current spy (initially the default spy, can be changed to a different one).

Developers can change the current spy at any time in runtime. Later, they can restore the proxy to use the default spy. This way the structure can proxy calls to the intended spy at the time. The spy may also reset the spy history.

Spymaster

The Spymaster abstract class holds all the spy proxies. It allows for setting up proxies, having all proxies use default spies, and resetting the history of all the spies.

Components

SinonSpyProxy

The SinonSpyProxy class serves as an implementation of the SpyProxy interface for Sinon spies.

SinonSpymaster

The SinonSpymaster serves as the implementation of the Spymaster class for Sinon spies.

Usage

The following snippet uses the Chai library for asserting.

import { SinonSpymaster } from '@grzpab/ts-spymaster';

// the setup phase
// setting up the spy manager and default spies
type Functions = Readonly<{
	fnc: (n: number) => number,
}>;

const spymaster = new SinonSpymaster<Functions>();
spymaster.setDefaultSpy('fnc', (n) => n);

// the pre-test phase
// just to show that the current spy is the default spy
const defaultSpy = spymaster.getCurrentSpy('fnc');

assert.equal(defaultSpy(10), 10);

// the test phase
// changing the current spy
spymaster.setCurrentSpy('fnc', (n) => 2*n);

const currentSpy = spymaster.getCurrentSpy('fnc');

assert.equal(currentSpy(10), 20);

// the post-test phase
// restoring the default spy
spymaster.restoreDefaultSpy('fnc');