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 🙏

© 2024 – Pkg Stats / Ryan Hefner

instatest

v0.3.3

Published

Super lightweight framework for instantaneous unit testing

Downloads

3

Readme

instatest

Super lightweight framework for instantaneous unit testing of JavaScript packages.

Installation

npm install instatest

Usage

Insert a test into your code via

import * as insta from "instatest";

insta.beginUnit("my-package", "my-file");

insta.test("My test", () => {
  insta.assert(2 + 2 == 4, "Test addition");
});

insta.endUnit("my-package", "my-file");

Running

npx instatest src

will search the src directory for all .js and .mjs files and run them. Afterwards, it will execute all found tests in the same order as they were found and display a summary of the result. Note that only tests are executed which are in units with the same package name as the current package.

Configuration

You can pass a list of files and directories to instatest. Directories are searched recursively for .js and .mjs files. For example, via

npx instatest index.js test

you run index.js and all .js and .mjs files located in the test directory or one of its subdirectories.

Of course, you can install instatest also as a script in your package.json file via

...
"scripts": {
    "test": "instatest index.js test",
    ...
  },
...

and then run it via

npm run test

Note that instatest assumes that your package is configured to use ES modules, so your package.json should also include

...
 "type": "module",
...

Tests

The following assumes that you have imported the instatest module via

import * as insta from "instatest";

The statement insta.test(descr, fn) executes the tests in function fn and groups the results together under the label descr. The function fn can be an async function.

Tests can be nested, for example:

insta.test("My Test", () => {
   insta.test("Addition", () => {
       insta.assertEq(2 + 2, 4);
       insta.assertEq(7 + 3, 10);
       insta.assertThrow(() => { throw 42; });
   });
   insta.test("Multiplication", () => {
       insta.assertEq(2 * 2, 4);
       insta.assertEq(7 * 3, 21);
   });
   insta.assertEq(1/0, Number.POSITIVE_INFINITY, "Division");
});

Assert

Asserts must be done from within a surrounding test. The following variants are available:

  • assert(cond, descr) or assertTrue(cond, descr): Asserts that cond is strictly equal to true.
  • assertFalse(cond, descr): Asserts that cond is strictly equal to false.
  • assertEq(x, y, descr): Asserts that values x and y are equal. Equality is implemented via eq, which is basically strict equality for primitive types, and deep equality for objects.
  • assertNEq(x, y, descr): Asserts that values x and y are unequal, i.e. that !eq(x, y).
  • assertThrow(fn, descr): Asserts that executing the function fn asynchronously results in an exception.
  • assertLazy(fn, descr): Asserts that asynchronous execution of the function fn results in a value strictly equal to true.

Units

Just as asserts live inside of tests, tests live inside of units. A unit has a package name, and can furthermore carry a list of arbitrary string qualifiers. Units are necessary so that testing can skip those tests which do not belong to the current package, but just to a package it depends on. A unit is started via

insta.beginUnit("package", ...);

and ends with

insta.endUnit("package", ...);

where the package name and qualifiers in beginUnit and endUnit must be the same, and unique compared to other units.

Instantaneous Testing

You can store your tests separately from the modules you are testing, or you can alternatively embed them directly in your modules. Directly embedding tests is encouraged, and we call it instantaneous testing. It does not come with significant performance penalties, because simply loading a module which contains an insta.test statement will not execute the test; rather it will just schedule it for execution. The scheduled tests can be executed manually via

insta.runTests(unitFilter);

Here unitFilter is a function that decides whether a particular test unit [packageName, q0, q1, ...] should be run. You can also pass a string packageName, or a prefix [packageName, q0, q1, ...] instead of a function.

By default the instatest CLI will use the current package name as a filter. To configure a list of packages, for example package1, package2 and package3, add the following to your package.json configuration file:

...
 "config": {
    "instatest": {
      "packages": "package1; package2; package3"
    },
    ...
  },
...

Running Your Tests In The Browser

By passing the --browser option to instatest, instead of running the tests directly, it will generate a directory instatest-browser, for example:

npx instatest src --browser

To make use of it, you should have webpack and http-server installed:

npm install --save-dev webpack webpack-cli http-server

Then first run webpack via

npx webpack --config=instatest-browser/webpack.config.js

If that step was successful, you can now run the tests in the browser:

npx http-server -c-1 instatest-browser -o

Assuming you have already registered instatest in your package.json as a test script, you can streamline this by adding a test-browser script to your package.json:

...
"scripts": {
    "test": "instatest src",
    "pretest-browser": "npm run test -- --browser && npx webpack --config=instatest-browser/webpack.config.js",
    "test-browser": "npx http-server -c-1 instatest-browser -o",
    ...
  },
...

Now calling npm run test-browser will first freshly generate the instatest-browser directory, run webpack, and then start up a local http-server and a browser running your tests.

Lockdown

Instatest encourages locking down your modules and APIs as much as possible. In particular, you can lock down instatest itself and the basic Object API via

insta.lockdown();

After executing above statement, the following will throw an error:

insta.assert.hey = "doesn't really make sense";

It also switches off the possibility to manipulate Object:

Object.really = "now why would you want to do that?";

will also throw an error.

To run your tests via npm in lockdown mode, configure instatest via the package.json of your package as follows:

...
 "config": {
    "instatest": {
      "lockdown": true
    },
    ...
  },
...

You can also pass --lockdown or --lockdown=true to instatest as an option.

There are two utility functions to help you lock down your own APIs:

  • insta.lockClass(cls) locks down the class cls

  • insta.lockFunc(fn) locks down the function fn