@@ -328,6 +328,8 @@ impl<'m, 'v> VariantObject<'m, 'v> {
328328
329329#[ cfg( test) ]
330330mod tests {
331+ use crate :: VariantBuilder ;
332+
331333 use super :: * ;
332334
333335 #[ test]
@@ -474,4 +476,112 @@ mod tests {
474476 let fields: Vec < _ > = variant_obj. iter ( ) . collect ( ) ;
475477 assert_eq ! ( fields. len( ) , 0 ) ;
476478 }
479+
480+ fn test_variant_object_with_count ( count : i32 , expected_field_id_size : OffsetSizeBytes ) {
481+ let mut builder = VariantBuilder :: new ( ) ;
482+ let mut obj = builder. new_object ( ) ;
483+ for val in 0 ..count {
484+ let key = format ! ( "id_{}" , val) ;
485+ obj. insert ( & key, val) ;
486+ }
487+
488+ obj. finish ( ) . unwrap ( ) ;
489+ let ( metadata, value) = builder. finish ( ) ;
490+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
491+
492+ if let Variant :: Object ( obj) = variant {
493+ assert_eq ! ( obj. len( ) , count as usize ) ;
494+ assert_eq ! ( obj. get( & format!( "id_{}" , 0 ) ) . unwrap( ) , Variant :: Int32 ( 0 ) ) ;
495+ assert_eq ! (
496+ obj. get( & format!( "id_{}" , count - 1 ) ) . unwrap( ) ,
497+ Variant :: Int32 ( count - 1 )
498+ ) ;
499+
500+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
501+ let header = VariantObjectHeader :: try_new ( header_byte) . unwrap ( ) ;
502+ assert_eq ! (
503+ header. field_id_size, expected_field_id_size,
504+ "Expected {}-byte field IDs, got {}-byte field IDs" ,
505+ expected_field_id_size as usize , header. field_id_size as usize
506+ ) ;
507+ } else {
508+ panic ! ( "Expected object variant" ) ;
509+ }
510+ }
511+
512+ #[ test]
513+ fn test_variant_object_257_elements ( ) {
514+ test_variant_object_with_count ( 2_i32 . pow ( 8 ) + 1 , OffsetSizeBytes :: Two ) ; // 2^8 + 1, expected 2-byte field IDs
515+ }
516+
517+ #[ test]
518+ fn test_variant_object_65537_elements ( ) {
519+ test_variant_object_with_count ( 2_i32 . pow ( 16 ) + 1 , OffsetSizeBytes :: Three ) ;
520+ // 2^16 + 1, expected 3-byte field IDs
521+ }
522+
523+ #[ test]
524+ fn test_variant_object_16777217_elements ( ) {
525+ test_variant_object_with_count ( 2_i32 . pow ( 24 ) + 1 , OffsetSizeBytes :: Four ) ;
526+ // 2^24 + 1, expected 4-byte field IDs
527+ }
528+
529+ #[ test]
530+ fn test_variant_object_small_sizes_255_elements ( ) {
531+ test_variant_object_with_count ( 255 , OffsetSizeBytes :: One ) ;
532+ }
533+
534+ fn test_variant_object_with_large_data (
535+ data_size_per_field : usize ,
536+ expected_field_offset_size : OffsetSizeBytes ,
537+ ) {
538+ let num_fields = 20 ;
539+ let mut builder = VariantBuilder :: new ( ) ;
540+ let mut obj = builder. new_object ( ) ;
541+
542+ let str_val = "a" . repeat ( data_size_per_field) ;
543+
544+ for val in 0 ..num_fields {
545+ let key = format ! ( "id_{}" , val) ;
546+ obj. insert ( & key, str_val. as_str ( ) ) ;
547+ }
548+
549+ obj. finish ( ) . unwrap ( ) ;
550+ let ( metadata, value) = builder. finish ( ) ;
551+ let variant = Variant :: try_new ( & metadata, & value) . unwrap ( ) ;
552+
553+ if let Variant :: Object ( obj) = variant {
554+ assert_eq ! ( obj. len( ) , num_fields) ;
555+ let header_byte = first_byte_from_slice ( & value) . unwrap ( ) ;
556+ let header = VariantObjectHeader :: try_new ( header_byte) . unwrap ( ) ;
557+ assert_eq ! (
558+ header. field_offset_size, expected_field_offset_size,
559+ "Expected {}-byte field offsets, got {}-byte field offsets" ,
560+ expected_field_offset_size as usize , header. field_offset_size as usize
561+ ) ;
562+ } else {
563+ panic ! ( "Expected object variant" ) ;
564+ }
565+ }
566+
567+ #[ test]
568+ fn test_variant_object_child_data_0_byte_offsets_minus_one ( ) {
569+ test_variant_object_with_large_data ( 10 , OffsetSizeBytes :: One ) ;
570+ }
571+
572+ #[ test]
573+ fn test_variant_object_256_bytes_child_data_3_byte_offsets ( ) {
574+ test_variant_object_with_large_data ( 256 + 1 , OffsetSizeBytes :: Two ) ; // 2^8 - 2^16 elements
575+ }
576+
577+ #[ test]
578+ fn test_variant_object_16777216_bytes_child_data_4_byte_offsets ( ) {
579+ test_variant_object_with_large_data ( 65536 + 1 , OffsetSizeBytes :: Three ) ; // 2^16 - 2^24 elements
580+ }
581+
582+ #[ test]
583+ fn test_variant_object_65535_bytes_child_data_2_byte_offsets ( ) {
584+ test_variant_object_with_large_data ( 16777216 + 1 , OffsetSizeBytes :: Four ) ;
585+ // 2^24
586+ }
477587}
0 commit comments