Skip to content

Commit c4e49e4

Browse files
dfa1claude
andcommitted
test: add forEachInt, forEachDouble, forEachLong unit tests
Cover happy path, empty array, single element, and wrap-around (length > buffer capacity, the constant-encoding case). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8a16119 commit c4e49e4

3 files changed

Lines changed: 242 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package io.github.dfa1.vortex.core.array;
2+
3+
import io.github.dfa1.vortex.core.DType;
4+
import io.github.dfa1.vortex.core.PType;
5+
import org.junit.jupiter.api.Nested;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.lang.foreign.Arena;
9+
import java.lang.foreign.MemorySegment;
10+
import java.lang.foreign.ValueLayout;
11+
import java.nio.ByteOrder;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
17+
class DoubleArrayTest {
18+
19+
private static final ValueLayout.OfDouble LE_DOUBLE =
20+
ValueLayout.JAVA_DOUBLE_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
21+
22+
private static DoubleArray of(double... values) {
23+
MemorySegment seg = Arena.ofAuto().allocate((long) values.length * 8, 8);
24+
for (int i = 0; i < values.length; i++) {
25+
seg.setAtIndex(LE_DOUBLE, i, values[i]);
26+
}
27+
DType dtype = new DType.Primitive(PType.F64, false);
28+
return new DoubleArray(dtype, values.length, seg);
29+
}
30+
31+
@Nested
32+
class ForEachDouble {
33+
34+
@Test
35+
void visitsAllElementsInOrder() {
36+
// Given
37+
DoubleArray sut = of(1.1, 2.2, 3.3, 4.4);
38+
List<Double> collected = new ArrayList<>();
39+
40+
// When
41+
sut.forEachDouble(collected::add);
42+
43+
// Then
44+
assertThat(collected).containsExactly(1.1, 2.2, 3.3, 4.4);
45+
}
46+
47+
@Test
48+
void emptyArray_consumerNeverCalled() {
49+
// Given
50+
DoubleArray sut = of();
51+
List<Double> collected = new ArrayList<>();
52+
53+
// When
54+
sut.forEachDouble(collected::add);
55+
56+
// Then
57+
assertThat(collected).isEmpty();
58+
}
59+
60+
@Test
61+
void singleElement_consumerCalledOnce() {
62+
// Given
63+
DoubleArray sut = of(3.14);
64+
List<Double> collected = new ArrayList<>();
65+
66+
// When
67+
sut.forEachDouble(collected::add);
68+
69+
// Then
70+
assertThat(collected).containsExactly(3.14);
71+
}
72+
73+
@Test
74+
void logicalLengthExceedsCapacity_wrapsAround() {
75+
// Given — constant-encoding: 1-element buffer, logical length 3; all 3 visits yield same value
76+
MemorySegment seg = Arena.ofAuto().allocate(8, 8);
77+
seg.setAtIndex(LE_DOUBLE, 0, 2.71);
78+
DoubleArray sut = new DoubleArray(new DType.Primitive(PType.F64, false), 3, seg);
79+
List<Double> collected = new ArrayList<>();
80+
81+
// When
82+
sut.forEachDouble(collected::add);
83+
84+
// Then
85+
assertThat(collected).containsExactly(2.71, 2.71, 2.71);
86+
}
87+
}
88+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package io.github.dfa1.vortex.core.array;
2+
3+
import io.github.dfa1.vortex.core.DType;
4+
import io.github.dfa1.vortex.core.PType;
5+
import org.junit.jupiter.api.Nested;
6+
import org.junit.jupiter.api.Test;
7+
8+
import java.lang.foreign.Arena;
9+
import java.lang.foreign.MemorySegment;
10+
import java.lang.foreign.ValueLayout;
11+
import java.nio.ByteOrder;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
15+
import static org.assertj.core.api.Assertions.assertThat;
16+
17+
class IntArrayTest {
18+
19+
private static final ValueLayout.OfInt LE_INT =
20+
ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
21+
22+
private static IntArray of(int... values) {
23+
MemorySegment seg = Arena.ofAuto().allocate((long) values.length * 4, 4);
24+
for (int i = 0; i < values.length; i++) {
25+
seg.setAtIndex(LE_INT, i, values[i]);
26+
}
27+
DType dtype = new DType.Primitive(PType.I32, false);
28+
return new IntArray(dtype, values.length, seg);
29+
}
30+
31+
@Nested
32+
class ForEachInt {
33+
34+
@Test
35+
void visitsAllElementsInOrder() {
36+
// Given
37+
IntArray sut = of(10, 20, 30, 40);
38+
List<Integer> collected = new ArrayList<>();
39+
40+
// When
41+
sut.forEachInt(collected::add);
42+
43+
// Then
44+
assertThat(collected).containsExactly(10, 20, 30, 40);
45+
}
46+
47+
@Test
48+
void emptyArray_consumerNeverCalled() {
49+
// Given
50+
IntArray sut = of();
51+
List<Integer> collected = new ArrayList<>();
52+
53+
// When
54+
sut.forEachInt(collected::add);
55+
56+
// Then
57+
assertThat(collected).isEmpty();
58+
}
59+
60+
@Test
61+
void singleElement_consumerCalledOnce() {
62+
// Given
63+
IntArray sut = of(42);
64+
List<Integer> collected = new ArrayList<>();
65+
66+
// When
67+
sut.forEachInt(collected::add);
68+
69+
// Then
70+
assertThat(collected).containsExactly(42);
71+
}
72+
73+
@Test
74+
void logicalLengthExceedsCapacity_wrapsAround() {
75+
// Given — constant-encoding: 1-element buffer, logical length 4; all 4 visits yield same value
76+
MemorySegment seg = Arena.ofAuto().allocate(4, 4);
77+
seg.setAtIndex(LE_INT, 0, 7);
78+
IntArray sut = new IntArray(new DType.Primitive(PType.I32, false), 4, seg);
79+
List<Integer> collected = new ArrayList<>();
80+
81+
// When
82+
sut.forEachInt(collected::add);
83+
84+
// Then
85+
assertThat(collected).containsExactly(7, 7, 7, 7);
86+
}
87+
}
88+
}

core/src/test/java/io/github/dfa1/vortex/core/array/LongArrayTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import io.github.dfa1.vortex.core.DType;
44
import io.github.dfa1.vortex.core.PType;
5+
import org.junit.jupiter.api.Nested;
56
import org.junit.jupiter.api.Test;
67

78
import java.lang.foreign.Arena;
89
import java.lang.foreign.MemorySegment;
910
import java.lang.foreign.ValueLayout;
1011
import java.nio.ByteOrder;
12+
import java.util.ArrayList;
13+
import java.util.List;
1114

1215
import static org.assertj.core.api.Assertions.assertThat;
1316

@@ -25,6 +28,67 @@ private static LongArray of(long... values) {
2528
return new LongArray(dtype, values.length, seg);
2629
}
2730

31+
@Nested
32+
class ForEachLong {
33+
34+
@Test
35+
void visitsAllElementsInOrder() {
36+
// Given
37+
LongArray sut = of(100L, 200L, 300L);
38+
List<Long> collected = new ArrayList<>();
39+
40+
// When
41+
sut.forEachLong(collected::add);
42+
43+
// Then
44+
assertThat(collected).containsExactly(100L, 200L, 300L);
45+
}
46+
47+
@Test
48+
void emptyArray_consumerNeverCalled() {
49+
// Given
50+
LongArray sut = of();
51+
List<Long> collected = new ArrayList<>();
52+
53+
// When
54+
sut.forEachLong(collected::add);
55+
56+
// Then
57+
assertThat(collected).isEmpty();
58+
}
59+
60+
@Test
61+
void singleElement_consumerCalledOnce() {
62+
// Given
63+
LongArray sut = of(99L);
64+
List<Long> collected = new ArrayList<>();
65+
66+
// When
67+
sut.forEachLong(collected::add);
68+
69+
// Then
70+
assertThat(collected).containsExactly(99L);
71+
}
72+
73+
@Test
74+
void logicalLengthExceedsCapacity_wrapsAround() {
75+
// Given — constant-encoding: 1-element buffer, logical length 4; all 4 visits yield same value
76+
MemorySegment seg = Arena.ofAuto().allocate(8, 8);
77+
seg.setAtIndex(LE_LONG, 0, 42L);
78+
LongArray sut = new LongArray(new DType.Primitive(PType.I64, false), 4, seg);
79+
List<Long> collected = new ArrayList<>();
80+
81+
// When
82+
sut.forEachLong(collected::add);
83+
84+
// Then
85+
assertThat(collected).containsExactly(42L, 42L, 42L, 42L);
86+
}
87+
}
88+
89+
@Nested
90+
class Fold {
91+
2892
@Test
2993
void fold_sum_returnsCorrectTotal() {
3094
// Given
@@ -72,4 +136,6 @@ void fold_emptyArray_returnsIdentity() {
72136
// Then
73137
assertThat(result).isEqualTo(42L);
74138
}
139+
140+
} // Fold
75141
}

0 commit comments

Comments
 (0)