Skip to content

fix: ComplyWith with negated expectations#635

Merged
vbreuss merged 1 commit intomainfrom
topic/fix-complywith-with-negated-expectations
Jun 19, 2025
Merged

fix: ComplyWith with negated expectations#635
vbreuss merged 1 commit intomainfrom
topic/fix-complywith-with-negated-expectations

Conversation

@vbreuss
Copy link
Copy Markdown
Member

@vbreuss vbreuss commented Jun 19, 2025

Fixes the negated expectation logic in the ComplyWith constraint by ensuring that the negation is applied only once during evaluation.

Fixes #632

Copilot AI review requested due to automatic review settings June 19, 2025 07:53
Copy link
Copy Markdown

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 fixes the negated expectation logic in the ComplyWith constraint by refining the error message and ensuring the negation is applied only once during evaluation.

  • Update the failure message in tests to reflect the correct negation behavior.
  • Introduce and utilize a new state flag (_isOnceNegated) to prevent multiple negations in the constraint evaluation.

Reviewed Changes

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

File Description
Tests/aweXpect.Tests/Collections/ThatEnumerable.All.ComplyWith.ImmutableTests.cs Updated the error message in the negated expectation test scenario to accurately report failures.
Source/aweXpect/That/ThatGeneric.CompliesWith.cs Added a new state flag (_isOnceNegated) and refactored the negation method to ensure a single negation is performed.
Comments suppressed due to low confidence (2)

Tests/aweXpect.Tests/Collections/ThatEnumerable.All.ComplyWith.ImmutableTests.cs:69

  • Please confirm that the updated error message 'but none of 7 were' clearly communicates the negated expectation failure, ensuring consistency with the intended behavior.
						             but none of 7 were

Source/aweXpect/That/ThatGeneric.CompliesWith.cs:105

  • Verify that the introduction of '_isOnceNegated' and its handling in 'NegateOnceIfNegated' works correctly in all use cases. Consider whether the state should be reset between validations if the same instance is reused.
			if (_isNegated && !_isOnceNegated)

@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown
Contributor

Test Results

    14 files   - 24      14 suites   - 24   2m 34s ⏱️ -2s
13 518 tests  - 28  13 516 ✅  - 27  2 💤  - 1  0 ❌ ±0 
37 605 runs   - 72  37 603 ✅  - 69  2 💤  - 3  0 ❌ ±0 

Results for commit d203cf3. ± Comparison against base commit 589bbf9.

This pull request removes 1377 and adds 1349 tests. Note that renamed tests count towards both.
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message2d6a07a4-4a80-479b-9f81-20c120ecf74f")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message57278fb9-f55c-4977-8152-47fafd296175")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messagede4a9bb8-64af-4785-ac93-631bca166c85")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message0c4ce5d2-2aac-420e-83fc-ff779bb32b21")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message22cccf64-a8ee-40d9-8a9d-03a7cbc20bbf")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messageef6b6124-f20a-4db6-a0d3-9cf151568333")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore80bc9a31-b3b8-40a6-8951-e0f2fc9b04ce")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore842751a7-e67e-42e9-be24-4761930fb9ed")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnorebf597c67-55a9-4a98-a400-3365c2244e11")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason630d2cc5-63af-4996-9d88-93c071829a6d")
…
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message82b8e177-69d9-4201-9090-3f2e61e22be3")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message8fd7c907-41f1-434d-9866-6c2de9af4c54")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messageb05a0c5e-eeed-4055-810e-8a60e1c6c1f2")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message8cfd655a-6fdd-4cfa-a79a-dcf24e7f2bdd")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messaged722c6c9-8817-413e-ac1e-f3a904b01354")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messagee0c71b73-e04e-4d36-bdb8-8d21fc0953cb")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore6bf24be5-da6e-4975-838a-4182ee4e3dae")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore76d3bdd6-aefd-43b4-b08f-da3a458779af")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnorebd0fc1c7-7190-4c17-b673-0ac0ef2c6506")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason2ecbc443-ac5c-4923-89d9-94d6a7d75829")
…

@vbreuss vbreuss enabled auto-merge (squash) June 19, 2025 07:59
@vbreuss vbreuss merged commit bc68bb4 into main Jun 19, 2025
13 checks passed
@vbreuss vbreuss deleted the topic/fix-complywith-with-negated-expectations branch June 19, 2025 08:02
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Benchmark Results

Details

BenchmarkDotNet v0.14.0, Ubuntu 24.04.2 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 8.0.411
[Host] : .NET 8.0.17 (8.0.1725.26602), X64 RyuJIT AVX2

Job=InProcess Toolchain=InProcessEmitToolchain IterationCount=15
LaunchCount=1 WarmupCount=10

Method Mean Error StdDev Gen0 Gen1 Allocated
Bool_aweXpect 177.8 ns 1.09 ns 0.97 ns 0.0281 - 472 B
Bool_FluentAssertions 227.1 ns 0.61 ns 0.51 ns 0.0567 - 952 B
Bool_TUnit 907.1 ns 3.61 ns 3.38 ns 0.1440 - 2416 B
Equivalency_aweXpect 284,214.3 ns 537.48 ns 448.82 ns 16.6016 0.4883 284940 B
Equivalency_FluentAssertions 2,170,784.0 ns 8,436.01 ns 7,478.31 ns 273.4375 46.8750 4584416 B
Equivalency_TUnit 658,693.7 ns 1,091.51 ns 967.60 ns 51.7578 2.9297 866777 B
Int_GreaterThan_aweXpect 206.7 ns 1.11 ns 0.92 ns 0.0467 - 784 B
Int_GreaterThan_FluentAssertions 236.6 ns 1.17 ns 1.04 ns 0.0730 - 1224 B
Int_GreaterThan_TUnit 1,205.9 ns 5.18 ns 4.85 ns 0.1774 - 2992 B
ItemsCount_AtLeast_aweXpect 443.7 ns 1.80 ns 1.69 ns 0.0830 - 1392 B
ItemsCount_AtLeast_FluentAssertions 446.6 ns 2.68 ns 2.51 ns 0.1197 - 2008 B
ItemsCount_AtLeast_TUnit 14,556.4 ns 66.67 ns 62.36 ns 1.6327 - 27488 B
String_aweXpect 346.1 ns 1.55 ns 1.45 ns 0.0672 - 1128 B
String_FluentAssertions 466.4 ns 1.94 ns 1.81 ns 0.1292 - 2168 B
String_TUnit 1,245.0 ns 4.92 ns 4.60 ns 0.1850 - 3096 B
StringArray_aweXpect 1,321.2 ns 4.09 ns 3.82 ns 0.1602 - 2712 B
StringArray_FluentAssertions 1,247.8 ns 3.97 ns 3.31 ns 0.2480 - 4152 B
StringArray_TUnit 2,714.5 ns 6.25 ns 5.85 ns 0.2708 - 4576 B
StringArrayInAnyOrder_aweXpect 1,457.7 ns 3.28 ns 3.07 ns 0.1717 - 2872 B
StringArrayInAnyOrder_FluentAssertions 149,834.7 ns 415.33 ns 368.18 ns 3.4180 - 64323 B
StringArrayInAnyOrder_TUnit 4,465.6 ns 13.64 ns 12.09 ns 0.3967 - 6744 B

@github-actions
Copy link
Copy Markdown
Contributor

👽 Mutation Results

Mutation testing badge

aweXpect

Details
File Score Killed Survived Timeout No Coverage Ignored Compile Errors Total Detected Total Undetected Total Mutants
That/ThatGeneric.CompliesWith.cs 80.00% 20 4 0 1 10 3 20 5 38

The final mutation score is 80.00%

Coverage Thresholds: high:80 low:60 break:0

aweXpect.Core

Details
File Score Killed Survived Timeout No Coverage Ignored Compile Errors Total Detected Total Undetected Total Mutants

The final mutation score is NaN%

Coverage Thresholds: high:80 low:60 break:0

github-actions Bot added a commit that referenced this pull request Jun 19, 2025
github-actions Bot added a commit that referenced this pull request Jun 19, 2025
@github-actions
Copy link
Copy Markdown
Contributor

This is addressed in release v2.16.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state: released The issue is released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ComplyWith with negated expectations is not working correctly

2 participants