Skip to content

Conversation

@perkops
Copy link
Member

@perkops perkops commented Sep 14, 2025

Summary

Upgrade and modernization of Atc.Test to xUnit v3 with improved data attribute capabilities, deterministic frozen value handling, stronger safety around specimen reuse, and CI pipeline upgrade to .NET 9.

Key Changes

Framework & Infrastructure

  • Migrated custom data attributes to xUnit v3 async extensibility (ValueTask<IReadOnlyCollection<ITheoryDataRow>>).
  • Library depends on xunit.v3.extensibility.core; consumers must add a direct PackageReference to xunit.v3.

Data Attribute Enhancements

MemberAutoNSubstituteDataAttribute

  • Two-phase frozen handling: (1) positional reuse (2) exact-type promotion of earlier supplied values.
  • Promotion restricted to exact declared type only (no interface/base widening).

ClassAutoNSubstituteDataAttribute

  • Positional-only reuse (no promotion) for explicitness.
  • Introduced FrozenParameterInjector (shared helper extracting and unifying frozen injection logic).

Frozen Semantics Hardening

  • Negative test preventing accidental cross-interface promotion (dual-interface specimen).
  • Replaced broad IsInstanceOfType matching with exact declared type + earliest index rule.
  • Documented scenarios: positional reuse, exact-type promotion, explicit non-promotion across interfaces.

Documentation & Developer Experience

  • Expanded XML docs (resolution order, promotion rules, fixture isolation).
  • Restructured README (Introduction, Why Atc.Test, Features, Getting Started, Advanced Usage, Requirements).
  • Added explicit xUnit v3 only compatibility section and optional guard snippet.
  • Explained rationale for not making xunit.v3 a transitive dependency.
  • Added a value proposition section (“Why Atc.Test”).

Tests

  • Added coverage for:
    • Positional frozen reuse
    • Earlier-supplied exact-type promotion
    • Negative non-promotion across interfaces
  • Reflection-based tests verify display name handling (where relevant) and metadata preservation for class data rows.

Refactoring & Cleanup

  • Centralized frozen logic in FrozenParameterInjector.
  • Reduced duplication between class and member data attributes.
  • Simplified display name handling (removed visual markers).
  • Ensured constructor argument exposure
  • Clarified separation of responsibilities (fixture creation vs injection pipeline).

CI / Pipeline Modernization

  • Updated pre-integration, post-integration, and release GitHub workflows to use .NET 9 (actions/setup-dotnet 9.0.x).

Breaking Changes

Area Change Impact Action Required
xUnit Version Requires xUnit v3 xUnit v2 projects will not compile Add PackageReference Include="xunit.v3"
Member Data Frozen Behavior Exact-type earlier supplied value promotion Some tests may now see reuse where a new instance was previously generated Remove [Frozen] or supply explicit alternate instance if reuse undesired
Assignable-Type Promotion Interface/base promotion removed May reveal hidden coupling or reliance on broad matching Adjust tests to explicitly freeze intended type
No Transitive xUnit xunit.v3 not pulled in indirectly Missing explicit reference causes compile errors Add explicit reference

Rationale

  • xUnit v3 provides cleaner async-aware data extensibility and richer row metadata.
  • Exact-type promotion increases ergonomics for member data while remaining predictable.
  • Negative tests codify design boundaries and prevent silent regression.
  • Central helper (FrozenParameterInjector) simplifies maintenance and future enhancement.
  • SDK pin ensures reproducible builds across contributors and CI.

Implementation Notes

Concern Approach
Promotion Selection Earliest supplied argument whose declared type exactly matches the [Frozen] parameter type
Member vs Class Data Promotion enabled only for member data; class data stays positional
Fixture Isolation New fixture instance per data row
Metadata Preservation ITheoryDataRow properties copied (Label, Explicit, Timeout, Traits) for supported sources
Display Names Simplified formatting; correctness prioritized over decorative markers

Closes #49

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR modernizes the Atc.Test library by upgrading from xUnit v2 to xUnit v3 and introduces a major version bump to 2.0. The upgrade enhances data attribute capabilities with async extensibility, implements deterministic frozen value handling with exact-type promotion, and improves safety around specimen reuse.

Key Changes

  • xUnit v3 Migration: Complete migration of data attributes to use async ValueTask<IReadOnlyCollection<ITheoryDataRow>> extensibility model
  • Enhanced Frozen Logic: Introduced two-phase frozen handling with positional reuse and exact-type promotion for member data attributes
  • Infrastructure Modernization: Updated CI pipelines to .NET 9, comprehensive README restructuring, and improved developer experience

Reviewed Changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
version.json Major version bump from 1.1 to 2.0 reflecting breaking changes
src/Atc.Test/Atc.Test.csproj Updated dependencies to xUnit v3 and added .NET 9 target framework
src/Atc.Test/MemberAutoNSubstituteDataAttribute.cs Complete rewrite to support async data generation with exact-type promotion
src/Atc.Test/ClassAutoNSubstituteDataAttribute.cs Migrated to async model with positional-only frozen injection
src/Atc.Test/FrozenParameterInjector.cs New shared helper centralizing frozen injection logic
test/Atc.Test.Tests/MemberAutoNSubstituteDataAttributeTests.cs Added comprehensive tests for frozen reuse scenarios
README.md Complete restructure with value proposition, compatibility notes, and usage examples
.github/workflows/ Updated CI workflows to use .NET 9

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Collaborator

@rickykaare rickykaare left a comment

Choose a reason for hiding this comment

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

Looks good 😊 Great job!

…te pattern

Use protected AutoDataAttribute(Func<IFixture>) constructor with lambda.
Fully qualify FixtureFactory to avoid shadowing with base property.
Ensures custom fixture customizations still applied post-migration.
…nc GetData

Replace IEnumerable<object[]> GetData override with ValueTask<IReadOnlyCollection<ITheoryDataRow>>.
Augment each row with frozen parameter injection + generated specimens.
Preserve row metadata; guard against null traits.
Align with v3 TheoryDataRow / ITheoryDataRow contract.
…ta pipeline

Remove obsolete [DataDiscoverer] (reflection abstractions removed in xUnit v3).
Replace deprecated ConvertDataItem override with async GetData(MethodInfo, DisposalTracker).
Wrap base data rows into new TheoryDataRow instances and append AutoFixture-generated specimens for missing parameters.
Preserve existing metadata (skip, explicit, traits, etc.).
@perkops perkops merged commit 0a98531 into main Sep 15, 2025
4 checks passed
@perkops perkops deleted the feature/upgrade branch September 15, 2025 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Any plans for update to xUnit V3 ?

4 participants