Skip to content

feat: support negated expectation on sort order#625

Merged
vbreuss merged 3 commits intomainfrom
topic/negate-isinascendingdescendingorder
May 20, 2025
Merged

feat: support negated expectation on sort order#625
vbreuss merged 3 commits intomainfrom
topic/negate-isinascendingdescendingorder

Conversation

@vbreuss
Copy link
Copy Markdown
Member

@vbreuss vbreuss commented May 20, 2025

This PR adds support for negated expectations on collection sort order by introducing new APIs and corresponding tests for both synchronous and asynchronous collections. Key changes include:

  • New methods: IsNotInAscendingOrder and IsNotInDescendingOrder with optional member accessor overloads.
  • Comprehensive test coverage for various collection types and scenarios.
  • Documentation updates to include examples of negated sort order expectations.

Sort order

You can now also verify whether the collection is not sorted in ascending or descending order:

await Expect.That([1, 3, 2]).IsNotInAscendingOrder();
await Expect.That(["c", "a", "b"]).IsNotInDescendingOrder();

## Sort order

You can now also verify whether the collection is not sorted in ascending or descending order:

```csharp
await Expect.That([1, 3, 2]).IsNotInAscendingOrder();
await Expect.That(["c", "a", "b"]).IsNotInDescendingOrder();
```
@vbreuss vbreuss self-assigned this May 20, 2025
Copilot AI review requested due to automatic review settings May 20, 2025 18:28
@vbreuss vbreuss added the enhancement New feature or request label May 20, 2025
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 adds support for negated expectations on collection sort order by introducing new APIs and corresponding tests for both synchronous and asynchronous collections. Key changes include:

  • New methods: IsNotInAscendingOrder and IsNotInDescendingOrder with optional member accessor overloads.
  • Comprehensive test coverage for various collection types and scenarios.
  • Documentation updates to include examples of negated sort order expectations.

Reviewed Changes

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

Show a summary per file
File Description
Tests/aweXpect.Tests/Collections/ThatEnumerable.IsNotInDescendingOrder.Tests.cs Added tests for negated descending order expectation.
Tests/aweXpect.Tests/Collections/ThatEnumerable.IsNotInAscendingOrder.Tests.cs Added tests for negated ascending order expectation.
Tests/aweXpect.Tests/Collections/ThatAsyncEnumerable.*.Tests.cs Added similar tests for asynchronous collections.
Tests/aweXpect.Api.Tests/Expected/aweXpect_netstandard2.0.txt
Tests/aweXpect.Api.Tests/Expected/aweXpect_net8.0.txt
Updated API definitions to include negated order methods.
Source/aweXpect/That/Collections/ThatEnumerable.IsInDescendingOrder.cs
ThatEnumerable.IsInAscendingOrder.cs
ThatAsyncEnumerable.IsInDescendingOrder.cs
ThatAsyncEnumerable.IsInAscendingOrder.cs
Implemented new negated order methods using the inversion of existing constraints.
Docs/pages/docs/expectations/07-collections.md Revised documentation to include examples for negated order expectations.
Comments suppressed due to low confidence (2)

Source/aweXpect/That/Collections/ThatEnumerable.IsInDescendingOrder.cs:58

  • [nitpick] Enhance the XML documentation to mention that this method works by inverting the standard descending order check, which can help users understand its behavior better.
/// Verifies that the collection is not in descending order.

Source/aweXpect/That/Collections/ThatEnumerable.IsInAscendingOrder.cs:58

  • [nitpick] Consider expanding the XML comment to clarify that this method inverts the ascending order check, providing users with additional context on the implementation.
/// Verifies that the collection is not in ascending order.

Comment thread Docs/pages/docs/expectations/07-collections.md Outdated
@vbreuss vbreuss enabled auto-merge (squash) May 20, 2025 18:30
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2025

Test Results

    14 files   -  24      14 suites   - 24   2m 14s ⏱️ -1s
10 980 tests + 52  10 978 ✅ + 52  2 💤 ±0  0 ❌ ±0 
29 982 runs  +144  29 980 ✅ +144  2 💤 ±0  0 ❌ ±0 

Results for commit b650ebf. ± Comparison against base commit c665913.

This pull request removes 1368 and adds 1420 tests. Note that renamed tests count towards both.
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message38772649-0540-49cb-a328-8d2a0abadcb8")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message3e7cd8ee-00be-4ae4-a506-a88f1cb7edbb")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messagec8f76572-c0c3-49ad-aabd-d261463eb7a1")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message1fb434db-fa8b-430f-96b7-133951fcd256")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messageb238de6c-d5d3-4a15-a1c6-64e8a9e6877a")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "messaged3d48070-080a-4e73-b6a2-129bd1ccec23")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore1f956029-0ea2-4b67-85dc-2a2c4c2f1e1c")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore2ea154b0-b752-4f37-bb91-4347cdeb161b")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnoreff50ab84-c00b-4654-808f-d07a356eb1bb")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason7435f422-17c7-4627-9367-d6e71dea3163")
…
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message39eb1cc7-aabd-423d-98ec-fcf05cfa87d2")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "message65699088-906b-4559-aa12-c14191773ecc")
aweXpect.Core.Tests.Core.Exceptions.FailExceptionTests ‑ Message_ShouldBeSet(message: "messageab0f3990-2a16-4bd4-a39b-e1b5b7f9b766")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message6b63ccdf-0003-453e-a985-fc6d8e2e8755")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message9a8c759b-f5f7-44fe-b142-d12ecc3ad712")
aweXpect.Core.Tests.Core.Exceptions.SkipExceptionTests ‑ Message_ShouldBeSet(message: "message9b8a05c0-3ec4-4b53-b037-8bcdc323d2e2")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore8feba4d9-f076-4f7e-9145-476a50445e53")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnore9340528f-5ec0-4c9c-8a53-69b900eae3eb")
aweXpect.Core.Tests.Equivalency.EquivalencyOptionsExtensionsTests ‑ Generic_For_IgnoringMember_ShouldSetOptionForType(memberToIgnore: "memberToIgnoreac991f19-1ac5-4898-8f0e-a17f644dab8c")
aweXpect.Core.Tests.FailTests ‑ Test_ShouldThrowException(reason: "reason4b7a3c96-3751-471b-a38b-ec8b7dfcab13")
…

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2025

🚀 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.409
[Host] : .NET 8.0.16 (8.0.1625.21506), X64 RyuJIT AVX2

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

Method Mean Error StdDev Gen0 Gen1 Allocated
Bool_aweXpect 176.6 ns 1.64 ns 1.37 ns 0.0281 - 472 B
Bool_FluentAssertions 234.6 ns 2.19 ns 1.83 ns 0.0567 - 952 B
Bool_TUnit 937.2 ns 7.94 ns 7.43 ns 0.1431 - 2416 B
Equivalency_aweXpect 283,750.3 ns 2,181.41 ns 2,040.49 ns 16.6016 0.4883 284940 B
Equivalency_FluentAssertions 2,243,054.9 ns 18,332.92 ns 17,148.63 ns 273.4375 46.8750 4584416 B
Equivalency_TUnit 678,606.6 ns 3,860.56 ns 3,611.17 ns 51.7578 2.9297 866777 B
Int_GreaterThan_aweXpect 218.7 ns 5.77 ns 5.40 ns 0.0467 - 784 B
Int_GreaterThan_FluentAssertions 252.3 ns 1.02 ns 0.80 ns 0.0730 - 1224 B
Int_GreaterThan_TUnit 1,241.1 ns 10.87 ns 10.17 ns 0.1774 - 2992 B
ItemsCount_AtLeast_aweXpect 447.4 ns 6.46 ns 6.04 ns 0.0830 - 1392 B
ItemsCount_AtLeast_FluentAssertions 469.5 ns 3.00 ns 2.80 ns 0.1197 - 2008 B
ItemsCount_AtLeast_TUnit 21,910.9 ns 157.51 ns 139.63 ns 1.6174 - 27488 B
String_aweXpect 346.6 ns 6.63 ns 6.20 ns 0.0672 - 1128 B
String_FluentAssertions 471.8 ns 8.61 ns 8.05 ns 0.1292 - 2168 B
String_TUnit 1,374.0 ns 15.74 ns 14.72 ns 0.1850 - 3096 B
StringArray_aweXpect 1,151.8 ns 8.97 ns 8.39 ns 0.1202 - 2024 B
StringArray_FluentAssertions 1,259.4 ns 5.97 ns 4.99 ns 0.2480 - 4152 B
StringArray_TUnit 3,232.8 ns 18.09 ns 16.92 ns 0.2708 - 4576 B
StringArrayInAnyOrder_aweXpect 1,333.2 ns 10.41 ns 9.74 ns 0.1297 - 2184 B
StringArrayInAnyOrder_FluentAssertions 151,660.4 ns 702.21 ns 622.49 ns 3.4180 - 63787 B
StringArrayInAnyOrder_TUnit 4,828.8 ns 30.19 ns 25.21 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/Collections/ThatAsyncEnumerable.IsInAscendingOrder.cs 100.00% 4 0 0 0 4 0 4 0 8
That/Collections/ThatAsyncEnumerable.IsInDescendingOrder.cs 100.00% 4 0 0 0 4 0 4 0 8
That/Collections/ThatEnumerable.IsInAscendingOrder.cs 100.00% 4 0 0 0 4 0 4 0 8
That/Collections/ThatEnumerable.IsInDescendingOrder.cs 100.00% 4 0 0 0 4 0 4 0 8

The final mutation score is 100.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

@sonarqubecloud
Copy link
Copy Markdown

@vbreuss vbreuss disabled auto-merge May 20, 2025 18:51
@vbreuss vbreuss merged commit 62a44eb into main May 20, 2025
12 checks passed
@vbreuss vbreuss deleted the topic/negate-isinascendingdescendingorder branch May 20, 2025 18:51
github-actions Bot added a commit that referenced this pull request May 20, 2025
github-actions Bot added a commit that referenced this pull request May 20, 2025
@github-actions
Copy link
Copy Markdown
Contributor

This is addressed in release v2.14.0.

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

Labels

enhancement New feature or request state: released The issue is released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants