@@ -400,6 +400,8 @@ impl<'m, 'v> VariantObject<'m, 'v> {
400400
401401#[ cfg( test) ]
402402mod tests {
403+ use crate :: VariantBuilder ;
404+
403405 use super :: * ;
404406
405407 #[ test]
@@ -618,4 +620,112 @@ mod tests {
618620 ArrowError :: InvalidArgumentError ( ref msg) if msg. contains( "Tried to extract byte(s) ..16 from 15-byte buffer" )
619621 ) ) ;
620622 }
623+
624+ fn test_variant_object_with_count ( count : i32 , expected_field_id_size : OffsetSizeBytes ) {
625+ let mut builder = VariantBuilder :: new ( ) ;
626+ let mut obj = builder. new_object ( ) ;
627+ for val in 0 ..count {
628+ let key = format ! ( "id_{}" , val) ;
629+ obj. insert ( & key, val) ;
630+ }
631+
632+ obj. finish ( ) . unwrap ( ) ;
633+ let ( metadata, value) = builder. finish ( ) ;
634+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
635+
636+ if let Variant :: Object ( obj) = variant {
637+ assert_eq ! ( obj. len( ) , count as usize ) ;
638+ assert_eq ! ( obj. get( & format!( "id_{}" , 0 ) ) . unwrap( ) , Variant :: Int32 ( 0 ) ) ;
639+ assert_eq ! (
640+ obj. get( & format!( "id_{}" , count - 1 ) ) . unwrap( ) ,
641+ Variant :: Int32 ( count - 1 )
642+ ) ;
643+
644+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
645+ let header = VariantObjectHeader :: try_new ( header_byte) . unwrap ( ) ;
646+ assert_eq ! (
647+ header. field_id_size, expected_field_id_size,
648+ "Expected {}-byte field IDs, got {}-byte field IDs" ,
649+ expected_field_id_size as usize , header. field_id_size as usize
650+ ) ;
651+ } else {
652+ panic ! ( "Expected object variant" ) ;
653+ }
654+ }
655+
656+ #[ test]
657+ fn test_variant_object_257_elements ( ) {
658+ test_variant_object_with_count ( 2_i32 . pow ( 8 ) + 1 , OffsetSizeBytes :: Two ) ; // 2^8 + 1, expected 2-byte field IDs
659+ }
660+
661+ #[ test]
662+ fn test_variant_object_65537_elements ( ) {
663+ test_variant_object_with_count ( 2_i32 . pow ( 16 ) + 1 , OffsetSizeBytes :: Three ) ;
664+ // 2^16 + 1, expected 3-byte field IDs
665+ }
666+
667+ #[ test]
668+ fn test_variant_object_16777217_elements ( ) {
669+ test_variant_object_with_count ( 2_i32 . pow ( 24 ) + 1 , OffsetSizeBytes :: Four ) ;
670+ // 2^24 + 1, expected 4-byte field IDs
671+ }
672+
673+ #[ test]
674+ fn test_variant_object_small_sizes_255_elements ( ) {
675+ test_variant_object_with_count ( 255 , OffsetSizeBytes :: One ) ;
676+ }
677+
678+ fn test_variant_object_with_large_data (
679+ data_size_per_field : usize ,
680+ expected_field_offset_size : OffsetSizeBytes ,
681+ ) {
682+ let num_fields = 20 ;
683+ let mut builder = VariantBuilder :: new ( ) ;
684+ let mut obj = builder. new_object ( ) ;
685+
686+ let str_val = "a" . repeat ( data_size_per_field) ;
687+
688+ for val in 0 ..num_fields {
689+ let key = format ! ( "id_{}" , val) ;
690+ obj. insert ( & key, str_val. as_str ( ) ) ;
691+ }
692+
693+ obj. finish ( ) . unwrap ( ) ;
694+ let ( metadata, value) = builder. finish ( ) ;
695+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
696+
697+ if let Variant :: Object ( obj) = variant {
698+ assert_eq ! ( obj. len( ) , num_fields) ;
699+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
700+ let header = VariantObjectHeader :: try_new ( header_byte) . unwrap ( ) ;
701+ assert_eq ! (
702+ header. field_offset_size, expected_field_offset_size,
703+ "Expected {}-byte field offsets, got {}-byte field offsets" ,
704+ expected_field_offset_size as usize , header. field_offset_size as usize
705+ ) ;
706+ } else {
707+ panic ! ( "Expected object variant" ) ;
708+ }
709+ }
710+
711+ #[ test]
712+ fn test_variant_object_child_data_0_byte_offsets_minus_one ( ) {
713+ test_variant_object_with_large_data ( 10 , OffsetSizeBytes :: One ) ;
714+ }
715+
716+ #[ test]
717+ fn test_variant_object_256_bytes_child_data_3_byte_offsets ( ) {
718+ test_variant_object_with_large_data ( 256 + 1 , OffsetSizeBytes :: Two ) ; // 2^8 - 2^16 elements
719+ }
720+
721+ #[ test]
722+ fn test_variant_object_16777216_bytes_child_data_4_byte_offsets ( ) {
723+ test_variant_object_with_large_data ( 65536 + 1 , OffsetSizeBytes :: Three ) ; // 2^16 - 2^24 elements
724+ }
725+
726+ #[ test]
727+ fn test_variant_object_65535_bytes_child_data_2_byte_offsets ( ) {
728+ test_variant_object_with_large_data ( 16777216 + 1 , OffsetSizeBytes :: Four ) ;
729+ // 2^24
730+ }
621731}
0 commit comments