Skip to content

fix: negation of Satisfy for collections - #752

Merged
vbreuss merged 1 commit into
mainfrom
topic/fix-negation-of-satisfy
Sep 3, 2025
Merged

fix: negation of Satisfy for collections#752
vbreuss merged 1 commit into
mainfrom
topic/fix-negation-of-satisfy

Conversation

@vbreuss

@vbreussvbreuss commented Sep 3, 2025

Copy link
Copy Markdown
Member

This PR fixes the negation of the Satisfy constraint for collections and adds comprehensive test coverage for negated assertions. The main issue was that negated collection constraints incorrectly applied grammar negation transformations when building expected messages, leading to confusing output when assertions failed.

Key Changes

  • Fixed negation logic in collection constraints by removing incorrect grammar negation calls
  • Added comprehensive test suites for negated collection count assertions (HasCount, AtLeast, MoreThan, etc.)
  • Restructured test files to include both regular and negated test classes
  • Also add some missing test cases for string-based collection operations (AsPrefix, AsSuffix)

Also add some missing test cases
@vbreussvbreuss self-assigned this Sep 3, 2025
CopilotAI review requested due to automatic review settings September 3, 2025 12:32
@vbreussvbreuss added the bug Something isn't working label Sep 3, 2025

CopilotAI 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.

Pull Request Overview

This PR fixes the negation of the Satisfy constraint for collections and adds comprehensive test coverage for negated assertions. The main issue was that negated collection constraints incorrectly applied grammar negation transformations when building expected messages, leading to confusing output when assertions failed.

Key Changes

  • Fixed negation logic in collection constraints by removing incorrect grammar negation calls
  • Added comprehensive test suites for negated collection count assertions (HasCount, AtLeast, MoreThan, etc.)
  • Restructured test files to include both regular and negated test classes
  • Added missing test coverage for string-based collection operations (AsPrefix, AsSuffix)

Reviewed Changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
Source/aweXpect/That/Collections/ThatEnumerable.csFixed negation logic by removing Grammars.Negate() calls in message formatting
Source/aweXpect/That/Collections/ThatAsyncEnumerable.csApplied same negation fixes for async enumerables and simplified constraint inheritance
Source/aweXpect/That/Collections/EnumerableQuantifier.All.csAdded special handling for negated "All" quantifier results
Tests/aweXpect.Tests/Collections/ThatEnumerable.HasCount.*.Tests.csRestructured test files with nested classes for regular and negated tests
Tests/aweXpect.Tests/Collections/ThatAsyncEnumerable.HasCount.*.Tests.csApplied same test restructuring for async enumerable tests
Tests/aweXpect.Tests/Collections/ThatEnumerable.All.Satisfy.Tests.csAdded comprehensive negated test coverage
Tests/aweXpect.Tests/Collections/ThatEnumerable.Contains.Tests.csAdded missing test cases for AsPrefix and AsSuffix operations

@vbreuss
vbreuss enabled auto-merge (squash) September 3, 2025 12:35
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown
Contributor

Test Results

14 files - 24 14 suites - 24 4m 27s ⏱️ +36s
17 340 tests + 9 17 337 ✅ + 9 3 💤 ±0 0 ❌ ±0 
48 684 runs +27 48 679 ✅ +27 5 💤 ±0 0 ❌ ±0 

Results for commit 00ba78f. ± Comparison against base commit a18e70c.

This pull request removes 1645 and adds 1654 tests. Note that renamed tests count towards both.
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message05531159-5b5d-4304-afd0-22111eec24ed")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message2f55b524-454f-4be2-a167-bac1343f0d68")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messageeb174bb8-e5bd-4741-99c8-1d634cf02720")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message3c5f81d0-8ad6-4cb2-b0f5-431532dc1084")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message3d939b11-ae5f-4f5c-aac0-18e71497e5ae")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messagef903b3c0-aaaa-4cf9-933d-304af81062fb")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore93c4be95-e863-41e9-88c7-2c26152284a8")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnoreb3e5a924-c6ab-4a4b-aeb8-84cc2c20352d")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnorecd350bec-bef5-4833-98bf-7b0ca1bf3475")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason855f9f3d-41cf-4ee2-97c9-d91c8762d960")
…
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message673b6a64-6b9c-44bc-bdfb-7d6127b714a2")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messagef226b5fa-0158-47cb-83a2-f5d850a35123")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messagef354d69d-ba14-4819-b6e0-0cc0512aeed2")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messageaba413bc-f730-4170-a7fa-68a93e943837")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messagee1ed28d2-9fa4-4e96-ab06-557a806dcd4c")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messagee9d6baf7-acb5-44e5-b57c-b6aae2d68a28")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore5a1abee4-552a-402f-8858-270c509451ba")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnoreb973f206-a5f7-4ab5-bd5f-6744cb12618d")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnorebfc9752f-837e-4d32-a5b3-db6279e98385")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason4aa7f177-df3e-4315-a127-9ab8b062edc1")
…

@vbreuss
vbreuss merged commit 3d063a5 into mainSep 3, 2025
14 checks passed
@vbreuss
vbreuss deleted the topic/fix-negation-of-satisfy branch September 3, 2025 12:41
github-actionsBot added a commit that referenced this pull request Sep 3, 2025
github-actionsBot added a commit that referenced this pull request Sep 3, 2025
@github-actions

Copy link
Copy Markdown
Contributor

🚀 Benchmark Results

Details

BenchmarkDotNet v0.14.0, Ubuntu 24.04.3 LTS (Noble Numbat)
AMD EPYC 7763, 1 CPU, 4 logical and 2 physical cores
.NET SDK 8.0.413
[Host] : .NET 8.0.19 (8.0.1925.36514), X64 RyuJIT AVX2

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

MethodMeanErrorStdDevGen0Gen1Allocated
Bool_aweXpect215.6 ns4.18 ns3.70 ns0.0300-504 B
Bool_FluentAssertions259.0 ns5.32 ns4.97 ns0.0567-952 B
Bool_TUnit957.0 ns18.68 ns17.47 ns0.1431-2408 B
Equivalency_aweXpect327,129.4 ns1,636.78 ns1,450.96 ns16.60160.4883285044 B
Equivalency_FluentAssertions2,375,419.2 ns36,999.37 ns34,609.23 ns273.437546.87504584416 B
Equivalency_TUnit683,358.4 ns5,942.66 ns5,268.02 ns51.75782.9297880545 B
Int_GreaterThan_aweXpect249.4 ns6.75 ns5.99 ns0.0486-816 B
Int_GreaterThan_FluentAssertions281.6 ns7.11 ns6.65 ns0.0730-1224 B
Int_GreaterThan_TUnit1,253.5 ns34.21 ns32.00 ns0.1774-2984 B
ItemsCount_AtLeast_aweXpect501.3 ns7.19 ns6.73 ns0.0868-1464 B
ItemsCount_AtLeast_FluentAssertions512.2 ns11.96 ns11.19 ns0.1192-2008 B
ItemsCount_AtLeast_TUnit17,862.6 ns193.88 ns181.35 ns1.6174-27480 B
String_aweXpect460.2 ns7.96 ns7.45 ns0.0734-1232 B
String_FluentAssertions493.9 ns12.69 ns11.25 ns0.1287-2168 B
String_TUnit1,269.1 ns16.48 ns15.42 ns0.1831-3072 B
StringArray_aweXpect1,820.3 ns14.53 ns13.59 ns0.1698-2856 B
StringArray_FluentAssertions1,400.1 ns20.02 ns18.73 ns0.2480-4152 B
StringArray_TUnit3,379.5 ns44.17 ns41.32 ns0.3128-5296 B
StringArrayInAnyOrder_aweXpect2,290.8 ns21.44 ns20.06 ns0.1793-3048 B
StringArrayInAnyOrder_FluentAssertions152,840.7 ns985.68 ns922.01 ns3.4180-63787 B
StringArrayInAnyOrder_TUnit4,031.3 ns43.21 ns40.42 ns0.3815-6488 B

@github-actions

Copy link
Copy Markdown
Contributor

👽 Mutation Results

Mutation testing badge

aweXpect

Details
FileScoreKilledSurvivedTimeoutNo CoverageIgnoredCompile ErrorsTotal DetectedTotal UndetectedTotal Mutants
That/Collections/EnumerableQuantifier.All.cs100.00%2401071325045
That/Collections/EnumerableQuantifier.MoreThan.cs100.00%2501071226045
That/Collections/ThatAsyncEnumerable.cs77.82%204233368416720759517
That/Collections/ThatEnumerable.cs82.49%308935711326231166752

The final mutation score is 81.99%

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

aweXpect.Core

Details
FileScoreKilledSurvivedTimeoutNo CoverageIgnoredCompile ErrorsTotal DetectedTotal UndetectedTotal Mutants
Delegates/ThatDelegate.WithoutValue.DoesNotThrow.cs100.00%190008619033

The final mutation score is 100.00%

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

@github-actions

Copy link
Copy Markdown
Contributor

This is addressed in release v2.23.0.

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

Labels

bugSomething isn't workingstate: releasedThe issue is released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@vbreuss