Skip to content

Conversation

@samtrion
Copy link
Contributor

@samtrion samtrion commented Nov 28, 2025

Summary by CodeRabbit

  • Tests

    • Migrated the test suite to a different test framework and updated data-driven test wiring and providers across many unit tests.
  • Chores

    • Updated test and build package references to align with the new test framework and tooling.
    • Expanded editor configuration to recognize an additional project file type.

✏️ Tip: You can customize this high-level summary in your review settings.

@samtrion samtrion self-assigned this Nov 28, 2025
@samtrion samtrion requested a review from a team as a code owner November 28, 2025 11:59
@samtrion samtrion requested review from Hnogared and removed request for a team November 28, 2025 11:59
@samtrion samtrion added state:ready for merge Indicates that a pull request has been reviewed and approved, and is ready to be merged into the mai type:feature Indicates a new feature or enhancement to be added. labels Nov 28, 2025
@coderabbitai
Copy link

coderabbitai bot commented Nov 28, 2025

Walkthrough

Repository-wide test framework migration from xUnit to TUnit; test data providers refactored from TheoryData<...> to IEnumerable of tuples; package references updated (xUnit/coverlet removed, TUnit and NetEvolve.Extensions.TUnit added); EditorConfig XML glob extended to include slnx.

Changes

Cohort / File(s) Summary
Configuration & Package Management
\.editorconfig, Directory.Packages.props
Added slnx to EditorConfig XML project file patterns. In Directory.Packages.props: removed GitVersion.MsBuild; made SonarAnalyzer.CSharp unconditional; removed coverlet and Microsoft.NET.Test.Sdk package versions; replaced xUnit-related packages (xunit, xunit.runner.visualstudio, NetEvolve.Extensions.XUnit) with TUnit and NetEvolve.Extensions.TUnit; added/updated TUnit-related package entries.
Test Project File
tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj
Updated NuGet package references to remove xUnit/coverlet entries and reference TUnit/NetEvolve.Extensions.TUnit (package list changed; no test logic changes).
Array / Collection Tests
tests/NetEvolve.Guard.Tests.Unit/EnsureArrayTests.cs, tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs
Replaced [Fact]/[Theory]/[MemberData] with [Test]/[MethodDataSource]; converted TheoryData<...> providers to IEnumerable<(...)> tuples; updated using directives to NetEvolve.Extensions.TUnit.
Comparable / Numeric / Temporal Tests
tests/NetEvolve.Guard.Tests.Unit/* (e.g., EnsureBigIntegerTests.cs, EnsureCharTests.cs, EnsureDateOnlyTests.cs, EnsureDateTimeOffsetTests.cs, EnsureDateTimeTests.cs, EnsureDecimalTests.cs, EnsureDoubleTests.cs, EnsureFloatTests.cs, EnsureHalfTests.cs, EnsureInt8Tests.cs, EnsureInt16Tests.cs, EnsureInt32Tests.cs, EnsureInt64Tests.cs, EnsureUInt8Tests.cs, EnsureUInt16Tests.cs, EnsureUInt32Tests.cs, EnsureUInt64Tests.cs, EnsureTimeOnlyTests.cs, EnsureTimeSpanTests.cs)
Migrated test attributes from xUnit to TUnit ([Theory]/[MemberData][Test]/[MethodDataSource]); converted all TheoryData<...> data providers to IEnumerable of tuples; adjusted literal initializers to tuple/List syntax; removed xUnit imports and added NetEvolve.Extensions.TUnit.
Type / Object / String Tests
tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs, EnsureObjectTests.cs, EnsureStringTests.cs, EnsureStructTests.cs, EnsureThatTests.cs
Replaced xUnit attributes ([Theory]/[InlineData], [Fact]) with TUnit equivalents ([Test]/[Arguments] where applicable); updated some test methods to async Task signatures; updated using directives.
FileSystem Tests
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs, tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs
Replaced [Theory]/[MemberData] with [Test]/[MethodDataSource]; converted TheoryData providers to IEnumerable<(...)> tuples; updated conditional branches and using directives to NetEvolve.Extensions.TUnit.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus on:
    • Verify all TheoryData<...>IEnumerable<(...)> signature changes compile and tuple element ordering matches test method parameters.
    • Confirm attribute replacements ([Theory]/[Fact]/[InlineData]/[MemberData] → TUnit equivalents) match the TUnit API/version used, especially MethodDataSource and Arguments semantics.
    • Check conditional compilation blocks (e.g., #if NET6_0_OR_GREATER) where NotPow2 data providers were converted for correct signatures.
    • Validate Directory.Packages.props edits (package removals/additions and SonarAnalyzer change) for build/test pipeline compatibility.

"I hopped through tests, one, two, three,
Swapped Fact for Test — how tidy we be!
Tuples in pockets, packages retuned,
EditorConfig welcomed slnx in tune.
— 🐇"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Switched to TUnit' clearly summarizes the main change—migrating the test framework from XUnit to TUnit across the codebase.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/switched-to-TUnit

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (1)

178-267: Critical: Data providers still use xUnit's TheoryData type.

All data provider methods still reference TheoryData<T>, which is an xUnit type that will not be available after removing the xUnit dependency. This will cause compilation errors. TUnit requires data sources to return IEnumerable<tuple>.

Apply these changes to convert the data providers to TUnit's tuple-based format:

-    public static TheoryData<bool, Half, Half, Half> GetInBetweenData =>
-        new TheoryData<bool, Half, Half, Half>
+    public static IEnumerable<(bool, Half, Half, Half)> GetInBetweenData =>
+        new (bool, Half, Half, Half)[]
         {
-            { true, MinValue, BaseValue, MaxValue },
-            { true, MaxValue, BaseValue, MinValue },
+            ( true, MinValue, BaseValue, MaxValue ),
+            ( true, MaxValue, BaseValue, MinValue ),
 #if NET6_0_OR_GREATER
             // Known Issue for .NET 5 - https://github.com/dotnet/runtime/issues/49983
-            { false, MinValue, MinValue, MaxValue },
+            ( false, MinValue, MinValue, MaxValue ),
 #endif
-            { false, MaxValue, MinValue, MaxValue },
-            { false, BaseValue, MinValue, MaxValue },
-            { false, BaseValue, MaxValue, MinValue },
+            ( false, MaxValue, MinValue, MaxValue ),
+            ( false, BaseValue, MinValue, MaxValue ),
+            ( false, BaseValue, MaxValue, MinValue ),
         };

-    public static TheoryData<bool, Half, Half, Half> GetNotBetweenData =>
-        new TheoryData<bool, Half, Half, Half>
+    public static IEnumerable<(bool, Half, Half, Half)> GetNotBetweenData =>
+        new (bool, Half, Half, Half)[]
         {
-            { false, MinValue, BaseValue, MaxValue },
-            { false, MaxValue, BaseValue, MinValue },
-            { true, BaseValue, MinValue, MaxValue },
-            { true, BaseValue, MaxValue, MinValue },
+            ( false, MinValue, BaseValue, MaxValue ),
+            ( false, MaxValue, BaseValue, MinValue ),
+            ( true, BaseValue, MinValue, MaxValue ),
+            ( true, BaseValue, MaxValue, MinValue ),
         };

-    public static TheoryData<bool, Half, Half> GetGreaterThanData =>
-        new TheoryData<bool, Half, Half>
+    public static IEnumerable<(bool, Half, Half)> GetGreaterThanData =>
+        new (bool, Half, Half)[]
         {
-            { true, BaseValue, MaxValue },
-            { true, BaseValue, BaseValue },
-            { false, BaseValue, MinValue },
+            ( true, BaseValue, MaxValue ),
+            ( true, BaseValue, BaseValue ),
+            ( false, BaseValue, MinValue ),
         };

-    public static TheoryData<bool, Half, Half> GetGreaterThanOrEqualData =>
-        new TheoryData<bool, Half, Half>
+    public static IEnumerable<(bool, Half, Half)> GetGreaterThanOrEqualData =>
+        new (bool, Half, Half)[]
         {
-            { true, BaseValue, MaxValue },
-            { false, BaseValue, BaseValue },
-            { false, BaseValue, MinValue },
+            ( true, BaseValue, MaxValue ),
+            ( false, BaseValue, BaseValue ),
+            ( false, BaseValue, MinValue ),
         };

-    public static TheoryData<bool, Half, Half> GetLessThanData =>
-        new TheoryData<bool, Half, Half>
+    public static IEnumerable<(bool, Half, Half)> GetLessThanData =>
+        new (bool, Half, Half)[]
         {
-            { true, BaseValue, MinValue },
-            { true, BaseValue, BaseValue },
-            { false, BaseValue, MaxValue },
+            ( true, BaseValue, MinValue ),
+            ( true, BaseValue, BaseValue ),
+            ( false, BaseValue, MaxValue ),
         };

-    public static TheoryData<bool, Half, Half> GetLessThanOrEqualData =>
-        new TheoryData<bool, Half, Half>
+    public static IEnumerable<(bool, Half, Half)> GetLessThanOrEqualData =>
+        new (bool, Half, Half)[]
         {
-            { true, BaseValue, MinValue },
-            { false, BaseValue, BaseValue },
-            { false, BaseValue, MaxValue },
+            ( true, BaseValue, MinValue ),
+            ( false, BaseValue, BaseValue ),
+            ( false, BaseValue, MaxValue ),
         };

-    public static TheoryData<bool, Half> GetNotNaNData =>
-        new TheoryData<bool, Half>
+    public static IEnumerable<(bool, Half)> GetNotNaNData =>
+        new (bool, Half)[]
         {
-            { true, NaN },
-            { false, BaseValue },
-            { false, MaxValue },
-            { false, MinValue },
+            ( true, NaN ),
+            ( false, BaseValue ),
+            ( false, MaxValue ),
+            ( false, MinValue ),
         };

-    public static TheoryData<bool, Half> GetNotInfinityData =>
-        new TheoryData<bool, Half>
+    public static IEnumerable<(bool, Half)> GetNotInfinityData =>
+        new (bool, Half)[]
         {
-            { true, PositiveInfinity },
-            { true, NegativeInfinity },
-            { false, MaxValue },
-            { false, MinValue },
+            ( true, PositiveInfinity ),
+            ( true, NegativeInfinity ),
+            ( false, MaxValue ),
+            ( false, MinValue ),
         };

-    public static TheoryData<bool, Half> GetNotNegativeInfinityData =>
-        new TheoryData<bool, Half>
+    public static IEnumerable<(bool, Half)> GetNotNegativeInfinityData =>
+        new (bool, Half)[]
         {
-            { false, PositiveInfinity },
-            { true, NegativeInfinity },
-            { false, MaxValue },
-            { false, MinValue },
+            ( false, PositiveInfinity ),
+            ( true, NegativeInfinity ),
+            ( false, MaxValue ),
+            ( false, MinValue ),
         };

-    public static TheoryData<bool, Half> GetNotPositiveInfinityData =>
-        new TheoryData<bool, Half>
+    public static IEnumerable<(bool, Half)> GetNotPositiveInfinityData =>
+        new (bool, Half)[]
         {
-            { true, PositiveInfinity },
-            { false, NegativeInfinity },
-            { false, MaxValue },
-            { false, MinValue },
+            ( true, PositiveInfinity ),
+            ( false, NegativeInfinity ),
+            ( false, MaxValue ),
+            ( false, MinValue ),
         };
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)

25-26: Critical: Complete the data source migration to TUnit.

The data source GetExistsData still uses xUnit's TheoryData<bool, string>, which is incompatible with TUnit. Based on the PR's migration pattern and other test files, data sources must return IEnumerable<(...)> tuples instead.

Apply this diff to complete the migration:

-    public static TheoryData<bool, string> GetExistsData =>
-        new TheoryData<bool, string> { { true, "/does.not.exists/" }, { false, Path.GetTempPath() } };
+    public static IEnumerable<(bool ThrowException, string DirectoryPath)> GetExistsData()
+    {
+        yield return (true, "/does.not.exists/");
+        yield return (false, Path.GetTempPath());
+    }
tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (1)

118-185: Critical: Incomplete migration from xUnit to TUnit - TheoryData still in use.

The test attributes have been updated to TUnit's [Test] and [MethodDataSource], but the data providers still use xUnit's TheoryData<> type. This creates a dependency on xUnit types even though xUnit packages have been removed from Directory.Packages.props.

Based on the related code snippets from EnsureCharTests.cs, EnsureDateTimeTests.cs, and other fully migrated files, data providers should be converted to IEnumerable<(...)> tuples.

Apply this pattern to complete the migration:

-    public static TheoryData<bool, sbyte, sbyte, sbyte> GetInBetweenData =>
-        new TheoryData<bool, sbyte, sbyte, sbyte>
+    public static IEnumerable<(bool, sbyte, sbyte, sbyte)> GetInBetweenData =>
         {
-            { true, MinValue, BaseValue, MaxValue },
-            { true, MaxValue, BaseValue, MinValue },
-            { false, MinValue, MinValue, MaxValue },
-            { false, MaxValue, MinValue, MaxValue },
-            { false, BaseValue, MinValue, MaxValue },
-            { false, BaseValue, MaxValue, MinValue },
+            (true, MinValue, BaseValue, MaxValue),
+            (true, MaxValue, BaseValue, MinValue),
+            (false, MinValue, MinValue, MaxValue),
+            (false, MaxValue, MinValue, MaxValue),
+            (false, BaseValue, MinValue, MaxValue),
+            (false, BaseValue, MaxValue, MinValue),
         };

Apply the same pattern to all other data providers: GetNotBetweenData, GetGreaterThanData, GetGreaterThanOrEqualData, GetLessThanData, GetLessThanOrEqualData, and GetNotPow2Data.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (1)

118-185: Critical: Incomplete migration from xUnit to TUnit - TheoryData still in use.

The data providers still use xUnit's TheoryData<> type despite the framework migration to TUnit. This is the same issue as in EnsureInt8Tests.cs and creates an inconsistency with fully migrated test files.

Convert all data providers from TheoryData<bool, uint, ...> to IEnumerable<(bool, uint, ...)> with tuple-based data initialization, following the pattern shown in EnsureCharTests.cs lines 118-146.

tests/NetEvolve.Guard.Tests.Unit/EnsureTimeOnlyTests.cs (1)

119-169: Critical: Incomplete migration from xUnit to TUnit - TheoryData still in use.

The data providers still use xUnit's TheoryData<> type despite the test attributes being updated to TUnit. This is inconsistent with the complete migration pattern demonstrated in EnsureCharTests.cs, EnsureDateTimeTests.cs, and EnsureDateTimeOffsetTests.cs.

Convert all data providers to IEnumerable<(bool, TimeOnly, ...)> format with tuple-based initialization.

♻️ Duplicate comments (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (1)

5-5: Int32 tests follow the same TUnit pattern as other numeric suites

EnsureInt32Tests cleanly mirrors the [Test]/[MethodDataSource] pattern used in the other numeric guard tests, with the same assertion logic and TheoryData-backed providers preserved. This should behave identically to the pre-migration xUnit theories assuming the shared data-source integration is configured as discussed on the UInt8 tests.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 171-172

tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (1)

5-5: Float guard tests correctly migrated to TUnit

The float guard tests now consistently use [Test] and [MethodDataSource] across all relational and NaN/Infinity scenarios, with the existing assertions and TheoryData providers preserved. This matches the approach in the other numeric test files; behaviour should remain the same provided the shared MethodDataSource/TheoryData integration is configured as per the earlier comment.

Also applies to: 19-20, 36-37, 53-54, 70-71, 87-88, 104-105, 121-122, 135-136, 149-150, 163-164

tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (1)

5-5: Int16 tests’ TUnit conversion matches the established pattern

This file follows the same [Test]/[MethodDataSource] structure and TheoryData-backed data providers as the other integral guard tests, keeping the original behaviours and exception expectations intact.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 171-172

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt64Tests.cs (1)

5-5: UInt64 tests are aligned with the rest of the TUnit migration

The unsigned 64-bit guard tests are now using [Test] and [MethodDataSource] with their existing TheoryData providers, consistent with the other numeric test files. No additional issues beyond the shared data-source consideration already raised on EnsureUInt8Tests.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 171-172

🧹 Nitpick comments (8)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1)

5-5: TUnit migration here is consistent; only a naming nit if you care

The switch to using NetEvolve.Extensions.TUnit; plus [Test] and [MethodDataSource(nameof(GetExistsData))] matches the pattern in EnsureDirectoryInfoTests and keeps the behavior of Exists_Theory_Expected intact. I don’t see any functional risks in this change.

If you want to clean up naming while you’re here, you could consider dropping Theory from the method name now that it’s no longer an xUnit theory (e.g., Exists_Expected), but that’s purely cosmetic.

Also applies to: 12-25

tests/NetEvolve.Guard.Tests.Unit/EnsureThatTests.cs (1)

10-19: TUnit data-driven migration looks correct; optional consistency tweak

The switch to [Test] + [Arguments(...)] for the three That_*_Theory_Expected methods preserves the original data sets and assertion behavior, and matches the patterns used in EnsureObjectTests, EnsureArrayTests, and EnsureCharTests. If you want maximal consistency with the rest of the suite, you could optionally extract the repeated null / "" argument sets into a [MethodDataSource] method, but it's not necessary for correctness here.

Please just confirm via the test run that TUnit correctly binds null in [Arguments(null)] for string? parameterName across all three tests.

Also applies to: 21-30, 32-41

tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (1)

20-49: [MethodDataSource] wiring looks correct; consider future-proofing the data source type

Using [MethodDataSource(nameof(GetNotNullOrEmptyData))] for both data-driven tests keeps them DRY and aligns with the patterns in the other migrated test files. The GetNotNullOrEmptyData source covers both throwing and non-throwing scenarios appropriately for the generic and non-generic overloads.

One thing to keep an eye on: the data source remains a TheoryData<bool, IEnumerable<string?>> property. If the broader goal is to remove xUnit dependencies entirely or to rely purely on TUnit/NetEvolve.Extensions.TUnit primitives, you may eventually want to:

  • Replace TheoryData<...> with whatever data shape TUnit prefers (e.g., an IEnumerable<object?[]> or equivalent), and/or
  • Convert the property into a static method if MethodDataSource ever tightens to method-only resolution.

Not a blocker for this PR, but worth confirming against how MethodDataSource is defined in NetEvolve.Extensions.TUnit and your longer-term test-stack plans.

Also applies to: 84-92

tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (1)

6-15: Migration setup looks correct.

The import to NetEvolve.Extensions.TUnit and the [UnitTest] attribute are properly configured.

Note: BaseValue at line 13 implicitly defaults to BigInteger.Zero. Consider adding an explicit initializer (= BigInteger.Zero) for clarity, matching the pattern used for MaxValue and MinValue.

tests/NetEvolve.Guard.Tests.Unit/EnsureObjectTests.cs (1)

10-13: Add explicit TUnit/Guard usings and consider [UnitTest] for consistency

The new [Test]/[Arguments] usage keeps the original test behaviour intact. Two minor consistency points:

  • This file relies on Test, Arguments, Assert, and Ensure being brought in via globals; unlike other test files, there’s no explicit using NetEvolve.Extensions.TUnit; / using NetEvolve.Guard;. For clarity (and to avoid surprises if globals change), consider adding those usings explicitly.
  • Other test classes are annotated with [UnitTest]. If you’re using that for filtering/categorization, it’s probably worth adding it to EnsureObjectTests as well.

Also applies to: 26-26, 33-33, 43-43, 53-53

tests/NetEvolve.Guard.Tests.Unit/EnsureStringTests.cs (1)

11-15: String tests’ TUnit conversion looks good; align usings with other files

The [Test]/[Arguments] migration for the string guards maintains the original semantics around null/empty/whitespace and regex patterns/options, and the [UnitTest] class attribute matches the rest of the suite.

Like EnsureObjectTests, this file appears to rely on global usings for Test, Arguments, Assert, and Ensure. For consistency with the other numeric test files (which explicitly add using NetEvolve.Extensions.TUnit; and using NetEvolve.Guard;), consider adding those here as well so the dependency on globals is explicit.

Also applies to: 32-36, 56-62, 90-101

tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (2)

17-117: Assertion style still xUnit‑like; clarify assertion library strategy

These tests still use Assert.Throws<ArgumentOutOfRangeException>(...) with void methods, which matches xUnit’s style rather than TUnit’s async fluent assertions (await Assert.That(() => action).Throws<Exception>();). (ithelp.ithome.com.tw)

If the goal of this PR is purely to switch the runner to TUnit while keeping xUnit assertions, this is fine as long as xunit.assert (or another assertion library that exposes Assert.Throws) remains referenced.

If you intend to fully migrate to TUnit.Assertions, you’ll eventually want to:

  • Change these tests to public async Task ...
  • Replace Assert.Throws<ArgumentOutOfRangeException>(() => ...) with await Assert.That(() => ...).Throws<ArgumentOutOfRangeException>();

I’d recommend deciding on a single assertion library per project to avoid confusion during future maintenance.

Can you confirm whether xunit.assert is still referenced in the test project, or if you plan a follow‑up PR to move these to TUnit.Assertions?


119-147: Prefer static methods over properties for MethodDataSource compatibility

The data sources are now strongly typed IEnumerable<(...)> sequences, which matches the TUnit pattern for method data sources. However, they’re exposed as static properties:

public static IEnumerable<(bool, DateOnly, DateOnly, DateOnly)> GetInBetweenData => [ ... ];

TUnit’s documentation shows [MethodDataSource] consuming a static method returning IEnumerable<(...)> (e.g., public static IEnumerable<(string Username, string Password)> GetAuthDetails()), not a property. (feed.nuget.org)

To stay closest to the documented API, avoid analyzer noise, and be future‑proof, I’d suggest turning these into methods:

-    public static IEnumerable<(bool, DateOnly, DateOnly, DateOnly)> GetInBetweenData =>
-        [
-            (true, MinValue, BaseValue, MaxValue),
-            (true, MaxValue, BaseValue, MinValue),
-            (false, MinValue, MinValue, MaxValue),
-            (false, MaxValue, MinValue, MaxValue),
-            (false, BaseValue, MinValue, MaxValue),
-            (false, BaseValue, MaxValue, MinValue),
-        ];
+    public static IEnumerable<(bool, DateOnly, DateOnly, DateOnly)> GetInBetweenData()
+        => [
+            (true, MinValue, BaseValue, MaxValue),
+            (true, MaxValue, BaseValue, MinValue),
+            (false, MinValue, MinValue, MaxValue),
+            (false, MaxValue, MinValue, MaxValue),
+            (false, BaseValue, MinValue, MaxValue),
+            (false, BaseValue, MaxValue, MinValue),
+        ];

…and do the same for the other four data sources.

Please confirm that MethodDataSource in your current TUnit version accepts properties as sources; if not, this change to methods will be required for the generator/analyzers to be happy.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 8e4c214 and 58517f0.

📒 Files selected for processing (31)
  • .editorconfig (1 hunks)
  • Directory.Packages.props (1 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureArrayTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeOffsetTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (7 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (11 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (11 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (11 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (5 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureObjectTests.cs (4 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureStringTests.cs (4 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (3 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureThatTests.cs (3 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureTimeOnlyTests.cs (7 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureTimeSpanTests.cs (7 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt64Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt8Tests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (12)
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (2)
  • Test (17-32)
  • Test (34-49)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1)
  • Test (12-25)
tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (1)
tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (1)
  • ExcludeFromCodeCoverage (6-46)
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt8Tests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (2)
tests/NetEvolve.Guard.Tests.Unit/EnsureArrayTests.cs (2)
  • Test (11-17)
  • Test (19-31)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (1)
  • Test (17-32)
tests/NetEvolve.Guard.Tests.Unit/EnsureObjectTests.cs (1)
src/NetEvolve.Guard/Ensure.cs (1)
  • Ensure (11-78)
tests/NetEvolve.Guard.Tests.Unit/EnsureArrayTests.cs (1)
tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (7)
  • ExcludeFromCodeCoverage (8-93)
  • Test (12-18)
  • Test (20-32)
  • Test (34-49)
  • Test (51-60)
  • Test (62-71)
  • Test (73-82)
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt64Tests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (2)
  • Test (17-32)
  • Test (34-49)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1)
  • Test (12-25)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (7)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
  • Test (68-83)
  • Test (85-100)
  • Test (102-117)
  • Test (150-162)
tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (3)
  • Test (17-32)
  • Test (34-49)
  • Test (51-66)
🪛 GitHub Actions: CI
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs

[error] 7-7: CS0246: The type or namespace name 'UnitTestAttribute' could not be found (missing using directive or assembly reference).

tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs

[error] 139-139: Was not formatted. Code formatting check failed. Expected formatting around line 139.

🔇 Additional comments (39)
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (2)

5-5: Using TUnit extension is correct for this test file

using NetEvolve.Extensions.TUnit; is appropriate here and aligns with the updated attribute usage and patterns in sibling test files. No further changes needed.


16-17: TUnit data-driven test attributes look consistent and correct

The conversion from xUnit theories/member data to [Test] + [MethodDataSource(...)] on these methods is consistent with other migrated tests (e.g., EnsureDateOnlyTests, EnsureCharTests, EnsureBigIntegerTests). Method names and parameter lists match the corresponding TheoryData providers, so behavior should remain unchanged.

Also applies to: 33-34, 50-51, 67-68, 84-85, 101-102, 170-172

tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (4)

5-5: LGTM! Namespace updated correctly for TUnit migration.

The using directive correctly switches from XUnit to TUnit extensions.


11-13: LGTM! Test attributes migrated correctly.

The test method properly migrates from xUnit's [Theory]/[InlineData] pattern to TUnit's [Test]/[Arguments] pattern while preserving test semantics.


26-29: LGTM! Nullable type test migrated correctly.

The parameterized test handling nullable int? correctly migrates to TUnit's [Arguments] pattern. This matches the approach used in EnsureGuidTests.cs for nullable types.


45-48: LGTM! Complex test case migrated correctly.

The test method handling both null and default value scenarios correctly migrates to TUnit. All test cases are preserved with proper argument mapping.

tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (7)

5-5: LGTM: Using directive correctly updated for TUnit.

The namespace change from NetEvolve.Extensions.XUnit to NetEvolve.Extensions.TUnit is correct and aligns with the framework migration.


16-31: LGTM: Test attributes correctly migrated.

The migration from xUnit's [Theory] and [MemberData] to TUnit's [Test] and [MethodDataSource] is correct. The test logic remains unchanged, which minimizes migration risk.


33-48: LGTM: Test attributes correctly migrated.

The attribute migration follows the same correct pattern as the other test methods.


50-65: LGTM: Test attributes correctly migrated.

The migration is consistent with the TUnit framework requirements.


67-82: LGTM: Test attributes correctly migrated.

The attribute changes are correct for the TUnit framework.


84-99: LGTM: Test attributes correctly migrated.

The migration follows the established pattern correctly.


101-116: LGTM: Test attributes correctly migrated.

All test methods in this file have been successfully migrated to TUnit. The test data sources using TheoryData<T> remain compatible, which is consistent with the migration pattern observed in other test files.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (2)

5-5: TUnit extension namespace import is consistent with the framework switch

The change to using NetEvolve.Extensions.TUnit; matches the rest of the migration and keeps [UnitTest], [Test], and [MethodDataSource] resolvable from the same extension package.

Please confirm CI/build picks up the correct TUnit package and that no remaining references to NetEvolve.Extensions.XUnit exist elsewhere in the solution.


16-17: Attribute migration to [Test] + [MethodDataSource] is correct and consistent

All theory-like tests now use [Test] with [MethodDataSource(nameof(...))], and each data source name maps to an existing static TheoryData<...> provider whose generic arguments match the method parameters. This matches the pattern used in the other TUnit-based Ensure*Tests files.

Please run the NetEvolve.Guard.Tests.Unit test project (or rely on CI) to validate that TUnit correctly binds each MethodDataSource and all migrated tests execute as expected.

Also applies to: 33-34, 50-51, 67-68, 84-85, 101-102, 171-172

tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (2)

10-12: LGTM! Clean xUnit to TUnit migration.

The test attribute migration from [Theory]/[InlineData] to [Test]/[Arguments] follows the documented TUnit pattern. The test data correctly validates the IsNotEmpty() behavior for both Guid.Empty (expects exception) and non-empty GUIDs.


26-29: <function_calls>

TUnit parameterized tests documentation official
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (1)

6-6: LGTM: Test attribute migration to TUnit is correct.

The import and test method attributes have been properly updated to use TUnit's [Test] and [MethodDataSource] patterns, consistent with the framework migration.

Also applies to: 20-21, 37-38, 54-55, 71-72, 88-89, 105-106, 122-123, 136-137, 150-151, 164-165

tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)

10-23: LGTM: Test method attributes correctly migrated to TUnit.

The test method attributes have been properly updated from xUnit's [Theory] and [MemberData] to TUnit's [Test] and [MethodDataSource]. The test logic remains unchanged and correct.

tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (2)

12-18: Simple [Test] migration keeps behavior unchanged

The NotNullOrEmpty_Null_ArgumentNullException test is now using [Test] with no other behavioral change; the guard call and expected exception remain identical, so this migration looks safe.


51-82: Remaining [Test] migrations for generic/collection overloads look good

The tests for IsNotNullOrEmpty<...> on IEnumerable<T>, arrays, and lists now use [Test] but otherwise keep the same exception expectations and inputs. This preserves coverage of the generic overloads and collection shapes without changing semantics.

tests/NetEvolve.Guard.Tests.Unit/EnsureBigIntegerTests.cs (3)

17-32: Test attribute migration is correct.

The migration from [Theory]/[MemberData] to [Test]/[MethodDataSource] follows the TUnit pattern correctly. The test logic and method signature remain appropriate for parameterized testing.


149-165: Conditional test migration is consistent.

The #if NET6_0_OR_GREATER block correctly migrates the IsPow2 test with the same TUnit patterns used elsewhere in the file. The test data correctly validates 63 (not a power of 2) and 64 (is a power of 2).


119-147: No refactoring needed; TUnit's MethodDataSource fully supports properties.

TUnit explicitly supports MethodDataSource on property getters, not just methods. The current expression-bodied property pattern used throughout the test file is correct and widely used across the codebase. The tests execute correctly with this pattern—no conversion to methods is necessary.

tests/NetEvolve.Guard.Tests.Unit/EnsureArrayTests.cs (2)

5-5: Framework migration: TUnit using directive added correctly.

The addition of the TUnit extensions namespace is appropriate for the framework migration.


11-11: Test attribute migration to TUnit is correct.

The migration from xUnit attributes to TUnit attributes follows the expected pattern.

Also applies to: 19-20

tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (2)

5-5: Using NetEvolve.Extensions.TUnit is correct and consistent with the TUnit migration

The new using aligns this test with the TUnit-based categorization model used elsewhere; no issues here.


19-20: Let me check if there's a custom TheoryData implementation or if this is truly a missing reference:
<function_calls>

#!/bin/bash

Check what's imported in EnsureDoubleTests.cs

echo "=== Imports in EnsureDoubleTests.cs ==="
head -20 tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs

echo ""
echo "=== Check if TheoryData is defined in NetEvolve.Extensions.TUnit ==="
find . -name "*.cs" -type f | xargs grep -l "class TheoryData" | head -5

echo ""
echo "=== Search for TheoryData definition ==="
rg -n "class TheoryData|namespace.*TheoryData" --type cs | head -10


</function_calls>

#!/bin/bash

# Check package versions and dependencies
echo "=== Full .csproj content ===" 
cat tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj

echo ""
echo "=== Check if xUnit.Abstractions is referenced ===" 
rg -i "xunit" tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj
</parameter>
</invoke>
</function_calls>

```shell
#!/bin/bash

# Search for TheoryData in NetEvolve.Extensions.TUnit namespace
echo "=== Looking for TheoryData in solution ===" 
find . -name "*.cs" | xargs grep -n "class TheoryData\|public static TheoryData" | head -20

echo ""
echo "=== Check NetEvolve.Extensions.TUnit if it exists ===" 
find . -path "*NetEvolve.Extensions.TUnit*" -name "*.cs" | head -10
</parameter>
tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj (1)

7-9: TUnit package wiring in test csproj looks consistent

The new PackageReference entries for Microsoft.Testing.Extensions.CodeCoverage, NetEvolve.Extensions.TUnit, and TUnit align with the migration to the TUnit/Microsoft.Testing.Platform stack and central package management. No issues from the project file alone; just ensure versions are correctly defined in Directory.Packages.props and that dotnet test picks up the new test framework as expected.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt8Tests.cs (1)

5-5: TUnit attribute migration is consistent; just confirm TheoryData compatibility

The switch to using NetEvolve.Extensions.TUnit; plus [Test] and [MethodDataSource] on all the byte guard tests is consistent with the rest of the suite, and the existing assertion logic is preserved.

The only thing to double‑check is that MethodDataSource in your TUnit setup supports TheoryData<...> as a data source (or that TheoryData is now provided by a non‑xUnit package). If not, these properties may need to return an IEnumerable<object?[]>/similar instead.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 171-172

Directory.Packages.props (1)

1-22: LGTM! Package migration from xUnit to TUnit completed successfully.

The package configuration cleanly removes all xUnit-related dependencies (xunit, xunit.runner.visualstudio, NetEvolve.Extensions.XUnit) and introduces TUnit equivalents (TUnit, NetEvolve.Extensions.TUnit). The code coverage tooling has also been modernized with Microsoft.Testing.Extensions.CodeCoverage. The addition of SonarAnalyzer.CSharp strengthens static analysis capabilities.

tests/NetEvolve.Guard.Tests.Unit/EnsureCharTests.cs (2)

5-5: LGTM! Complete migration to TUnit framework.

This file demonstrates the correct migration pattern with both test attributes ([Test]/[MethodDataSource]) and data providers (IEnumerable<(...)> tuples) fully converted from xUnit to TUnit.


118-146: LGTM! Data providers correctly migrated to tuple-based format.

The conversion from TheoryData<bool, char, ...> to IEnumerable<(bool, char, ...)> with tuple literals is the correct approach for TUnit compatibility. This pattern should be applied to files like EnsureInt8Tests.cs and EnsureUInt32Tests.cs that still use TheoryData.

.editorconfig (1)

45-45: LGTM! EditorConfig updated to support newer solution file format.

The addition of slnx to the XML project files glob ensures consistent formatting for the new Visual Studio solution file format.

tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (2)

5-5: LGTM! Complete migration to TUnit framework.

The framework migration is correctly implemented with both test attributes and data providers fully converted to TUnit patterns.


139-139: I'll help you verify the formatting issue in the test file. Let me start by examining the file and understanding the context around line 139.
<function_calls>

wc -l tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs

</function_calls>
<function_calls>

sed -n '130,150p' tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs

</function_calls>

Now let me check the project configuration for formatting standards:
<function_calls>

find . -maxdepth 3 -type f ( -name ".csharpierrc*" -o -name ".editorconfig" -o -name "csharpier.json" ) 2>/dev/null

</function_calls>

Let me also check if there's any CI configuration that specifies the formatter:
<function_calls>

find . -maxdepth 3 -type f ( -name ".yml" -o -name ".yaml" ) | head -10

</function_calls>

<function_calls>

ls -la .github/workflows/ 2>/dev/null || echo "No .github/workflows directory"

</function_calls>

tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeOffsetTests.cs (2)

5-5: LGTM! Complete migration to TUnit framework.

This file demonstrates the correct and complete migration pattern with both test attributes and data providers fully converted from xUnit to TUnit.


132-162: LGTM! Data providers correctly migrated to tuple-based format.

The conversion to IEnumerable<(bool, DateTimeOffset, ...)> with tuple literals is correctly implemented and consistent with other fully migrated test files.

tests/NetEvolve.Guard.Tests.Unit/EnsureDateOnlyTests.cs (1)

6-11: TUnit integration & categorization look consistent

using NetEvolve.Extensions.TUnit; with the [UnitTest] class attribute is aligned with the extensions package’s intended usage; nothing to change here assuming the project references TUnit.Core as well.

Please just confirm the test project has TUnit.Core (and any global usings for TUnit.Core) wired up so [Test] and [MethodDataSource] are resolved from the expected assembly. (feed.nuget.org)

@codecov
Copy link

codecov bot commented Nov 28, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.77%. Comparing base (47a3446) to head (8228411).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #494   +/-   ##
=======================================
  Coverage   99.77%   99.77%           
=======================================
  Files         162      162           
  Lines         437      437           
  Branches       82       82           
=======================================
  Hits          436      436           
  Misses          1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (7)
tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (1)

39-39: Simplify redundant assignment pattern.

The pattern int result = _ = Ensure.That(value).IsNotNull(); is unnecessarily complex. The discard operator serves no purpose when the result is already assigned to a variable.

Apply this diff:

-            int result = _ = Ensure.That(value).IsNotNull();
+            int result = Ensure.That(value).IsNotNull();

And similarly at line 61:

-            int result = _ = Ensure.That(value).IsNotNullOrDefault();
+            int result = Ensure.That(value).IsNotNullOrDefault();

Also applies to: 61-61

tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (2)

18-18: Optional: rename tests to drop the _Theory_ suffix

The methods are now plain [Test] cases rather than framework “theories”, but their names still contain _Theory_ (e.g., InBetween_Theory_Expected). Consider renaming to something like InBetween_Expected, NotBetween_Expected, etc., to avoid confusion for future readers and stay terminology‑aligned with the current test framework.

Also applies to: 35-35, 52-52, 69-69, 86-86, 103-103


118-146: Optional: unify collection initializer style in data providers

GetInBetweenData / GetNotBetweenData use the collection expression syntax ([...]), while the 3‑tuple providers use new[] { ... }. Both are fine, but using a single style across all decimal test data sources (either all [...] or all new[] { ... }) would slightly improve readability and consistency with the rest of the suite.

tests/NetEvolve.Guard.Tests.Unit/EnsureTimeOnlyTests.cs (1)

119-169: Data providers successfully migrated with minor style inconsistency.

The data providers have been correctly converted from TheoryData to IEnumerable<(...)> with tuple literals. However, this file uses List<(...)> with nested collection initializers (e.g., { { (...) } }), while other migrated test files (EnsureInt64Tests.cs, EnsureFloatTests.cs) use array initialization (e.g., new[] { (...) }).

For consistency across the test suite, consider using array initialization like other test files:

-    public static IEnumerable<(bool, TimeOnly, TimeOnly, TimeOnly)> GetInBetweenData =>
-        new List<(bool, TimeOnly, TimeOnly, TimeOnly)>
-        {
-            { (true, MinValue, BaseValue, MaxValue) },
-            { (true, MaxValue, BaseValue, MinValue) },
-            { (false, MinValue, MinValue, MaxValue) },
-            { (false, MaxValue, MinValue, MaxValue) },
-            { (false, BaseValue, MinValue, MaxValue) },
-            { (false, BaseValue, MaxValue, MinValue) },
-        };
+    public static IEnumerable<(bool, TimeOnly, TimeOnly, TimeOnly)> GetInBetweenData =>
+        new[]
+        {
+            (true, MinValue, BaseValue, MaxValue),
+            (true, MaxValue, BaseValue, MinValue),
+            (false, MinValue, MinValue, MaxValue),
+            (false, MaxValue, MinValue, MaxValue),
+            (false, BaseValue, MinValue, MaxValue),
+            (false, BaseValue, MaxValue, MinValue),
+        };

Apply the same pattern to all other data providers in this file.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (1)

118-168: Consider using array initializers for consistency.

The data providers here use new List<(...)> while other migrated test files (EnsureInt8Tests.cs, EnsureInt32Tests.cs, EnsureDoubleTests.cs) use new[] array initializers. For consistency and minor allocation reduction, consider using arrays:

-    public static IEnumerable<(bool, ushort, ushort, ushort)> GetInBetweenData =>
-        new List<(bool, ushort, ushort, ushort)>
+    public static IEnumerable<(bool, ushort, ushort, ushort)> GetInBetweenData =>
+        new[]
         {
-            { (true, MinValue, BaseValue, MaxValue) },
+            (true, MinValue, BaseValue, MaxValue),
             ...
         };
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (1)

118-168: Consider using array initializers for consistency.

Same observation as EnsureUInt16Tests.cs: this file uses new List<(...)> while other migrated test files use new[] array initializers. For consistency across the test suite, consider using arrays.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt8Tests.cs (1)

118-168: Consider consistency with other test files.

For consistency with EnsureInt16Tests.cs and EnsureDateTimeTests.cs, which both use new[] for their data providers, consider using the same array syntax here.

Also applies to: 185-185

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between 58517f0 and c3c3228.

📒 Files selected for processing (24)
  • Directory.Packages.props (1 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (7 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (6 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureStringTests.cs (4 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (3 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureThatTests.cs (3 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureTimeOnlyTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureTimeSpanTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt64Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt8Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs
  • tests/NetEvolve.Guard.Tests.Unit/EnsureStringTests.cs
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs
  • tests/NetEvolve.Guard.Tests.Unit/EnsureUInt64Tests.cs
  • tests/NetEvolve.Guard.Tests.Unit/EnsureTimeSpanTests.cs
🧰 Additional context used
🧬 Code graph analysis (5)
tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (2)
tests/NetEvolve.Guard.Tests.Unit/EnsureStringTests.cs (1)
  • ExcludeFromCodeCoverage (8-126)
tests/NetEvolve.Guard.Tests.Unit/EnsureThatTests.cs (1)
  • ExcludeFromCodeCoverage (7-43)
tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (3)
  • Test (19-34)
  • Test (36-51)
  • Test (53-68)
tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (3)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (3)
  • Test (19-34)
  • Test (36-51)
  • Test (53-68)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (3)
  • Test (19-34)
  • Test (36-51)
  • Test (53-68)
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (5)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (2)
  • Test (19-34)
  • Test (36-51)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1)
  • Test (12-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & Tests / Run Tests / Testing .NET solution
🔇 Additional comments (71)
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (3)

6-6: LGTM! Framework import updated correctly.

The import change from xUnit to TUnit extensions is correct and necessary for this migration.


20-21: LGTM! Test attributes migrated correctly.

All test methods have been consistently updated with TUnit attributes ([Test] and [MethodDataSource]). The data source references remain intact and test logic is preserved.

Also applies to: 37-38, 54-55, 71-72, 88-89, 105-106, 122-123, 136-137, 150-151, 164-165


178-223: LGTM! Data providers migrated correctly to tuple-based format.

All data provider methods have been successfully converted from TheoryData<...> to IEnumerable<(...)> with tuple-based data. The test data values are preserved, and the tuple syntax provides a cleaner, more concise representation. The conditional compilation for .NET 6+ edge cases is correctly maintained.

tests/NetEvolve.Guard.Tests.Unit/EnsureStructTests.cs (2)

5-6: LGTM! Framework migration imports are correct.

The added imports align with the TUnit framework migration and support the async test pattern.


12-25: Verify test coverage consistency.

Unlike NotNull_Theory_Expected and NotNullOrDefault_Theory_Expected, this test doesn't capture and verify the result value in the non-exception path (line 23). Consider whether result type and value assertions should be added for consistency.

tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (1)

16-116: Decimal guard tests and data providers are consistent and correct

The migration to parameterized tests backed by tuple‑based data sources looks solid:

  • Each test’s parameter list (bool throwException, decimal value, ...) aligns with the corresponding IEnumerable<(...)> tuple ordering.
  • The throwException flag correctly controls Assert.Throws<ArgumentOutOfRangeException>(nameof(value), ...) vs the non‑throwing Ensure.That(...).Is* calls for all Between/NotBetween and relational variants.
  • The decimal scenarios mirror the existing Int32/TimeSpan patterns (min/base/max combinations, reversed bounds, and boundary comparisons), so behavior should stay consistent across types.

No functional issues spotted here; this file’s TUnit migration for decimal looks ready.

Please run the decimal test suite (and the overall test project) on your side to confirm everything passes after the framework switch.

Also applies to: 118-146

tests/NetEvolve.Guard.Tests.Unit/EnsureGuidTests.cs (3)

5-5: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


11-25: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[InlineData] to TUnit's [Test]/[Arguments] pattern while preserving the test logic.


27-46: LGTM! Test attributes correctly migrated.

The parameterized test has been successfully migrated to TUnit's attribute pattern with multiple [Arguments] declarations.

tests/NetEvolve.Guard.Tests.Unit/EnsureThatTests.cs (4)

5-5: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


11-20: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[InlineData] to TUnit's [Test]/[Arguments] pattern.


22-31: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


33-42: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.

tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (8)

7-7: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


13-19: LGTM! Test attribute correctly migrated.

The test has been successfully migrated from xUnit's [Fact] to TUnit's [Test] attribute.


21-33: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[MemberData] to TUnit's [Test]/[MethodDataSource] pattern.


35-50: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


52-61: LGTM! Test attribute correctly migrated.

The test has been successfully migrated from xUnit's [Fact] to TUnit's [Test] attribute.


63-72: LGTM! Test attribute correctly migrated.

The test has been successfully migrated to TUnit's [Test] attribute.


74-83: LGTM! Test attribute correctly migrated.

The test has been successfully migrated to TUnit's [Test] attribute.


85-93: LGTM! Data provider successfully migrated to tuple-based pattern.

The data provider has been correctly converted from TheoryData<bool, IEnumerable<string?>> to IEnumerable<(bool, IEnumerable<string?>)> with tuple literals, aligning with TUnit's data-driven testing approach.

Directory.Packages.props (1)

13-13: LGTM! SonarAnalyzer.CSharp made unconditional.

The SonarAnalyzer.CSharp package reference has been updated to be unconditional with version 10.16.0.128591.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (9)

5-5: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


16-31: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[MemberData] to TUnit's [Test]/[MethodDataSource] pattern.


33-48: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


50-65: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


67-82: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


84-99: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


101-116: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


118-148: LGTM! Data providers successfully migrated to tuple-based pattern.

The data providers have been correctly converted from TheoryData to IEnumerable<(...)> with tuple literals using array initialization, aligning with TUnit's data-driven testing approach.


151-165: LGTM! Conditional test correctly migrated.

The NET6_0_OR_GREATER conditional test and its data provider have been successfully migrated to TUnit's attribute pattern.

tests/NetEvolve.Guard.Tests.Unit/EnsureTimeOnlyTests.cs (7)

6-6: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


17-32: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[MemberData] to TUnit's [Test]/[MethodDataSource] pattern.


34-49: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


51-66: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


68-83: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


85-100: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


102-117: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.

tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (12)

5-5: LGTM! Successfully migrated to TUnit namespace.

The namespace import has been correctly updated from xUnit to TUnit.


19-34: LGTM! Test attributes correctly migrated.

The test has been successfully migrated from xUnit's [Theory]/[MemberData] to TUnit's [Test]/[MethodDataSource] pattern.


36-51: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


53-68: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


70-85: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


87-102: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


104-119: LGTM! Test attributes correctly migrated.

The test has been successfully migrated to TUnit's attribute pattern.


121-133: LGTM! Test attributes correctly migrated.

The float NaN test has been successfully migrated to TUnit's attribute pattern.


135-147: LGTM! Test attributes correctly migrated.

The float infinity test has been successfully migrated to TUnit's attribute pattern.


149-161: LGTM! Test attributes correctly migrated.

The negative infinity test has been successfully migrated to TUnit's attribute pattern.


163-175: LGTM! Test attributes correctly migrated.

The positive infinity test has been successfully migrated to TUnit's attribute pattern.


177-219: LGTM! Data providers successfully migrated to tuple-based pattern.

All data providers have been correctly converted from TheoryData to IEnumerable<(...)> with tuple literals using array initialization, including the float-specific special value tests (NaN, infinity). This aligns with TUnit's data-driven testing approach.

tests/NetEvolve.Guard.Tests.Unit/NetEvolve.Guard.Tests.Unit.csproj (1)

7-8: Based on my verification:

TUnit packages are available and secure, but the claimed replacement cannot be verified.

Findings:

  • Both packages exist on NuGet: TUnit (v1.2.11) and NetEvolve.Extensions.TUnit (v3.1.0)
  • No xUnit references found anywhere in the codebase
  • No known security vulnerabilities detected
  • NetEvolve.Extensions.TUnit is a legitimate compatibility library from github.com/dailydevops with MIT license

Issue: The review comment claims "xUnit-related packages have been cleanly replaced with TUnit equivalents," but no xUnit packages are present in the repository, and the git history is not available to verify this replacement claim. The comment appears to make assumptions about prior state that cannot be confirmed from the current codebase.


LGTM! TUnit package references are valid and compatible.

The package references point to legitimate, available packages on NuGet with no known security issues. However, note that the claim about replacing xUnit-related packages cannot be verified from the current codebase—no xUnit references exist in the repository.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (4)

5-5: LGTM!

The import change to NetEvolve.Extensions.TUnit correctly aligns with the test framework migration.


16-31: LGTM!

The test attribute migration from [Theory]/[MemberData] to [Test]/[MethodDataSource] is correctly implemented. The test logic remains unchanged.


118-148: LGTM!

The data providers are correctly migrated to tuple-based IEnumerable<(...)> format using array initializers. The tuple element order matches the test method parameter signatures.


151-166: LGTM!

The conditional NET6_0_OR_GREATER block is correctly migrated with proper TUnit attributes and tuple-based data provider.

tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (4)

5-5: LGTM!

Import correctly updated for TUnit framework.


19-34: LGTM!

Test method correctly migrated with [Test]/[MethodDataSource] attributes. The parameterized test pattern is preserved.


121-133: LGTM!

The NotNaN_Theory_Expected test is correctly migrated with appropriate TUnit attributes.


177-219: LGTM!

All data providers correctly migrated to tuple-based IEnumerable<(...)> format. The double-specific providers for NaN and Infinity cases are properly structured with correct tuple arities.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (4)

5-5: LGTM!

Import correctly updated for TUnit framework.


16-31: LGTM!

Test method correctly migrated with preserved test logic.


118-148: LGTM!

Data providers correctly use tuple-based IEnumerable<(...)> with array initializers, consistent with other migrated test files.


151-166: LGTM!

The NET6_0_OR_GREATER conditional block is correctly migrated.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt16Tests.cs (3)

5-5: LGTM!

Import correctly updated for TUnit framework.


16-31: LGTM!

Test method correctly migrated with preserved test logic.


171-186: LGTM!

The NET6_0_OR_GREATER conditional block is correctly migrated.

tests/NetEvolve.Guard.Tests.Unit/EnsureUInt32Tests.cs (3)

5-5: LGTM!

Import correctly updated for TUnit framework.


16-31: LGTM!

Test method correctly migrated with preserved test logic.


171-186: LGTM!

The NET6_0_OR_GREATER conditional block is correctly migrated.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (1)

5-5: Framework migration successfully implemented.

The migration from xUnit to TUnit is correctly applied throughout this file. Test attributes changed from [Theory]/[MemberData] to [Test]/[MethodDataSource], and data providers now return IEnumerable<(...)> with tuple-based data using array syntax.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 118-148, 151-152, 165-165

tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (1)

5-5: Framework migration successfully implemented.

The migration from xUnit to TUnit is correctly applied throughout this file. Test attributes changed from [Theory]/[MemberData] to [Test]/[MethodDataSource], and data providers now return IEnumerable<(...)> with tuple-based data using array syntax.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102, 118-148

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (1)

19-175: Attribute + data-shape migration looks good; consider aligning exception tests with TUnit’s async pattern

The migration from [Theory]/[MemberData] to [Test]/[MethodDataSource] with tuple-based IEnumerable data is consistent and the parameter ordering in your test methods matches the tuple shapes from the providers. Once the providers are changed to static methods (see other comment), this wiring should be fine.

One thing to consider (non-blocking for this PR): TUnit’s migration docs and assertion docs strongly encourage async Task tests and await Assert.ThrowsAsync<T>(...) (or fluent await Assert.That(() => ...).Throws<>()) instead of synchronous Assert.Throws<T>, for both sync and async code paths. (tunit.dev)

As a follow‑up refactor, you could move these tests to the idiomatic style, for example:

-    [Test]
-    [MethodDataSource(nameof(GetInBetweenData))]
-    public void InBetween_Theory_Expected(bool throwException, double value, double min, double max)
+    [Test]
+    [MethodDataSource(nameof(GetInBetweenData))]
+    public async Task InBetween_Theory_Expected(bool throwException, double value, double min, double max)
     {
         if (throwException)
         {
-            _ = Assert.Throws<ArgumentOutOfRangeException>(
-                nameof(value),
-                () => _ = Ensure.That(value).IsBetween(min, max)
-            );
+            await Assert.ThrowsAsync<ArgumentOutOfRangeException>(
+                () => Task.Run(() => _ = Ensure.That(value).IsBetween(min, max))
+            );
         }
         else
         {
-            _ = Ensure.That(value).IsBetween(min, max);
+            _ = Ensure.That(value).IsBetween(min, max);
         }
     }

(similar pattern for the other guard tests).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Knowledge base: Disabled due to Reviews -> Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between c3c3228 and 8228411.

📒 Files selected for processing (13)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeOffsetTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (8 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (7 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (2 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (12 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (6 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (9 hunks)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs
🧰 Additional context used
🧬 Code graph analysis (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (2)
  • ExcludeFromCodeCoverage (8-36)
  • Test (12-25)
tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (3)
  • Test (19-34)
  • Test (36-51)
  • Test (53-68)
tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (4)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDecimalTests.cs (6)
  • Test (16-31)
  • Test (33-48)
  • Test (50-65)
  • Test (67-82)
  • Test (84-99)
  • Test (101-116)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (1)
  • Test (11-24)
tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (3)
  • Test (19-34)
  • Test (36-51)
  • Test (53-68)
tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (1)
tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (2)
  • ExcludeFromCodeCoverage (7-28)
  • Test (11-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build & Tests / Run Tests / Testing .NET solution
🔇 Additional comments (39)
tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeTests.cs (2)

5-5: LGTM! Clean framework migration.

The migration from xUnit to TUnit is executed correctly. The using statement, test attributes ([Theory] → [Test], [MemberData] → [MethodDataSource]), and test logic are all properly updated while preserving the original test behavior.

Also applies to: 16-17, 33-34, 50-51, 67-68, 84-85, 101-102


118-146: LGTM! Data providers correctly refactored.

The data provider methods have been correctly refactored from TheoryData<...> to IEnumerable<(...)> with tuple-based collection initializers. The tuple arity matches the test method parameters, and all test data values are preserved.

tests/NetEvolve.Guard.Tests.Unit/EnsureFileInfoTests.cs (2)

12-13: LGTM: Test attribute migration to TUnit.

The migration from [Theory]/[MemberData] to [Test]/[MethodDataSource] correctly follows TUnit conventions and is consistent with the pattern used in EnsureDirectoryInfoTests.cs.


27-35: LGTM: Data provider migrated to tuple-based enumerable.

The conversion from TheoryData<bool, string> to IEnumerable<(bool, string)> with collection expression syntax is correctly implemented and aligns with the TUnit framework requirements. The conditional compilation for different .NET versions is properly preserved.

tests/NetEvolve.Guard.Tests.Unit/EnsureFloatTests.cs (3)

5-5: LGTM! Import updated for TUnit framework migration.

The import change to NetEvolve.Extensions.TUnit correctly supports the repository-wide test framework migration.


19-20: LGTM! Test attributes consistently migrated to TUnit.

All test method attributes have been correctly updated from [Theory]/[MemberData] to [Test]/[MethodDataSource], following the established pattern across the codebase.

Also applies to: 36-37, 53-54, 70-71, 87-88, 104-105, 121-122, 135-136, 149-150, 163-164


177-217: LGTM! Data providers correctly refactored to tuple-based enumerable.

All test data providers have been successfully migrated from TheoryData<...> to IEnumerable<(...)> using collection expressions. The tuple signatures correctly match their corresponding test method parameters, and the test data covers appropriate boundary conditions.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt64Tests.cs (3)

5-5: LGTM!

Import correctly updated from xUnit to TUnit extension library, consistent with the framework migration.


16-17: Test attribute migration looks correct.

The switch from [Theory]/[MemberData] to [Test]/[MethodDataSource] is consistent with TUnit's parameterized test pattern.

Also applies to: 33-34, 50-51, 67-68, 84-85, 101-102, 149-150


118-146: TUnit's [MethodDataSource] fully supports static properties returning IEnumerable<T> — no changes needed.

Based on TUnit documentation and the codebase inspection, the data providers in EnsureInt64Tests.cs (lines 118-146) are correctly implemented. They are:

  • Static properties (not methods) using expression-bodied syntax (=>)
  • Returning IEnumerable of tuples as required
  • Fully compatible with [MethodDataSource] attribute

The TUnit framework explicitly supports this pattern: "MethodDataSource can be applied to required properties (property injection). In AOT mode the property data source must be static and follows the same rules as method data sources." This codebase implements it correctly.

tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeOffsetTests.cs (3)

16-17: Test attribute migration is consistent and correct.

All test methods have been properly migrated from xUnit's [Theory] and [MemberData] to TUnit's [Test] and [MethodDataSource] attributes. The use of nameof() maintains type safety for data source references.

Also applies to: 38-39, 60-61, 77-78, 98-99, 115-116


132-160: Data provider conversion is accurate and well-structured.

All data providers have been correctly converted from TheoryData<...> to IEnumerable<(...)> using modern C# collection expressions and tuple syntax. The test data logic is preserved and accurate:

  • Range checks properly test inclusive/exclusive boundaries
  • Comparison operators correctly validate edge cases (equal, greater, lesser)
  • Boolean flags accurately indicate expected exception behavior

5-5: I'll verify the concerns about the import statement and the TUnit/NetEvolve.Extensions.TUnit compatibility. Let me start by examining the project dependencies and configuration.
<function_calls>

#!/bin/bash

Search for project files that might contain dependency information

find . -type f ( -name ".csproj" -o -name ".sln" -o -name ".nuspec" -o -name "appsettings.json" ) | head -20


</function_calls>

Now let me check the actual test file to understand the migration context:
<function_calls>

#!/bin/bash

Read the test file to see the context of the import

cat -n tests/NetEvolve.Guard.Tests.Unit/EnsureDateTimeOffsetTests.cs | head -30


</function_calls>

Let me also search for the project file to find TUnit dependencies:
<function_calls>

#!/bin/bash

Find and read the test project file to check TUnit/NetEvolve.Extensions.TUnit dependencies

find . -path "/tests/NetEvolve.Guard.Tests.Unit/.csproj" -type f -exec cat {} ;


</function_calls>

<function_calls>

NetEvolve.Extensions.TUnit library C# NuGet package compatibility
</function_calls>

I'm investigating the import statement and its compatibility. Please provide the results of these queries so I can verify whether the import and TUnit setup are correct.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs (4)

5-10: LGTM!

The import switch to NetEvolve.Extensions.TUnit and the [UnitTest] attribute align with the TUnit migration pattern used consistently across the test suite.


16-17: Test attribute migration looks correct.

All test methods consistently use [Test] with [MethodDataSource] to replace xUnit's [Theory]/[MemberData] pattern. The test method bodies remain unchanged, and the pattern matches other migrated test files in the repository.

Also applies to: 33-34, 50-51, 67-68, 84-85, 101-102


148-164: LGTM!

The conditional NET6_0_OR_GREATER block is correctly preserved for the IsPow2 functionality. The test attribute migration and data provider refactoring follow the same pattern as the rest of the file.


118-146: I'll verify whether TUnit's MethodDataSource attribute works with properties or only methods. Let me start by examining the test file and searching for relevant documentation.
<function_calls>


cd /repo && find . -name "EnsureInt32Tests.cs" -type f | head -5


</function_calls>

<function_calls>


cd /repo && cat -n tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | head -200


</function_calls>

<function_calls>


cd /repo && wc -l tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

<function_calls>


cd /repo && cat tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | head -250


</function_calls>

<function_calls>


cd /repo && cat tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

Now let me search for TUnit documentation and examples to verify MethodDataSource behavior:
<function_calls>

TUnit MethodDataSource property vs method data provider

</function_calls>

<function_calls>

TUnit MethodDataSource documentation IEnumerable property

</function_calls>

<function_calls>

"TUnit" "MethodDataSource" github

</function_calls>

<function_calls>

TUnit testing framework MethodDataSource how to use

</function_calls>

Let me also check the codebase for other usages of MethodDataSource to understand the pattern:
<function_calls>


cd /repo && rg -n "MethodDataSource" --type csharp -B 3 -A 3 | head -100


</function_calls>

<function_calls>


cd /repo && rg -n "MethodDataSource" --type csharp


</function_calls>

<function_calls>


cd /repo && rg -in "datasource" --type csharp tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

<function_calls>


cd /repo && cat -n tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | sed -n '1,50p'


</function_calls>

<function_calls>


cd /repo && cat -n tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | sed -n '50,150p'


</function_calls>

Let me search for TUnit documentation on their GitHub:
<function_calls>

site:github.com TUnit MethodDataSource

</function_calls>

<function_calls>

site:github.com/thomhurst/TUnit MethodDataSource

</function_calls>

Let me search for the project documentation more directly:
<function_calls>


cd /repo && find . -name "*.md" -type f | xargs rg -l "TUnit|MethodDataSource|data source" | head -10


</function_calls>

<function_calls>


cd /repo && cat -n tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | sed -n '150,300p'


</function_calls>

Let me also check what version of TUnit is being used:
<function_calls>


cd /repo && find . -name ".csproj" -o -name ".sln" | xargs rg -l "TUnit" | head -5


</function_calls>

<function_calls>


cd /repo && find . -name "*.csproj" -type f | xargs grep -l "TUnit" | head -3


</function_calls>

<function_calls>


cd /repo && find . -path "./tests/" -name ".csproj" | head -3


</function_calls>

<function_calls>


cd /repo && ls -la tests/NetEvolve.Guard.Tests.Unit/


</function_calls>

<function_calls>


cd /repo && find . -name "*Tests.Unit.csproj" -o -name "Guard.Tests.csproj" | head -5


</function_calls>

<function_calls>


cd /repo && find tests -name "*.csproj" 2>/dev/null


</function_calls>

<function_calls>


cd /repo && fd ".csproj$" tests


</function_calls>

<function_calls>


cd /repo && find . -name "Directory.Packages.props" -o -name "global.json" | xargs cat 2>/dev/null | head -50


</function_calls>

Let me look at the test file more comprehensively to understand the actual structure:
<function_calls>


cd /repo && wc -l tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs && tail -100 tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

<function_calls>


cd /repo && grep -n "public.*IEnumerable" tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

<function_calls>


cd /repo && grep -n "Between|GreaterThan|LessThan" tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs | head -30


</function_calls>

<function_calls>


cd /repo && python3 << 'EOF'
with open('tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs', 'r') as f:
lines = f.readlines()

Find all test methods and data provider properties

for i, line in enumerate(lines, 1):
if 'public void' in line or 'public async' in line or 'public static IEnumerable' in line:
# Print the line and a few lines before/after for context
start = max(0, i-3)
end = min(len(lines), i+2)
print(f"\n--- Lines {start+1}-{end} ---")
for j in range(start, end):
print(f"{j+1:4d}: {lines[j]}", end='')
EOF


</function_calls>

Now let me search for TUnit documentation about how data sources work:
<function_calls>

"TUnit" test framework "data" "IEnumerable" how to pass

</function_calls>

<function_calls>

TUnit testing framework documentation parameters IEnumerable

</function_calls>

Let me check if there's a TUnit nuget package documentation:
<function_calls>

TUnit nuget package documentation

</function_calls>

<function_calls>

site:nuget.org TUnit

</function_calls>

Let me check TUnit GitHub repository directly for documentation:
<function_calls>

TUnit GitHub thomhurst documentation parameterized tests

</function_calls>

<function_calls>

github.com/thomhurst/TUnit README data attributes

</function_calls>

Let me try a different approach and look for actual TUnit usage examples online:
<function_calls>

"TUnit" C# testing "Arguments" "MethodDataSource"

</function_calls>

<function_calls>

TUnit "Arguments" attribute how to use examples

</function_calls>

Let me check if there are other test files in the repo that might show TUnit usage patterns:
<function_calls>


cd /repo && find tests -name "*.cs" -type f | head -10 | xargs head -30


</function_calls>

<function_calls>


cd /repo && ls tests/NetEvolve.Guard.Tests.Unit/ | head -20


</function_calls>

<function_calls>


cd /repo && head -100 tests/NetEvolve.Guard.Tests.Unit/EnsureArgumentTests.cs


</function_calls>

Now, let me search for the exact TUnit MethodDataSource documentation by looking at the TUnit source or documentation:
<function_calls>

"MethodDataSource" TUnit property method name

</function_calls>

<function_calls>

TUnit MethodDataSource source code reflection

</function_calls>

Let me search for TUnit documentation on GitHub more directly:
<function_calls>

site:github.com/thomhurst/TUnit "MethodDataSource"

</function_calls>

<function_calls>

site:github.com/thomhurst/TUnit wiki data attributes

</function_calls>

Let me try a broader search for TUnit parameterized testing:
<function_calls>

TUnit parameterized testing documentation

</function_calls>

<function_calls>

"TUnit" "parameterized" testing IEnumerable

</function_calls>

Let me look for TUnit's actual source code on GitHub to understand MethodDataSource:
<function_calls>

site:raw.githubusercontent.com thomhurst TUnit MethodDataSource

</function_calls>

Let me check if this repo has any documentation or README files that explain the testing approach:
<function_calls>


cd /repo && find . -name "README*" -o -name "*.md" | head -10 | xargs cat 2>/dev/null | head -100


</function_calls>

Let me look directly at recent TUnit releases and their documentation:
<function_calls>

"TUnit" release notes 2024 2025 MethodDataSource

</function_calls>

Let me try searching specifically for how TUnit uses reflection to find data sources:
<function_calls>

TUnit reflection GetMethod GetProperty data source

</function_calls>

Now let me search for TUnit's actual attribute name and how it works:
<function_calls>

TUnit "Arguments" attribute IEnumerable tuple data

</function_calls>

Let me check TUnit's actual documentation by searching for their official docs site:
<function_calls>

TUnit documentation site "data" "method" "property"

</function_calls>

Let me try a more direct search for the actual TUnit code repository URL:
<function_calls>

"TUnit" C# testing framework GitHub

</function_calls>

Let me check if there's a package reference file in the repo:
<function_calls>


cd /repo && find . -name ".json" -path "/tests/*" | xargs grep -l "TUnit" 2>/dev/null


</function_calls>

<function_calls>


cd /repo && find . -type f ( -name ".csproj" -o -name ".props" -o -name "*.json" ) | xargs grep -i "tunit" 2>/dev/null | head -10


</function_calls>

Let me get the full EnsureInt32Tests file to understand the complete picture:
<function_calls>


cd /repo && head -200 tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

<function_calls>


cd /repo && sed -n '200,350p' tests/NetEvolve.Guard.Tests.Unit/EnsureInt32Tests.cs


</function_calls>

Based on my research, let me provide the rewritten review comment:

Data provider refactoring is compatible with TUnit framework.

The migration from TheoryData<...> to IEnumerable<(...)> tuples using collection expressions aligns with TUnit's parameterized test patterns. TUnit's Arguments attribute and associated data source resolution supports both property-based and method-based data providers through reflection lookups by member name, so the property-based approach is valid and functionally equivalent.

tests/NetEvolve.Guard.Tests.Unit/EnsureDirectoryInfoTests.cs (2)

11-12: LGTM! Test attributes correctly migrated to TUnit.

The migration from xUnit's [Theory]/[MemberData] to TUnit's [Test]/[MethodDataSource] is correct and follows the pattern established in other test files.


26-27: LGTM! Data provider correctly migrated to TUnit pattern.

The migration from TheoryData<bool, string> to IEnumerable<(bool, string)> with tuple-based collection expression is correct. The test data is appropriate:

  • Non-existent path triggers exception validation
  • Temp directory validates successful existence check
tests/NetEvolve.Guard.Tests.Unit/EnsureHalfTests.cs (3)

6-7: TUnit import aligns with updated test attributes

The added using NetEvolve.Extensions.TUnit; matches the use of [Test] / [MethodDataSource] in this class; no issues seen.

If you haven’t already, please ensure the project references the expected TUnit package version and that no lingering xUnit usings remain in the test projects.


20-177: [Test] / [MethodDataSource] migration for Half tests looks consistent

The migration of these theory-style tests to [Test] plus [MethodDataSource] keeps signatures, parameter ordering, and exception expectations in line with the existing Double/Decimal/DateTime tests. The throwException flag semantics (expecting ArgumentOutOfRangeException / ArgumentException vs. success) remain correct.


178-221: Tuple-based data providers correctly cover Half edge cases

The new IEnumerable<(...)> providers match the method signatures and expected behaviors:

  • Between/NotBetween cases correctly distinguish in-range vs out-of-range scenarios, including swapped min/max handling and the NET6_0_OR_GREATER Half issue.
  • Greater/Less and their *OrEqual variants use BaseValue, MinValue, and MaxValue in the right combinations for throwing vs non-throwing cases.
  • NaN/Infinity datasets correctly drive the NotNaN/NotInfinity variants, including positive/negative infinity separation.

Use of collection expressions keeps the data concise and readable. No issues found.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt8Tests.cs (7)

16-31: InBetween test and data mapping look correct

The InBetween_Theory_Expected test plus GetInBetweenData correctly mark out‑of‑range and invalid (swapped) bounds as throwException = true, and in‑range (including endpoints and swapped bounds) as false. This aligns with an inclusive IsBetween semantics and matches the patterns used in the other numeric tests.

Also applies to: 118-126


33-48: NotBetween coverage is symmetric with InBetween

NotBetween_Theory_Expected and GetNotBetweenData mirror the InBetween cases: values outside the range (including with swapped bounds) are marked as non‑throwing, while in‑range values are marked as throwing. This gives good symmetric coverage of the IsNotBetween guard.

Also applies to: 128-134


50-65: GreaterThan strict comparison cases are well‑chosen

For GreaterThan_Theory_Expected and GetGreaterThanData, equality and “less than” cases are correctly marked as throwing, with a single clear “greater than” case as non‑throwing, which is sufficient and precise coverage of strict > behavior around typical boundaries.

Also applies to: 136-137


67-82: GreaterThanOrEqual data correctly distinguishes equality

The GreaterThanOrEqual_Theory_Expected test plus GetGreaterThanOrEqualData properly treat only the strictly lower and upper‑greater cases as throwing, and the equality / greater‑than‑min cases as non‑throwing, matching >= semantics.

Also applies to: 139-140


84-99: LessThan strict comparison data mirrors GreaterThan

LessThan_Theory_Expected with GetLessThanData correctly marks equality and “greater than” as throwing and a single “less than” case as non‑throwing, symmetrically covering strict < behavior around BaseValue.

Also applies to: 142-143


101-116: LessThanOrEqual inclusivity is exercised at both ends

The LessThanOrEqual_Theory_Expected test and GetLessThanOrEqualData use cases where value is below, equal to, and above the comparison value, with only the above case marked to throw. This matches <= semantics and complements the strict LessThan tests.

Also applies to: 145-146


149-161: Pow2 test data correctly separates non‑pow2 and pow2 values

NotPow2_Theory_Expected plus GetNotPow2Data use 63 (non‑power of two) as the throwing case and 64 (power of two) as the non‑throwing case, which is a clear and appropriate boundary pair for validating IsPow2() on sbyte.

Also applies to: 163-163

tests/NetEvolve.Guard.Tests.Unit/EnsureIEnumerableTests.cs (7)

7-7: Import is minimal and appropriate

The added using cleanly scopes in the new test framework types without introducing extra dependencies in this file.


13-13: [Test] annotation for null-case test is correctly migrated

The null-argument test remains parameterless and continues to assert ArgumentNullException, so the behavioral intent is preserved under the new framework.


21-22: Data-driven test wiring matches the new data provider shape

[Test] plus [MethodDataSource(nameof(GetNotNullOrEmptyData))] aligns with the method signature (bool throwException, IEnumerable<string?> values) and the static data provider returning (bool, IEnumerable<string?>) tuples, preserving the previous theory semantics. Based on library context, this matches the intended TUnit pattern.


35-37: Generic overload test reuses the common data source correctly

The generic TEnumerable variant uses the same GetNotNullOrEmptyData source and mirrors the non-generic test’s expectations, giving good coverage of both overloads without duplicating data.


52-52: [Test] annotation for generic null-case is consistent

This test still targets the generic overload with a null enumerable and expects ArgumentNullException, matching the original behavior after framework migration.


63-63: [Test] annotation for array empty-case is consistent

The array-based empty-case test remains focused on ArgumentException for an empty collection, and the new attribute wiring doesn’t change its behavior.


74-74: [Test] annotation for list empty-case is consistent

The list-based empty-case test mirrors the array variant and is correctly migrated to the new [Test] attribute without altering semantics.

tests/NetEvolve.Guard.Tests.Unit/EnsureDoubleTests.cs (1)

5-10: TUnit + NetEvolve category integration looks consistent

Switching the extension import to NetEvolve.Extensions.TUnit and keeping [UnitTest] on the class is consistent with how that package is meant to be used for categorization on top of TUnit. (nuget.org)

No changes needed here from this file’s perspective.

tests/NetEvolve.Guard.Tests.Unit/EnsureInt16Tests.cs (2)

16-31: TUnit test wiring and guard assertions look consistent

The migration to [Test] + [MethodDataSource] maintains the previous semantics: throwException cleanly drives the Assert.Throws vs success path, nameof(value) keeps parameter-name verification, and each guard method (IsBetween, IsNotBetween, comparison ops, IsPow2) is exercised in both throwing and non-throwing scenarios. I don’t see behavioral regressions here.

Also applies to: 33-48, 50-65, 67-82, 84-99, 101-116, 149-161


118-146: The review comment's core concern is invalid—[MethodDataSource] supports static properties and does not require conversion to methods.

Verification reveals:

  • The test suite consistently uses [MethodDataSource] with static properties returning direct tuples across all test files (EnsureInt16Tests, EnsureDoubleTests, EnsureArrayTests, etc.).
  • Tests execute successfully in CI/CD (.github/workflows/cicd.yml runs full build and test suite), proving data source discovery works as-is.
  • NetEvolve.Extensions.TUnit 3.1.0 (used by this repo) supports both static properties and unwrapped tuple returns for synchronous data sources; Func<> wrapping is only required for async/lazy evaluation scenarios.

The tuple data semantics remain correct for all guard tests, and no refactoring is needed.

@samtrion samtrion merged commit 21e4fa4 into main Nov 28, 2025
12 checks passed
@samtrion samtrion deleted the feature/switched-to-TUnit branch November 28, 2025 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state:ready for merge Indicates that a pull request has been reviewed and approved, and is ready to be merged into the mai type:feature Indicates a new feature or enhancement to be added.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants