diff --git a/OmegaLeo.HelperLib.Tests/Extensions/IListExtensionsTests.cs b/OmegaLeo.HelperLib.Tests/Extensions/IListExtensionsTests.cs new file mode 100644 index 0000000..bc8cb99 --- /dev/null +++ b/OmegaLeo.HelperLib.Tests/Extensions/IListExtensionsTests.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using OmegaLeo.HelperLib.Extensions; + +namespace OmegaLeo.HelperLib.Tests.Extensions; + +public class IListExtensionsTests +{ + [Fact] + public void Swap_WithValidIndices_SwapsElements() + { + // Arrange + var list = new List { 1, 2, 3, 4 }; + + // Act + list.Swap(0, 2); + + // Assert + Assert.Equal(3, list[0]); + Assert.Equal(2, list[1]); + Assert.Equal(1, list[2]); + Assert.Equal(4, list[3]); + } + + [Fact] + public void Swap_WithItems_SwapsElementsByValue() + { + // Arrange + var list = new List { "A", "B", "C", "D" }; + + // Act + list.Swap("A", "C"); + + // Assert + Assert.Equal("C", list[0]); + Assert.Equal("B", list[1]); + Assert.Equal("A", list[2]); + Assert.Equal("D", list[3]); + } + + [Fact] + public void Replace_ExistingItem_ReplacesSuccessfully() + { + // Arrange + var list = new List { 1, 2, 3, 4 }; + + // Act + list.Replace(2, 20); + + // Assert + Assert.Equal(1, list[0]); + Assert.Equal(20, list[1]); + Assert.Equal(3, list[2]); + Assert.Equal(4, list[3]); + } + + [Fact] + public void Replace_NonExistingItem_DoesNotModifyList() + { + // Arrange + var list = new List { 1, 2, 3, 4 }; + var originalList = new List(list); + + // Act + list.Replace(99, 100); + + // Assert + Assert.Equal(originalList, list); + } + + [Fact] + public void Random_NonEmptyList_ReturnsElement() + { + // Arrange + var list = new List { 1, 2, 3, 4, 5 }; + + // Act + var result = list.Random(); + + // Assert + Assert.Contains(result, list); + } + + [Fact] + public void Random_WithCount_ReturnsCorrectNumberOfElements() + { + // Arrange + var list = new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + + // Act + var result = list.Random(3); + + // Assert + Assert.Equal(3, result.Count); + Assert.All(result, item => Assert.Contains(item, list)); + } + + [Fact] + public void Random_CountZero_ThrowsException() + { + // Arrange + var list = new List { 1, 2, 3 }; + + // Act & Assert + Assert.Throws(() => list.Random(0)); + } + + [Fact] + public void Random_NegativeCount_ThrowsException() + { + // Arrange + var list = new List { 1, 2, 3 }; + + // Act & Assert + Assert.Throws(() => list.Random(-1)); + } + + [Fact] + public void Shuffle_ModifiesListOrder() + { + // Arrange + var list = new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + var originalList = new List(list); + + // Act + list.Shuffle(); + + // Assert - List should contain same elements but likely in different order + Assert.Equal(originalList.Count, list.Count); + Assert.All(originalList, item => Assert.Contains(item, list)); + // Note: There's a tiny chance the shuffle returns the same order, but it's extremely unlikely with 10 elements + } + + [Fact] + public void Shuffle_EmptyList_DoesNotThrow() + { + // Arrange + var list = new List(); + + // Act & Assert + var exception = Record.Exception(() => list.Shuffle()); + Assert.Null(exception); + } + + [Fact] + public void Swap_SameIndex_DoesNotModifyList() + { + // Arrange + var list = new List { 1, 2, 3 }; + var originalList = new List(list); + + // Act + list.Swap(1, 1); + + // Assert + Assert.Equal(originalList, list); + } +} diff --git a/OmegaLeo.HelperLib.Tests/Extensions/MathExtensionsTests.cs b/OmegaLeo.HelperLib.Tests/Extensions/MathExtensionsTests.cs new file mode 100644 index 0000000..a6c69ed --- /dev/null +++ b/OmegaLeo.HelperLib.Tests/Extensions/MathExtensionsTests.cs @@ -0,0 +1,112 @@ +using System.Collections.Generic; +using System.Linq; +using OmegaLeo.HelperLib.Extensions; + +namespace OmegaLeo.HelperLib.Tests.Extensions; + +public class MathExtensionsTests +{ + [Fact] + public void AverageWithNullValidation_Int_WithValues_ReturnsCorrectAverage() + { + // Arrange + var numbers = new List { 1, 2, 3, 4 }; + + // Act + var result = numbers.AverageWithNullValidation(); + + // Assert + Assert.Equal(2, result); + } + + [Fact] + public void AverageWithNullValidation_Int_EmptyList_ReturnsZero() + { + // Arrange + var emptyList = new List(); + + // Act + var result = emptyList.AverageWithNullValidation(); + + // Assert + Assert.Equal(0, result); + } + + [Fact] + public void AverageWithNullValidation_Double_WithValues_ReturnsCorrectAverage() + { + // Arrange + var numbers = new List { 1.5, 2.5, 3.5 }; + + // Act + var result = numbers.AverageWithNullValidation(); + + // Assert + Assert.Equal(2.5, result); + } + + [Fact] + public void AverageWithNullValidation_Double_EmptyList_ReturnsZero() + { + // Arrange + var emptyList = new List(); + + // Act + var result = emptyList.AverageWithNullValidation(); + + // Assert + Assert.Equal(0.0, result); + } + + [Fact] + public void AverageWithNullValidation_Float_WithValues_ReturnsCorrectAverage() + { + // Arrange + var numbers = new List { 1.5f, 2.5f, 3.5f }; + + // Act + var result = numbers.AverageWithNullValidation(); + + // Assert + Assert.Equal(2.5f, result); + } + + [Fact] + public void AverageWithNullValidation_Float_EmptyList_ReturnsZero() + { + // Arrange + var emptyList = new List(); + + // Act + var result = emptyList.AverageWithNullValidation(); + + // Assert + Assert.Equal(0.0f, result); + } + + [Fact] + public void AverageWithNullValidation_Int_SingleValue_ReturnsThatValue() + { + // Arrange + var singleValue = new List { 5 }; + + // Act + var result = singleValue.AverageWithNullValidation(); + + // Assert + Assert.Equal(5, result); + } + + [Fact] + public void AverageWithNullValidation_Int_NegativeValues_ReturnsCorrectAverage() + { + // Arrange + var negativeNumbers = new List { -10, -20, -30 }; + + // Act + var result = negativeNumbers.AverageWithNullValidation(); + + // Assert + Assert.Equal(-20, result); + } +} diff --git a/OmegaLeo.HelperLib.Tests/Helpers/BenchmarkUtilityTests.cs b/OmegaLeo.HelperLib.Tests/Helpers/BenchmarkUtilityTests.cs new file mode 100644 index 0000000..27609aa --- /dev/null +++ b/OmegaLeo.HelperLib.Tests/Helpers/BenchmarkUtilityTests.cs @@ -0,0 +1,146 @@ +using System; +using System.Threading; +using OmegaLeo.HelperLib.Helpers; + +namespace OmegaLeo.HelperLib.Tests.Helpers; + +public class BenchmarkUtilityTests +{ + [Fact] + public void Record_ExecutesActionAndReturnsElapsedTime() + { + // Arrange + var executed = false; + + // Act + var elapsed = BenchmarkUtility.Record(() => + { + executed = true; + Thread.Sleep(10); // Small delay to ensure measurable time + }); + + // Assert + Assert.True(executed); + Assert.True(elapsed >= 0); // Should have some elapsed time + } + + [Fact] + public void RecordAndSaveToResults_SavesResultsUnderKey() + { + // Arrange + var key = "test-benchmark-" + Guid.NewGuid(); + + // Act + var elapsed = BenchmarkUtility.RecordAndSaveToResults(key, () => + { + Thread.Sleep(5); + }); + + var results = BenchmarkUtility.GetResults(key); + + // Assert + Assert.True(elapsed >= 0); + Assert.NotNull(results); + Assert.Single(results); + Assert.Equal(elapsed, results[0]); + } + + [Fact] + public void StartAndStop_RecordsElapsedTime() + { + // Arrange + var key = "start-stop-test-" + Guid.NewGuid(); + + // Act + BenchmarkUtility.Start(key); + Thread.Sleep(10); + BenchmarkUtility.Stop(key); + + var results = BenchmarkUtility.GetResults(key); + + // Assert + Assert.NotNull(results); + Assert.Single(results); + Assert.True(results[0] >= 0); + } + + [Fact] + public void Start_MultipleTimesWithSameKey_RecordsMultipleResults() + { + // Arrange + var key = "multiple-runs-" + Guid.NewGuid(); + + // Act + BenchmarkUtility.Start(key); + Thread.Sleep(5); + BenchmarkUtility.Stop(key); + + BenchmarkUtility.Start(key); + Thread.Sleep(5); + BenchmarkUtility.Stop(key); + + var results = BenchmarkUtility.GetResults(key); + + // Assert + Assert.NotNull(results); + Assert.Equal(2, results.Count); + } + + [Fact] + public void ClearResults_RemovesAllBenchmarks() + { + // Arrange + var key1 = "clear-test-1-" + Guid.NewGuid(); + var key2 = "clear-test-2-" + Guid.NewGuid(); + + BenchmarkUtility.RecordAndSaveToResults(key1, () => Thread.Sleep(1)); + BenchmarkUtility.RecordAndSaveToResults(key2, () => Thread.Sleep(1)); + + // Act + BenchmarkUtility.ClearResults(); + + var results1 = BenchmarkUtility.GetResults(key1); + var results2 = BenchmarkUtility.GetResults(key2); + + // Assert + Assert.NotNull(results1); + Assert.Empty(results1); + Assert.NotNull(results2); + Assert.Empty(results2); + } + + [Fact] + public void GetAllResults_ReturnsAllBenchmarkData() + { + // Arrange + BenchmarkUtility.ClearResults(); // Clean slate + + var key1 = "all-results-1-" + Guid.NewGuid(); + var key2 = "all-results-2-" + Guid.NewGuid(); + + BenchmarkUtility.RecordAndSaveToResults(key1, () => Thread.Sleep(1)); + BenchmarkUtility.RecordAndSaveToResults(key2, () => Thread.Sleep(1)); + + // Act + var allResults = BenchmarkUtility.GetAllResults(); + + // Assert + Assert.NotNull(allResults); + Assert.True(allResults.ContainsKey(key1)); + Assert.True(allResults.ContainsKey(key2)); + } + + [Fact] + public void GetResults_NonExistentKey_ReturnsEmptyList() + { + // Arrange + var nonExistentKey = "non-existent-" + Guid.NewGuid(); + + // Act + var results = BenchmarkUtility.GetResults(nonExistentKey); + + // Assert + Assert.NotNull(results); + Assert.Empty(results); + } +} diff --git a/OmegaLeo.HelperLib.Tests/Models/NeoDictionaryTests.cs b/OmegaLeo.HelperLib.Tests/Models/NeoDictionaryTests.cs new file mode 100644 index 0000000..16cd3c9 --- /dev/null +++ b/OmegaLeo.HelperLib.Tests/Models/NeoDictionaryTests.cs @@ -0,0 +1,263 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using OmegaLeo.HelperLib.Models; + +namespace OmegaLeo.HelperLib.Tests.Models; + +public class NeoDictionaryTests +{ + [Fact] + public void Add_AddsItemSuccessfully() + { + // Arrange + var dict = new NeoDictionary(); + + // Act + dict.Add("one", 1); + dict.Add("two", 2); + + // Assert + Assert.Equal(2, dict.Items.Count); + Assert.Equal("one", dict.Items[0].Key); + Assert.Equal(1, dict.Items[0].Value); + } + + [Fact] + public void TryGetValue_ExistingKey_ReturnsTrue() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("test", 42); + + // Act + var result = dict.TryGetValue("test", out var value); + + // Assert + Assert.True(result); + Assert.Equal(42, value); + } + + [Fact] + public void TryGetValue_NonExistingKey_ReturnsFalse() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("test", 42); + + // Act + var result = dict.TryGetValue("nonexistent", out var value); + + // Assert + Assert.False(result); + Assert.Equal(default(int), value); + } + + [Fact] + public void TryGetValueFromIndex_ValidIndex_ReturnsTrue() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("first", 1); + dict.Add("second", 2); + + // Act + var result = dict.TryGetValueFromIndex(1, out var value); + + // Assert + Assert.True(result); + Assert.Equal(2, value); + } + + [Fact] + public void TryGetValueFromIndex_InvalidIndex_ReturnsFalse() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("first", 1); + + // Act + var result = dict.TryGetValueFromIndex(5, out var value); + + // Assert + Assert.False(result); + Assert.Equal(default(int), value); + } + + [Fact] + public void ToDictionary_ConvertsToStandardDictionary() + { + // Arrange + var neoDict = new NeoDictionary(); + neoDict.Add("a", 1); + neoDict.Add("b", 2); + + // Act + var standardDict = neoDict.ToDictionary(); + + // Assert + Assert.Equal(2, standardDict.Count); + Assert.Equal(1, standardDict["a"]); + Assert.Equal(2, standardDict["b"]); + } + + [Fact] + public void ImplicitConversion_ConvertsToStandardDictionary() + { + // Arrange + var neoDict = new NeoDictionary(); + neoDict.Add("x", 10); + neoDict.Add("y", 20); + + // Act + Dictionary standardDict = neoDict; + + // Assert + Assert.Equal(2, standardDict.Count); + Assert.Equal(10, standardDict["x"]); + Assert.Equal(20, standardDict["y"]); + } + + [Fact] + public void Any_EmptyDictionary_ReturnsFalse() + { + // Arrange + var dict = new NeoDictionary(); + + // Act + var result = dict.Any(); + + // Assert + Assert.False(result); + } + + [Fact] + public void Any_WithItems_ReturnsTrue() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("item", 1); + + // Act + var result = dict.Any(); + + // Assert + Assert.True(result); + } + + [Fact] + public void Any_WithPredicate_FiltersCorrectly() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("one", 1); + dict.Add("five", 5); + dict.Add("ten", 10); + + // Act + var result = dict.Any(item => item.Value > 5); + + // Assert + Assert.True(result); + } + + [Fact] + public void Where_FiltersItems() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("one", 1); + dict.Add("two", 2); + dict.Add("three", 3); + dict.Add("four", 4); + + // Act + var filtered = dict.Where(item => item.Value > 2); + + // Assert + Assert.Equal(2, filtered.Count()); + Assert.All(filtered, item => Assert.True(item.Value > 2)); + } + + [Fact] + public void FirstOrDefault_EmptyDictionary_ReturnsNull() + { + // Arrange + var dict = new NeoDictionary(); + + // Act + var result = dict.FirstOrDefault(); + + // Assert + Assert.Null(result); + } + + [Fact] + public void FirstOrDefault_WithItems_ReturnsFirstItem() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("first", 1); + dict.Add("second", 2); + + // Act + var result = dict.FirstOrDefault(); + + // Assert + Assert.NotNull(result); + Assert.Equal("first", result.Key); + Assert.Equal(1, result.Value); + } + + [Fact] + public void LastOrDefault_WithItems_ReturnsLastItem() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("first", 1); + dict.Add("second", 2); + dict.Add("third", 3); + + // Act + var result = dict.LastOrDefault(); + + // Assert + Assert.NotNull(result); + Assert.Equal("third", result.Key); + Assert.Equal(3, result.Value); + } + + [Fact] + public void AddRange_FromNeoDictionary_AddsAllItems() + { + // Arrange + var dict1 = new NeoDictionary(); + dict1.Add("a", 1); + dict1.Add("b", 2); + + var dict2 = new NeoDictionary(); + dict2.Add("c", 3); + + // Act + dict2.AddRange(dict1); + + // Assert + Assert.Equal(3, dict2.Items.Count); + } + + [Fact] + public void Count_ReturnsCorrectCount() + { + // Arrange + var dict = new NeoDictionary(); + dict.Add("one", 1); + dict.Add("two", 2); + dict.Add("three", 3); + + // Act + var count = dict.Count(); + + // Assert + Assert.Equal(3, count); + } +} diff --git a/OmegaLeo.HelperLib.Tests/OmegaLeo.HelperLib.Tests.csproj b/OmegaLeo.HelperLib.Tests/OmegaLeo.HelperLib.Tests.csproj new file mode 100644 index 0000000..9421774 --- /dev/null +++ b/OmegaLeo.HelperLib.Tests/OmegaLeo.HelperLib.Tests.csproj @@ -0,0 +1,27 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + diff --git a/OmegaLeo.HelperLib.sln b/OmegaLeo.HelperLib.sln index 4d5071e..938bd8a 100755 --- a/OmegaLeo.HelperLib.sln +++ b/OmegaLeo.HelperLib.sln @@ -36,6 +36,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Shared", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.XmlDocGenerator", "OmegaLeo.HelperLib.XmlDocGenerator\OmegaLeo.HelperLib.XmlDocGenerator.csproj", "{1BB073B8-F03B-4F9A-A526-F38CB3800AA5}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Tests", "OmegaLeo.HelperLib.Tests\OmegaLeo.HelperLib.Tests.csproj", "{55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -166,6 +168,18 @@ Global {1BB073B8-F03B-4F9A-A526-F38CB3800AA5}.Release|x64.Build.0 = Release|Any CPU {1BB073B8-F03B-4F9A-A526-F38CB3800AA5}.Release|x86.ActiveCfg = Release|Any CPU {1BB073B8-F03B-4F9A-A526-F38CB3800AA5}.Release|x86.Build.0 = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|x64.ActiveCfg = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|x64.Build.0 = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|x86.ActiveCfg = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Debug|x86.Build.0 = Debug|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|Any CPU.Build.0 = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|x64.ActiveCfg = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|x64.Build.0 = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|x86.ActiveCfg = Release|Any CPU + {55C4F738-3B98-42D6-BCD2-6A9D6E0FC07D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE