Skip to content

Promote test support to crate#114

Merged
leynos merged 5 commits intomainfrom
codex/promote-tests/support-to-test_support-crate
Aug 13, 2025
Merged

Promote test support to crate#114
leynos merged 5 commits intomainfrom
codex/promote-tests/support-to-test_support-crate

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Aug 12, 2025

Summary

  • extract test helpers into new test_support crate
  • remove allow(unused_code) attributes from test utilities
  • update tests to depend on the new crate

Testing

  • make fmt
  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_689bbf62cf80832287838e7140381734

Summary by Sourcery

Extract test utilities into a dedicated test_support crate and update the test suite to use it, simplifying imports, adjusting helper signatures, and ensuring safe environment mutation concurrency.

New Features:

  • Extract common test helpers into a new test_support crate providing fake_ninja, PathGuard, EnvLock, and environment utilities

Enhancements:

  • Refactor existing tests to import helpers from test_support instead of local modules, update fake_ninja exit_code type from i32 to u8, and wrap environment variable mutations with EnvLock

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Aug 12, 2025

Reviewer's Guide

Extract common test utilities into a standalone test_support crate, remove redundant annotations, and update all existing tests to import and adapt to the new crate’s refined API.

Entity relationship diagram for test_support crate modules

erDiagram
    ENV ||--o| ENVLOCK : manages
    PATH_GUARD ||--o| ENV : uses
    FAKE_NINJA ||--o| ENV : simulates
Loading

Class diagram for test_support crate modules

classDiagram
    class Env {
        +fn set_var()
        +fn get_var()
        +fn remove_var()
    }
    class PathGuard {
        +fn new()
        +fn guard_path()
    }
    class EnvLock {
        +fn lock_env()
        +fn unlock_env()
    }
    class FakeNinja {
        +fn run()
        +fn output()
    }
    EnvLock --> Env : manages
    PathGuard --> Env : uses
    FakeNinja --> Env : simulates
    test_support : Env
    test_support : PathGuard
    test_support : EnvLock
    test_support : FakeNinja
Loading

File-Level Changes

Change Details Files
Introduce standalone test_support crate for shared test utilities
  • Create new test_support crate with lib.rs and modules (env, env_lock, path_guard, check_ninja)
  • Add test_support as a path dependency in workspace Cargo.toml
  • Move existing support utilities into test_support/src and define Cargo.toml
test_support/src/lib.rs
test_support/src/env.rs
test_support/src/path_guard.rs
test_support/src/env_lock.rs
test_support/src/check_ninja.rs
test_support/Cargo.toml
Cargo.toml
Remove redundant allow and fixture annotations from utility modules
  • Strip allow(dead_code) attributes from env and path_guard functions
  • Remove rstest fixture annotations from helper functions
test_support/src/env.rs
test_support/src/path_guard.rs
Refactor tests to import utilities from test_support and adapt to API changes
  • Replace local support module imports with use test_support::...
  • Update fake_ninja calls to use u8 exit codes and crate’s function
  • Add EnvLock.acquire around unsafe env var modifications and import PathGuard
  • Remove old module declarations for moved support files
tests/runner_tests.rs
tests/assert_cmd_tests.rs
tests/cucumber.rs
tests/steps/process_steps.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 12, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Summary by CodeRabbit

  • Tests

    • Introduced a shared test utilities crate to unify and simplify test helpers.
    • Consolidated test imports and removed duplicated local modules.
    • Improved environment handling and isolation in tests, including serialisation when mutating global state.
    • Enforced valid exit code ranges in test helpers.
    • No changes to application behaviour.
  • Chores

    • Added a development dependency to support the new shared test utilities.

Walkthrough

Add a new test_support crate and register it as a dev-dependency; move test helpers (PathGuard, EnvLock, fake_ninja, env helpers) into that crate and update tests to import and use those shared utilities.

Changes

Cohort / File(s) Summary
Workspace config
Cargo.toml
Add dev-dependency: test_support = { path = "test_support" }.
Test support crate manifest
test_support/Cargo.toml
Add new crate test_support (name/version/edition/rust-version/publish=false) with dependencies: tempfile = "3.8.0", mockable = { version = "0.3", features = ["mock"] }; dev-dependency rstest = "0.18.0".
Test support library root
test_support/src/lib.rs
Add public modules check_ninja, env, env_lock, path_guard; re-export PathGuard; add pub fn fake_ninja(exit_code: u8) -> (TempDir, PathBuf) with OS-specific executable creation.
Env module tidy
test_support/src/env.rs
Consolidate imports; remove rstest::fixture import and several #[allow(...)] attributes; preserve functionality.
Path guard tidy
test_support/src/path_guard.rs
Change EnvLock import to crate::env_lock::EnvLock and remove some #[allow(...)] attributes; public API unchanged.
Tests switched to shared helpers
tests/assert_cmd_tests.rs, tests/cucumber.rs, tests/env_path_tests.rs, tests/path_guard_tests.rs, tests/runner_tests.rs, tests/steps/process_steps.rs
Remove local tests/support modules; import helpers from test_support (e.g., fake_ninja, PathGuard, EnvLock, check_ninja); update call sites and types to use re-exports and u8 fake_ninja signature where applicable; rename one cucumber step function to install_fake_ninja.
Removed legacy support module
tests/support/mod.rs
Remove old in-repo test support module and its helpers (fake_ninja, mock_path_to, fake_ninja_pwd, PathGuard re-export, submodules).

Sequence Diagram(s)

sequenceDiagram
  participant Test as Test
  participant TS as test_support::fake_ninja
  participant FS as Filesystem

  Test->>TS: call fake_ninja(exit_code: u8)
  TS->>FS: create TempDir
  TS->>FS: write platform-specific executable (ninja / ninja.cmd)
  TS->>FS: set permissions (Unix) / write batch (Windows)
  TS-->>Test: return (TempDir, PathBuf)
  Test->>Test: add dir to PATH or install into test world
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Poem

A tiny crate where helpers meet,
PATHs are tended, ninjas greet.
Tests now import a single light,
Old support removed, new fixtures right.
Shared tools hum, and CI sleeps tight.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the "Integrations" page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1ef402 and da4ff81.

📒 Files selected for processing (4)
  • test_support/Cargo.toml (1 hunks)
  • test_support/src/lib.rs (1 hunks)
  • tests/runner_tests.rs (4 hunks)
  • tests/steps/process_steps.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • test_support/src/lib.rs
  • tests/steps/process_steps.rs
  • tests/runner_tests.rs
🔍 Additional research (Deepwiki)

Summary of additional context found (relevant to reviewing this PR):

  • Repository docs describe the project's testing architecture and standards: heavy use of rstest fixtures, cucumber-rs for BDD, insta snapshot tests, and expectations around test helpers/fixtures and TempDir usage — aligns with moving shared test helpers into a test_support crate.,

  • Developer Guide & Testing pages note Make targets (make fmt / make lint / make test), strict linting and test quality gates, and CI expectations (snapshots, INSTA_UPDATE behavior) — confirms author’s reported local checks (fmt/lint/test) and the importance of keeping test helpers deterministic and well-isolated.

  • Docs include details on test data, manifest parsing, and environment/Path handling patterns used by tests (TempDir, env guards, exclusive EnvLock), which supports verifying that the moved helpers (fake_ninja, PathGuard, EnvLock, mocked_path_env) must preserve semantics and cleanup.

Tools used:

🔇 Additional comments (11)
test_support/Cargo.toml (1)

1-14: LGTM! Clean test-support crate configuration.

The manifest is well-structured with appropriate dependencies and configuration. The publish = false correctly prevents accidental publication, and the Rust 2024 edition with minimum version specification ensures compatibility. Dependencies are properly scoped with rstest in dev-dependencies to avoid transitive leakage.

tests/steps/process_steps.rs (2)

9-13: LGTM! Clean imports from test_support crate.

The imports are well-organised and bring in all necessary utilities from the new test_support crate. The inclusion of fake_ninja directly in the import list maintains consistency with the other imported symbols.


29-33: LGTM! Proper exit code validation and function naming.

The function correctly validates the exit code range (0-255) with an appropriate error message and uses the imported fake_ninja function consistently. The function rename from fake_ninja to install_fake_ninja better reflects its actual purpose of setting up the test environment.

tests/runner_tests.rs (4)

6-12: LGTM! Comprehensive test_support imports with proper serialisation.

The imports are well-organised and include all necessary utilities from the test_support crate. The inclusion of EnvLock properly addresses thread safety concerns for environment variable mutations.


37-38: LGTM! Proper exit code type and function call.

The fixture signature correctly uses u8 for the exit code parameter, which accurately models OS exit code semantics (0-255). The call to fake_ninja(exit_code) uses the properly imported function.


211-217: LGTM! Proper environment variable serialisation.

The test correctly acquires an EnvLock before mutating the process-global NINJA_ENV variable. The SAFETY comment accurately documents that EnvLock serialises access to process-global state, and the fake_ninja(0u8) call uses the correct exit code type.


236-246: LGTM! Comprehensive environment cleanup with proper serialisation.

The cleanup logic properly restores the original environment variable state, handling both cases where the variable existed previously or was unset. The SAFETY comment accurately documents the exclusive access guarantee provided by EnvLock, and the explicit resource cleanup ensures proper test hygiene.

test_support/src/lib.rs (4)

1-12: LGTM! Comprehensive crate documentation.

The module-level documentation clearly describes the crate's purpose as a test-support utility, outlines the main functionality areas, and includes appropriate warnings about test-only usage. The platform compatibility note is helpful for maintainers.


13-18: LGTM! Clean module organisation with documented re-export.

The module declarations are well-organised and the PathGuard re-export includes proper documentation explaining its purpose for ergonomic access in tests.


25-42: LGTM! Excellent documentation with practical example.

The function documentation is comprehensive, including the critical note about TempDir lifetime management and a practical usage example. The example clearly demonstrates the intended usage pattern and cleanup behaviour.


43-98: LGTM! Robust cross-platform implementation with excellent error handling.

The function implementation properly handles both Unix and Windows platforms with platform-specific executable formats. The error handling is exemplary, providing detailed context including file paths and underlying IO errors. The use of u8 for exit codes correctly models OS semantics, and the platform-specific conditional compilation ensures appropriate behaviour on each target.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/promote-tests/support-to-test_support-crate

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @leynos - I've reviewed your changes - here's some feedback:

  • Consider moving the test_support path dependency into [dev-dependencies] instead of [dependencies], since it’s only used by tests.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider moving the `test_support` path dependency into `[dev-dependencies]` instead of `[dependencies]`, since it’s only used by tests.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

14 files reviewed, 1 comment

Edit Code Review Bot Settings | Greptile

Comment thread test_support/src/lib.rs Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🔭 Outside diff range comments (5)
test_support/src/env.rs (2)

72-90: Add a short usage example to the public API

Augment the docs for prepend_dir_to_path with a minimal example to meet the documentation guidelines and make intent explicit.

Example to add to the doc comment:

/// # Examples
/// ```
/// use test_support::env::{SystemEnv, prepend_dir_to_path};
/// let env = SystemEnv::new();
/// let dir = tempfile::tempdir().expect("temp dir");
/// let _guard = prepend_dir_to_path(&env, dir.path());
/// // PATH now starts with `dir` and will be restored when `_guard` is dropped.
/// ```

1-5: Ensure doctest access to helpers per org guidance

Doctests for the main crate typically cannot rely on a separate dev-only crate. Add a small #[cfg(doctest)] bridge in the primary crate to re-export the minimal helpers needed (e.g., PathGuard, prepend_dir_to_path), or expose doctest-only helpers as per the Deepwiki guidance. This keeps doctest ergonomics while retaining a dedicated test-support crate.

Reference: Deepwiki recommendations on promoting test support and doctest gating.

test_support/src/path_guard.rs (2)

46-56: Fix misleading doc for PathGuard::new

The function does not capture PATH; it accepts a previously captured value. Correct the docs to avoid confusion.

 impl PathGuard {
-    /// Create a guard capturing the current `PATH` using the real environment.
-    ///
-    /// Returns a guard that restores the variable when dropped.
+    /// Create a guard that will restore a previously captured `PATH`.
+    ///
+    /// Pass `original` as the current value of `PATH` (e.g., from
+    /// `std::env::var_os("PATH")`). The guard restores this value when dropped.
     pub fn new(original: Option<OsString>) -> Self {
         let state = original.map_or(OriginalPath::Unset, OriginalPath::Set);
         Self {
             original: Some(state),
             env: StdEnv,
         }
     }
 }

10-19: Route environment removal via the Env abstraction

Avoid calling std::env::remove_var directly. Extend Env with remove_var so Drop uses the same abstraction and centralises unsafety and locking policy.

-/// Environment abstraction for setting variables.
+/// Environment abstraction for mutating variables.
 pub trait Env {
     /// Set `key` to `val` within the environment.
@@
-    unsafe fn set_var(&mut self, key: &str, val: &OsStr);
+    unsafe fn set_var(&mut self, key: &str, val: &OsStr);
+    /// Remove `key` from the environment.
+    ///
+    /// # Safety
+    ///
+    /// Mutating process globals is `unsafe` in Rust 2024.
+    unsafe fn remove_var(&mut self, key: &str);
 }
@@
 impl Env for StdEnv {
     unsafe fn set_var(&mut self, key: &str, val: &OsStr) {
         unsafe { std::env::set_var(key, val) };
     }
+    unsafe fn remove_var(&mut self, key: &str) {
+        unsafe { std::env::remove_var(key) }
+    }
 }
@@
 impl<E: Env> Drop for PathGuard<E> {
     fn drop(&mut self) {
         let _lock = EnvLock::acquire();
         match self.original.take() {
             Some(OriginalPath::Set(path)) => {
                 // Nightly marks `set_var` unsafe; restoring cleans up global state.
                 unsafe { self.env.set_var("PATH", &path) };
             }
-            Some(OriginalPath::Unset) | None => unsafe { std::env::remove_var("PATH") },
+            Some(OriginalPath::Unset) | None => unsafe { self.env.remove_var("PATH") },
         }
     }
 }

Also applies to: 24-28, 74-85

tests/runner_tests.rs (1)

207-242: Serialise NINJA_ENV mutations with EnvLock

Guard both the override and restoration with EnvLock to match the project’s approach to process-global state and avoid test flakiness under parallel execution.

-    unsafe {
-        std::env::set_var(NINJA_ENV, &ninja_path);
-    }
+    {
+        let _lock = EnvLock::acquire();
+        unsafe { std::env::set_var(NINJA_ENV, &ninja_path); }
+    }
@@
-    unsafe {
-        if let Some(val) = original {
-            std::env::set_var(NINJA_ENV, val);
-        } else {
-            std::env::remove_var(NINJA_ENV);
-        }
-    }
+    {
+        let _lock = EnvLock::acquire();
+        unsafe {
+            if let Some(val) = original {
+                std::env::set_var(NINJA_ENV, val);
+            } else {
+                std::env::remove_var(NINJA_ENV);
+            }
+        }
+    }
♻️ Duplicate comments (1)
test_support/src/lib.rs (1)

18-34: Fix Unix-only behaviour; add Windows support and strengthen diagnostics

The current implementation writes a POSIX shell script named “ninja” and only sets mode on Unix. On Windows, this won’t be executable, which will break tests. Implement a Windows batch variant (ninja.cmd) or gate the function to Unix. Also improve expect() messages to aid debugging, and document Panics/Platform/Examples in Rustdoc. This echoes previous feedback on expect messages.

Apply this diff:

-/// Create a fake Ninja executable that exits with `exit_code`.
-///
-/// Returns the temporary directory and the path to the executable.
+/// Create a fake Ninja executable that exits with `exit_code`.
+///
+/// Returns the temporary directory and the full path to the created executable.
+///
+/// # Panics
+/// Panics if the temporary directory cannot be created, the script cannot be written,
+/// or (on Unix) executable permissions cannot be set.
+///
+/// # Platform
+/// - Unix: creates a POSIX shell script named `ninja` with mode 0o755.
+/// - Windows: creates a batch file named `ninja.cmd` that exits with the given code.
+///
+/// # Examples
+/// ```no_run
+/// let (dir, path) = test_support::fake_ninja(42);
+/// assert!(path.exists());
+/// drop(dir); // cleans up the temporary directory
+/// ```
 pub fn fake_ninja(exit_code: i32) -> (TempDir, PathBuf) {
-    let dir = TempDir::new().expect("temp dir");
-    let path = dir.path().join("ninja");
-    let mut file = File::create(&path).expect("script");
-    writeln!(file, "#!/bin/sh\nexit {exit_code}").expect("write script");
-    #[cfg(unix)]
-    {
-        use std::os::unix::fs::PermissionsExt;
-        let mut perms = fs::metadata(&path).expect("meta").permissions();
-        perms.set_mode(0o755);
-        fs::set_permissions(&path, perms).expect("perms");
-    }
-    (dir, path)
+    let dir = TempDir::new().expect("create temporary directory for fake ninja");
+
+    #[cfg(unix)]
+    let path = dir.path().join("ninja");
+    #[cfg(windows)]
+    let path = dir.path().join("ninja.cmd");
+
+    let mut file = File::create(&path).expect("create fake ninja program");
+
+    #[cfg(unix)]
+    {
+        writeln!(file, "#!/bin/sh\nexit {exit_code}")
+            .expect("write shell script for fake ninja");
+        use std::os::unix::fs::PermissionsExt;
+        let mut perms = fs::metadata(&path)
+            .expect("read permissions for fake ninja")
+            .permissions();
+        perms.set_mode(0o755);
+        fs::set_permissions(&path, perms)
+            .expect("set executable permissions for fake ninja");
+    }
+
+    #[cfg(windows)]
+    {
+        // Use CRLF line endings for cmd.exe
+        writeln!(file, "@echo off\r\nexit /B {exit_code}\r")
+            .expect("write batch script for fake ninja");
+    }
+
+    (dir, path)
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9e5c209 and 9a6a4da.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • Cargo.toml (1 hunks)
  • test_support/Cargo.toml (1 hunks)
  • test_support/src/env.rs (1 hunks)
  • test_support/src/lib.rs (1 hunks)
  • test_support/src/path_guard.rs (1 hunks)
  • tests/assert_cmd_tests.rs (2 hunks)
  • tests/cucumber.rs (2 hunks)
  • tests/env_path_tests.rs (1 hunks)
  • tests/path_guard_tests.rs (1 hunks)
  • tests/runner_tests.rs (3 hunks)
  • tests/steps/process_steps.rs (2 hunks)
  • tests/support/mod.rs (0 hunks)
💤 Files with no reviewable changes (1)
  • tests/support/mod.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Use functions and composition. Avoid repetition by extracting reusable logic. Prefer generators or comprehensions, and declarative code to imperative repetition when readable.
Small, meaningful functions. Functions must be small, clear in purpose, single responsibility, and obey command/query segregation.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer single line versions of functions where appropriate.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Keep file size manageable. No single code file may be longer than 400 lines. Long switch statements or dispatch tables should be broken up by feature and constituents colocated with targets. Large blocks of test data should be moved to external data files.
Illustrate with clear examples. Function documentation must include clear examples demonstrating the usage and outcome of the function. Test documentation should omit examples where the example serves only to reiterate the test logic.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
...

Files:

  • tests/steps/process_steps.rs
  • tests/assert_cmd_tests.rs
  • test_support/src/env.rs
  • tests/env_path_tests.rs
  • tests/path_guard_tests.rs
  • test_support/src/lib.rs
  • test_support/src/path_guard.rs
  • tests/cucumber.rs
  • tests/runner_tests.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/steps/process_steps.rs
  • tests/assert_cmd_tests.rs
  • test_support/src/env.rs
  • tests/env_path_tests.rs
  • tests/path_guard_tests.rs
  • test_support/src/lib.rs
  • test_support/src/path_guard.rs
  • tests/cucumber.rs
  • tests/runner_tests.rs
Cargo.toml

📄 CodeRabbit Inference Engine (AGENTS.md)

Cargo.toml: Use explicit version ranges in Cargo.toml and keep dependencies up-to-date.
Mandate caret requirements for all dependencies. All crate versions specified in Cargo.toml must use SemVer-compatible caret requirements (e.g., some-crate = "1.2.3").
Prohibit unstable version specifiers. The use of wildcard (*) or open-ended inequality (>=) version requirements is strictly forbidden. Tilde requirements (~) should only be used where a dependency must be locked to patch-level updates for a specific, documented reason.

Files:

  • Cargo.toml
🧬 Code Graph Analysis (5)
tests/steps/process_steps.rs (1)
test_support/src/lib.rs (1)
  • fake_ninja (21-34)
tests/assert_cmd_tests.rs (2)
test_support/src/lib.rs (1)
  • fake_ninja (21-34)
tests/steps/process_steps.rs (1)
  • fake_ninja (28-32)
tests/env_path_tests.rs (1)
test_support/src/env.rs (2)
  • mocked_path_env (46-53)
  • prepend_dir_to_path (77-90)
test_support/src/lib.rs (3)
tests/env_path_tests.rs (1)
  • std (39-41)
tests/steps/process_steps.rs (1)
  • fake_ninja (28-32)
test_support/src/path_guard.rs (1)
  • new (50-56)
tests/runner_tests.rs (3)
test_support/src/env.rs (1)
  • prepend_dir_to_path (77-90)
test_support/src/lib.rs (1)
  • fake_ninja (21-34)
tests/steps/process_steps.rs (1)
  • fake_ninja (28-32)
🔍 MCP Research (1 server)

Deepwiki:

⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (10)
test_support/Cargo.toml (1)

1-9: Validate test-support crate aligns with our test-helper architecture

  • test-support crate is imported exclusively by integration tests under tests/ (runner_tests.rs, path_guard_tests.rs, env_path_tests.rs, cucumber.rs, assert_cmd_tests.rs, steps/process_steps.rs)
  • No #[cfg(doctest)]-guarded helpers found

Deepwiki prescribes in-crate fixtures behind #[cfg(test)] for unit tests; a separate crate is acceptable for sharing helpers across crates. Confirm this dedicated crate is the intended approach. If doctests require helpers, introduce a minimal helper module in the primary crate behind #[cfg(doctest)].

Cargo.toml (2)

72-72: LGTM: Wire up test_support as a dev-dependency.

The path dependency is correctly scoped under dev-dependencies and won’t affect release builds.


63-77: No stale legacy support references remain

  • Confirmed absence of mod support, use support::…, crate::support, tests/support or support::fake_ninja across the repository.
  • All tests now import exclusively from the test_support crate.
tests/assert_cmd_tests.rs (2)

10-10: LGTM: Import fake_ninja from test_support.

The import is correct and scoped to the test.


29-29: LGTM: Use fake_ninja to seed PATH with a controlled ninja.

The setup ensures deterministic execution for the build test.

test_support/src/env.rs (1)

12-12: Consolidate crate imports: LGTM

Keep this combined import; it reduces churn across intra-crate moves and preserves clarity.

tests/env_path_tests.rs (1)

7-10: Switch tests to test_support imports: LGTM

The rewire removes local test modules and uses the dedicated test_support crate. This aligns the suite and avoids duplication.

tests/cucumber.rs (1)

24-25: World state type change: LGTM

Using Option<PathGuard> in CliWorld is appropriate for per-scenario PATH isolation.

test_support/src/path_guard.rs (1)

8-8: Module path update for EnvLock: LGTM

The move to crate::env_lock::EnvLock improves clarity and decouples from parent-module layout.

tests/runner_tests.rs (1)

36-41: Switch to test_support::fake_ninja: LGTM

The fixture now uses the unified helper; this removes duplication and keeps the intent clear.

Comment thread test_support/Cargo.toml
Comment thread test_support/src/lib.rs Outdated
Comment thread test_support/src/lib.rs Outdated
Comment thread test_support/src/lib.rs
Comment thread tests/cucumber.rs Outdated
Comment thread tests/path_guard_tests.rs Outdated
Comment thread tests/runner_tests.rs
Comment thread tests/steps/process_steps.rs
Comment thread tests/steps/process_steps.rs
Comment thread tests/steps/process_steps.rs Outdated
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🔭 Outside diff range comments (1)
tests/runner_tests.rs (1)

206-241: Acquire EnvLock when setting/restoring NINJA_ENV.

Guard the set_var/restore with EnvLock so mutations are serialised and scoped to this test.

Apply this diff:

 #[test]
 #[serial]
 fn run_respects_env_override_for_ninja() {
-    let (temp_dir, ninja_path) = fake_ninja(0);
+    let (temp_dir, ninja_path) = fake_ninja(0);
     let original = std::env::var_os(NINJA_ENV);
+    let _lock = EnvLock::acquire();
     unsafe {
         std::env::set_var(NINJA_ENV, &ninja_path);
     }
@@
     assert!(result.is_ok());
 
     unsafe {
         if let Some(val) = original {
             std::env::set_var(NINJA_ENV, val);
         } else {
             std::env::remove_var(NINJA_ENV);
         }
     }
     drop(ninja_path);
     drop(temp_dir);
 }
♻️ Duplicate comments (7)
tests/path_guard_tests.rs (1)

8-8: Import PathGuard from crate root; keep Env trait scoped locally [done].

Leverage the crate’s re-export and keep the trait import local to this module for clarity. Change aligns with prior guidance.

tests/cucumber.rs (1)

4-4: Use the crate root re-export for PathGuard [done].

Shorten the path and keep types consistent across the test suite. Matches the new test_support API.

Also applies to: 24-25

tests/runner_tests.rs (1)

6-10: Import EnvLock to serialise NINJA_ENV mutations.

Mutating process environment without the lock introduces test flakiness under parallel runs and violates your unsafe contract. Pull EnvLock into scope.

Apply this diff:

 use test_support::{
     PathGuard, check_ninja,
     env::{SystemEnv, prepend_dir_to_path},
     fake_ninja,
+    env_lock::EnvLock,
 };
tests/steps/process_steps.rs (2)

9-13: Import fake_ninja alongside check_ninja/env [done].

Avoid mixed FQ/imported usage and keep imports cohesive.


29-31: Use the imported fake_ninja symbol [done].

Call the locally imported fake_ninja for consistency.

test_support/src/lib.rs (2)

1-6: Broaden crate-level documentation and state test-only intent.

Clarify scope, primary utilities, and platform notes in the crate docs.

Apply this diff:

-//! Test-only utilities for integration and unit tests.
-//!
-//! This crate offers helpers for crafting fake executables, manipulating the
-//! environment, and guarding global state so tests can exercise process
-//! interactions without touching the host system.
+//! Test-support crate for Netsuke.
+//!
+//! This crate provides test-only utilities:
+//! - creating fake executables for process-related tests
+//! - manipulating PATH safely (PathGuard)
+//! - serialising environment mutation across tests (EnvLock)
+//!
+//! All items are intended for use in tests within this workspace; do not use in production code.
+//!
+//! Platform notes: fake executables are implemented for Unix and Windows.

12-12: Document the re-export for discoverability.

Attach Rustdoc to explain why PathGuard is re-exported at the crate root.

Apply this diff:

+/// Re-export of `PathGuard` for crate-level ergonomics in tests.
 pub use path_guard::PathGuard;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a6a4da and 24b6f28.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • test_support/Cargo.toml (1 hunks)
  • test_support/src/env.rs (1 hunks)
  • test_support/src/lib.rs (1 hunks)
  • tests/cucumber.rs (2 hunks)
  • tests/path_guard_tests.rs (1 hunks)
  • tests/runner_tests.rs (3 hunks)
  • tests/steps/process_steps.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Use functions and composition. Avoid repetition by extracting reusable logic. Prefer generators or comprehensions, and declarative code to imperative repetition when readable.
Small, meaningful functions. Functions must be small, clear in purpose, single responsibility, and obey command/query segregation.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer single line versions of functions where appropriate.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Keep file size manageable. No single code file may be longer than 400 lines. Long switch statements or dispatch tables should be broken up by feature and constituents colocated with targets. Large blocks of test data should be moved to external data files.
Illustrate with clear examples. Function documentation must include clear examples demonstrating the usage and outcome of the function. Test documentation should omit examples where the example serves only to reiterate the test logic.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
...

Files:

  • test_support/src/lib.rs
  • tests/path_guard_tests.rs
  • test_support/src/env.rs
  • tests/cucumber.rs
  • tests/steps/process_steps.rs
  • tests/runner_tests.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • test_support/src/lib.rs
  • tests/path_guard_tests.rs
  • test_support/src/env.rs
  • tests/cucumber.rs
  • tests/steps/process_steps.rs
  • tests/runner_tests.rs
🧬 Code Graph Analysis (3)
test_support/src/lib.rs (2)
tests/env_path_tests.rs (1)
  • std (39-41)
test_support/src/path_guard.rs (1)
  • new (50-56)
tests/steps/process_steps.rs (1)
test_support/src/lib.rs (1)
  • fake_ninja (22-49)
tests/runner_tests.rs (2)
test_support/src/env.rs (1)
  • prepend_dir_to_path (75-88)
test_support/src/lib.rs (1)
  • fake_ninja (22-49)
🔍 Additional research (Deepwiki)

Summary of relevant findings for PR #114 ("Promote test support to crate"):

  • The repository docs/wiki show the project already uses a shared test-helper pattern and a strict CI/testing policy; the PR adds a new test_support crate (test_support/Cargo.toml + src/) and updates tests to import helpers from test_support instead of local tests/support modules.,

  • Key changes to review:

    • Workspace Cargo.toml now adds test_support as a path dev-dependency; test_support/Cargo.toml sets publish = false and edition = "2024". Verify workspace membership and that path is correct for CI/test matrix.
    • test_support exposes modules/env helpers: path_guard, env, env_lock and a fake_ninja function; tests were updated to use test_support::{...} and to remove tests/support/mod.rs (which previously provided these helpers). Confirm public API/visibility and re-exports (pub use path_guard::PathGuard) match updated import sites.
    • Some #[allow(dead_code,...)] and rstest fixture attributes were removed in moved files (env.rs, path_guard.rs). Check for resulting compiler warnings/failing clippy rules or test fixture behavior changes—repo enforces strict lint/test gates.
    • New dependencies in test_support: tempfile, mockable (with "mock" feature), rstest as dev-dep. Confirm versions are acceptable and don’t conflict with workspace dev-dependencies.
    • Author ran make fmt, make lint, make test. Still verify CI (format, clippy, tests including cucumber/insta snapshots) passes with the relocated helpers.

Files/areas to spot-check in review:

  • Workspace Cargo.toml + test_support/Cargo.toml (path, publish=false, edition, dependency versions).
  • test_support/src/lib.rs exports and fake_ninja implementation (cross-platform script creation and tempdir handling).
  • All updated tests imports/usages (cucumber.rs, runner_tests.rs, env_path_tests.rs, path_guard_tests.rs, assert_cmd_tests.rs, steps/*) for compile and fixture behavior.
  • Removal of tests/support/mod.rs — ensure no remaining references to the old module and no lost helper behavior (e.g., mock_path_to or fake_ninja_pwd if still used).
  • Lint/test impacts from removed #[allow(...)] and removed rstest fixture attributes.

Tools consulted:

  • Repository wiki/pages listing and full content used as context:,
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (5)
test_support/src/env.rs (1)

11-11: Co-locate crate imports; keep the API tidy [LGTM].

Importing EnvLock and PathGuard from crate::… is correct for intra-crate use and matches the moved module structure.

test_support/Cargo.toml (3)

5-5: Prevent publication: confirmed.

Keep publish = false; this correctly prevents accidental publication of the internal test-support crate.


11-12: Keep rstest scoped to dev-dependencies.

Leave rstest under [dev-dependencies] to avoid leaking test macros transitively.


4-4: Confirm CI nightly toolchain supports Rust 2024 edition

  • rust-toolchain.toml pins channel to nightly-2025-06-26 with rustfmt and clippy.
  • Both Cargo.toml at the workspace root and test_support/Cargo.toml declare edition = "2024".
  • test_support appears only under [dev-dependencies].

No further changes required.

test_support/src/lib.rs (1)

7-10: Export test helpers without cfg gating.

Do not wrap these pub mod exports with #[cfg(test)]; dependent crates import this crate as a dev-dependency, and cfg-gating here would hide the modules from them.

Comment thread test_support/Cargo.toml
Comment thread test_support/src/lib.rs Outdated
Comment thread test_support/src/lib.rs Outdated
Comment thread test_support/src/lib.rs Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
tests/runner_tests.rs (2)

209-241: Serialise NINJA_ENV mutations with EnvLock.

Guard both the set and restore operations to avoid races with other tests that may read or write the environment concurrently.

Apply this diff to protect the unsafe environment mutations:

 #[test]
 #[serial]
 fn run_respects_env_override_for_ninja() {
-    let (temp_dir, ninja_path) = fake_ninja(0u8);
+    let (temp_dir, ninja_path) = fake_ninja(0u8);
     let original = std::env::var_os(NINJA_ENV);
-    unsafe {
-        std::env::set_var(NINJA_ENV, &ninja_path);
-    }
+    {
+        let _lock = EnvLock::acquire();
+        unsafe {
+            std::env::set_var(NINJA_ENV, &ninja_path);
+        }
+    }
@@
-    unsafe {
-        if let Some(val) = original {
-            std::env::set_var(NINJA_ENV, val);
-        } else {
-            std::env::remove_var(NINJA_ENV);
-        }
-    }
+    {
+        let _lock = EnvLock::acquire();
+        unsafe {
+            if let Some(val) = original {
+                std::env::set_var(NINJA_ENV, val);
+            } else {
+                std::env::remove_var(NINJA_ENV);
+            }
+        }
+    }
     drop(ninja_path);
     drop(temp_dir);
 }

6-10: Import EnvLock to serialise environment mutations.

Pull EnvLock into scope; you mutate NINJA_ENV later and should guard those unsafe calls.

Apply this diff to the use list:

 use test_support::{
     PathGuard, check_ninja,
     env::{SystemEnv, prepend_dir_to_path},
+    env_lock::EnvLock,
     fake_ninja,
 };
test_support/src/lib.rs (2)

18-18: Document the re-export for discoverability.

Explain why PathGuard is re-exported at the crate root so it shows up in generated docs.

Apply this diff:

-pub use path_guard::PathGuard;
+/// Re-export PathGuard for crate-level ergonomics in tests.
+pub use path_guard::PathGuard;

13-17: Gate helper modules for test-only builds.

Constrain public helper modules to test/doc-test builds to prevent accidental use in non-test contexts.

Apply this diff:

-pub mod check_ninja;
-pub mod env;
-pub mod env_lock;
-pub mod path_guard;
+#[cfg(any(test, doctest))]
+pub mod check_ninja;
+#[cfg(any(test, doctest))]
+pub mod env;
+#[cfg(any(test, doctest))]
+pub mod env_lock;
+#[cfg(any(test, doctest))]
+pub mod path_guard;

Follow up: Ensure the crate remains listed only under [dev-dependencies] in workspace Cargo.toml.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24b6f28 and d1ef402.

📒 Files selected for processing (4)
  • test_support/src/lib.rs (1 hunks)
  • tests/assert_cmd_tests.rs (2 hunks)
  • tests/runner_tests.rs (3 hunks)
  • tests/steps/process_steps.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Comment why, not what. Explain assumptions, edge cases, trade-offs, or complexity. Don't echo the obvious.
Use functions and composition. Avoid repetition by extracting reusable logic. Prefer generators or comprehensions, and declarative code to imperative repetition when readable.
Small, meaningful functions. Functions must be small, clear in purpose, single responsibility, and obey command/query segregation.
Name things precisely. Use clear, descriptive variable and function names. For booleans, prefer names with is, has, or should.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Place function attributes after doc comments.
Do not use return in single-line functions.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer single line versions of functions where appropriate.
Clippy warnings MUST be disallowed.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Keep file size manageable. No single code file may be longer than 400 lines. Long switch statements or dispatch tables should be broken up by feature and constituents colocated with targets. Large blocks of test data should be moved to external data files.
Illustrate with clear examples. Function documentation must include clear examples demonstrating the usage and outcome of the function. Test documentation should omit examples where the example serves only to reiterate the test logic.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status.
...

Files:

  • test_support/src/lib.rs
  • tests/runner_tests.rs
  • tests/assert_cmd_tests.rs
  • tests/steps/process_steps.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • test_support/src/lib.rs
  • tests/runner_tests.rs
  • tests/assert_cmd_tests.rs
  • tests/steps/process_steps.rs
🧬 Code Graph Analysis (4)
test_support/src/lib.rs (2)
tests/env_path_tests.rs (1)
  • std (39-41)
test_support/src/path_guard.rs (1)
  • new (50-56)
tests/runner_tests.rs (2)
test_support/src/env.rs (1)
  • prepend_dir_to_path (75-88)
test_support/src/lib.rs (1)
  • fake_ninja (43-98)
tests/assert_cmd_tests.rs (1)
test_support/src/lib.rs (1)
  • fake_ninja (43-98)
tests/steps/process_steps.rs (1)
test_support/src/lib.rs (1)
  • fake_ninja (43-98)
🪛 GitHub Actions: CI
tests/steps/process_steps.rs

[error] 27-33: Rust formatting check failed: cargo fmt --check detected formatting changes in tests/steps/process_steps.rs. Run 'cargo fmt' to fix formatting.

🔍 Additional research (Context7, Deepwiki)

Summary of relevant context found

  • PR goal: promote local test helpers into a new test_support crate and update tests to use it (workspace Cargo.toml updated to add test_support; author ran make fmt / make lint / make test).

  • New test_support crate:

    • test_support/Cargo.toml added (package test_support, deps: tempfile, mockable with "mock" feature; dev-dep rstest).
    • Modules added/re-exported: path_guard, env, env_lock, check_ninja; pub fn fake_ninja(exit_code: u8) implemented (platform-specific executable creation, returns (TempDir, PathBuf)).
  • Tests updated to import from test_support (replaced local tests/support module):

    • Many test files switched to use test_support::{..., fake_ninja, PathGuard, env::{...}, env_lock::EnvLock, check_ninja, ...}. Calls adjusted to use fake_ninja(0u8) etc. tests/support/mod.rs was removed. PathGuard types re-exported at crate root. #[allow(dead_code)] attributes removed from moved code.
  • Notable API/behavioral notes:

    • Public test helpers surface preserved (fake_ninja, PathGuard, mocked_path_env, prepend_dir_to_path) though some lint/test-utility attributes were removed; function signatures largely unchanged except fake_ninja now takes/returns u8 for exit code.
  • Limitations: attempted request for recent commits / PR 114 diffs returned that git/PR details/diffs are not accessible from the tool (cannot fetch commit list or file diffs). Use the repo context above for file-level changes.

🔇 Additional comments (7)
tests/assert_cmd_tests.rs (2)

10-10: Adopt shared helper crate for fake_ninja.

Import fake_ninja from test_support to centralise test utilities and reduce duplication. Good move.


29-29: Use u8 for exit code to match helper API.

Passing 0u8 matches fake_ninja’s signature and keeps platform semantics precise. The PATH override is correctly scoped to the child process via Command::env.

tests/runner_tests.rs (1)

35-40: Fixture migration to fake_ninja(u8) is correct.

Using the shared helper with a u8 exit code aligns with the new API and keeps the fixtures small and focused.

tests/steps/process_steps.rs (2)

3-3: Keep world type import local.

Importing CliWorld at the top-level improves readability of step signatures. No issues.


9-13: Unify test_support imports.

Import fake_ninja alongside check_ninja and env to avoid mixed FQ/imported usage within the module.

test_support/src/lib.rs (2)

1-11: Provide clear crate-level docs for test-only scope and platform notes.

The crate docs set expectations, list utilities, and call out platform behaviour. Good coverage.


43-98: Implement platform-correct fake_ninja with descriptive panics.

The helper now models exit codes as u8, emits a .cmd on Windows and a POSIX script on Unix, and surfaces context-rich panic messages. This is robust and test-friendly.

Comment thread tests/steps/process_steps.rs Outdated
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 13, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 13, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 13, 2025

@sourcery-ai review

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@leynos leynos merged commit 888fc6b into main Aug 13, 2025
4 checks passed
@leynos leynos deleted the codex/promote-tests/support-to-test_support-crate branch August 13, 2025 22:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant