Metadata-Version: 2.4
Name: msri
Version: 0.2.4
License-File: LICENSE
Summary: Show-me-state: e2e testing as directed graphs of filesystem states
Home-Page: https://github.com/cjohnhanson/missouri
License-Expression: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# missouri

> Show-me state. End-to-end testing as directed graphs of filesystem
> states.

Missouri tests a CLI tool by modeling its behavior as a directed graph of
filesystem states. A state is a directory. It holds the exact files that
must exist at that point in the test. A transition is a shell command.
Missouri runs the command, then compares the resulting directory against
the target state directory, byte for byte.

There is no assertion language. The expected state is the directory.

## How it works

A test suite is a set of directories, and each directory is a state. Each
state's `.missouri/missouri.yml` declares its transitions. A transition
names a command to run and the state directory that the filesystem must
match after the command. Missouri finds every path through the graph,
runs each path in a temp directory with a cleared environment, and diffs
the result against the target.

```
clean/                  # starting state (empty project)
  .missouri/
    missouri.yml        # transitions: [{command: "echo hello > out.txt", target: ../built}]
built/                  # expected state after command
  .missouri/
    missouri.yml
  out.txt               # file that should exist: contains "hello"
```

```
$ missouri run
✓ [1/1]
PASS clean → built 14ms

1 passed, 0 failed, 1 step in 14ms
```

A state can have several outgoing transitions, which is branching, and
several states can point at the same target, which is convergence. The
directory tree is the test suite.

## Isolation

Every command runs with `env_clear()`. The process inherits no
environment variable from the host. Declare every variable a test needs
in the test config. The test then behaves the same on your machine and in
CI.

A `packages` list gives each command programs from nixpkgs. With
`docker: true`, missouri runs a command inside a Docker container.

## Beyond filesystem diffs

A state can also declare assertions. An assertion is a shell command, and
its exit code and output decide whether it passes. A transition can
declare a custom comparator for a file that a byte-for-byte diff reads
wrong, and a background service for a command that needs a server
running. An agent assertion hands a judgment call to an LLM.

## Install

The command is `missouri`, whichever package you install.

**[Archives of precompiled binaries are available for macOS and
Linux.](https://github.com/cjohnhanson/missouri/releases)** The Linux
binaries are static executables. Each archive holds the binary, its man
pages, the README and the licence. There is no Windows build.

| Package manager | Package | Command |
| --- | --- | --- |
| [Homebrew](https://brew.sh) | [cjohnhanson/tap/missouri](https://github.com/cjohnhanson/homebrew-tap) | `brew install cjohnhanson/tap/missouri` |
| [Cargo](https://doc.rust-lang.org/cargo/) | [missouri](https://crates.io/crates/missouri) | `cargo install --locked missouri` |
| [uv](https://docs.astral.sh/uv/) | [msri](https://pypi.org/project/msri/) | `uv tool install msri` |
| [npm](https://www.npmjs.com) | [@cjohnhanson/msri](https://www.npmjs.com/package/@cjohnhanson/msri) | `npm install -g @cjohnhanson/msri` |

On Debian or Ubuntu, download the `.deb` from the [releases
page](https://github.com/cjohnhanson/missouri/releases) and install it:

```
wget https://github.com/cjohnhanson/missouri/releases/download/v0.2.3/missouri_0.2.3-1_amd64.deb
sudo dpkg -i missouri_0.2.3-1_amd64.deb
```

To run it once without installing anything:

```
uvx msri run
npx @cjohnhanson/msri run
```

### Building

missouri is written in Rust, so you need a [Rust
installation](https://www.rust-lang.org/) to compile it. missouri
compiles with Rust 1.88 or newer. A C compiler is needed as well, which
`aws-lc-sys` uses for its cryptography.

To build missouri:

```
git clone https://github.com/cjohnhanson/missouri
cd missouri
cargo build --release
./target/release/missouri --version
```

## Usage

```
missouri init              # set up a new project
missouri state add <name>  # create a state directory
missouri run               # execute all test paths
missouri run -v            # verbose output
missouri list              # show states, transitions, paths
missouri validate          # check graph is well-formed
missouri report            # generate a report from a recorded run
missouri docs [topic]      # bundled documentation
```

## Documentation

- [What is Missouri?](docs/what-is-missouri.md). The testing model, why graphs, and how a path runs.
- [Getting Started](docs/getting-started.md). A walkthrough of a first test suite.
- [Writing Tests](docs/writing-tests.md). Transitions, assertions, comparators, and services.
- [CLI Reference](docs/cli-reference.md). Every command and every config field.

## Related

- [tisket](https://github.com/cjohnhanson/tisket). An issue tracker. Markdown issues with YAML frontmatter, in the repository.
- [zettel](https://github.com/cjohnhanson/zettel). Zettelkasten notes for a repository.
- [almanac](https://github.com/cjohnhanson/almanac). An agent skill index over pluggable sources.
- [gaff](https://github.com/cjohnhanson/gaff). A context-lifecycle handler for coding agents.
- [mdstore](https://github.com/cjohnhanson/mdstore). The frontmattered markdown library that tisket, zettel, and almanac store documents with.

## License

MIT.

