Fix Type assignability assertions to evaluate represented type (not RuntimeType) - #6711
Conversation
Co-authored-by: thomhurst <30480171+thomhurst@users.noreply.github.com>
Type assignability assertions to evaluate represented type (not RuntimeType)
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38b97aab7a
ℹ️ 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 SummaryThe PR makes direct
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| src/TUnit.Assertions/Conditions/TypeAssertionExtensions.cs | Adds generated runtime-Type assignability assertions with explicit null-argument failures. |
| src/TUnit.Assertions/Conditions/TypeOfAssertion.cs | Adds represented-type semantics to the relevant generic assignability assertion implementations. |
| src/TUnit.Assertions/Extensions/Assert.cs | Introduces and prioritizes the specialized assertion entry point for nullable Type values. |
| src/TUnit.Assertions/Sources/TypeValueAssertion.cs | Defines the direct Type assertion source and its represented-type generic assignability methods. |
| tests/TUnit.Assertions.Tests/TypeAssertionTests.cs | Covers direct generic, runtime-Type, TypeInfo, null-argument, chaining, and generic-source behavior. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A["Assert.That(typeof(Dog))"] --> B["TypeValueAssertion"]
B --> C{"Assignability overload"}
C -->|"Generic target"| D["typeof(Target).IsAssignableFrom(typeof(Dog))"]
C -->|"Runtime Type target"| E["expectedType.IsAssignableFrom(typeof(Dog))"]
D --> F["Assertion result"]
E --> F
Reviews (7): Last reviewed commit: "fix(assertions): prioritize Type overloa..." | Re-trigger Greptile
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ae67b7490
ℹ️ 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".
Code ReviewI reviewed this PR by tracing the fix's design and empirically verifying findings by building the branch and running targeted repro tests. The core goal — making 1. Fix only covers the direct entry point, not indirect chains (confirmed by test)
Verified directly: Animal? result = await Assert.That(typeof(Dog)).IsClass().And.IsAssignableTo<Animal>();
// assertion passes, but result == null (confirmed via test run: RESULT_IS_NULL=True)Why this matters: 2. Missing null-check on new Type-targeted overloads (confirmed by test)
The new Verified directly: await Assert.That(typeof(Dog)).IsAssignableTo(null!);
// throws raw System.NullReferenceException instead of a graceful assertion failure (EXCEPTION_TYPE=System.NullReferenceException)Why this matters: every other TUnit assertion fails gracefully with a clear assertion message on invalid input; a raw NRE breaks that contract and gives users a confusing stack trace instead of an assertion failure message pointing at the actual mistake. 3. Shared base-class fix may widen behavior beyond
|
Code review (follow-up)I checked the current head ( 1. Gap 2 (missing null-check) — still unaddressedTUnit/src/TUnit.Assertions/Conditions/TypeAssertionExtensions.cs Lines 86 to 98 in 8e58dc6
2. Gap 1 (indirect
|
Updated [TUnit](https://github.com/thomhurst/TUnit) from 1.65.68 to 1.66.16. <details> <summary>Release notes</summary> _Sourced from [TUnit's releases](https://github.com/thomhurst/TUnit/releases)._ ## 1.66.16 <!-- Release notes generated using configuration in .github/release.yml at v1.66.16 --> ## What's Changed ### Other Changes * fix: isolated name is lowercase (#6727) by @koryphaee in thomhurst/TUnit#6728 * fix: preserve concurrent Assert.Multiple failures by @thomhurst in thomhurst/TUnit#6730 * fix: preserve original HTTP mock request content by @thomhurst in thomhurst/TUnit#6731 ### Dependencies * chore(deps): update tunit to 1.66.10 by @thomhurst in thomhurst/TUnit#6726 * chore(deps): update dependency dompurify to v3.4.15 by @thomhurst in thomhurst/TUnit#6732 **Full Changelog**: thomhurst/TUnit@v1.66.10...v1.66.16 ## 1.66.10 <!-- Release notes generated using configuration in .github/release.yml at v1.66.10 --> ## What's Changed ### Other Changes * fix: restore null suppression for built-in assertion methods by @thomhurst in thomhurst/TUnit#6725 ### Dependencies * chore(deps): update tunit to 1.66.8 by @thomhurst in thomhurst/TUnit#6724 **Full Changelog**: thomhurst/TUnit@v1.66.8...v1.66.10 ## 1.66.8 <!-- Release notes generated using configuration in .github/release.yml at v1.66.8 --> ## What's Changed ### Other Changes * fix(ci): make issue triage work for external reporters by @thomhurst in thomhurst/TUnit#6720 * fix(ci): run code review on pull requests from forks by @thomhurst in thomhurst/TUnit#6722 * fix: suppress nullability warnings after Should NotBeNull assertions by @mvanhorn in thomhurst/TUnit#6700 * fix: Avoid HTML report CLI option clashes by @mvanhorn in thomhurst/TUnit#6677 ### Dependencies * chore(deps): update tunit to 1.66.0 by @thomhurst in thomhurst/TUnit#6719 * chore(deps): update dependency microsoft.kiota.abstractions to 2.1.1 by @thomhurst in thomhurst/TUnit#6721 * chore(deps): update dependency awssdk.sqs to 4.0.100.12 by @thomhurst in thomhurst/TUnit#6723 **Full Changelog**: thomhurst/TUnit@v1.66.0...v1.66.8 ## 1.66.0 <!-- Release notes generated using configuration in .github/release.yml at v1.66.0 --> ## What's Changed ### Other Changes * Compile all C# documentation snippets by @thomhurst in thomhurst/TUnit#6695 * Fix `Type` assignability assertions to evaluate represented type (not `RuntimeType`) by @thomhurst with @Copilot in thomhurst/TUnit#6711 * Clarify ClassDataSource constructor requirements by @thomhurst in thomhurst/TUnit#6716 * Add programmatic HTML reporting settings by @thomhurst in thomhurst/TUnit#6699 * Fix timeout cancellation diagnostics by @thomhurst in thomhurst/TUnit#6715 ### Dependencies * chore(deps): update tunit to 1.65.68 by @thomhurst in thomhurst/TUnit#6682 * chore(deps): update dependency verify.tool to v0.9.1 by @thomhurst in thomhurst/TUnit#6683 * chore(deps): update dependency mockolate to 3.4.1 by @thomhurst in thomhurst/TUnit#6685 * chore(deps): update dependency serialize-javascript to v7.1.1 by @thomhurst in thomhurst/TUnit#6687 * chore(deps): update dependency qs to v6.16.0 by @thomhurst in thomhurst/TUnit#6691 * chore(deps): update dependency system.reactive to v7 by @thomhurst in thomhurst/TUnit#6696 * chore(deps): update dependency imposter to 0.1.10 by @thomhurst in thomhurst/TUnit#6701 * chore(deps): update dependency microsoft.kiota.abstractions to 2.1.0 by @thomhurst in thomhurst/TUnit#6704 * chore(deps): update mstest to 4.4.0 by @thomhurst in thomhurst/TUnit#6705 * chore(deps): update dependency dotnet-trace to v10 by @thomhurst in thomhurst/TUnit#6706 * chore(deps): update microsoft.testing by @thomhurst in thomhurst/TUnit#6703 * chore(deps): update microsoft.testing by @thomhurst in thomhurst/TUnit#6713 * chore(deps): bump fast-uri from 3.1.5 to 3.1.7 in /docs by @dependabot[bot] in thomhurst/TUnit#6707 **Full Changelog**: thomhurst/TUnit@v1.65.68...v1.66.0 Commits viewable in [compare view](thomhurst/TUnit@v1.65.68...v1.66.16). </details> [](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 this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Assert.That(typeof(Dog)).IsAssignableTo<Animal>()was evaluating the runtime type of theTypeinstance (RuntimeType) rather than the represented type (Dog), causing valid assignability checks to fail. This PR alignsTypeassignability behavior with documented usage.Assertion semantics fix
Typevalues as the target of assignability checks.IsAssignableTo<T>()andIsAssignableFrom<T>()paths when the asserted value is aType.Type-specific API surface (generator-backed)
Type-targeted overloads using assertion generation:IsAssignableTo(this Type value, Type expectedType)IsAssignableFrom(this Type value, Type sourceType)TypeAPI explicit and consistent with other generated assertions.Regression coverage
Typeassignability scenarios to ensure documentedtypeof(...)usage remains valid.