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

machina-test

v1.0.0

Published

Jest/Vitest custom matchers for testing machina FSMs.

Readme

machina-test

Testing tools for machina FSMs — graph topology matchers and property-based runtime testing.

import "machina-test";
import { walkAll } from "machina-test";

// Graph matchers — does the wiring look right?
expect(fsm).toHaveNoUnreachableStates();
expect(fsm).toAlwaysReach("delivered", { from: "placed" });
expect(fsm).toNeverReach("shipped", { from: "cancelled" });

// Runtime testing — does it actually work?
walkAll(() => createMyFsm(), {
    invariant({ ctx }) {
        /* assert a rule that must always hold */
    },
});

Graph matchers are built on machina-inspect. walkAll runs the FSM live with randomized inputs.

Install

npm install --save-dev machina-test
# or
pnpm add -D machina-test

machina >= 6.1.0 is a peer dependency. Either jest or vitest must be available as the host test runner.

Setup

Import machina-test in your test files (or in a setup file that runs after the framework's globals are available). The import registers the matchers via expect.extend() as a side effect.

// in each test file
import "machina-test";

// or in jest.setup.ts / vitest.setup.ts
import "machina-test";

That's it. TypeScript users get autocomplete for all three matchers automatically.

Matchers

toHaveNoUnreachableStates()

Asserts that every state in the FSM is reachable from initialState. Delegates to machina-inspect's inspectGraph(), which recurses into child FSM graphs.

expect(fsm).toHaveNoUnreachableStates();

toAlwaysReach(targetState, { from })

Asserts that a path exists from from to targetState in the FSM's top-level graph. BFS over all edges (both "definite" and "possible"). Top-level graph only — does not traverse into _child FSMs.

expect(fsm).toAlwaysReach("delivered", { from: "placed" });

"Always" refers to graph topology — the plumbing exists — not runtime certainty. Whether the path executes at runtime depends on which handlers fire.

toNeverReach(targetState, { from })

Asserts that no path exists from from to targetState. The logical inverse of toAlwaysReach.

expect(fsm).toNeverReach("shipped", { from: "cancelled" });

.not variants

Standard Jest/Vitest negation works as expected:

expect(fsm).not.toAlwaysReach("shipped", { from: "cancelled" });
expect(fsm).not.toNeverReach("delivered", { from: "placed" });

Invalid state names

Typos produce clean test failures (not thrown exceptions) with actionable messages:

State 'shiped' does not exist in FSM 'order-workflow'. Available states: placed, validating, processing, shipped, delivered, cancelled, refunded.

Testing hierarchical FSMs

toAlwaysReach and toNeverReach operate on the top-level graph only. They do not traverse into _child FSMs. This is intentional — it avoids ambiguity around composite state names and keeps assertions explicit about which level you're testing.

To test a child FSM, pass it directly to expect():

// Test the parent — sees browsing, checkout, confirmation
expect(checkout).toAlwaysReach("confirmation", { from: "browsing" });

// Test the child — sees entering-details, processing, authorized, declined
const payment = createPaymentFsm();
expect(payment).toAlwaysReach("authorized", { from: "entering-details" });
expect(payment).toNeverReach("entering-details", { from: "authorized" });

The one exception: toHaveNoUnreachableStates() does recurse into children via inspectGraph(). An orphaned state in a child surfaces as a failure when called on the parent.

walkAll — Runtime Testing

The matchers check graph topology — does a path exist? walkAll checks runtime behavior — does the FSM actually work when you feed it random inputs?

import { walkAll, WalkFailureError } from "machina-test";

const result = walkAll(
    () => createMyFsm(), // factory: fresh FSM per walk
    {
        walks: 200, // 200 independent walks
        maxSteps: 20, // up to 20 handle() calls per walk
        seed: 42, // deterministic — same sequence every run
        inputs: {
            begin: () => Math.floor(Math.random() * 200),
        },
        invariant({ ctx }) {
            // checked after every transition — throw to fail
            if ((ctx as any).balance < 0) {
                throw new Error("balance went negative");
            }
        },
    }
);

On failure, WalkFailureError carries the seed, step number, and full input sequence. Pass the seed back to replay the exact walk that failed:

try {
    walkAll(factory, config);
} catch (err) {
    if (err instanceof WalkFailureError) {
        // err.seed, err.step, err.state, err.inputSequence
        // Replay: walkAll(factory, { ...config, seed: err.seed })
    }
}

Both Fsm and BehavioralFsm are supported. See the docs for full configuration reference, payload generators, input filtering, and BehavioralFsm client factories.

See also

License

MIT