Skip to content

test: consolidate duplicated toy test-domains into one shared, fixture-friendly module #239

Description

@joeldsouzax

Problem

The test suite has no shared test-domain module, so the same toy aggregate is redefined from scratch across many files. This violates CLAUDE.md Rule 8 ("Each invariant tested once in a canonical location… don't duplicate the same property test across 3-5 files with different domain types").

An API-tightness audit (2026-06-28) found ~9 independent near-identical Counter/Count domain definitions and a duplicated AccountState across the two store examples. A mod shared_domain | common | test_support | fixtures does not exist anywhere in the workspace (confirmed by grep).

Evidence (CounterEvent / CounterState / CountEvent / CountState redefined independently)

  • crates/nexus/tests/aggregate_fixture_tests.rs:40,51,79
  • crates/nexus/tests/kernel_tests/aggregate_root_tests.rs:39,58,90
  • crates/nexus/tests/kernel_tests/property_tests.rs:46,63
  • crates/nexus-macros/tests/macro_property_tests.rs:34,51
  • crates/nexus-store/tests/repository_qa_tests.rs:65,84
  • crates/nexus-store/tests/zero_copy_event_store_tests.rs:34
  • crates/nexus-store/tests/snapshot_integration_tests.rs:38,54
  • crates/nexus-store/tests/projection_tests.rs:261
  • examples/projection-tokio/tests/loop_tests.rs:71

Plus AccountState defined twice: examples/inmemory/src/main.rs:130 and examples/store-and-kernel/src/main.rs:127.

Proposal

Create one canonical, fixture-friendly test domain (e.g. Counter + Account + OrderSaga with their events/commands/errors) in a shared location reusable across crates, and replace the duplicated definitions with imports.

Notes / constraints:

  • Cross-crate test reuse in Rust needs either a dev-dependency shared crate or per-crate tests/common/mod.rs includes — pick the lightest approach that the gate (nix flake check, default features) covers. See [[project_gate_nextest_default_features]] consideration: a self dev-dependency may be needed so feature-gated test domains are exercised in CI.
  • Keep example domains (inmemory, store-and-kernel) as-is if their duplication is pedagogically intentional; the priority is the tests/ duplication.

Scope

Test-only refactor. No production src/ changes (per CLAUDE.md: never touch production source for test infra).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions