using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; using SqrtSpace.SpaceTime.Collections; using Xunit; namespace SqrtSpace.SpaceTime.Tests.Collections; public class AdaptiveListTests { [Fact] public void AdaptiveList_StartsAsArray() { // Arrange & Act var list = new AdaptiveList(); list.Add(1); list.Add(2); list.Add(3); // Assert list.Count.Should().Be(3); list.CurrentImplementation.Should().Be("List"); list[0].Should().Be(1); list[1].Should().Be(2); list[2].Should().Be(3); } [Fact] public void AdaptiveList_TransitionsToList() { // Arrange var list = new AdaptiveList(); // Act - Add items beyond array threshold for (int i = 0; i < 20; i++) // ArrayThreshold is typically 16 { list.Add(i); } // Assert list.CurrentImplementation.Should().Be("List"); list.Count.Should().Be(20); list[10].Should().Be(10); } [Fact] public void AdaptiveList_TransitionsToSegmented() { // Arrange var list = new AdaptiveList(); // Act - Add items beyond list threshold for (int i = 0; i < 15_000; i++) // ListThreshold is typically 10,000 { list.Add(i); } // Assert // Note: AdaptiveList doesn't have SegmentedList implementation // list.CurrentImplementation.Should().Be("SegmentedList"); list.Count.Should().Be(15_000); list[7500].Should().Be(7500); } [Fact] public void AdaptiveList_Insert_InsertsAtCorrectPosition() { // Arrange var list = new AdaptiveList(); list.Add("first"); list.Add("third"); // Act list.Insert(1, "second"); // Assert list.Count.Should().Be(3); list[0].Should().Be("first"); list[1].Should().Be("second"); list[2].Should().Be("third"); } [Fact] public void AdaptiveList_RemoveAt_RemovesCorrectItem() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { 1, 2, 3, 4, 5 }); // Act list.RemoveAt(2); // Assert list.Count.Should().Be(4); list.Should().BeEquivalentTo(new[] { 1, 2, 4, 5 }); } [Fact] public void AdaptiveList_Remove_RemovesFirstOccurrence() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { 1, 2, 3, 2, 4 }); // Act var removed = list.Remove(2); // Assert removed.Should().BeTrue(); list.Count.Should().Be(4); list.Should().BeEquivalentTo(new[] { 1, 3, 2, 4 }); } [Fact] public void AdaptiveList_IndexOf_FindsCorrectIndex() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { "apple", "banana", "cherry", "date" }); // Act var index = list.IndexOf("cherry"); // Assert index.Should().Be(2); } [Fact] public void AdaptiveList_IndexOf_ReturnsNegativeOneForNotFound() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { "apple", "banana", "cherry" }); // Act var index = list.IndexOf("date"); // Assert index.Should().Be(-1); } [Fact] public void AdaptiveList_Contains_ReturnsTrueForExisting() { // Arrange var list = new AdaptiveList(); list.AddRange(Enumerable.Range(1, 100)); // Act & Assert list.Contains(50).Should().BeTrue(); list.Contains(101).Should().BeFalse(); } [Fact] public void AdaptiveList_Clear_RemovesAllItems() { // Arrange var list = new AdaptiveList(); list.AddRange(Enumerable.Range(1, 50)); // Act list.Clear(); // Assert list.Count.Should().Be(0); list.CurrentImplementation.Should().Be("List"); } [Fact] public void AdaptiveList_CopyTo_CopiesAllItems() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { 1, 2, 3, 4, 5 }); var array = new int[8]; // Act list.CopyTo(array, 2); // Assert array.Should().BeEquivalentTo(new[] { 0, 0, 1, 2, 3, 4, 5, 0 }); } [Fact] public void AdaptiveList_GetEnumerator_EnumeratesAllItems() { // Arrange var list = new AdaptiveList(); var expected = Enumerable.Range(1, 10).ToList(); list.AddRange(expected); // Act var result = new List(); foreach (var item in list) { result.Add(item); } // Assert result.Should().BeEquivalentTo(expected); } [Fact] public void AdaptiveList_IndexerSet_UpdatesValue() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { "one", "two", "three" }); // Act list[1] = "TWO"; // Assert list[1].Should().Be("TWO"); list.Count.Should().Be(3); } [Fact] public void AdaptiveList_IndexOutOfRange_ThrowsException() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { 1, 2, 3 }); // Act & Assert var action1 = () => _ = list[-1]; action1.Should().Throw(); var action2 = () => _ = list[3]; action2.Should().Throw(); } [Fact] public void AdaptiveList_AddRange_AddsMultipleItems() { // Arrange var list = new AdaptiveList(); var items = Enumerable.Range(1, 100).ToList(); // Act list.AddRange(items); // Assert list.Count.Should().Be(100); list.Should().BeEquivalentTo(items); } [Fact] public void AdaptiveList_DataPersistenceAcrossTransitions() { // Arrange var list = new AdaptiveList(); var testData = Enumerable.Range(0, 100) .Select(i => $"item{i}") .ToList(); // Act - Add data forcing transitions foreach (var item in testData) { list.Add(item); } // Assert - Verify all data is preserved list.Count.Should().Be(100); for (int i = 0; i < 100; i++) { list[i].Should().Be($"item{i}"); } } // Commented out: AdaptiveList doesn't have Sort() method // [Fact] // public void AdaptiveList_Sort_SortsItems() // { // // Arrange // var list = new AdaptiveList(); // var random = new Random(42); // var items = Enumerable.Range(1, 50).OrderBy(_ => random.Next()).ToList(); // list.AddRange(items); // // Act // list.Sort(); // // Assert // list.Should().BeInAscendingOrder(); // } // Commented out: AdaptiveList doesn't have Sort(IComparer) method // [Fact] // public void AdaptiveList_Sort_WithComparer_UsesComparer() // { // // Arrange // var list = new AdaptiveList(); // list.AddRange(new[] { "apple", "Banana", "cherry", "Date" }); // // Act // list.Sort(StringComparer.OrdinalIgnoreCase); // // Assert // list.Should().BeEquivalentTo(new[] { "apple", "Banana", "cherry", "Date" }); // } // Commented out: AdaptiveList doesn't have Reverse() method // [Fact] // public void AdaptiveList_Reverse_ReversesOrder() // { // // Arrange // var list = new AdaptiveList(); // list.AddRange(new[] { 1, 2, 3, 4, 5 }); // // Act // list.Reverse(); // // Assert // list.Should().BeEquivalentTo(new[] { 5, 4, 3, 2, 1 }); // } [Fact] public void AdaptiveList_ToArray_ReturnsArray() { // Arrange var list = new AdaptiveList(); list.AddRange(new[] { 1, 2, 3, 4, 5 }); // Act // AdaptiveList doesn't have ToArray(), but we can use LINQ var array = list.ToArray(); // Assert array.Should().BeEquivalentTo(new[] { 1, 2, 3, 4, 5 }); array.Should().BeOfType(); } [Fact] public void AdaptiveList_FindAll_ReturnsMatchingItems() { // Arrange var list = new AdaptiveList(); list.AddRange(Enumerable.Range(1, 20)); // Act // AdaptiveList doesn't have FindAll(), use LINQ Where instead var evens = list.Where(x => x % 2 == 0).ToList(); // Assert evens.Should().HaveCount(10); evens.Should().BeEquivalentTo(new[] { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }); } [Fact] public void AdaptiveList_RemoveAll_RemovesMatchingItems() { // Arrange var list = new AdaptiveList(); list.AddRange(Enumerable.Range(1, 10)); // Act // AdaptiveList doesn't have RemoveAll(), manually remove matching items var toRemove = list.Where(x => x % 2 == 0).ToList(); var removed = 0; foreach (var item in toRemove) { if (list.Remove(item)) removed++; } // Assert removed.Should().Be(5); list.Should().BeEquivalentTo(new[] { 1, 3, 5, 7, 9 }); } // Commented out: AdaptiveList doesn't have Capacity property // [Fact] // public void AdaptiveList_WithInitialCapacity_PreallocatesSpace() // { // // Arrange & Act // var list = new AdaptiveList(100); // // Assert // list.Count.Should().Be(0); // list.Capacity.Should().BeGreaterOrEqualTo(100); // } // Commented out: AdaptiveList doesn't have TrimExcess() method or Capacity property // [Fact] // public void AdaptiveList_TrimExcess_ReducesCapacity() // { // // Arrange // var list = new AdaptiveList(100); // list.AddRange(new[] { 1, 2, 3, 4, 5 }); // // Act // list.TrimExcess(); // // Assert // list.Count.Should().Be(5); // list.Capacity.Should().BeLessThan(100); // } }