Skip to content

Commit ba5f7b4

Browse files
committed
better tests
Signed-off-by: Connor Tsui <[email protected]>
1 parent 1b32f6c commit ba5f7b4

File tree

1 file changed

+83
-202
lines changed

1 file changed

+83
-202
lines changed
Lines changed: 83 additions & 202 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: Apache-2.0
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

4+
use vortex_dtype::NativePType;
45
use vortex_vector::VectorMutOps;
6+
use vortex_vector::VectorOps;
57
use vortex_vector::bool::BoolVector;
68
use vortex_vector::bool::BoolVectorMut;
79
use vortex_vector::primitive::PVector;
@@ -10,137 +12,75 @@ use vortex_vector::primitive::PrimitiveVector;
1012

1113
use crate::take::Take;
1214

13-
/// Tests `Take` on `PVector` with mixed validity in both data and indices.
14-
///
15-
/// This test covers:
16-
/// - Taking from a vector with some null values.
17-
/// - Using indices that have some null values.
18-
/// - Verifying that nulls in the data propagate correctly.
19-
/// - Verifying that nulls in indices result in null outputs.
20-
/// - Using non-sequential indices to test the general case.
15+
/// Helper to collect a `PVector` into a `Vec<Option<T>>` for easy comparison.
16+
fn collect_pvector<T: NativePType>(v: &PVector<T>) -> Vec<Option<T>> {
17+
(0..v.len()).map(|i| v.get(i).copied()).collect()
18+
}
19+
20+
/// Helper to collect a `BoolVector` into a `Vec<Option<bool>>` for easy comparison.
21+
fn collect_bool_vector(v: &BoolVector) -> Vec<Option<bool>> {
22+
(0..v.len()).map(|i| v.get(i)).collect()
23+
}
24+
2125
#[test]
2226
fn test_pvector_take_with_nullable_indices() {
23-
// Data: [10, null, 30, 40, null, 60]
24-
let data: PVectorMut<i32> = [Some(10), None, Some(30), Some(40), None, Some(60)]
25-
.into_iter()
26-
.collect();
27-
let data = data.freeze();
28-
29-
// Indices: [0, null, 2, 5, null] (u32 indices with nulls)
30-
let indices: PVectorMut<u32> = [Some(0), None, Some(2), Some(5), None]
31-
.into_iter()
32-
.collect();
33-
let indices = indices.freeze();
27+
let data: PVector<i32> =
28+
PVectorMut::from_iter([Some(10), None, Some(30), Some(40), None, Some(60)]).freeze();
29+
let indices: PVector<u32> =
30+
PVectorMut::from_iter([Some(0), None, Some(2), Some(5), None]).freeze();
3431

3532
let result = (&data).take(&indices);
3633

37-
// Expected: [10, null, 30, 60, null]
38-
// - Index 0 -> data[0] = 10 (valid)
39-
// - Index null -> null (null index produces null)
40-
// - Index 2 -> data[2] = 30 (valid)
41-
// - Index 5 -> data[5] = 60 (valid)
42-
// - Index null -> null (null index produces null)
43-
assert_eq!(result.get(0), Some(&10));
44-
assert_eq!(result.get(1), None); // Null index.
45-
assert_eq!(result.get(2), Some(&30));
46-
assert_eq!(result.get(3), Some(&60));
47-
assert_eq!(result.get(4), None); // Null index.
34+
assert_eq!(
35+
collect_pvector(&result),
36+
vec![Some(10), None, Some(30), Some(60), None]
37+
);
4838
}
4939

50-
/// Tests `Take` on `PVector` using `PrimitiveVector` indices (type-erased).
51-
///
52-
/// This ensures the generic `Take<PrimitiveVector>` impl works correctly by dispatching to the
53-
/// typed implementation.
5440
#[test]
5541
fn test_pvector_take_with_primitive_vector_indices() {
56-
// Data: [100, 200, null, 400, 500]
57-
let data: PVectorMut<i64> = [Some(100), Some(200), None, Some(400), Some(500)]
58-
.into_iter()
59-
.collect();
60-
let data = data.freeze();
61-
62-
// Indices as PrimitiveVector (u16): [4, 2, 0, 1]
63-
let indices: PVectorMut<u16> = [4u16, 2, 0, 1].into_iter().collect();
64-
let indices: PrimitiveVector = indices.freeze().into();
42+
let data: PVector<i64> =
43+
PVectorMut::from_iter([Some(100), Some(200), None, Some(400), Some(500)]).freeze();
44+
let indices: PrimitiveVector = PVectorMut::from_iter([4u16, 2, 0, 1]).freeze().into();
6545

6646
let result: PVector<i64> = (&data).take(&indices);
6747

68-
// Expected: [500, null, 100, 200]
69-
assert_eq!(result.get(0), Some(&500));
70-
assert_eq!(result.get(1), None); // data[2] is null.
71-
assert_eq!(result.get(2), Some(&100));
72-
assert_eq!(result.get(3), Some(&200));
48+
assert_eq!(
49+
collect_pvector(&result),
50+
vec![Some(500), None, Some(100), Some(200)]
51+
);
7352
}
7453

75-
/// Tests `Take` on `BoolVector` with mixed validity in both data and indices.
76-
///
77-
/// This test covers:
78-
/// - Taking from a boolean vector with some null values.
79-
/// - Using indices that have some null values.
80-
/// - Verifying that nulls in the data propagate correctly.
81-
/// - Verifying that nulls in indices result in null outputs.
8254
#[test]
8355
fn test_bool_vector_take_with_nullable_indices() {
84-
// Data: [true, null, false, true, null, false]
85-
let data: BoolVectorMut = [Some(true), None, Some(false), Some(true), None, Some(false)]
86-
.into_iter()
87-
.collect();
88-
let data = data.freeze();
89-
90-
// Indices: [5, null, 0, 3, null, 2] (u32 indices with nulls)
91-
let indices: PVectorMut<u32> = [Some(5), None, Some(0), Some(3), None, Some(2)]
92-
.into_iter()
93-
.collect();
94-
let indices = indices.freeze();
56+
let data: BoolVector =
57+
BoolVectorMut::from_iter([Some(true), None, Some(false), Some(true), None, Some(false)])
58+
.freeze();
59+
let indices: PVector<u32> =
60+
PVectorMut::from_iter([Some(5), None, Some(0), Some(3), None, Some(2)]).freeze();
9561

9662
let result = (&data).take(&indices);
9763

98-
// Expected: [false, null, true, true, null, false]
99-
// - Index 5 -> data[5] = false (valid)
100-
// - Index null -> null (null index produces null)
101-
// - Index 0 -> data[0] = true (valid)
102-
// - Index 3 -> data[3] = true (valid)
103-
// - Index null -> null (null index produces null)
104-
// - Index 2 -> data[2] = false (valid)
105-
assert_eq!(result.get(0), Some(false));
106-
assert_eq!(result.get(1), None); // Null index.
107-
assert_eq!(result.get(2), Some(true));
108-
assert_eq!(result.get(3), Some(true));
109-
assert_eq!(result.get(4), None); // Null index.
110-
assert_eq!(result.get(5), Some(false));
64+
assert_eq!(
65+
collect_bool_vector(&result),
66+
vec![Some(false), None, Some(true), Some(true), None, Some(false)]
67+
);
11168
}
11269

113-
/// Tests `Take` on `BoolVector` using `PrimitiveVector` indices (type-erased).
114-
///
115-
/// This ensures the generic `Take<PrimitiveVector>` impl works correctly for `BoolVector`.
11670
#[test]
11771
fn test_bool_vector_take_with_primitive_vector_indices() {
118-
// Data: [true, false, null, true, false]
119-
let data: BoolVectorMut = [Some(true), Some(false), None, Some(true), Some(false)]
120-
.into_iter()
121-
.collect();
122-
let data = data.freeze();
123-
124-
// Indices as PrimitiveVector (u64): [4, 2, 1, 0, 3]
125-
let indices: PVectorMut<u64> = [4u64, 2, 1, 0, 3].into_iter().collect();
126-
let indices: PrimitiveVector = indices.freeze().into();
72+
let data: BoolVector =
73+
BoolVectorMut::from_iter([Some(true), Some(false), None, Some(true), Some(false)]).freeze();
74+
let indices: PrimitiveVector = PVectorMut::from_iter([4u64, 2, 1, 0, 3]).freeze().into();
12775

12876
let result: BoolVector = (&data).take(&indices);
12977

130-
// Expected: [false, null, false, true, true]
131-
assert_eq!(result.get(0), Some(false)); // data[4]
132-
assert_eq!(result.get(1), None); // data[2] is null.
133-
assert_eq!(result.get(2), Some(false)); // data[1]
134-
assert_eq!(result.get(3), Some(true)); // data[0]
135-
assert_eq!(result.get(4), Some(true)); // data[3]
78+
assert_eq!(
79+
collect_bool_vector(&result),
80+
vec![Some(false), None, Some(false), Some(true), Some(true)]
81+
);
13682
}
13783

138-
/// Tests `Take` on `BitBuffer` covering both code paths.
139-
///
140-
/// This test covers:
141-
/// - The `take_byte_bool` path (small buffer, len <= 4096).
142-
/// - The `take_bool` path (large buffer, len > 4096).
143-
/// - Non-sequential indices to verify correct bit extraction.
14484
#[test]
14585
fn test_bit_buffer_take_small_and_large() {
14686
use vortex_buffer::BitBuffer;
@@ -149,135 +89,76 @@ fn test_bit_buffer_take_small_and_large() {
14989
let small: BitBuffer = [true, false, true, true, false, true, false, false]
15090
.into_iter()
15191
.collect();
152-
let indices = [7u32, 0, 2, 5, 1];
153-
let result = (&small).take(&indices[..]);
92+
let result = (&small).take(&[7u32, 0, 2, 5, 1][..]);
15493

155-
assert_eq!(result.len(), 5);
156-
assert!(!result.value(0)); // small[7] = false
157-
assert!(result.value(1)); // small[0] = true
158-
assert!(result.value(2)); // small[2] = true
159-
assert!(result.value(3)); // small[5] = true
160-
assert!(!result.value(4)); // small[1] = false
94+
let values: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
95+
assert_eq!(values, vec![false, true, true, true, false]);
16196

16297
// Large buffer (uses take_bool path, len > 4096).
16398
let large: BitBuffer = (0..5000).map(|i| i % 3 == 0).collect();
164-
let indices = [4999u32, 0, 1, 2, 3, 4998];
165-
let result = (&large).take(&indices[..]);
99+
let result = (&large).take(&[4999u32, 0, 1, 2, 3, 4998][..]);
166100

167-
assert_eq!(result.len(), 6);
168-
assert!(!result.value(0)); // 4999 % 3 != 0
169-
assert!(result.value(1)); // 0 % 3 == 0
170-
assert!(!result.value(2)); // 1 % 3 != 0
171-
assert!(!result.value(3)); // 2 % 3 != 0
172-
assert!(result.value(4)); // 3 % 3 == 0
173-
assert!(result.value(5)); // 4998 % 3 == 0
101+
let values: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
102+
assert_eq!(values, vec![false, true, false, false, true, true]);
174103
}
175104

176-
/// Tests `Take` on `Mask` covering all mask variants and nullable index handling.
177-
///
178-
/// This test covers:
179-
/// - `Mask::AllTrue` with slice indices.
180-
/// - `Mask::AllFalse` with slice indices.
181-
/// - `Mask::Values` with slice indices.
182-
/// - `Mask::AllTrue` with nullable `PVector` indices (returns cloned validity).
183-
/// - `Mask::AllFalse` with nullable `PVector` indices.
184-
/// - `Mask::Values` with nullable `PVector` indices (both small and large paths).
185105
#[test]
186106
fn test_mask_take_all_variants() {
187107
use vortex_mask::Mask;
188108

189-
// Test AllTrue with slice indices.
190-
let all_true = Mask::AllTrue(10);
191-
let indices = [9u32, 0, 5];
192-
let result = (&all_true).take(&indices[..]);
109+
// AllTrue with slice indices.
110+
let result = (&Mask::AllTrue(10)).take(&[9u32, 0, 5][..]);
193111
assert!(result.all_true());
194112
assert_eq!(result.len(), 3);
195113

196-
// Test AllFalse with slice indices.
197-
let all_false = Mask::AllFalse(10);
198-
let result = (&all_false).take(&indices[..]);
114+
// AllFalse with slice indices.
115+
let result = (&Mask::AllFalse(10)).take(&[9u32, 0, 5][..]);
199116
assert!(result.all_false());
200117
assert_eq!(result.len(), 3);
201118

202-
// Test Values with slice indices.
119+
// Values with slice indices.
203120
let values = Mask::from_iter([true, false, true, true, false, true]);
204-
let indices = [5u32, 1, 0, 4];
205-
let result = (&values).take(&indices[..]);
206-
assert_eq!(result.len(), 4);
207-
assert!(result.value(0)); // values[5] = true
208-
assert!(!result.value(1)); // values[1] = false
209-
assert!(result.value(2)); // values[0] = true
210-
assert!(!result.value(3)); // values[4] = false
211-
212-
// Test AllTrue with nullable PVector indices (some indices are null).
213-
// When self is AllTrue, result validity equals indices validity.
214-
let all_true = Mask::AllTrue(10);
215-
let indices: PVectorMut<u32> = [Some(0), None, Some(5), None, Some(9)]
216-
.into_iter()
217-
.collect();
218-
let indices = indices.freeze();
219-
let result = (&all_true).take(&indices);
220-
assert_eq!(result.len(), 5);
221-
assert!(result.value(0)); // Valid index.
222-
assert!(!result.value(1)); // Null index -> false.
223-
assert!(result.value(2)); // Valid index.
224-
assert!(!result.value(3)); // Null index -> false.
225-
assert!(result.value(4)); // Valid index.
226-
227-
// Test AllFalse with nullable PVector indices (result is always AllFalse).
228-
let all_false = Mask::AllFalse(10);
229-
let result = (&all_false).take(&indices);
121+
let result = (&values).take(&[5u32, 1, 0, 4][..]);
122+
let bools: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
123+
assert_eq!(bools, vec![true, false, true, false]);
124+
125+
// AllTrue with nullable PVector indices.
126+
let indices: PVector<u32> =
127+
PVectorMut::from_iter([Some(0), None, Some(5), None, Some(9)]).freeze();
128+
let result = (&Mask::AllTrue(10)).take(&indices);
129+
let bools: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
130+
assert_eq!(bools, vec![true, false, true, false, true]);
131+
132+
// AllFalse with nullable PVector indices.
133+
let result = (&Mask::AllFalse(10)).take(&indices);
230134
assert!(result.all_false());
231135
assert_eq!(result.len(), 5);
232136

233-
// Test Values with nullable PVector indices.
234-
// Combines mask values with index nullability.
137+
// Values with nullable PVector indices.
235138
let values = Mask::from_iter([true, false, true, false, true, false]);
236-
let indices: PVectorMut<u32> = [Some(0), None, Some(1), Some(4), None]
237-
.into_iter()
238-
.collect();
239-
let indices = indices.freeze();
139+
let indices: PVector<u32> =
140+
PVectorMut::from_iter([Some(0), None, Some(1), Some(4), None]).freeze();
240141
let result = (&values).take(&indices);
241-
assert_eq!(result.len(), 5);
242-
assert!(result.value(0)); // values[0] = true, index valid.
243-
assert!(!result.value(1)); // Null index -> false.
244-
assert!(!result.value(2)); // values[1] = false.
245-
assert!(result.value(3)); // values[4] = true, index valid.
246-
assert!(!result.value(4)); // Null index -> false.
142+
let bools: Vec<bool> = (0..result.len()).map(|i| result.value(i)).collect();
143+
assert_eq!(bools, vec![true, false, false, true, false]);
247144
}
248145

249-
/// Tests `Take` on `PrimitiveVector` using `PVector` indices.
250-
///
251-
/// This ensures the type-erased `PrimitiveVector` can be taken with typed `PVector` indices,
252-
/// covering the `Take<PVector<I>> for &PrimitiveVector` implementation.
253146
#[test]
254147
fn test_primitive_vector_take_with_pvector_indices() {
255-
// Data as PrimitiveVector (i32): [10, 20, null, 40, 50]
256-
let data: PVectorMut<i32> = [Some(10), Some(20), None, Some(40), Some(50)]
257-
.into_iter()
258-
.collect();
259-
let data: PrimitiveVector = data.freeze().into();
260-
261-
// Indices as PVector<u16> with some nulls: [4, null, 2, 0, null]
262-
let indices: PVectorMut<u16> = [Some(4), None, Some(2), Some(0), None]
263-
.into_iter()
264-
.collect();
265-
let indices = indices.freeze();
148+
let data: PrimitiveVector =
149+
PVectorMut::from_iter([Some(10i32), Some(20), None, Some(40), Some(50)])
150+
.freeze()
151+
.into();
152+
let indices: PVector<u16> =
153+
PVectorMut::from_iter([Some(4), None, Some(2), Some(0), None]).freeze();
266154

267155
let result = (&data).take(&indices);
268156

269-
// Expected: [50, null, null, 10, null]
270-
// - Index 4 -> data[4] = 50 (valid)
271-
// - Index null -> null (null index produces null)
272-
// - Index 2 -> data[2] = null (data is null)
273-
// - Index 0 -> data[0] = 10 (valid)
274-
// - Index null -> null (null index produces null)
275157
let PrimitiveVector::I32(result) = result else {
276-
panic!("Expected I32 variant");
158+
panic!("Expected I32 variant")
277159
};
278-
assert_eq!(result.get(0), Some(&50));
279-
assert_eq!(result.get(1), None); // Null index.
280-
assert_eq!(result.get(2), None); // data[2] is null.
281-
assert_eq!(result.get(3), Some(&10));
282-
assert_eq!(result.get(4), None); // Null index.
160+
assert_eq!(
161+
collect_pvector(&result),
162+
vec![Some(50), None, None, Some(10), None]
163+
);
283164
}

0 commit comments

Comments
 (0)