]>
Commit | Line | Data |
---|---|---|
1d09f67e TL |
1 | // Licensed to the Apache Software Foundation (ASF) under one or more |
2 | // contributor license agreements. See the NOTICE file distributed with | |
3 | // this work for additional information regarding copyright ownership. | |
4 | // The ASF licenses this file to You under the Apache License, Version 2.0 | |
5 | // (the "License"); you may not use this file except in compliance with | |
6 | // the License. You may obtain a copy of the License at | |
7 | // | |
8 | // http://www.apache.org/licenses/LICENSE-2.0 | |
9 | // | |
10 | // Unless required by applicable law or agreed to in writing, software | |
11 | // distributed under the License is distributed on an "AS IS" BASIS, | |
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | // See the License for the specific language governing permissions and | |
14 | // limitations under the License. | |
15 | ||
16 | namespace Apache.Arrow.Tests | |
17 | { | |
18 | using System; | |
19 | using System.Linq; | |
20 | using Xunit; | |
21 | ||
22 | /// <summary> | |
23 | /// The <see cref="ArrowBufferBitmapBuilderTests"/> class provides unit tests for the | |
24 | /// <see cref="ArrowBuffer.BitmapBuilder"/> class. | |
25 | /// </summary> | |
26 | public class ArrowBufferBitmapBuilderTests | |
27 | { | |
28 | public class Append | |
29 | { | |
30 | [Theory] | |
31 | [InlineData(new bool[] {}, false, 1, 0, 1)] | |
32 | [InlineData(new bool[] {}, true, 1, 1, 0)] | |
33 | [InlineData(new[] { true, false }, true, 3, 2, 1)] | |
34 | [InlineData(new[] { true, false }, false, 3, 1, 2)] | |
35 | public void IncreasesLength( | |
36 | bool[] initialContents, | |
37 | bool valueToAppend, | |
38 | int expectedLength, | |
39 | int expectedSetBitCount, | |
40 | int expectedUnsetBitCount) | |
41 | { | |
42 | // Arrange | |
43 | var builder = new ArrowBuffer.BitmapBuilder(); | |
44 | builder.AppendRange(initialContents); | |
45 | ||
46 | // Act | |
47 | var actualReturnValue = builder.Append(valueToAppend); | |
48 | ||
49 | // Assert | |
50 | Assert.Equal(builder, actualReturnValue); | |
51 | Assert.Equal(expectedLength, builder.Length); | |
52 | Assert.True(builder.Capacity >= expectedLength); | |
53 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
54 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
55 | } | |
56 | ||
57 | [Theory] | |
58 | [InlineData(new bool[] {}, false)] | |
59 | [InlineData(new bool[] {}, true)] | |
60 | [InlineData(new[] { true, false }, true)] | |
61 | [InlineData(new[] { true, false }, false)] | |
62 | public void AfterClearIncreasesLength(bool[] initialContentsToClear, bool valueToAppend) | |
63 | { | |
64 | // Arrange | |
65 | var builder = new ArrowBuffer.BitmapBuilder(); | |
66 | builder.AppendRange(initialContentsToClear); | |
67 | builder.Clear(); | |
68 | ||
69 | // Act | |
70 | var actualReturnValue = builder.Append(valueToAppend); | |
71 | ||
72 | // Assert | |
73 | Assert.Equal(builder, actualReturnValue); | |
74 | Assert.Equal(1, builder.Length); | |
75 | Assert.True(builder.Capacity >= 1); | |
76 | Assert.Equal(valueToAppend ? 1 : 0, builder.SetBitCount); | |
77 | Assert.Equal(valueToAppend ? 0 : 1, builder.UnsetBitCount); | |
78 | } | |
79 | ||
80 | [Fact] | |
81 | public void IncreasesCapacityWhenRequired() | |
82 | { | |
83 | // Arrange | |
84 | var builder = new ArrowBuffer.BitmapBuilder(); | |
85 | int initialCapacity = builder.Capacity; | |
86 | builder.AppendRange(Enumerable.Repeat(true, initialCapacity)); // Fill to capacity. | |
87 | ||
88 | // Act | |
89 | var actualReturnValue = builder.Append(true); | |
90 | ||
91 | // Assert | |
92 | Assert.Equal(builder, actualReturnValue); | |
93 | Assert.Equal(initialCapacity + 1, builder.Length); | |
94 | Assert.True(builder.Capacity >= initialCapacity + 1); | |
95 | } | |
96 | } | |
97 | ||
98 | public class AppendRange | |
99 | { | |
100 | [Theory] | |
101 | [InlineData(new bool[] {}, new bool[] {}, 0, 0, 0)] | |
102 | [InlineData(new bool[] {}, new[] { true, false }, 2, 1, 1)] | |
103 | [InlineData(new[] { true, false }, new bool[] {}, 2, 1, 1)] | |
104 | [InlineData(new[] { true, false }, new[] { true, false }, 4, 2, 2)] | |
105 | public void IncreasesLength( | |
106 | bool[] initialContents, | |
107 | bool[] toAppend, | |
108 | int expectedLength, | |
109 | int expectedSetBitCount, | |
110 | int expectedUnsetBitCount) | |
111 | { | |
112 | // Arrange | |
113 | var builder = new ArrowBuffer.BitmapBuilder(); | |
114 | builder.AppendRange(initialContents); | |
115 | ||
116 | // Act | |
117 | var actualReturnValue = builder.AppendRange(toAppend); | |
118 | ||
119 | // Assert | |
120 | Assert.Equal(builder, actualReturnValue); | |
121 | Assert.Equal(expectedLength, builder.Length); | |
122 | Assert.True(builder.Capacity >= expectedLength); | |
123 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
124 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
125 | } | |
126 | } | |
127 | ||
128 | public class Build | |
129 | { | |
130 | [Theory] | |
131 | [InlineData(new bool[] { }, new byte[] { })] | |
132 | [InlineData(new[] { true, false, true, false }, new byte[] { 0b00000101 })] | |
133 | [InlineData( | |
134 | new[] { true, false, true, false, true, false, true, false, true, false, true, false }, | |
135 | new byte[] { 0b01010101, 0b00000101 })] | |
136 | public void AppendedRangeBitPacks(bool[] contents, byte[] expectedBytes) | |
137 | { | |
138 | // Arrange | |
139 | var builder = new ArrowBuffer.BitmapBuilder(); | |
140 | builder.AppendRange(contents); | |
141 | ||
142 | // Act | |
143 | var buf = builder.Build(); | |
144 | ||
145 | // Assert | |
146 | AssertBuffer(expectedBytes, buf); | |
147 | } | |
148 | } | |
149 | ||
150 | public class Clear | |
151 | { | |
152 | [Theory] | |
153 | [InlineData(10)] | |
154 | [InlineData(100)] | |
155 | public void ClearingSetsBitCountToZero(int numBitsBeforeClear) | |
156 | { | |
157 | // Arrange | |
158 | var builder = new ArrowBuffer.BitmapBuilder(); | |
159 | var data = Enumerable.Repeat(true, numBitsBeforeClear).Select(x => x).ToArray(); | |
160 | builder.AppendRange(data); | |
161 | ||
162 | // Act | |
163 | var actualReturnValue = builder.Clear(); | |
164 | ||
165 | // Assert | |
166 | Assert.Equal(builder, actualReturnValue); | |
167 | Assert.Equal(0, builder.Length); | |
168 | } | |
169 | } | |
170 | ||
171 | public class Resize | |
172 | { | |
173 | [Theory] | |
174 | [InlineData(new bool[] {}, 256, 0, 256)] | |
175 | [InlineData(new[] { true, true, true, true}, 256, 4, 252)] | |
176 | [InlineData(new[] { false, false, false, false}, 256, 0, 256)] | |
177 | [InlineData(new[] { true, true, true, true}, 2, 2, 0)] | |
178 | [InlineData(new[] { true, true, true, true}, 0, 0, 0)] | |
179 | public void LengthHasExpectedValueAfterResize( | |
180 | bool[] bits, int newSize, int expectedSetBitCount, int expectedUnsetBitCount) | |
181 | { | |
182 | // Arrange | |
183 | var builder = new ArrowBuffer.BitmapBuilder(); | |
184 | builder.AppendRange(bits); | |
185 | ||
186 | // Act | |
187 | var actualReturnValue = builder.Resize(newSize); | |
188 | ||
189 | // Assert | |
190 | Assert.Equal(builder, actualReturnValue); | |
191 | Assert.True(builder.Capacity >= newSize); | |
192 | Assert.Equal(newSize, builder.Length); | |
193 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
194 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
195 | } | |
196 | ||
197 | [Fact] | |
198 | public void NegativeLengthThrows() | |
199 | { | |
200 | // Arrange | |
201 | var builder = new ArrowBuffer.BitmapBuilder(); | |
202 | builder.Append(false); | |
203 | builder.Append(true); | |
204 | ||
205 | // Act/Assert | |
206 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Resize(-1)); | |
207 | } | |
208 | } | |
209 | ||
210 | public class Reserve | |
211 | { | |
212 | [Theory] | |
213 | [InlineData(0, 0, 0)] | |
214 | [InlineData(0, 0, 8)] | |
215 | [InlineData(8, 8, 8)] | |
216 | [InlineData(8, 8, 16)] | |
217 | public void CapacityIncreased(int initialCapacity, int numBitsToAppend, int additionalCapacity) | |
218 | { | |
219 | // Arrange | |
220 | var builder = new ArrowBuffer.BitmapBuilder(initialCapacity); | |
221 | builder.AppendRange(Enumerable.Repeat(true, numBitsToAppend)); | |
222 | ||
223 | // Act | |
224 | var actualReturnValue = builder.Reserve(additionalCapacity); | |
225 | ||
226 | // Assert | |
227 | Assert.Equal(builder, actualReturnValue); | |
228 | Assert.True(builder.Capacity >= numBitsToAppend + additionalCapacity); | |
229 | } | |
230 | ||
231 | [Fact] | |
232 | public void NegtativeCapacityThrows() | |
233 | { | |
234 | // Arrange | |
235 | var builder = new ArrowBuffer.BitmapBuilder(); | |
236 | ||
237 | // Act/Assert | |
238 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Reserve(-1)); | |
239 | } | |
240 | } | |
241 | ||
242 | public class Set | |
243 | { | |
244 | [Theory] | |
245 | [InlineData( | |
246 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
247 | 2, | |
248 | new byte[] { 0b01010101, 0b00000001 }, | |
249 | 5, 5)] | |
250 | [InlineData( | |
251 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
252 | 3, | |
253 | new byte[] { 0b01011101, 0b00000001 }, | |
254 | 6, 4)] | |
255 | [InlineData( | |
256 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
257 | 8, | |
258 | new byte[] { 0b01010101, 0b00000001 }, | |
259 | 5, 5)] | |
260 | [InlineData( | |
261 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
262 | 9, | |
263 | new byte[] { 0b01010101, 0b00000011 }, | |
264 | 6, 4)] | |
265 | public void OverloadWithNoValueParameterSetsAsExpected( | |
266 | bool[] bits, int indexToSet, byte[] expectedBytes, | |
267 | int expectedSetBitCount, int expectedUnsetBitCount) | |
268 | { | |
269 | // Arrange | |
270 | var builder = new ArrowBuffer.BitmapBuilder(); | |
271 | builder.AppendRange(bits); | |
272 | ||
273 | // Act | |
274 | var actualReturnValue = builder.Set(indexToSet); | |
275 | ||
276 | // Assert | |
277 | Assert.Equal(builder, actualReturnValue); | |
278 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
279 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
280 | var buf = builder.Build(); | |
281 | AssertBuffer(expectedBytes, buf); | |
282 | } | |
283 | ||
284 | [Theory] | |
285 | [InlineData( | |
286 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
287 | 2, true, | |
288 | new byte[] { 0b01010101, 0b00000001 }, | |
289 | 5, 5)] | |
290 | [InlineData( | |
291 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
292 | 2, false, | |
293 | new byte[] { 0b01010001, 0b00000001 }, | |
294 | 4, 6)] | |
295 | [InlineData( | |
296 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
297 | 3, true, | |
298 | new byte[] { 0b01011101, 0b00000001 }, | |
299 | 6, 4)] | |
300 | [InlineData( | |
301 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
302 | 3, false, | |
303 | new byte[] { 0b01010101, 0b00000001 }, | |
304 | 5, 5)] | |
305 | [InlineData( | |
306 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
307 | 8, true, | |
308 | new byte[] { 0b01010101, 0b00000001 }, | |
309 | 5, 5)] | |
310 | [InlineData( | |
311 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
312 | 8, false, | |
313 | new byte[] { 0b01010101, 0b00000000 }, | |
314 | 4, 6)] | |
315 | [InlineData( | |
316 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
317 | 9, true, | |
318 | new byte[] { 0b01010101, 0b00000011 }, | |
319 | 6, 4)] | |
320 | [InlineData( | |
321 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
322 | 9, false, | |
323 | new byte[] { 0b01010101, 0b00000001 }, | |
324 | 5, 5)] | |
325 | public void OverloadWithValueParameterSetsAsExpected( | |
326 | bool[] bits, int indexToSet, bool valueToSet, byte[] expectedBytes, | |
327 | int expectedSetBitCount, int expectedUnsetBitCount) | |
328 | { | |
329 | // Arrange | |
330 | var builder = new ArrowBuffer.BitmapBuilder(); | |
331 | builder.AppendRange(bits); | |
332 | ||
333 | // Act | |
334 | var actualReturnValue = builder.Set(indexToSet, valueToSet); | |
335 | ||
336 | // Assert | |
337 | Assert.Equal(builder, actualReturnValue); | |
338 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
339 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
340 | var buf = builder.Build(); | |
341 | AssertBuffer(expectedBytes, buf); | |
342 | } | |
343 | ||
344 | [Theory] | |
345 | [InlineData(0, -1)] | |
346 | [InlineData(0, 0)] | |
347 | [InlineData(1, 1)] | |
348 | [InlineData(10, 10)] | |
349 | [InlineData(10, 11)] | |
350 | public void BadIndexThrows(int numBitsToAppend, int indexToSet) | |
351 | { | |
352 | // Arrange | |
353 | var builder = new ArrowBuffer.BitmapBuilder(); | |
354 | var bits = Enumerable.Repeat(true, numBitsToAppend); | |
355 | builder.AppendRange(bits); | |
356 | ||
357 | // Act/Assert | |
358 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Set(indexToSet)); | |
359 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Set(indexToSet, true)); | |
360 | } | |
361 | } | |
362 | ||
363 | public class Swap | |
364 | { | |
365 | [Theory] | |
366 | [InlineData( | |
367 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
368 | 0, 2, | |
369 | new byte[] { 0b01010101, 0b00000001 })] | |
370 | [InlineData( | |
371 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
372 | 0, 3, | |
373 | new byte[] { 0b01011100, 0b00000001 })] | |
374 | [InlineData( | |
375 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
376 | 4, 8, | |
377 | new byte[] { 0b01010101, 0b00000001 })] | |
378 | [InlineData( | |
379 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
380 | 4, 9, | |
381 | new byte[] { 0b01000101, 0b00000011 })] | |
382 | public void SwapsAsExpected(bool[] bits, int firstIndex, int secondIndex, byte[] expectedBytes) | |
383 | { | |
384 | // Arrange | |
385 | var builder = new ArrowBuffer.BitmapBuilder(); | |
386 | builder.AppendRange(bits); | |
387 | ||
388 | // Act | |
389 | var actualReturnValue = builder.Swap(firstIndex, secondIndex); | |
390 | ||
391 | // Assert | |
392 | Assert.Equal(builder, actualReturnValue); | |
393 | var buf = builder.Build(); | |
394 | AssertBuffer(expectedBytes, buf); | |
395 | } | |
396 | ||
397 | [Theory] | |
398 | [InlineData(0, -1, 0)] | |
399 | [InlineData(0, 0, -1)] | |
400 | [InlineData(0, 0, 0)] | |
401 | [InlineData(1, 0, 1)] | |
402 | [InlineData(1, 1, 0)] | |
403 | [InlineData(1, 0, -1)] | |
404 | [InlineData(1, -1, 0)] | |
405 | [InlineData(1, 1, 1)] | |
406 | [InlineData(10, 10, 0)] | |
407 | [InlineData(10, 0, 10)] | |
408 | [InlineData(10, 10, 10)] | |
409 | [InlineData(10, 11, 0)] | |
410 | [InlineData(10, 0, 11)] | |
411 | [InlineData(10, 11, 11)] | |
412 | public void BadIndicesThrows(int numBitsToAppend, int firstIndex, int secondIndex) | |
413 | { | |
414 | // Arrange | |
415 | var builder = new ArrowBuffer.BitmapBuilder(); | |
416 | var bits = Enumerable.Repeat(true, numBitsToAppend); | |
417 | builder.AppendRange(bits); | |
418 | ||
419 | // Act/Assert | |
420 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Swap(firstIndex, secondIndex)); | |
421 | } | |
422 | } | |
423 | ||
424 | public class Toggle | |
425 | { | |
426 | [Theory] | |
427 | [InlineData( | |
428 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
429 | 2, | |
430 | new byte[] { 0b01010001, 0b00000001 }, | |
431 | 4, 6)] | |
432 | [InlineData( | |
433 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
434 | 3, | |
435 | new byte[] { 0b01011101, 0b00000001 }, | |
436 | 6, 4)] | |
437 | [InlineData( | |
438 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
439 | 8, | |
440 | new byte[] { 0b01010101, 0b00000000 }, | |
441 | 4, 6)] | |
442 | [InlineData( | |
443 | new[] { true, false, true, false, true, false, true, false, true, false}, | |
444 | 9, | |
445 | new byte[] { 0b01010101, 0b00000011 }, | |
446 | 6, 4)] | |
447 | public void TogglesAsExpected( | |
448 | bool[] bits, int indexToToggle, byte[] expectedBytes, | |
449 | int expectedSetBitCount, int expectedUnsetBitCount) | |
450 | { | |
451 | // Arrange | |
452 | var builder = new ArrowBuffer.BitmapBuilder(); | |
453 | builder.AppendRange(bits); | |
454 | ||
455 | // Act | |
456 | var actualReturnValue = builder.Toggle(indexToToggle); | |
457 | ||
458 | // Assert | |
459 | Assert.Equal(builder, actualReturnValue); | |
460 | Assert.Equal(expectedSetBitCount, builder.SetBitCount); | |
461 | Assert.Equal(expectedUnsetBitCount, builder.UnsetBitCount); | |
462 | var buf = builder.Build(); | |
463 | AssertBuffer(expectedBytes, buf); | |
464 | } | |
465 | ||
466 | [Theory] | |
467 | [InlineData(0, -1)] | |
468 | [InlineData(0, 0)] | |
469 | [InlineData(1, 1)] | |
470 | [InlineData(10, 10)] | |
471 | [InlineData(10, 11)] | |
472 | public void BadIndexThrows(int numBitsToAppend, int indexToToggle) | |
473 | { | |
474 | // Arrange | |
475 | var builder = new ArrowBuffer.BitmapBuilder(); | |
476 | var bits = Enumerable.Repeat(true, numBitsToAppend); | |
477 | builder.AppendRange(bits); | |
478 | ||
479 | // Act/Assert | |
480 | Assert.Throws<ArgumentOutOfRangeException>(() => builder.Toggle(indexToToggle)); | |
481 | } | |
482 | } | |
483 | ||
484 | private static void AssertBuffer(byte[] expectedBytes, ArrowBuffer buf) | |
485 | { | |
486 | Assert.True(buf.Length >= expectedBytes.Length); | |
487 | for (int i = 0; i < expectedBytes.Length; i++) | |
488 | { | |
489 | Assert.Equal(expectedBytes[i], buf.Span[i]); | |
490 | } | |
491 | } | |
492 | } | |
493 | } |