write-tests
Write Tests
Guide for writing tests in Syncpack using the TestBuilder pattern.
TDD Workflow (Mandatory)
- Study existing tests — Read 2-3 tests in same file, identify the pattern, match it exactly
- Write failing test — Never invent APIs; read source to see what exists
- Verify it fails — Run
just testto confirm - Ask user to confirm — Get approval before implementing
- Implement minimal code — Only what's needed to pass
- Clean up — Run
just format, fix warnings, refactor if needed
Golden Rule
Always use TestBuilder — Never manually construct Context in tests.
Quick Start
use {
crate::{
instance_state::{FixableInstance::*, InstanceState, ValidInstance::*},
test::{
builder::TestBuilder,
expect::{expect, ExpectedInstance},
},
},
serde_json::json,
};
#[test]
fn test_descriptive_name() {
let ctx = TestBuilder::new()
.with_packages(vec![
json!({"name": "pkg-a", "dependencies": {"react": "17.0.0"}}),
])
.with_version_group(json!({
"dependencies": ["react"],
"pinVersion": "18.0.0"
}))
.build_and_visit_packages();
expect(&ctx).to_have_instances(vec![
ExpectedInstance {
state: InstanceState::fixable(DiffersToPin),
dependency_name: "react",
id: "react in /dependencies of pkg-a",
actual: "17.0.0",
expected: Some("18.0.0"),
overridden: None,
},
]);
}
TestBuilder Methods
Packages
.with_package(json!({...})) // Single package
.with_packages(vec![json!({...})]) // Multiple packages
Version Groups
.with_version_group(json!({...})) // Single group
.with_version_groups(vec![...]) // Multiple groups
Configuration
.with_config(json!({...})) // Custom config
.with_semver_group(json!({...})) // Semver rules
.with_strict(true) // Strict mode
Registry (for update command)
.with_registry_updates(json!({"react": ["17.0.0", "18.0.0"]}))
.with_update_target(UpdateTarget::Latest)
Build
.build() // Without visiting (rare)
.build_and_visit_packages() // With visiting (most common)
Location String Format
{dependency} in {location} of {package}
Examples:
"react in /dependencies of pkg-a""lodash in /devDependencies of pkg-b""pnpm in /packageManager of pkg-c"
Running Tests
just test # All tests
cargo test test_name -- --nocapture # Specific test with output
cargo test banned_test # Tests matching pattern
Test Organisation
- Integration tests:
src/visit_packages/*_test.rs(preferred) - Unit tests: Co-located as
*_test.rs(e.g.,src/foo.rs→src/foo_test.rs) - Test utilities:
src/test/builder.rs,src/test/expect.rs
Common Patterns
→ Full patterns and examples: patterns.md
Good Test Examples
Study these files:
src/visit_packages/banned_test.rs— Comprehensive examplessrc/visit_packages/pinned_test.rs— Version group testingsrc/visit_packages/preferred_semver_test.rs— Local package and highest/lowest semver handling
Common Mistakes
| Wrong | Right |
|---|---|
Context { ... } |
TestBuilder::new()... |
.build() then check states |
.build_and_visit_packages() |
ctx.instances[0] |
.find(|i| i.dependency.name == "react") |
More from jamiemason/syncpack
search-code
Search for code patterns in Syncpack. Use when finding symbols, implementations, or understanding how code is used. Covers ast-grep for Rust and grep/rg for other cases.
11fix-bug
Debug and fix bugs in Syncpack using scientific debugging methodology. Use when a test is failing, unexpected behaviour occurs, or investigating issues. Covers hypothesis-driven debugging and TDD-based fixes.
10review-docs
Review and improve Syncpack documentation for clarity, completeness, and consistency. Use when enhancing docs or validating before publication.
10add-feature
Add new features to Syncpack including commands and validation logic. Use when implementing new CLI commands, adding InstanceState variants, or extending version group behaviour.
10write-code
Rust code style and conventions for Syncpack. Use when writing or modifying Rust code. Covers functional patterns, imports, naming, and quality standards.
10signal-over-noise
Maximize useful information per word by removing filler, obvious explanations, and hedging language. Use when writing documentation, error messages, code comments, or any communication where clarity and conciseness matter.
10