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

justo.spy

v1.0.0-alpha2.0

Published

Test spies.

Downloads

7

Readme

justo.spy

A test stub library.

Proudly made with ♥ in Valencia, Spain, EU.

Developed in Dogma, compiled to JavaScript.

Module

The library must be included using the module justo.spy and importing as follows:

import spy from "justo.spy";

spy is an object to create spies.

Test doubles

A test double is an object representing another, used for performing unit tests. Types:

  • Test dummies. Test double responding to calls with no action.
  • Test stubs. Test double responding to calls with predefined responses.
  • Test spies. Test double monitoring the calls to a function or to an object.

Test spies

A spy is a test double to monitor the calls to a function or to an object.

Function spies

A function spy represents an object to monitor a function. When the function is called, the spy registers the call info.

This type of spy is created as follows:

function spy.func(fn) : FnProxy

spy.func() returns a proxy to use as the monitored function.

Example:

var sum = spy.func(function(x, y) { return x + y; });

sum(1, 2);  //returns 3
sum(3, 4);  //returns 7

When we need to spy a dummy function, use:

function spy.func() : FnProxy

Function spy data

We can query the spy to know how the function has been called and finished. For this aim, we need to get the spy object using spy():

function spy(fnProxy) : FnSpy

The spy must be queried as follows:

var sum = spy.func(function(x, y) { return x + y; });

sum(1, 2);  //returns 3
sum(3, 4);  //returns 7

var s = spy(sum);

s.called();           //returns 2
s.calledWith([1, 2]); //returns 1

Example:

//imports
import assert from "justo.assert";
import spy from "justo.spy";

//spying
const sum = spy.func(function(x, y) { return x + y; });

sum(1, 2);
sum(3, 4);

//asserting
const s = spy(sum);

assert(s.called()).eq(2);
assert(s.calledWith([1, 2])).eq(1);
assert(s.calledWith([3, 4])).eq(1);
assert(s.calledWith([5, 6])).eq(0);
assert(s.alwaysCalledWith([1, 2])).eq(false);

The spy methods are:

//return a given call
call(number)                    //returns {args, value, error}

//return the last call
lastCall()                      //returns {args, value, error}

//how many times the function was called
called()                        //returns number

//how many times the function was called with the given arguments
calledWith([a1, a2, ...])       //returns number
calledWith(argument)            //returns number

//check whether the function always called with the given arguments
alwaysCalledWith([a1, a2, ...]) //returns bool
alwaysCalledWith(argument)      //returns bool

//how many times the function returned
returned()                      //returns number

//how many times the function returned a given value
returned(value)                 //returns number

//check whether the function always returned
alwaysReturned()                //returns bool

//check whether the function always returned a given value
alwaysReturned(value)           //returns bool

//how many times the function raised an error
raised()                        //returns number

//how many times the function raised a given error
raised(err)                     //returns number

//check whether the function always raised an error
alwaysRaised()                  //returns bool

//check whether the function always raised a given error
alwaysRaised(err)               //returns bool

Object spies

An object spy monitors the access to the members of an object.

This type of spy is created as follows:

function spy.obj(object, member) : ObjProxy
function spy.obj(object, members) : ObjProxy

spy() returns the proxy to use as the monitored object.

The members to monitor can be fields or methods. To spy a field, we must use the format @field. Instead to monitor a method, method().

Example:

var u = spy.obj(user, ["@username", "changePassword()"])

u.username = "new-username"
u.changePassword("new-password")

Object spy data

We can query the spy to know how the object has been accessed as follows:

spy(objProxy).called("method()")
spy(objProxy).calledWith("method()", [1, 2])

Example:

//imports
import assert from "justo.assert";
import spy from "justo.spy";

//spying
var user = spy.obj(originalUser, ["changePassword()"]);

user.changePassword("new-pwd1");
user.changePassword("new-pwd2");

//asserting
var s = spy(user);

assert(s.called("changePassword()")).eq(2);
assert(s.calledWith("changePassword()", ["new-pwd1"])).eq(1);
assert(s.calledWith("changePassword()", ["new-pwd2"])).eq(1);
assert(s.calledWith("changePassword()", ["other-pwd"])).eq(0);

The spy methods are:

//return a given call/access
call("method()", number)                    //returns {args, value, error}
call("@field", number)                      //returns {accessor, value, error}

//return the last call/access
lastCall("method()")                        //returns {args, value, error}
lastCall("@field")                          //returns {accessor, value, error}

//how many times a method was called or a field was accessed
called("method()")                          //returns number
called("@field")                            //returns number

//how many times a method was called with the given arguments
calledWith("method()", [a1, a2, ...])       //returns number
calledWith("method()", argument)            //returns number

//check whether a method always called with the given arguments
alwaysCalledWith("method()", [a1, a2, ...]) //returns bool
alwaysCalledWith("method()", argument)      //returns bool

//how many times a member returned
returned("method()")                        //returns number
returned("@field")                          //returns number

//how many times a member returned given value
returned("method()", value)                 //returns number
returned("@field", value)                   //returns number

//check whether a member always returned
alwaysReturned("method()")                  //returns bool
alwaysReturned("@field")                    //returns bool

//check whether a member always returned a given value
alwaysReturned("method()", value)           //returns bool
alwaysReturned("@field", value)             //returns bool

//how many times a member raised an error
raised("method()")                          //returns number
raised("@field")                            //returns number

//how many times a member raised a given error
raised("method()", msg)                     //returns number
raised("@field", msg)                       //returns number

//check whether a member always raised an error
alwaysRaised("method()")                    //returns bool
alwaysRaised("@field")                      //returns bool

//check whether a member always raised a given error
alwaysRaised("method()", msg)               //returns bool
alwaysRaised("@field", msg)                 //returns bool