@@ -124,6 +124,14 @@ TEST_F(TestListArray, Equality) {
124124 ASSERT_TRUE (array->RangeEquals (1 , 5 , 0 , slice));
125125}
126126
127+ TEST_F (TestListArray, ValuesEquality) {
128+ auto type = list (int32 ());
129+ auto left = ArrayFromJSON (type, " [[1, 2], [3], [0]]" );
130+ auto right = ArrayFromJSON (type, " [[1, 2], [3], [100000]]" );
131+ auto offset = 2 ;
132+ EXPECT_FALSE (left->Slice (offset)->Equals (right->Slice (offset)));
133+ }
134+
127135TEST_F (TestListArray, TestResize) {}
128136
129137TEST_F (TestListArray, TestFromArrays) {
@@ -332,4 +340,210 @@ TEST_F(TestListArray, TestBuilderPreserveFieleName) {
332340 ASSERT_EQ (" counts" , type.value_field ()->name ());
333341}
334342
343+ // ----------------------------------------------------------------------
344+ // FixedSizeList tests
345+
346+ class TestFixedSizeListArray : public TestBuilder {
347+ public:
348+ void SetUp () {
349+ TestBuilder::SetUp ();
350+
351+ value_type_ = int32 ();
352+ type_ = fixed_size_list (value_type_, list_size ());
353+
354+ std::unique_ptr<ArrayBuilder> tmp;
355+ ASSERT_OK (MakeBuilder (pool_, type_, &tmp));
356+ builder_.reset (checked_cast<FixedSizeListBuilder*>(tmp.release ()));
357+ }
358+
359+ void Done () {
360+ std::shared_ptr<Array> out;
361+ FinishAndCheckPadding (builder_.get (), &out);
362+ result_ = std::dynamic_pointer_cast<FixedSizeListArray>(out);
363+ }
364+
365+ protected:
366+ static constexpr int32_t list_size () { return 2 ; }
367+ std::shared_ptr<DataType> value_type_;
368+
369+ std::shared_ptr<FixedSizeListBuilder> builder_;
370+ std::shared_ptr<FixedSizeListArray> result_;
371+ };
372+
373+ TEST_F (TestFixedSizeListArray, Equality) {
374+ Int32Builder* vb = checked_cast<Int32Builder*>(builder_->value_builder ());
375+
376+ std::shared_ptr<Array> array, equal_array, unequal_array;
377+ std::vector<int32_t > equal_values = {1 , 2 , 3 , 4 , 5 , 2 , 2 , 2 , 5 , 6 };
378+ std::vector<int32_t > unequal_values = {1 , 2 , 2 , 2 , 3 , 4 , 5 , 2 };
379+
380+ // setup two equal arrays
381+ ASSERT_OK (builder_->AppendValues (equal_values.size () / list_size ()));
382+ ASSERT_OK (vb->AppendValues (equal_values.data (), equal_values.size ()));
383+ ASSERT_OK (builder_->Finish (&array));
384+
385+ ASSERT_OK (builder_->AppendValues (equal_values.size () / list_size ()));
386+ ASSERT_OK (vb->AppendValues (equal_values.data (), equal_values.size ()));
387+
388+ ASSERT_OK (builder_->Finish (&equal_array));
389+
390+ // now an unequal one
391+ ASSERT_OK (builder_->AppendValues (unequal_values.size () / list_size ()));
392+ ASSERT_OK (vb->AppendValues (unequal_values.data (), unequal_values.size ()));
393+ ASSERT_OK (builder_->Finish (&unequal_array));
394+
395+ // Test array equality
396+ AssertArraysEqual (*array, *array);
397+ AssertArraysEqual (*array, *equal_array);
398+ EXPECT_FALSE (equal_array->Equals (unequal_array));
399+ EXPECT_FALSE (unequal_array->Equals (equal_array));
400+
401+ // Test range equality
402+ EXPECT_TRUE (array->RangeEquals (0 , 1 , 0 , unequal_array));
403+ EXPECT_FALSE (array->RangeEquals (0 , 2 , 0 , unequal_array));
404+ EXPECT_FALSE (array->RangeEquals (1 , 2 , 1 , unequal_array));
405+ EXPECT_TRUE (array->RangeEquals (1 , 3 , 2 , unequal_array));
406+ }
407+
408+ TEST_F (TestFixedSizeListArray, TestAppendNull) {
409+ ASSERT_OK (builder_->AppendNull ());
410+ ASSERT_OK (builder_->AppendNull ());
411+
412+ Done ();
413+
414+ ASSERT_OK (ValidateArray (*result_));
415+ ASSERT_TRUE (result_->IsNull (0 ));
416+ ASSERT_TRUE (result_->IsNull (1 ));
417+
418+ ASSERT_EQ (0 , result_->value_offset (0 ));
419+ ASSERT_EQ (list_size (), result_->value_offset (1 ));
420+
421+ auto values = result_->values ();
422+ ASSERT_EQ (list_size () * 2 , values->length ());
423+ }
424+
425+ TEST_F (TestFixedSizeListArray, TestAppendNulls) {
426+ ASSERT_OK (builder_->AppendNulls (3 ));
427+
428+ Done ();
429+
430+ ASSERT_OK (ValidateArray (*result_));
431+ ASSERT_EQ (result_->length (), 3 );
432+ ASSERT_EQ (result_->null_count (), 3 );
433+ ASSERT_TRUE (result_->IsNull (0 ));
434+ ASSERT_TRUE (result_->IsNull (1 ));
435+ ASSERT_TRUE (result_->IsNull (2 ));
436+
437+ ASSERT_EQ (0 , result_->value_offset (0 ));
438+ ASSERT_EQ (list_size (), result_->value_offset (1 ));
439+ ASSERT_EQ (list_size () * 2 , result_->value_offset (2 ));
440+
441+ auto values = result_->values ();
442+ ASSERT_EQ (list_size () * 3 , values->length ());
443+ }
444+
445+ void ValidateBasicFixedSizeListArray (const FixedSizeListArray* result,
446+ const std::vector<int32_t >& values,
447+ const std::vector<uint8_t >& is_valid) {
448+ ASSERT_OK (ValidateArray (*result));
449+ ASSERT_EQ (1 , result->null_count ());
450+ ASSERT_LE (result->values ()->null_count (), 2 );
451+
452+ ASSERT_EQ (3 , result->length ());
453+ for (int32_t i = 0 ; i < 3 ; ++i) {
454+ ASSERT_EQ (i * result->value_length (), result->value_offset (i));
455+ }
456+
457+ for (int i = 0 ; i < result->length (); ++i) {
458+ ASSERT_EQ (is_valid[i] == 0 , result->IsNull (i));
459+ }
460+
461+ ASSERT_EQ (result->length () * result->value_length (), result->values ()->length ());
462+ auto varr = std::dynamic_pointer_cast<Int32Array>(result->values ());
463+
464+ for (size_t i = 0 ; i < values.size (); ++i) {
465+ if (is_valid[i / result->value_length ()] == 0 ) {
466+ continue ;
467+ }
468+ ASSERT_EQ (values[i], varr->Value (i));
469+ }
470+ }
471+
472+ TEST_F (TestFixedSizeListArray, TestBasics) {
473+ std::vector<int32_t > values = {0 , 1 , 2 , 3 , 4 , 5 };
474+ std::vector<uint8_t > is_valid = {1 , 0 , 1 };
475+
476+ Int32Builder* vb = checked_cast<Int32Builder*>(builder_->value_builder ());
477+
478+ int pos = 0 ;
479+ for (size_t i = 0 ; i < values.size () / list_size (); ++i) {
480+ if (is_valid[i] == 0 ) {
481+ ASSERT_OK (builder_->AppendNull ());
482+ pos += list_size ();
483+ continue ;
484+ }
485+ ASSERT_OK (builder_->Append ());
486+ for (int j = 0 ; j < list_size (); ++j) {
487+ ASSERT_OK (vb->Append (values[pos++]));
488+ }
489+ }
490+
491+ Done ();
492+ ValidateBasicFixedSizeListArray (result_.get (), values, is_valid);
493+ }
494+
495+ TEST_F (TestFixedSizeListArray, BulkAppend) {
496+ std::vector<int32_t > values = {0 , 1 , 2 , 3 , 4 , 5 };
497+ std::vector<uint8_t > is_valid = {1 , 0 , 1 };
498+
499+ Int32Builder* vb = checked_cast<Int32Builder*>(builder_->value_builder ());
500+
501+ ASSERT_OK (builder_->AppendValues (values.size () / list_size (), is_valid.data ()));
502+ for (int32_t value : values) {
503+ ASSERT_OK (vb->Append (value));
504+ }
505+ Done ();
506+ ValidateBasicFixedSizeListArray (result_.get (), values, is_valid);
507+ }
508+
509+ TEST_F (TestFixedSizeListArray, BulkAppendInvalid) {
510+ std::vector<int32_t > values = {0 , 1 , 2 , 3 , 4 , 5 };
511+ std::vector<uint8_t > is_valid = {1 , 0 , 1 };
512+
513+ Int32Builder* vb = checked_cast<Int32Builder*>(builder_->value_builder ());
514+
515+ ASSERT_OK (builder_->AppendValues (values.size () / list_size (), is_valid.data ()));
516+ for (int32_t value : values) {
517+ ASSERT_OK (vb->Append (value));
518+ }
519+ for (int32_t value : values) {
520+ ASSERT_OK (vb->Append (value));
521+ }
522+
523+ Done ();
524+ ASSERT_RAISES (Invalid, ValidateArray (*result_));
525+ }
526+
527+ TEST_F (TestFixedSizeListArray, TestZeroLength) {
528+ // All buffers are null
529+ Done ();
530+ ASSERT_OK (ValidateArray (*result_));
531+ }
532+
533+ TEST_F (TestFixedSizeListArray, TestBuilderPreserveFieleName) {
534+ auto list_type_with_name = fixed_size_list (field (" counts" , int32 ()), list_size ());
535+
536+ std::unique_ptr<ArrayBuilder> tmp;
537+ ASSERT_OK (MakeBuilder (pool_, list_type_with_name, &tmp));
538+ builder_.reset (checked_cast<FixedSizeListBuilder*>(tmp.release ()));
539+
540+ ASSERT_OK (builder_->AppendValues (4 ));
541+
542+ std::shared_ptr<Array> list_array;
543+ ASSERT_OK (builder_->Finish (&list_array));
544+
545+ const auto & type = checked_cast<FixedSizeListType&>(*list_array->type ());
546+ ASSERT_EQ (" counts" , type.value_field ()->name ());
547+ }
548+
335549} // namespace arrow
0 commit comments