Skip to content

Commit 0aa886a

Browse files
committed
Feat: Add unit tests for SpanLinq Select, SelectMany, Max, and All
1 parent e69b745 commit 0aa886a

File tree

11 files changed

+2951
-2
lines changed

11 files changed

+2951
-2
lines changed

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqFirstExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static T First<T>(this in ReadOnlySpan<T> span, Func<T, bool> predicate)
3030
T element = span[i];
3131
if (predicate(element)) return element;
3232
}
33-
33+
3434
return default;
3535
}
3636

src/CodeOfChaos.Extensions/SpanLinq/SpanLinqSelectExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public static void Select<TSource, TResult>(
1515
Func<TSource, TResult> selector,
1616
Span<TResult> destination
1717
) {
18-
if (source.Length != destination.Length) throw new ArgumentException("Destination span is too small");
18+
if (source.Length > destination.Length) throw new ArgumentException("Destination span is too small");
1919

2020
for (int i = 0; i < source.Length; i++) {
2121
destination[i] = selector(source[i]);
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// ---------------------------------------------------------------------------------------------------------------------
2+
// Imports
3+
// ---------------------------------------------------------------------------------------------------------------------
4+
using CodeOfChaos.SpanLINQ;
5+
6+
namespace Tests.CodeOfChaos.Extensions.SpanLinq;
7+
// ---------------------------------------------------------------------------------------------------------------------
8+
// Code
9+
// ---------------------------------------------------------------------------------------------------------------------
10+
public class SpanLinqAllTests {
11+
private record TestItem(int Value);
12+
13+
[Test]
14+
public async Task All() {
15+
// Arrange
16+
Span<int> span = [2, 4, 6, 8];
17+
18+
// Act
19+
bool result = span.All(static x => x % 2 == 0);
20+
21+
// Assert
22+
await Assert.That(result).IsTrue();;
23+
}
24+
25+
[Test]
26+
public async Task All_Span_SomeElementsDoNotMatchPredicate_ShouldReturnFalse() {
27+
// Arrange
28+
Span<int> numbers = [2, 4, 5, 8];
29+
30+
// Act
31+
bool result = numbers.All(x => x % 2 == 0);
32+
33+
// Assert
34+
await Assert.That(result).IsFalse();
35+
}
36+
37+
[Test]
38+
public async Task All_Span_EmptySpan_ShouldReturnTrue() {
39+
// Arrange
40+
Span<int> emptySpan = [];
41+
42+
// Act
43+
bool result = emptySpan.All(x => x > 0);
44+
45+
// Assert
46+
await Assert.That(result).IsTrue();
47+
}
48+
49+
[Test]
50+
public async Task All_Span_SingleElementMatches_ShouldReturnTrue() {
51+
// Arrange
52+
Span<int> singleElement = [10];
53+
54+
// Act
55+
bool result = singleElement.All(x => x > 5);
56+
57+
// Assert
58+
await Assert.That(result).IsTrue();
59+
}
60+
61+
[Test]
62+
public async Task All_Span_SingleElementDoesNotMatch_ShouldReturnFalse() {
63+
// Arrange
64+
Span<int> singleElement = [3];
65+
66+
// Act
67+
bool result = singleElement.All(x => x > 5);
68+
69+
// Assert
70+
await Assert.That(result).IsFalse();
71+
}
72+
73+
[Test]
74+
public async Task All_ReadOnlySpan_AllElementsMatchPredicate_ShouldReturnTrue() {
75+
// Arrange
76+
ReadOnlySpan<int> numbers = [1, 3, 5, 7];
77+
78+
// Act
79+
bool result = numbers.All(x => x % 2 == 1);
80+
81+
// Assert
82+
await Assert.That(result).IsTrue();
83+
}
84+
85+
[Test]
86+
public async Task All_ReadOnlySpan_SomeElementsDoNotMatchPredicate_ShouldReturnFalse() {
87+
// Arrange
88+
ReadOnlySpan<int> numbers = [1, 3, 4, 7];
89+
90+
// Act
91+
bool result = numbers.All(x => x % 2 == 1);
92+
93+
// Assert
94+
await Assert.That(result).IsFalse();
95+
}
96+
97+
[Test]
98+
public async Task All_ReadOnlySpan_EmptySpan_ShouldReturnTrue() {
99+
// Arrange
100+
ReadOnlySpan<int> emptySpan = [];
101+
102+
// Act
103+
bool result = emptySpan.All(x => x < 0);
104+
105+
// Assert
106+
await Assert.That(result).IsTrue();
107+
}
108+
109+
[Test]
110+
public async Task All_WithCustomType_AllElementsMatchPredicate_ShouldReturnTrue() {
111+
// Arrange
112+
var items = new TestItem[] {
113+
new(10),
114+
new(20),
115+
new(30)
116+
};
117+
Span<TestItem> span = items;
118+
119+
// Act
120+
bool result = span.All(x => x.Value >= 10);
121+
122+
// Assert
123+
await Assert.That(result).IsTrue();
124+
}
125+
126+
[Test]
127+
public async Task All_WithCustomType_SomeElementsDoNotMatchPredicate_ShouldReturnFalse() {
128+
// Arrange
129+
var items = new TestItem[] {
130+
new(5),
131+
new(20),
132+
new(30)
133+
};
134+
Span<TestItem> span = items;
135+
136+
// Act
137+
bool result = span.All(x => x.Value >= 10);
138+
139+
// Assert
140+
await Assert.That(result).IsFalse();
141+
}
142+
143+
[Test]
144+
public async Task All_WithStringType_AllElementsMatchPredicate_ShouldReturnTrue() {
145+
// Arrange
146+
Span<string> words = ["hello", "world", "test"];
147+
148+
// Act
149+
bool result = words.All(x => x.Length >= 4);
150+
151+
// Assert
152+
await Assert.That(result).IsTrue();
153+
}
154+
155+
[Test]
156+
public async Task All_WithStringType_SomeElementsDoNotMatchPredicate_ShouldReturnFalse() {
157+
// Arrange
158+
Span<string> words = ["hi", "world", "test"];
159+
160+
// Act
161+
bool result = words.All(x => x.Length >= 4);
162+
163+
// Assert
164+
await Assert.That(result).IsFalse();
165+
}
166+
167+
[Test]
168+
public async Task All_WithNegativeNumbers_AllElementsMatchPredicate_ShouldReturnTrue() {
169+
// Arrange
170+
Span<int> numbers = [-5, -10, -15];
171+
172+
// Act
173+
bool result = numbers.All(x => x < 0);
174+
175+
// Assert
176+
await Assert.That(result).IsTrue();
177+
}
178+
179+
[Test]
180+
public async Task All_ShortCircuitEvaluation_ShouldStopOnFirstFalse() {
181+
// Arrange
182+
var callCount = 0;
183+
Span<int> numbers = [1, 2, 3, 4, 5];
184+
185+
// Act
186+
bool result = numbers.All(x => {
187+
callCount++;
188+
return x < 3;// Will be false for elements 3, 4, 5
189+
});
190+
191+
// Assert
192+
await Assert.That(result).IsFalse();
193+
await Assert.That(callCount).IsLessThanOrEqualTo(3);// Should stop early
194+
}
195+
196+
}

0 commit comments

Comments
 (0)