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

@jsenv/snapshot

v2.11.19

Published

Snapshot testing

Downloads

914

Readme

snapshot

npm package

A tool to generate snapshots during tests.

A word on snapshot testing

Snapshot testing consists into:

  1. Making code execution produce file(s). They are called snapshots.
  2. Make further code execution follow these steps:
    1. Read existing snapshot
    2. Execute code
    3. Read new snapshot
    4. Compare the two snapshots and throw if there is a diff

This force code execution to produce the same snapshots. Meaning that code being tested still behave as expected.

How it works

@jsenv/snapshot behaves as follow:

When there is no snapshot(s), the snapshot won't be compared. It happens the very first time you generate snapshots or because all snapshot files have been removed for some reason.

For all next code executions, snapshots are compared and

  • An error is thrown when process.env.CI is set (code is executed in CI).
  • Otherwise nothing special happens (it's your job to review eventual diff in the snapshots, using git diff for example)

Every function accepts a throwWhenDiff param to throw even if runned locally. You can also set process.env.CI before executing your code.

takeFileSnapshot(fileUrl)

The code below ensure writeFileTxt write content into "./file.txt".
Changing that behaviour would fail snapshot comparison.

import { writeFileSync } from "node:fs";
import { takeFileSnapshot } from "@jsenv/snapshot";

const fileTxtUrl = new URL("./file.txt", import.meta.url);
const writeFileTxt = (content) => {
  writeFileSync(writeFileTxt, content);
};

// take snapshot of "./file.txt"
const fileSnapshot = takeFileSnapshot(fileTxtUrl);
writeFileTxt("Hello world");
// compare the state of "./file.txt" with previous version
fileSnapshot.compare();

takeDirectorySnapshot(directoryUrl)

The code below ensure writeManyFiles always write twos file: "./dir/a.txt" and "./dir/b.txt" with the content "a" and "b".
Changing that behaviour would fail snapshot comparison.

import { writeFileSync } from "node:fs";
import { takeDirectorySnapshot } from "@jsenv/snapshot";

const directoryUrl = new URL("./dir/", import.meta.url);
const writeManyFiles = () => {
  writeFileSync(new URL("./a.txt", directoryUrl), "a");
  writeFileSync(new URL("./b.txt", directoryUrl), "b");
};

// take snapshot of "./dir/"
const directorySnapshot = takeDirectorySnapshot(directoryUrl);
writeFileTxt(directoryUrl);
// compare the state of "./dir/" with previous version
directorySnapshot.compare();

snapshotTests(testFileUrl, fnRegistertingTests, options)

This function is wonderful:

import { snapshotTests } from "@jsenv/snapshot";

const getCircleArea = (circleRadius) => {
  if (isNaN(circleRadius)) {
    throw new TypeError(
      `circleRadius must be a number, received ${circleRadius}`,
    );
  }
  return circleRadius * circleRadius * Math.PI;
};

await snapshotTests(import.meta.url, ({ test }) => {
  test("when radius is 2", () => {
    return getCircleArea(2);
  });

  test("when radius is 10", () => {
    return getCircleArea(10);
  });

  test("when radius is null", () => {
    return getCircleArea(null);
  });
});

The code above is executing getCircleArea and produces a markdown files describing how it goes.
This markdown will be compared with any previous version ensuring getCircleArea still behave as expected.

See the markdown at ./docs/_circle_area.test.js/circle_area.test.js.md

Why is it so wonderful?

  • You don't have to assert anything, you just call the function
  • The markdown files can be reviewed to ensure it is what you expect
  • The markdown files can be used as documentation
  • Changes in the source code would be reflected in the markdown making it easy to review

There is a few more very helpul things hapenning:

Advanced examples:

Fluctuating values replacement

Snapshots will be generated on your machine or the machine of an other contributor, then on the CI.

Each execution will happen in a different context. This context influence behaviour of the code and as a consequence might change the snapshot being generated.

  • time
  • operating system
  • filesystem location
  • available ressources,
  • and so on...

To ensure the snapshot generated is not influenced, all fluctuating values are replaced with stable values.

  • Things like "2s" becomes "Xs"
  • Filesystem urls dynamic parts are replaced
  • Port in https urls is removed
  • and so on...

If something is fluctuating and makes your snapshot testing unstable, you can open an issue or create a pull request.