Skip to content

Preserve whole-tuple method inference across wrapped and async data sources #7638

Closed

Description

@thomhurst

Generic method data sources must infer the same test instantiations in generated and reflection discovery when a tuple is the whole first argument and later arguments are omitted. PR #7631 contains this behavior but exceeded its review budget; extract this deliverable independently and fix its remaining wrapper-normalization defects.

Scope

Start from fresh origin/main. Reuse only whole-row boundary/inference changes from preserved branch issue-7629-tuple-parity, head 2a1cc3753c847cfc3393accc5b8adae517e75895 (#7631). Own strict whole-row matching in src/TUnit.Core/Helpers/TupleHelper.cs, corresponding DataSourceHelpers.cs and TestDataRowUnwrapper.cs boundary checks, src/TUnit.Engine/Helpers/DataUnwrapper.cs whole-first-row handling, and whole-row/explicit-method-type inference in src/TUnit.Engine/Discovery/ReflectionTestDataCollector.cs and src/TUnit.Core.SourceGenerator/Generators/TestMetadataGenerator.cs. Keep sole-tuple conversion/reconstruction changes out of this extraction. Shared files require selected hunks, never whole-file replacement.

Own focused whole-row fixtures, generator snapshots, helper unit tests, engine integration expectations and the corresponding rule-table documentation. Use static sources so this change remains independent of instance-source discovery.

Acceptance

  • Preserve a compatible whole tuple argument with optional, params and collecting-array tails; distinguish nested spread rows and enforce repeated generic bindings and constructed tuple invariance.
  • Preserve inferred instantiations alongside [GenerateGenericTest] explicit instantiations for direct, Func, TestDataRow, inner/outer Func and reference-tuple rows; deduplicate a sole bare-T reference tuple against its explicit whole-row type. Ordinary spread array/nullable columns retain existing last-column inference.
  • Resolve Greptile thread PRRT_kwDOLJDcx860AwXk on Preserve tuple inference and runtime element conversions #7631: generated wrapper lookup must recognize derived TestDataRow<T> records consistently with reflection. Cover IEnumerable<Row> where Row derives from TestDataRow<(int,string)>, explicit long, and Run<T>((T,string) row).
  • Resolve Codex thread PRRT_kwDOLJDcx860AxWl on Preserve tuple inference and runtime element conversions #7631: normalize supported asynchronous source return wrappers before reflection explicit inference. Cover Task<IEnumerable<Func<(int,string)>>> with explicit long and an optional tail, plus supported ValueTask/async-enumerable shapes where applicable.
  • Verify both findings against the current implementation before fixing; assert identical discovered methods and failure outcomes in both discovery modes.
  • Run affected generator snapshots, helper tests and targeted shared fixtures in both modes; verify Native AOT publishing. Engine integration tests run only in CI per AGENTS.md. Commit only intentional verified snapshots.

No dependency on the sibling sole-tuple reconstruction deliverable: use the existing main behavior for sole tuple conversions. Preserve previous #7631 dispositions relevant to this scope and link #7622 for narrowly scoped analyzer false positives. Matcher maintainability follow-up remains #7588. Supersedes the whole-row portion of #7629, under parent #7351.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium: edge case, mode divergence, flaky test, or workaround existsbugSomething isn't workingin-progressWork is in progress

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions