Skip to content

fix: Allow Item.Member after HasSingleItem - #6583

Merged
thomhurst merged 1 commit into
thomhurst:mainfrom
SnakyBeaky:fix/hassingleitem-item-member
Aug 11, 2026
Merged

fix: Allow Item.Member after HasSingleItem#6583
thomhurst merged 1 commit into
thomhurst:mainfrom
SnakyBeaky:fix/hassingleitem-item-member

Conversation

@SnakyBeaky

@SnakyBeaky SnakyBeaky commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Description

Ensure TypeErasedAssertion uses the standard assertion execution pipeline, preserving deferred pre-work from HasSingleItem().Item.

Added a regression coverage test for the issue.

Related Issue

Fixes #6581

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Performance improvement
  • Refactoring (no functional changes)

Checklist

Required

  • I have read the Contributing Guidelines
  • If this is a new feature, I started a discussion first and received agreement
  • My code follows the project's code style (modern C# syntax, proper naming conventions)
  • I have written tests that prove my fix is effective or my feature works

Testing

  • All existing tests pass (dotnet test)
  • I have added tests that cover my changes
  • I have tested both source-generated and reflection modes (if applicable)

Summary by CodeRabbit

  • Bug Fixes

    • Fixed member assertions used after single-item assertions so they now complete successfully instead of returning an invalid result.
    • Corrected behavior for both predicate-based and non-predicate member assertions.
  • Tests

    • Added coverage for asynchronous member assertion scenarios following single-item checks.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

TypeErasedAssertion<T> now evaluates through CheckAsync and returns a passed result. Regression tests cover member assertions after HasSingleItem(), with and without a predicate.

Changes

Member assertion fix

Layer / File(s) Summary
Evaluation fix and regression coverage
src/TUnit.Assertions/Conditions/MemberAssertion.cs, tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs
TypeErasedAssertion<T> now uses CheckAsync and returns AssertionResult.Passed after the inner assertion. Issue6581Tests covers direct and predicate-based member assertions after HasSingleItem().

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A rabbit checks the member chain,
No null result breaks the train.
Single items now pass through,
Predicates work as they should too.
Hop, hop—tests confirm the fix! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary bug fix: enabling Item.Member after HasSingleItem.
Linked Issues check ✅ Passed The fix uses the standard assertion pipeline and adds regression tests for Item.Member after HasSingleItem, covering both predicate forms [#6581].
Out of Scope Changes check ✅ Passed The changes are limited to the assertion pipeline fix and focused regression tests for the linked issue [#6581].
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

This PR routes type-erased member assertions through the standard assertion pipeline so deferred pre-work is preserved for HasSingleItem().Item.Member(...).

  • Replaces the custom TypeErasedAssertion.AssertAsync() override with a standard CheckAsync() implementation.
  • Adds regression tests for ordinary and predicate-based HasSingleItem() chains.

Confidence Score: 5/5

The PR appears safe to merge, with no actionable correctness or security issues identified.

The changed wrapper preserves deferred pre-work through mapped assertion contexts, executes it once, and continues to propagate inner assertion failures through the existing exception and assertion-scope mechanisms.

Important Files Changed

Filename Overview
src/TUnit.Assertions/Conditions/MemberAssertion.cs Moves type-erased member assertion execution into the base assertion pipeline, preserving mapped pending pre-work without introducing duplicate execution or failure masking.
tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs Adds focused regression coverage for member assertions following both forms of HasSingleItem().Item.

Reviews (1): Last reviewed commit: "fix: Allow Item.Member after HasSingleIt..." | Re-trigger Greptile

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs (1)

13-15: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add failing member-assertion cases.

These tests prove that the chain does not throw for matching values. They do not prove that Member(...).IsEqualTo(...) executes. If the inner assertion were skipped, both tests would still pass. Add negative-path cases with a mismatched member value and the existing assertion-failure helper.

Also applies to: 27-29

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs` around lines 13 - 15,
Add negative-path tests in the affected member-assertion test cases, using a
mismatched member value and the existing assertion-failure helper. Ensure each
case verifies that Member(...).IsEqualTo(...) executes and reports failure,
while preserving the current matching-value coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs`:
- Around line 13-15: Add negative-path tests in the affected member-assertion
test cases, using a mismatched member value and the existing assertion-failure
helper. Ensure each case verifies that Member(...).IsEqualTo(...) executes and
reports failure, while preserving the current matching-value coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6e93d3a9-f5da-404c-8f8e-52710a8c4987

📥 Commits

Reviewing files that changed from the base of the PR and between 5eabbe3 and a804aa5.

📒 Files selected for processing (2)
  • src/TUnit.Assertions/Conditions/MemberAssertion.cs
  • tests/TUnit.Assertions.Tests/Bugs/Issue6581Tests.cs

@thomhurst

Copy link
Copy Markdown
Owner

Thanks @SnakyBeaky !

@thomhurst
thomhurst merged commit b2ce57c into thomhurst:main Aug 11, 2026
11 of 12 checks passed
This was referenced Aug 11, 2026
This was referenced Aug 14, 2026
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.

[Bug]: .Item.Member(...) after .HasSingleItem() throws InvalidOperationException

2 participants