Skip to content

Match method data source attributes by fully qualified identity - #7649

Merged
thomhurst merged 1 commit into
mainfrom
issue-7648-method-source-identity
Nov 5, 2026
Merged

thomhurst merged 1 commit into
mainfrom
issue-7648-method-source-identity

Conversation

@thomhurst

@thomhurst thomhurst commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Generic test inference could treat unrelated attributes named MethodDataSourceAttribute or InstanceMethodDataSourceAttribute as TUnit data sources, introducing type instantiations from unrelated metadata. Classification, duplicate-row grouping, deferred sources, and class-source inference now check the fully qualified TUnit identity consistently.

Regression fixtures put both lookalike attributes beside genuine static and instance sources. The reviewed generator snapshot emits only the intended int instantiations, and engine integration coverage checks exactly two passing rows in both discovery modes.

Validation:

Closes #7648

Summary by CodeRabbit

  • Bug Fixes
    • Tests using method-based data sources now generate and run with the intended values, including generic static and instance sources. Unrelated data-source attributes no longer contribute extra test rows, helping ensure test counts and results reflect the applicable sources.

@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The source generator now identifies method data-source attributes by fully qualified, non-generic names in inference, filtering, and bucketing paths. Regression tests combine TUnit sources with unrelated attributes that share their simple names and verify generated and runtime test results.

Changes: Method data-source identity

Layer / File(s) Summary
Qualified attribute matching
src/TUnit.Core.SourceGenerator/Generators/TestMetadataGenerator.cs
Inference, filtering, and bucketing paths use qualified attribute identities for method data sources. A shared predicate recognizes the static and instance attributes. The [Arguments] bucket now matches the exact qualified ArgumentsAttribute name.
Static and instance source fixtures
tests/TUnit.TestProject/Bugs/_7648/MethodSourceIdentityTests.cs
The fixture combines unrelated same-name attributes with TUnit static and instance sources. Both tests use integer source values; the fixture also defines an unrelated string source.
Generated output and engine assertions
tests/TUnit.Core.SourceGenerator.Tests/Bugs/7648/Tests7648.cs, tests/TUnit.Core.SourceGenerator.Tests/Tests7648.Test.verified.txt, tests/TUnit.Engine.Tests/Issue7648Tests.cs
The generator test checks that the int source identities are present and string variants are absent. The engine test checks for two passed tests and zero failed tests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Possibly related issues

Merge Risk: Minimal · up to d4798

The change appears ready to merge after normal checks; no concrete regression remains identified.

Pre-merge checks: Passed 5

Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "Match method data source attributes by fully qualified identity" matches the main change. The raw summary says the generator now identifies method and instance method data-source attributes…
Linked Issues check Passed Directly linked issue #7648 requires fully qualified identity checks for method data source classification and filtering. It also requires regression fixtures with unrelated MethodDataSourceAttribute …
Out of Scope Changes check Passed Changes in the reviewed diff fall into four groups:
1. Method data source identity checks in TestMetadataGenerator.cs. These implement #7648 directly.
2. Fixtures and tests: Bugs/_7648 fixtures, the T…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Full details: Title check

Explanation

The title "Match method data source attributes by fully qualified identity" matches the main change. The raw summary says the generator now identifies method and instance method data-source attributes by their globally qualified, non-generic names instead of short names. The PR objectives describe the same change to classification, duplicate-row grouping, deferred sources, and class-source inference. The title is specific and concise, and it names the primary change.

Full details: Linked Issues check

Explanation

Directly linked issue #7648 requires fully qualified identity checks for method data source classification and filtering. It also requires regression fixtures with unrelated MethodDataSourceAttribute and InstanceMethodDataSourceAttribute types, and matching generated and reflection rows.

Code evidence (merge base to reviewed head, TestMetadataGenerator.cs):

  • Classification in TryAddInstantiation (formerly simple-name check at about line 1260) now calls IsMethodDataSourceAttribute, which compares GloballyQualifiedNonGeneric() against global::TUnit.Core.MethodDataSourceAttribute or InstanceMethodDataSourceAttributeName.
  • Duplicate-row grouping (JoinsDuplicate and methodRow join) uses the same helper.
  • Source filtering (formerly the simple-name check at about line 1469) compares the fully qualified name.
  • The deferred instance-source join, the bucket switch, the instance-explicit-types helper, the uninferred-failure path, and GetOwnClassMethodDataSourcesForInstantiation all use fully qualified identity.

Test evidence: the PR adds Bugs/_7648 fixtures with lookalike attributes beside genuine static and instance sources, a verified generator snapshot (Tests7648.Test.verified.txt) that emits only int instantiations, and Issue7648Tests that checks two passing rows in both TestMode values. The test results are author-reported. I did not run them. The snapshot and fixture contents were taken from the PR summary, not from direct file reads.

The shared identity helper suggested in the issue is present. No unmet coding requirement was found in the reviewed changes.

Full details: Out of Scope Changes check

Explanation

Changes in the reviewed diff fall into four groups:

  1. Method data source identity checks in TestMetadataGenerator.cs. These implement #7648 directly.
  2. Fixtures and tests: Bugs/_7648 fixtures, the Tests7648 generator test, the verified snapshot, and Issue7648Tests. These support #7648 directly.
  3. An ArgumentsAttribute bucket change. The switch case changed from a simple name plus IsOrInherits check to an exact match on global::TUnit.Core.ArgumentsAttribute. This is not a method data source attribute. It uses the same identity-matching pattern in the same switch, and it removes simple-name matching of lookalike ArgumentsAttribute types. The PR description does not name this change. The PR objectives say adjacent ArgumentsAttribute simple-name checks are tracked in #7650. The connection to #7648 is by mechanism, not by requirement. This change is minor and does not add new behavior for method data sources.
  4. The non-null guard on methodRow, added to remove a nullable warning. This is a supporting change.

No demonstrated unrelated change was found.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 4 files. (1 skipped: 1 unsupported.)

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

A rabbit checks each source by name,
No stray twin joins the test-run game.
The static rows bring integers through,
The instance rows bring integers too.
Two tests pass beneath the moon,
While string-shaped rows leave the room.

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 924b89ab-16be-44ec-adbe-d3c15feff231
Commits

Reviewing files that changed from the base of the PR and between b9d47de and d47986c.

Files selected for processing: 5

  • src/TUnit.Core.SourceGenerator/Generators/TestMetadataGenerator.cs
  • tests/TUnit.Core.SourceGenerator.Tests/Bugs/7648/Tests7648.cs
  • tests/TUnit.Core.SourceGenerator.Tests/Tests7648.Test.verified.txt
  • tests/TUnit.Engine.Tests/Issue7648Tests.cs
  • tests/TUnit.TestProject/Bugs/_7648/MethodSourceIdentityTests.cs

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 4 remain after this review.

@thomhurst

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-05T14:47:03.104521Z d47986c Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Review

The change is correct and well scoped. Name-only matching (Name is "MethodDataSourceAttribute") is replaced with fully qualified identity checks. I checked that GloballyQualifiedNonGeneric exists in the generator's TypeExtensions. The new IsMethodDataSourceAttribute helper and the InstanceMethodDataSourceAttributeName constant remove most of the duplicated string literals.

The regression fixtures put lookalike attributes beside the real ones. The generator snapshot and the engine test cover both discovery modes.

Non-blocking suggestions:

  • A few spots still repeat the literal "global::TUnit.Core.MethodDataSourceAttribute" and "global::TUnit.Core.ArgumentsAttribute". These are the bucket switch, the ArgumentsAttribute checks in TryAddInstantiation, and the GetOwnClassMethodDataSources… check. Add constants for them next to InstanceMethodDataSourceAttributeName. Better still, give ArgumentsAttribute its own helper like the one for method data sources, so the two identity checks cannot drift apart.
  • specificAttr.AttributeClass?.Name == "ArgumentsAttribute" (around line 1050) and methodRow?.AttributeClass?.Name == "ArgumentsAttribute" (around line 1060) still match by name only. This is the same class of bug the PR fixes, so a lookalike ArgumentsAttribute would be treated as a literal row. Please convert these too.
  • StaticPropertyInitializationGenerator.cs:322 still uses attributeClassName == "MethodDataSourceAttribute". It may be out of scope, but it looks like the same hazard. Please check it or file a follow-up issue.
  • In the typedDataSourceBucket loop, GloballyQualifiedNonGeneric() is called twice per attribute. Hoist it into a local.

Overall this is good to merge once the ArgumentsAttribute name checks are addressed or deliberately deferred.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: e032133b0a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@greptile-apps

greptile-apps Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no blocking issues were found.

Summary

The generator now checks fully qualified TUnit attribute names instead of short names.

  • Generic test rows come only from TUnit method-source attributes.

Reviews (2) · Last reviewed commit: "Fix method data source attribute identit..." · Reviewed by Greptile

@thomhurst

Copy link
Copy Markdown
Owner Author

Reviewed every conversation comment, review, inline comment and review thread on e032133. Codex reports completed with no findings; Greptile has no actionable findings; there are no inline threads.

Disposition of Claude's non-blocking suggestions: the remaining ArgumentsAttribute simple-name checks extend beyond the two duplicate-row checks (class-row filtering also uses short names), and the static-property parser is a separate path. Confirmed both on current main and tracked their audit and regression coverage in #7650. Deliberately defer those existing adjacent paths to that follow-up so this PR retains #7648's method-source inference scope. The constants/helper consolidation and repeated display conversion are also recorded there as non-blocking cleanup.

Claude's verdict permits merge once the ArgumentsAttribute checks are addressed or deliberately deferred; the follow-up above supplies that disposition. Promoting this unchanged, reviewed head to ready starts the full CI checks and a fresh Claude review. Auto-merge will be armed only after that Claude run passes and its comment is checked.

@thomhurst
thomhurst marked this pull request as ready for review November 5, 2026 13:36
@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Review

The change is correct and focused. It replaces name-only checks (Name is "MethodDataSourceAttribute") with fully qualified identity checks through a shared IsMethodDataSourceAttribute helper and a const for the instance variant. The lookalike-attribute fixtures cover both the generator snapshot and the engine run in both modes.

Notes:

  • Leftover name-only check: CodeGenerators/StaticPropertyInitializationGenerator.cs:322 still compares attributeClassName == "MethodDataSourceAttribute". It is outside the inference path this PR fixes, but it is the same class of bug. Either fix it here or file a follow-up issue.
  • Repeated calls: GloballyQualifiedNonGeneric() is called twice in a row in the typed-source bucket loop (around line 1468). Hoist it into a local. The generator runs incrementally, so cheap string work matters.
  • Constants: global::TUnit.Core.MethodDataSourceAttribute and global::TUnit.Core.ArgumentsAttribute are inline string literals, while the instance variant has a const. Making all three consts would be more consistent.
  • Symbol comparison: if a well-known type lookup is available, SymbolEqualityComparer on the symbol avoids string allocation. That would be a broader refactor, not needed for this PR.

None of these block merging. Nice regression coverage.

@thomhurst
thomhurst marked this pull request as draft November 5, 2026 14:29
@thomhurst
thomhurst force-pushed the issue-7648-method-source-identity branch from e032133 to d47986c Compare November 5, 2026 14:30
@thomhurst

Copy link
Copy Markdown
Owner Author

Resolved the new conflict with main in d47986c. Run 42037264658 completed successfully; it is no longer the blocker. Rebased onto b9d47de, retaining main’s qualified ArgumentsAttribute checks and this PR’s qualified method-source checks at the shared insertion points. An explicit non-null row guard also removes the nullable warning introduced by the helper call.

Validation: generator snapshots passed (353 passed, 1 skipped), with no snapshot changes. TestProject net10.0 single-worker build passed; the targeted MethodSourceIdentityTests fixture passed exactly 2 tests in generated mode and exactly 2 in reflection mode. The initial parallel build hit the existing MSB4166 problem tracked by #7468. Engine integration remains for CI per repository instructions.

Returned to draft for fresh Claude and Codex review of the rebased head. Prior non-blocking cleanup remains tracked in #7650, which now has PR #7651; this PR does not depend on that follow-up.

@codex review

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Review

The change looks correct and well scoped. Every bare Name comparison for MethodDataSourceAttribute and InstanceMethodDataSourceAttribute in TestMetadataGenerator.cs now uses the fully qualified TUnit identity. That covers classification, duplicate-row joining, deferred sources, the uninferred-source bucket and the class-level source scan.

Checked:

  • InstanceMethodDataSourceAttributeName is defined at line 27. The new IsMethodDataSourceAttribute helper removes the repeated Name is ... or ... checks.
  • The methodRow is not null guard avoids passing a null row to AddRow. The old code relied on null-conditional behaviour there.
  • The regression fixtures put lookalike attributes next to the genuine ones. The snapshot and the exact-count engine test, run in both modes, would catch a regression.

Non-blocking suggestions:

  1. src/TUnit.Core.SourceGenerator/CodeGenerators/StaticPropertyInitializationGenerator.cs:322 still uses attributeClassName == "MethodDataSourceAttribute". It may have the same lookalike problem for static properties. Please check whether it needs the same fix, or open a follow-up issue.
  2. Consider moving IsMethodDataSourceAttribute and the name constants into a shared helper such as DataSourceAttributeHelper. Other generators could then reuse them, which avoids this kind of drift.
  3. GloballyQualifiedNonGeneric() builds a string on each call. That is fine for these paths, but a SymbolEqualityComparer check against the compilation's well-known type would avoid the allocation in hot loops.

I did not run the tests. The PR description says the engine integration suite is left to CI, so that result still needs to come from CI.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: d47986cdde

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@thomhurst
thomhurst marked this pull request as ready for review November 5, 2026 14:45
@thomhurst

Copy link
Copy Markdown
Owner Author

Run 42037264658 succeeded and is no longer a blocker. Rechecked all conversation comments, reviews, inline comments and review threads: Claude and Codex both approve current head d47986c, with no unresolved threads. Claude’s non-blocking static-property audit and shared-helper/allocation suggestions remain covered by #7650 and its open PR #7651; neither is a prerequisite for this scoped fix.

Promoted the unchanged head to ready. Full CI is now running, and promotion started Claude run 42048096489. Auto-merge must wait until that run passes and its new review comment is dispositioned. No code changes or local validation were needed in this unit.

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Review: LGTM.

The PR replaces the simple-name checks (Name is "MethodDataSourceAttribute" ...) with fully qualified identity checks. That closes the lookalike-attribute leak from #7648. I checked the diff and found no correctness issues.

  • The checks are consistent across classification, duplicate-row grouping, deferred sources, constraint-violation diagnostics and class-source inference. A shared IsMethodDataSourceAttribute helper and an InstanceMethodDataSourceAttributeName constant replace the repeated string literals.
  • The bucket switch now matches on the qualified name. This is equivalent to the old ArgumentsAttribute when IsOrInherits check, because the old Name match only accepted that exact name anyway.
  • The methodRow is not null guard in the duplicate-join branch is a small null-safety improvement.
  • The regression fixtures put lookalike attributes beside real static and instance sources. The snapshot and the DoesNotContain assertions confirm only int instantiations are emitted. The engine test covers both discovery modes.

Optional follow-up: "global::TUnit.Core.MethodDataSourceAttribute" is still a literal in a few places, while the instance variant has a constant. A matching MethodDataSourceAttributeName constant would make the pair symmetric.

I did not run the tests locally.

🤖 Generated with Claude Code

@thomhurst

Copy link
Copy Markdown
Owner Author

Run 42048096489 completed successfully on d47986c; the earlier wait is cleared. Read every review, inline comment, review thread and PR conversation comment again. Claude’s post-promotion review is LGTM, Codex’s completed summary names this exact head and has no findings, and CodeRabbit and Greptile report no actionable findings. No inline comments or review threads exist.

The optional constants/helper/allocation cleanup remains dispositioned in #7650 and its open PR #7651; these are follow-ups rather than prerequisites. The PR body already closes #7648. All current CI checks, including both Engine tests and AOT platforms, passed. Current main protection requires those checks and resolved conversations, with no formal approval count. Proceeding through the repository merge gate for the unchanged head.

@thomhurst
thomhurst merged commit 0ace815 into main Nov 5, 2026
40 checks passed
@thomhurst
thomhurst deleted the issue-7648-method-source-identity branch November 5, 2026 15:19
This was referenced Nov 7, 2026
github-actions Bot pushed a commit to sharafutdinovdi/revit-model-mcp that referenced this pull request Nov 8, 2026
Updated [TUnit](https://github.com/thomhurst/TUnit) from 1.78.0 to
1.81.10.

<details>
<summary>Release notes</summary>

_Sourced from [TUnit's
releases](https://github.com/thomhurst/TUnit/releases)._

## 1.81.10

<!-- Release notes generated using configuration in .github/release.yml
at v1.81.10 -->

## What's Changed
### Other Changes
* Preserve private type values in generated executable test attributes
by @​thomhurst in thomhurst/TUnit#7667
* feat(sourcegen): inherit XML docs from [AssertionExtension] classes by
@​JohnVerheij in thomhurst/TUnit#7692
### Dependencies
* Update all non-major dependencies to 1.81.5 by @​thomhurst in
thomhurst/TUnit#7690


**Full Changelog**:
thomhurst/TUnit@v1.81.5...v1.81.10

## 1.81.5

<!-- Release notes generated using configuration in .github/release.yml
at v1.81.5 -->

## What's Changed
### Other Changes
* feat(sourcegen): inherit XML docs from [GenerateAssertion] source
methods by @​JohnVerheij in thomhurst/TUnit#7687
* fix(mocks): stop verification leaving setups on void-shaped members by
@​thomhurst in thomhurst/TUnit#7688
### Dependencies
* Update all non-major dependencies by @​thomhurst in
thomhurst/TUnit#7681
* Update dependency OpenTelemetry.Instrumentation.AspNetCore to 1.20.2
by @​thomhurst in thomhurst/TUnit#7685


**Full Changelog**:
thomhurst/TUnit@v1.81.0...v1.81.5

## 1.81.0

<!-- Release notes generated using configuration in .github/release.yml
at v1.81.0 -->

## What's Changed
### Other Changes
* Extract Windows engine hang dump stacks in CI by @​thomhurst in
thomhurst/TUnit#7584
* Cut STAThreadTests repeats so the Windows reflection pass run fits its
timeout by @​thomhurst in thomhurst/TUnit#7594
* Preserve expected-value semantics when migrating xUnit Assert.Single
by @​thomhurst in thomhurst/TUnit#7586
* Capture Windows loader ownership and thread CPU times by @​thomhurst
in thomhurst/TUnit#7603
* Isolate the full passing engine session from sibling test processes by
@​thomhurst in thomhurst/TUnit#7606
* Remove unused concrete metadata generation chain by @​thomhurst in
thomhurst/TUnit#7569
* Avoid temporary arrays in singleton tuple binding by @​thomhurst in
thomhurst/TUnit#7583
* Fix ParallelTests overlap assertion for late repetitions by
@​thomhurst in thomhurst/TUnit#7600
* Fix nullable generic class method-row analyzer validation by
@​thomhurst in thomhurst/TUnit#7613
* Fix generated property injection into boxed structs by @​thomhurst in
thomhurst/TUnit#7612
* Make Playwright template navigation deterministic by @​thomhurst in
thomhurst/TUnit#7604
* Release objects and complete teardown for dependency-skipped tests by
@​thomhurst in thomhurst/TUnit#7605
* Support typed tuple rows before optional parameters by @​thomhurst in
thomhurst/TUnit#7608
* Cover null rows in generic class type inference by @​thomhurst in
thomhurst/TUnit#7621
* Skip certificate trust preparation for HTTP-only Aspire test resources
by @​thomhurst in thomhurst/TUnit#7618
* Accept convertible typed rows before optional test parameters by
@​thomhurst in thomhurst/TUnit#7619
* Preserve nullable class discovery parity and constructor precedence by
@​thomhurst in thomhurst/TUnit#7614
* Preserve whole tuple rows before omitted trailing arrays by
@​thomhurst in thomhurst/TUnit#7625
* Fix reflection inference for concrete params arrays by @​thomhurst in
thomhurst/TUnit#7627
* Remove obsolete nullable method-row analyzer suppression by
@​thomhurst in thomhurst/TUnit#7626
* Infer generic method arguments from instance data sources by
@​thomhurst in thomhurst/TUnit#7630
* test: cover discarded method-row lifecycle isolation (#​7373) by
@​thomhurst in thomhurst/TUnit#7632
* Allow DI scopes to opt out of resolved object ownership by @​thomhurst
in thomhurst/TUnit#7633
* Give TestBuilder rows explicit cleanup owners by @​thomhurst in
thomhurst/TUnit#7637
* Preserve whole-tuple inference across wrapped and async sources by
@​thomhurst in thomhurst/TUnit#7641
* Fix reported compiler warnings in regression fixtures by @​thomhurst
in thomhurst/TUnit#7645
* fix(core): track external ownership per row scope by @​thomhurst in
thomhurst/TUnit#7635
* Fix remaining regression fixture compiler warnings by @​thomhurst in
thomhurst/TUnit#7646
* Fix generic class argument row edge cases by @​thomhurst in
thomhurst/TUnit#7647
* Preserve sole-tuple inference and runtime conversion parity by
@​thomhurst in thomhurst/TUnit#7643
* Match method data source attributes by fully qualified identity by
@​thomhurst in thomhurst/TUnit#7649
* Treat null method data sources as empty in both execution modes by
@​thomhurst in thomhurst/TUnit#7652
* Fix xUnit proper-set migration operands and strictness by @​thomhurst
in thomhurst/TUnit#7653
* Fix mock setup identifier collisions by @​thomhurst in
thomhurst/TUnit#7658
* fix(generator): qualify built-in data-source row classification by
@​thomhurst in thomhurst/TUnit#7651
* Capture macOS native runtime crashes for diagnosis by @​thomhurst in
thomhurst/TUnit#7659
* Restore nullable diagnostics in mock generated-code regression guards
by @​thomhurst in thomhurst/TUnit#7661
* Avoid mock predicate conversion local name collisions by @​thomhurst
in thomhurst/TUnit#7655
* Install browsers with the resolved .NET Playwright package by
@​thomhurst in thomhurst/TUnit#7673
* Remove nullable and assertion warnings from unit tests by @​thomhurst
in thomhurst/TUnit#7670
* Preserve keyword escapes in generated attribute factory type names by
@​thomhurst in thomhurst/TUnit#7669
* Fix default mock argument matching by @​thomhurst in
thomhurst/TUnit#7676
* Preserve category and property filters on generic discovery failures
by @​thomhurst in thomhurst/TUnit#7663
* Preserve keyword escapes in generated type expressions by @​thomhurst
in thomhurst/TUnit#7675
* Encapsulate row lifetime and constructor state replay by @​thomhurst
in thomhurst/TUnit#7678
* Diagnose unsupported span params on test methods by @​thomhurst in
thomhurst/TUnit#7679
 ... (truncated)

## 1.80.0

<!-- Release notes generated using configuration in .github/release.yml
at v1.80.0 -->

## What's Changed
### Other Changes
* Share evaluated constructor-row state across discovery modes by
@​thomhurst in thomhurst/TUnit#7497
* Diagnose static data-source properties in inaccessible containing
types by @​thomhurst in thomhurst/TUnit#7503
* Extract typed-row binding and verify invocation parity by @​thomhurst
in thomhurst/TUnit#7507
* Accept omitted optional MethodDataSource arguments in TUnit0001 by
@​thomhurst in thomhurst/TUnit#7486
* Preserve null-containing tuples from static method data sources by
@​thomhurst in thomhurst/TUnit#7469
* Fix dependencies on deferred enumeration tests by @​thomhurst in
thomhurst/TUnit#7471
* Preserve DI scope ownership and synchronize concurrent property
registration by @​thomhurst in
thomhurst/TUnit#7476
* Infer typed row generic arguments through interfaces and base classes
by @​thomhurst in thomhurst/TUnit#7508
* Keep session cleanup from disposing another session’s data sources by
@​thomhurst in thomhurst/TUnit#7509
* Fix recursive generated tuple argument conversions by @​thomhurst in
thomhurst/TUnit#7515
* Share generic class row selection and pairing policy by @​thomhurst in
thomhurst/TUnit#7498
* Raise data-source delegates at test lifecycle stages by @​thomhurst in
thomhurst/TUnit#7521
* Fix class argument literals to use constructor parameter types by
@​thomhurst in thomhurst/TUnit#7496
* Accept numeric widening for single reference-tuple data parameters by
@​thomhurst in thomhurst/TUnit#7510
* fix(core): preserve optional F# async support without AOT warnings by
@​thomhurst in thomhurst/TUnit#7526
* Fix timeouts for synchronously blocking test bodies by @​thomhurst in
thomhurst/TUnit#7527
* Fix Native AOT getters for generic test class property metadata by
@​thomhurst in thomhurst/TUnit#7524
* Refresh stale core generator snapshots by @​thomhurst in
thomhurst/TUnit#7549
* Infer generic class types from inherited literal arguments by
@​thomhurst in thomhurst/TUnit#7544
* Make duplicate-stop cancellation regression independent of thread-pool
scheduling by @​thomhurst in
thomhurst/TUnit#7546
* Fix colliding generator diagnostic IDs by @​thomhurst in
thomhurst/TUnit#7538
* Fix generic array binding inside tuple data-source parameters by
@​thomhurst in thomhurst/TUnit#7541
* Discover AOT converters from method data source return types by
@​thomhurst in thomhurst/TUnit#7547
* Check tuple conversion analyzer policy against runtime binding by
@​thomhurst in thomhurst/TUnit#7559
* Deduplicate disposal span callbacks on .NET 8 by @​thomhurst in
thomhurst/TUnit#7557
* Preserve generic tuple rows from instance data sources by @​thomhurst
in thomhurst/TUnit#7548
* Expect source operators to bind in AOT in the tuple conversion matrix
by @​thomhurst in thomhurst/TUnit#7580
* Preserve containing generic types in TUnit0001 diagnostics by
@​thomhurst in thomhurst/TUnit#7563
* Populate reflection class property metadata by @​thomhurst in
thomhurst/TUnit#7550
* Verify every generic class/method argument pair executes once by
@​thomhurst in thomhurst/TUnit#7558
* Exclude indexers from generated class property metadata by @​thomhurst
in thomhurst/TUnit#7560
* Fix synchronous factory timeout cancellation classification by
@​thomhurst in thomhurst/TUnit#7561
* Add packaged F# async trimming smoke coverage by @​thomhurst in
thomhurst/TUnit#7562
* Remove unused metadata generation entry points by @​thomhurst in
thomhurst/TUnit#7570
* Remove unused streaming test builder path by @​thomhurst in
thomhurst/TUnit#7535
* Isolate test registration callback failures by @​thomhurst in
thomhurst/TUnit#7556

### Dependencies
* Update mcr.microsoft.com/dotnet/sdk Docker tag to v11 by @​thomhurst
in thomhurst/TUnit#7513
* Update dependency Microsoft.Kiota.Abstractions to 2.1.6 by @​thomhurst
in thomhurst/TUnit#7512
* Update all non-major dependencies to 1.79.0 by @​thomhurst in
thomhurst/TUnit#7528
* Update all non-major dependencies by @​thomhurst in
thomhurst/TUnit#7536


**Full Changelog**:
thomhurst/TUnit@v1.79.0...v1.80.0

## 1.79.0

<!-- Release notes generated using configuration in .github/release.yml
at v1.79.0 -->

## What's Changed
### Other Changes
* test(sourcegen): parse fixtures as a real build in all generator test
harnesses by @​thomhurst in thomhurst/TUnit#7319
* test(sourcegen): fix net472 compile of AotConverterScanTests
obsolete-conversion fixture by @​thomhurst in
thomhurst/TUnit#7330
* fix(sourcegen): emit typeof(Nullable<>) for a T? parameter of a
generic test method by @​thomhurst in
thomhurst/TUnit#7322
* test: fix ClassDataSourceTupleTests to exercise class-level tuple
unwrapping by @​thomhurst in
thomhurst/TUnit#7318
* fix(fsharp): pin FSharp.Core in TUnit.Assertions.FSharp independent of
the building SDK by @​thomhurst in
thomhurst/TUnit#7321
* fix(sourcegen): pick MethodDataSource overloads declared on base types
like reflection by @​thomhurst in
thomhurst/TUnit#7323
* fix(reflection): close generic methods over a typed data source's
declared types without [GenerateGenericTest] by @​thomhurst in
thomhurst/TUnit#7324
* fix(engine): run every overload of a [Test] method in filtered runs by
@​thomhurst in thomhurst/TUnit#7332
* fix: bind a tuple row whole to a tuple parameter followed by optional
parameters by @​thomhurst in
thomhurst/TUnit#7341
* fix(core): keep and dispose data-source roots when object-graph
tracking throws by @​thomhurst in
thomhurst/TUnit#7342
* fix(engine): lower default maximum parallel tests to 2x processor
count by @​thomhurst in thomhurst/TUnit#7354
* ci: cut duplicate TFM and packaging work from the Windows and macOS
jobs by @​thomhurst in thomhurst/TUnit#7357
* ci: run engine tests in their own job and drop the per-child test-host
relaunch by @​thomhurst in thomhurst/TUnit#7364
* fix(sourcegen): split untyped class data source rows by the generic
class type they infer by @​thomhurst in
thomhurst/TUnit#7339
* fix(engine): read a generic class's own class-level [MethodDataSource]
member on the closed class by @​thomhurst in
thomhurst/TUnit#7336
* fix(analyzers): TUnit0001 unwraps only the Func/TestDataRow layers the
runtime removes by @​thomhurst in
thomhurst/TUnit#7347
* test: make SharedType.None leakage tests independent of build order by
@​thomhurst in thomhurst/TUnit#7385
* fix(generic): infer method type arguments from [Arguments<T>] rows in
both modes by @​thomhurst in
thomhurst/TUnit#7343
* fix(generic): infer class type arguments through T[] constructor
parameters from any class row by @​thomhurst in
thomhurst/TUnit#7346
* fix(engine): await the Task of async runtime dynamic tests by
@​thomhurst in thomhurst/TUnit#7363
* feat(engine): add dispose spans for shared data-source objects by
@​thomhurst in thomhurst/TUnit#7396
* fix(engine): stop copying build-time output to TestSessionContext by
@​thomhurst in thomhurst/TUnit#7397
* feat(mocks): argument-aware Returns for Task/ValueTask members by
@​thomhurst in thomhurst/TUnit#7404
* fix(generic): a type-free class [Arguments] row lets method rows infer
T, with matching constructor binding in both modes by @​thomhurst in
thomhurst/TUnit#7392
* feat(scripts): finish open loop PRs before starting new issues by
@​thomhurst in thomhurst/TUnit#7423
* fix(mocks): preserve nullable generic constraints by @​thomhurst in
thomhurst/TUnit#7414
* Retain class sources sharing an inferred generic instantiation by
@​thomhurst in thomhurst/TUnit#7420
* Fix reflection data source overloads with omitted optional arguments
by @​thomhurst in thomhurst/TUnit#7421
* feat(playwright): honor HEADED and BROWSER environment variables by
@​thomhurst in thomhurst/TUnit#7395
* docs: enable Windows long paths before worktree checkout by
@​thomhurst in thomhurst/TUnit#7416
* Fix duplicate dynamic builder invocation in reflection mode by
@​thomhurst in thomhurst/TUnit#7424
* fix(mocks): bind explicit method type arguments on
Mock.Of<IGeneric<X>>() by @​thomhurst in
thomhurst/TUnit#7406
* fix(mocks): Is<T>(predicate) passes T, not T?, for non-nullable T by
@​thomhurst in thomhurst/TUnit#7405
* fix(engine): deliver row builder-context events to the test and raise
OnDispose once per test (#​7381) by @​thomhurst in
thomhurst/TUnit#7384
* fix: report generic classes whose data cannot infer types at compile
time by @​thomhurst in thomhurst/TUnit#7425
* fix(core): hold shared instances fetched while runtime tests register
by @​thomhurst in thomhurst/TUnit#7391
* fix(mocks): match null literals in generated predicate overloads by
@​thomhurst in thomhurst/TUnit#7415
* fix(mocks): qualify extern-aliased types with their alias in generated
code by @​thomhurst in thomhurst/TUnit#7403
* fix(generic): fail wrongly sized [GenerateGenericTest] in
source-generated mode by @​thomhurst in
thomhurst/TUnit#7344
* fix(sourcegen): generate a data source factory for
[InstanceMethodDataSource] (#​7225) by @​thomhurst in
thomhurst/TUnit#7348
* fix(aspire): preserve caller cancellation over startup cleanup faults
by @​thomhurst in thomhurst/TUnit#7447
* fix(tests): remove polling throughput requirement on shared runners by
@​thomhurst in thomhurst/TUnit#7448
* fix(html-reporter): scope report state per session when sessions
overlap by @​thomhurst in thomhurst/TUnit#7400
* fix(analyzers): validate class data against TestConstructor by
@​thomhurst in thomhurst/TUnit#7449
* Infer generic method types from typed array rows in both discovery
modes by @​thomhurst in thomhurst/TUnit#7460
* Share generic method inference policy between discovery modes by
@​thomhurst in thomhurst/TUnit#7455
 ... (truncated)

Commits viewable in [compare
view](thomhurst/TUnit@v1.78.0...v1.81.10).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=TUnit&package-manager=nuget&previous-version=1.78.0&new-version=1.81.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
Pull Requests — d47986cd Deployed Nov 5, 2026 by thomhurst via modularpipeline (macos-latest) #21448
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.

Match method data source attributes by fully qualified identity

1 participant