diff --git a/CLAUDE.md b/CLAUDE.md index 37911b1..535fb19 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -228,3 +228,26 @@ public class WorkOrderViewModel // Avoid: record types for DTOs public record WorkOrderViewModel(string OrderNumber, DateTime? CompletionDate); ``` + +### Test Assertions: Use Shouldly, Not FluentAssertions + +This project uses **Shouldly** for test assertions. Do not use FluentAssertions. + +```csharp +// Preferred: Shouldly +result.ShouldBe(expected); +result.ShouldBeNull(); +result.ShouldNotBeNull(); +list.ShouldBeEmpty(); +list.Count().ShouldBe(3); +await Should.ThrowAsync(act); + +// Avoid: FluentAssertions +result.Should().Be(expected); +result.Should().BeNull(); +await act.Should().ThrowAsync(); +``` + +Custom extension methods in `Infrastructure/ShouldlyExtensions.cs` provide additional assertions: +- `ShouldBeCloseTo(DateTime, TimeSpan)` - DateTime tolerance comparison +- `ShouldBeEquivalentTo(IEnumerable)` - Collection equivalence (order-independent) diff --git a/NEW/tests/JdeScoping.Database.Tests/Functions/ComplexTableFunctionTests.cs b/NEW/tests/JdeScoping.Database.Tests/Functions/ComplexTableFunctionTests.cs index ba16ddb..a62f2f8 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Functions/ComplexTableFunctionTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Functions/ComplexTableFunctionTests.cs @@ -1,8 +1,8 @@ using Dapper; -using FluentAssertions; using JdeScoping.Core.Models.Search; using JdeScoping.Core.ViewModels; using JdeScoping.Database.Tests.Infrastructure; +using Shouldly; namespace JdeScoping.Database.Tests.Functions; @@ -39,10 +39,10 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(3); - resultList.Should().Contain(x => x.LotNumber == "LOT001" && x.ItemNumber == "ITEM001"); - resultList.Should().Contain(x => x.LotNumber == "LOT002" && x.ItemNumber == "ITEM002"); - resultList.Should().Contain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003"); + resultList.Count.ShouldBe(3); + resultList.ShouldContain(x => x.LotNumber == "LOT001" && x.ItemNumber == "ITEM001"); + resultList.ShouldContain(x => x.LotNumber == "LOT002" && x.ItemNumber == "ITEM002"); + resultList.ShouldContain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003"); } [Fact] @@ -58,7 +58,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -73,7 +73,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -85,7 +85,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -100,7 +100,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -115,7 +115,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -136,10 +136,10 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(3); - resultList.Should().Contain(x => x.LotNumber == "LOT001" && x.ItemNumber == null); - resultList.Should().Contain(x => x.LotNumber == null && x.ItemNumber == "ITEM002"); - resultList.Should().Contain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003"); + resultList.Count.ShouldBe(3); + resultList.ShouldContain(x => x.LotNumber == "LOT001" && x.ItemNumber == null); + resultList.ShouldContain(x => x.LotNumber == null && x.ItemNumber == "ITEM002"); + resultList.ShouldContain(x => x.LotNumber == "LOT003" && x.ItemNumber == "ITEM003"); } [Fact] @@ -163,9 +163,9 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(2); - resultList.Should().Contain(x => x.LotNumber == "LOT-001" && x.ItemNumber == "ITEM_001"); - resultList.Should().Contain(x => x.LotNumber == "LOT.002" && x.ItemNumber == "ITEM/002"); + resultList.Count.ShouldBe(2); + resultList.ShouldContain(x => x.LotNumber == "LOT-001" && x.ItemNumber == "ITEM_001"); + resultList.ShouldContain(x => x.LotNumber == "LOT.002" && x.ItemNumber == "ITEM/002"); } #endregion @@ -212,10 +212,10 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(3); - resultList.Should().Contain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == "MIS001" && x.MisRevision == "A"); - resultList.Should().Contain(x => x.ItemNumber == "ITEM002" && x.OperationNumber == "20" && x.MisNumber == "MIS002" && x.MisRevision == "B"); - resultList.Should().Contain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C"); + resultList.Count.ShouldBe(3); + resultList.ShouldContain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == "MIS001" && x.MisRevision == "A"); + resultList.ShouldContain(x => x.ItemNumber == "ITEM002" && x.OperationNumber == "20" && x.MisNumber == "MIS002" && x.MisRevision == "B"); + resultList.ShouldContain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C"); } [Fact] @@ -231,7 +231,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -246,7 +246,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -258,7 +258,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -273,7 +273,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -288,7 +288,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -309,10 +309,10 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(3); - resultList.Should().Contain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == null && x.MisRevision == null); - resultList.Should().Contain(x => x.ItemNumber == null && x.OperationNumber == null && x.MisNumber == "MIS002" && x.MisRevision == "B"); - resultList.Should().Contain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C"); + resultList.Count.ShouldBe(3); + resultList.ShouldContain(x => x.ItemNumber == "ITEM001" && x.OperationNumber == "10" && x.MisNumber == null && x.MisRevision == null); + resultList.ShouldContain(x => x.ItemNumber == null && x.OperationNumber == null && x.MisNumber == "MIS002" && x.MisRevision == "B"); + resultList.ShouldContain(x => x.ItemNumber == "ITEM003" && x.OperationNumber == "30" && x.MisNumber == "MIS003" && x.MisRevision == "C"); } [Fact] @@ -332,12 +332,12 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); + resultList.Count.ShouldBe(1); var result = resultList.First(); - result.ItemNumber.Should().Be("ITEM001"); - result.OperationNumber.Should().Be("10"); - result.MisNumber.Should().BeNull(); - result.MisRevision.Should().BeNull(); + result.ItemNumber.ShouldBe("ITEM001"); + result.OperationNumber.ShouldBe("10"); + result.MisNumber.ShouldBeNull(); + result.MisRevision.ShouldBeNull(); } [Fact] @@ -366,12 +366,12 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); + resultList.Count.ShouldBe(1); var result = resultList.First(); - result.ItemNumber.Should().Be("ITEM-001"); - result.OperationNumber.Should().Be("10A"); - result.MisNumber.Should().Be("MIS.001"); - result.MisRevision.Should().Be("A-1"); + result.ItemNumber.ShouldBe("ITEM-001"); + result.OperationNumber.ShouldBe("10A"); + result.MisNumber.ShouldBe("MIS.001"); + result.MisRevision.ShouldBe("A-1"); } #endregion @@ -394,7 +394,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().HaveCount(100); + results.Count().ShouldBe(100); } [Fact] @@ -419,7 +419,7 @@ public class ComplexTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().HaveCount(100); + results.Count().ShouldBe(100); } [Fact] @@ -436,9 +436,9 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); - resultList.First().LotNumber.Should().BeNull(); - resultList.First().ItemNumber.Should().BeNull(); + resultList.Count.ShouldBe(1); + resultList.First().LotNumber.ShouldBeNull(); + resultList.First().ItemNumber.ShouldBeNull(); } [Fact] @@ -455,12 +455,12 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); + resultList.Count.ShouldBe(1); var result = resultList.First(); - result.ItemNumber.Should().BeNull(); - result.OperationNumber.Should().BeNull(); - result.MisNumber.Should().BeNull(); - result.MisRevision.Should().BeNull(); + result.ItemNumber.ShouldBeNull(); + result.OperationNumber.ShouldBeNull(); + result.MisNumber.ShouldBeNull(); + result.MisRevision.ShouldBeNull(); } [Fact] @@ -479,9 +479,9 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); - resultList.First().LotNumber.Should().HaveLength(30); - resultList.First().ItemNumber.Should().HaveLength(128); + resultList.Count.ShouldBe(1); + resultList.First().LotNumber.Length.ShouldBe(30); + resultList.First().ItemNumber.Length.ShouldBe(128); } [Fact] @@ -502,12 +502,12 @@ public class ComplexTableFunctionTests : DatabaseTestBase // Assert var resultList = results.ToList(); - resultList.Should().HaveCount(1); + resultList.Count.ShouldBe(1); var result = resultList.First(); - result.ItemNumber.Should().HaveLength(128); - result.OperationNumber.Should().HaveLength(10); - result.MisNumber.Should().HaveLength(10); - result.MisRevision.Should().HaveLength(10); + result.ItemNumber.Length.ShouldBe(128); + result.OperationNumber.Length.ShouldBe(10); + result.MisNumber.Length.ShouldBe(10); + result.MisRevision.Length.ShouldBe(10); } #endregion diff --git a/NEW/tests/JdeScoping.Database.Tests/Functions/ScalarFunctionTests.cs b/NEW/tests/JdeScoping.Database.Tests/Functions/ScalarFunctionTests.cs index a9eb036..3e62370 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Functions/ScalarFunctionTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Functions/ScalarFunctionTests.cs @@ -1,7 +1,7 @@ using Dapper; -using FluentAssertions; using JdeScoping.Core.Models.Search; using JdeScoping.Database.Tests.Infrastructure; +using Shouldly; namespace JdeScoping.Database.Tests.Functions; @@ -28,7 +28,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeCloseTo(expectedDate, TimeSpan.FromSeconds(1)); + result.ShouldBeCloseTo(expectedDate, TimeSpan.FromSeconds(1)); } [Fact] @@ -44,7 +44,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -56,7 +56,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -71,7 +71,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -86,7 +86,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } #endregion @@ -107,7 +107,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeCloseTo(expectedDate, TimeSpan.FromSeconds(1)); + result.ShouldBeCloseTo(expectedDate, TimeSpan.FromSeconds(1)); } [Fact] @@ -123,7 +123,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -135,7 +135,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -150,7 +150,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -165,7 +165,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } #endregion @@ -185,7 +185,8 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeTrue(); + result.ShouldNotBeNull(); + result.Value.ShouldBeTrue(); } [Fact] @@ -201,7 +202,8 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeFalse(); + result.ShouldNotBeNull(); + result.Value.ShouldBeFalse(); } [Fact] @@ -213,7 +215,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -228,7 +230,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } [Fact] @@ -243,7 +245,7 @@ public class ScalarFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - result.Should().BeNull(); + result.ShouldBeNull(); } #endregion diff --git a/NEW/tests/JdeScoping.Database.Tests/Functions/SimpleTableFunctionTests.cs b/NEW/tests/JdeScoping.Database.Tests/Functions/SimpleTableFunctionTests.cs index b2c44d0..e9998e1 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Functions/SimpleTableFunctionTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Functions/SimpleTableFunctionTests.cs @@ -1,7 +1,7 @@ using Dapper; -using FluentAssertions; using JdeScoping.Core.Models.Search; using JdeScoping.Database.Tests.Infrastructure; +using Shouldly; namespace JdeScoping.Database.Tests.Functions; @@ -27,7 +27,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo([12345L, 67890L, 11111L]); + results.ShouldBeEquivalentTo([12345L, 67890L, 11111L]); } [Fact] @@ -43,7 +43,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -58,7 +58,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -70,7 +70,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -85,7 +85,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -100,7 +100,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -119,7 +119,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - null values should be filtered out - results.Should().BeEquivalentTo([12345L, 67890L]); + results.ShouldBeEquivalentTo([12345L, 67890L]); } #endregion @@ -139,7 +139,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo(["ITEM001", "ITEM002", "ITEM003"]); + results.ShouldBeEquivalentTo(["ITEM001", "ITEM002", "ITEM003"]); } [Fact] @@ -155,7 +155,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -170,7 +170,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -182,7 +182,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -197,7 +197,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -212,7 +212,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -228,7 +228,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - null values should be filtered out - results.Should().BeEquivalentTo(["ITEM001", "ITEM002"]); + results.ShouldBeEquivalentTo(["ITEM001", "ITEM002"]); } [Fact] @@ -244,7 +244,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo(["ITEM-001", "ITEM_002", "ITEM.003"]); + results.ShouldBeEquivalentTo(["ITEM-001", "ITEM_002", "ITEM.003"]); } #endregion @@ -264,7 +264,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo(["PC01", "PC02", "PC03"]); + results.ShouldBeEquivalentTo(["PC01", "PC02", "PC03"]); } [Fact] @@ -280,7 +280,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -295,7 +295,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -307,7 +307,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -322,7 +322,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -337,7 +337,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -353,7 +353,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - null values should be filtered out - results.Should().BeEquivalentTo(["PC01", "PC02"]); + results.ShouldBeEquivalentTo(["PC01", "PC02"]); } #endregion @@ -373,7 +373,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo(["WC001", "WC002", "WC003"]); + results.ShouldBeEquivalentTo(["WC001", "WC002", "WC003"]); } [Fact] @@ -389,7 +389,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -404,7 +404,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -416,7 +416,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -431,7 +431,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -446,7 +446,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -462,7 +462,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - null values should be filtered out - results.Should().BeEquivalentTo(["WC001", "WC002"]); + results.ShouldBeEquivalentTo(["WC001", "WC002"]); } #endregion @@ -482,7 +482,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEquivalentTo(["OP001", "OP002", "OP003"]); + results.ShouldBeEquivalentTo(["OP001", "OP002", "OP003"]); } [Fact] @@ -498,7 +498,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -513,7 +513,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -525,7 +525,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -540,7 +540,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -555,7 +555,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().BeEmpty(); + results.ShouldBeEmpty(); } [Fact] @@ -571,7 +571,7 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - null values should be filtered out - results.Should().BeEquivalentTo(["OP001", "OP002"]); + results.ShouldBeEquivalentTo(["OP001", "OP002"]); } #endregion @@ -592,8 +592,8 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - results.Should().HaveCount(1000); - results.Should().BeEquivalentTo(workOrders); + results.Count().ShouldBe(1000); + results.ShouldBeEquivalentTo(workOrders); } [Fact] @@ -610,8 +610,8 @@ public class SimpleTableFunctionTests : DatabaseTestBase new { SearchId = searchId }); // Assert - value should be truncated to 128 characters - results.Should().HaveCount(1); - results.First().Should().HaveLength(128); + results.Count().ShouldBe(1); + results.First().Length.ShouldBe(128); } #endregion diff --git a/NEW/tests/JdeScoping.Database.Tests/Infrastructure/ShouldlyExtensions.cs b/NEW/tests/JdeScoping.Database.Tests/Infrastructure/ShouldlyExtensions.cs new file mode 100644 index 0000000..a6cd335 --- /dev/null +++ b/NEW/tests/JdeScoping.Database.Tests/Infrastructure/ShouldlyExtensions.cs @@ -0,0 +1,45 @@ +using Shouldly; + +namespace JdeScoping.Database.Tests.Infrastructure; + +/// +/// Extension methods for Shouldly to support patterns from FluentAssertions. +/// +public static class ShouldlyExtensions +{ + /// + /// Asserts that a nullable DateTime is close to the expected value within a tolerance. + /// Equivalent to FluentAssertions' BeCloseTo. + /// + public static void ShouldBeCloseTo(this DateTime? actual, DateTime expected, TimeSpan tolerance) + { + actual.ShouldNotBeNull(); + Math.Abs((actual.Value - expected).TotalMilliseconds) + .ShouldBeLessThanOrEqualTo(tolerance.TotalMilliseconds); + } + + /// + /// Asserts that a DateTime is close to the expected value within a tolerance. + /// Equivalent to FluentAssertions' BeCloseTo. + /// + public static void ShouldBeCloseTo(this DateTime actual, DateTime expected, TimeSpan tolerance) + { + Math.Abs((actual - expected).TotalMilliseconds) + .ShouldBeLessThanOrEqualTo(tolerance.TotalMilliseconds); + } + + /// + /// Asserts that two collections contain equivalent items (same items, order independent). + /// Equivalent to FluentAssertions' BeEquivalentTo for simple types. + /// + public static void ShouldBeEquivalentTo(this IEnumerable actual, IEnumerable expected) + { + var actualList = actual.ToList(); + var expectedList = expected.ToList(); + actualList.Count.ShouldBe(expectedList.Count, "Collections should have the same count"); + foreach (var item in expectedList) + { + actualList.ShouldContain(item); + } + } +} diff --git a/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj b/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj index 8363820..eda758c 100644 --- a/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj +++ b/NEW/tests/JdeScoping.Database.Tests/JdeScoping.Database.Tests.csproj @@ -11,7 +11,6 @@ - diff --git a/NEW/tests/JdeScoping.Database.Tests/Procedures/ProcessMisStagingDataProcedureTests.cs b/NEW/tests/JdeScoping.Database.Tests/Procedures/ProcessMisStagingDataProcedureTests.cs index 77857c8..d699cab 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Procedures/ProcessMisStagingDataProcedureTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Procedures/ProcessMisStagingDataProcedureTests.cs @@ -1,6 +1,6 @@ using Dapper; -using FluentAssertions; using JdeScoping.Database.Tests.Infrastructure; +using Shouldly; namespace JdeScoping.Database.Tests.Procedures; @@ -57,7 +57,7 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase "SELECT COUNT(*) FROM MisData_Curr WHERE MisNumber = @MisNumber", new { MisNumber = testMisNumber }); - finalCurrCount.Should().Be(initialCurrCount, "Debug mode should not modify data"); + finalCurrCount.ShouldBe(initialCurrCount, "Debug mode should not modify data"); } finally { @@ -93,9 +93,11 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase WHERE MisNumber = @MisNumber", new { MisNumber = testMisNumber }); - record.Should().NotBeNull("Record should be inserted to MisData_Curr"); - ((string)record.Status).Should().Be("Current"); - ((DateTime?)record.ObsoleteDate).Should().BeNull(); + // Use Assert.NotNull instead of Shouldly for dynamic null check + // (Shouldly's .ShouldNotBeNull() fails with dynamic null due to runtime binding) + Assert.NotNull(record); + ((string)record.Status).ShouldBe("Current"); + ((DateTime?)record.ObsoleteDate).ShouldBeNull(); } finally { @@ -144,9 +146,9 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase WHERE MisNumber = @MisNumber AND RevID = 'A'", new { MisNumber = testMisNumber }); - histRecord.Should().NotBeNull("Old version should be moved to MisData_Hist"); - ((string)histRecord.Status).Should().Be("BackLevel"); - ((DateTime?)histRecord.ObsoleteDate).Should().NotBeNull(); + Assert.NotNull(histRecord); + ((string)histRecord.Status).ShouldBe("BackLevel"); + ((DateTime?)histRecord.ObsoleteDate).ShouldNotBeNull(); // Assert - new version should be in current with Current status var currRecord = await Connection.QuerySingleOrDefaultAsync( @@ -155,9 +157,9 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase WHERE MisNumber = @MisNumber AND RevID = 'B'", new { MisNumber = testMisNumber }); - currRecord.Should().NotBeNull("New version should be in MisData_Curr"); - ((string)currRecord.Status).Should().Be("Current"); - ((DateTime?)currRecord.ObsoleteDate).Should().BeNull(); + Assert.NotNull(currRecord); + ((string)currRecord.Status).ShouldBe("Current"); + ((DateTime?)currRecord.ObsoleteDate).ShouldBeNull(); } finally { @@ -192,7 +194,7 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase @"SELECT MisNumber FROM MisData_Curr WHERE MisNumber = @MisNumber", new { MisNumber = testMisNumber }); - record.Should().NotBeNull("Record should be inserted with IIS_ prefix removed"); + Assert.NotNull(record); } finally { @@ -212,6 +214,6 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase "EXEC dbo.usp_ProcessMisStagingData @SaveChanges = 1"); // Assert - await act.Should().NotThrowAsync(); + await Should.NotThrowAsync(act); } } diff --git a/NEW/tests/JdeScoping.Database.Tests/Procedures/StoredProcedureExistsTests.cs b/NEW/tests/JdeScoping.Database.Tests/Procedures/StoredProcedureExistsTests.cs index d40cd3d..d7b356e 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Procedures/StoredProcedureExistsTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Procedures/StoredProcedureExistsTests.cs @@ -1,6 +1,6 @@ using Dapper; -using FluentAssertions; using JdeScoping.Database.Tests.Infrastructure; +using Shouldly; namespace JdeScoping.Database.Tests.Procedures; @@ -28,42 +28,42 @@ public class StoredProcedureExistsTests : DatabaseTestBase public async Task usp_SubmitSearch_Exists() { var exists = await ProcedureExistsAsync("usp_SubmitSearch"); - exists.Should().BeTrue("usp_SubmitSearch should be created by migration 040"); + exists.ShouldBeTrue("usp_SubmitSearch should be created by migration 040"); } [Fact] public async Task usp_StartSearch_Exists() { var exists = await ProcedureExistsAsync("usp_StartSearch"); - exists.Should().BeTrue("usp_StartSearch should be created by migration 041"); + exists.ShouldBeTrue("usp_StartSearch should be created by migration 041"); } [Fact] public async Task usp_CompleteSearch_Exists() { var exists = await ProcedureExistsAsync("usp_CompleteSearch"); - exists.Should().BeTrue("usp_CompleteSearch should be created by migration 042"); + exists.ShouldBeTrue("usp_CompleteSearch should be created by migration 042"); } [Fact] public async Task usp_ResetPartialSearches_Exists() { var exists = await ProcedureExistsAsync("usp_ResetPartialSearches"); - exists.Should().BeTrue("usp_ResetPartialSearches should be created by migration 043"); + exists.ShouldBeTrue("usp_ResetPartialSearches should be created by migration 043"); } [Fact] public async Task usp_ValidateSearchCriteria_Exists() { var exists = await ProcedureExistsAsync("usp_ValidateSearchCriteria"); - exists.Should().BeTrue("usp_ValidateSearchCriteria should be created by migration 048"); + exists.ShouldBeTrue("usp_ValidateSearchCriteria should be created by migration 048"); } [Fact] public async Task usp_ProcessMisStagingData_Exists() { var exists = await ProcedureExistsAsync("usp_ProcessMisStagingData"); - exists.Should().BeTrue("usp_ProcessMisStagingData should be created by migration 049"); + exists.ShouldBeTrue("usp_ProcessMisStagingData should be created by migration 049"); } [Fact] @@ -86,7 +86,7 @@ public class StoredProcedureExistsTests : DatabaseTestBase WHERE schema_id = SCHEMA_ID('dbo') AND name LIKE 'usp_%'"); - actualCount.Should().BeGreaterThanOrEqualTo( + actualCount.ShouldBeGreaterThanOrEqualTo( expectedProcedures.Length, $"Database should have at least {expectedProcedures.Length} stored procedures"); } diff --git a/NEW/tests/JdeScoping.Database.Tests/Procedures/ValidateSearchCriteriaProcedureTests.cs b/NEW/tests/JdeScoping.Database.Tests/Procedures/ValidateSearchCriteriaProcedureTests.cs index 9148b73..3619689 100644 --- a/NEW/tests/JdeScoping.Database.Tests/Procedures/ValidateSearchCriteriaProcedureTests.cs +++ b/NEW/tests/JdeScoping.Database.Tests/Procedures/ValidateSearchCriteriaProcedureTests.cs @@ -1,8 +1,8 @@ using Dapper; -using FluentAssertions; using JdeScoping.Core.Models.Search; using JdeScoping.Database.Tests.Infrastructure; using Microsoft.Data.SqlClient; +using Shouldly; namespace JdeScoping.Database.Tests.Procedures; @@ -26,7 +26,7 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = searchId }); // Assert - await act.Should().NotThrowAsync(); + await Should.NotThrowAsync(act); } [Fact] @@ -38,9 +38,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = 99999 }); // Assert - var ex = await act.Should().ThrowAsync(); - ex.Which.Number.Should().Be(50001); - ex.Which.Message.Should().Contain("Search ID 99999 not found"); + var ex = await Should.ThrowAsync(act); + ex.Number.ShouldBe(50001); + ex.Message.ShouldContain("Search ID 99999 not found"); } [Fact] @@ -55,9 +55,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = searchId }); // Assert - var ex = await act.Should().ThrowAsync(); - ex.Which.Number.Should().Be(50002); - ex.Which.Message.Should().Contain("has no criteria"); + var ex = await Should.ThrowAsync(act); + ex.Number.ShouldBe(50002); + ex.Message.ShouldContain("has no criteria"); } [Fact] @@ -72,9 +72,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = searchId }); // Assert - var ex = await act.Should().ThrowAsync(); - ex.Which.Number.Should().Be(50002); - ex.Which.Message.Should().Contain("has no criteria"); + var ex = await Should.ThrowAsync(act); + ex.Number.ShouldBe(50002); + ex.Message.ShouldContain("has no criteria"); } [Fact] @@ -89,9 +89,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = searchId }); // Assert - var ex = await act.Should().ThrowAsync(); - ex.Which.Number.Should().Be(50003); - ex.Which.Message.Should().Contain("has invalid JSON"); + var ex = await Should.ThrowAsync(act); + ex.Number.ShouldBe(50003); + ex.Message.ShouldContain("has invalid JSON"); } [Fact] @@ -106,6 +106,6 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase new { SearchId = searchId }); // Assert - await act.Should().NotThrowAsync(); + await Should.NotThrowAsync(act); } }