ejectest
Extract inline #[cfg(test)] mod tests { ... } into separate _tests.rs files.
Why?
Inline tests are convenient — until your files grow too large. Manually moving tests to a separate file means editing the source and creating a new test file with the right module path. That's busywork. ejectest does it in one command.
Usage
apply takes a file or a directory. Given a directory it walks the tree
(recursively, honouring .gitignore), ejecting every file with an inline
#[cfg(test)] mod tests { ... } block and skipping files already external
or without a test module. Re-running on an ejected tree is a no-op, so the
one-time migration and any later sweep are a single command.
check scans a file or directory (recursively, honouring .gitignore)
and exits non-zero when any file still carries an inline
#[cfg(test)] mod tests { ... } block — the cargo fmt --check idiom
for the sibling-test-file convention.
Both subcommands accept --format <text|json>. JSON output has the
same structure for a single file and for a directory tree:
# {"files":[{"path":"src/lib.rs","status":"inline"}],"summary":{"total":1,"inline":1,"external":0,"no_tests":0}}
Install
Or download a pre-built binary from the latest release.
Nix flake
Add ejectest as a flake input and include it in your dev shell:
{
inputs = {
ejectest = {
url = "github:mlavrinenko/ejectest";
inputs.nixpkgs.follows = "nixpkgs";
};
# ... other inputs
};
outputs = { ejectest, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system: {
devShells.default = nixpkgs.legacyPackages.${system}.mkShell {
nativeBuildInputs = [
ejectest.packages.${system}.default
];
};
});
}
Or run it directly without installing:
Library usage
Add to your Cargo.toml with default features disabled:
= { = "0.2", = false }
let result = eject_tests?;
// result.modified_source — source with tests replaced by a #[path] stub
// result.test_content — extracted test file contents
// result.test_file_name — e.g. "lib_tests.rs"
// Read-only detection (powers `ejectest check`):
match classify_source
Contributing
See CONTRIBUTING.md for development setup and coding conventions.
License
MIT