@@ -359,4 +359,142 @@ class WeaverTest extends AirSpec:
359
359
result.get.getMessage.contains(" Cannot convert" ) shouldBe true
360
360
}
361
361
362
+ test(" weave ListMap[String, Int]" ) {
363
+ val v = scala.collection.immutable.ListMap (" a" -> 1 , " b" -> 2 , " c" -> 3 )
364
+ val msgpack = ObjectWeaver .weave(v)
365
+ val v2 = ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , Int ]](msgpack)
366
+ v shouldBe v2
367
+ // Verify order is preserved
368
+ v.keys.toList shouldBe v2.keys.toList
369
+ v.values.toList shouldBe v2.values.toList
370
+ }
371
+
372
+ test(" weave empty ListMap[String, Int]" ) {
373
+ val v = scala.collection.immutable.ListMap .empty[String , Int ]
374
+ val msgpack = ObjectWeaver .weave(v)
375
+ val v2 = ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , Int ]](msgpack)
376
+ v shouldBe v2
377
+ }
378
+
379
+ test(" weave ListMap[Int, String]" ) {
380
+ val v = scala.collection.immutable.ListMap (1 -> " one" , 2 -> " two" , 3 -> " three" )
381
+ val msgpack = ObjectWeaver .weave(v)
382
+ val v2 = ObjectWeaver .unweave[scala.collection.immutable.ListMap [Int , String ]](msgpack)
383
+ v shouldBe v2
384
+ // Verify order is preserved
385
+ v.keys.toList shouldBe v2.keys.toList
386
+ v.values.toList shouldBe v2.values.toList
387
+ }
388
+
389
+ test(" ListMap[String, Int] toJson" ) {
390
+ val v = scala.collection.immutable.ListMap (" x" -> 10 , " y" -> 20 , " z" -> 30 )
391
+ val json = ObjectWeaver .toJson(v)
392
+ val v2 = ObjectWeaver .fromJson[scala.collection.immutable.ListMap [String , Int ]](json)
393
+ v shouldBe v2
394
+ // Verify order is preserved
395
+ v.keys.toList shouldBe v2.keys.toList
396
+ v.values.toList shouldBe v2.values.toList
397
+ }
398
+
399
+ test(" nested ListMap[String, List[Int]]" ) {
400
+ val v = scala
401
+ .collection
402
+ .immutable
403
+ .ListMap (" numbers" -> List (1 , 2 , 3 ), " more" -> List (4 , 5 ), " empty" -> List .empty[Int ])
404
+ val msgpack = ObjectWeaver .weave(v)
405
+ val v2 = ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , List [Int ]]](msgpack)
406
+ v shouldBe v2
407
+ // Verify order is preserved
408
+ v.keys.toList shouldBe v2.keys.toList
409
+ }
410
+
411
+ test(" nested ListMap[String, ListMap[String, Int]]" ) {
412
+ val v = scala
413
+ .collection
414
+ .immutable
415
+ .ListMap (
416
+ " group1" -> scala.collection.immutable.ListMap (" a" -> 1 , " b" -> 2 ),
417
+ " group2" -> scala.collection.immutable.ListMap (" x" -> 10 , " y" -> 20 ),
418
+ " empty" -> scala.collection.immutable.ListMap .empty[String , Int ]
419
+ )
420
+ val msgpack = ObjectWeaver .weave(v)
421
+ val v2 = ObjectWeaver .unweave[
422
+ scala.collection.immutable.ListMap [String , scala.collection.immutable.ListMap [String , Int ]]
423
+ ](msgpack)
424
+ v shouldBe v2
425
+ // Verify order is preserved for outer map
426
+ v.keys.toList shouldBe v2.keys.toList
427
+ // Verify order is preserved for inner maps
428
+ v(" group1" ).keys.toList shouldBe v2(" group1" ).keys.toList
429
+ v(" group2" ).keys.toList shouldBe v2(" group2" ).keys.toList
430
+ }
431
+
432
+ test(" ListMap preserves insertion order" ) {
433
+ // Create ListMap with specific order
434
+ val builder = scala.collection.immutable.ListMap .newBuilder[String , Int ]
435
+ builder += (" third" -> 3 )
436
+ builder += (" first" -> 1 )
437
+ builder += (" second" -> 2 )
438
+ val v = builder.result()
439
+
440
+ val msgpack = ObjectWeaver .weave(v)
441
+ val v2 = ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , Int ]](msgpack)
442
+
443
+ // Verify values are correct
444
+ v shouldBe v2
445
+ // Verify insertion order is preserved
446
+ v.keys.toList shouldBe List (" third" , " first" , " second" )
447
+ v2.keys.toList shouldBe List (" third" , " first" , " second" )
448
+ v.values.toList shouldBe List (3 , 1 , 2 )
449
+ v2.values.toList shouldBe List (3 , 1 , 2 )
450
+ }
451
+
452
+ test(" handle malformed ListMap data gracefully" ) {
453
+ import wvlet .ai .core .msgpack .spi .MessagePack
454
+ // Create a malformed msgpack where we claim there are more pairs than we provide
455
+ val packer = MessagePack .newPacker()
456
+ packer.packMapHeader(3 ) // Say we have 3 key-value pairs
457
+ packer.packString(" key1" ) // Valid first key
458
+ packer.packInt(1 ) // Valid first value
459
+ packer.packString(" key2" ) // Valid second key
460
+ packer.packInt(2 ) // Valid second value
461
+ // Missing third key-value pair!
462
+
463
+ val malformedMsgpack = packer.toByteArray
464
+
465
+ val result =
466
+ try
467
+ ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , Int ]](malformedMsgpack)
468
+ None
469
+ catch
470
+ case e : Exception =>
471
+ Some (e)
472
+
473
+ result.isDefined shouldBe true
474
+ }
475
+
476
+ test(" handle malformed ListMap value gracefully" ) {
477
+ import wvlet .ai .core .msgpack .spi .MessagePack
478
+ // Create a malformed msgpack map with wrong value type
479
+ val packer = MessagePack .newPacker()
480
+ packer.packMapHeader(2 ) // Say we have 2 key-value pairs
481
+ packer.packString(" key1" ) // Valid first key
482
+ packer.packInt(1 ) // Valid first value
483
+ packer.packString(" key2" ) // Valid second key
484
+ packer.packString(" invalid" ) // Invalid second value for ListMap[String, Int]
485
+
486
+ val malformedMsgpack = packer.toByteArray
487
+
488
+ val result =
489
+ try
490
+ ObjectWeaver .unweave[scala.collection.immutable.ListMap [String , Int ]](malformedMsgpack)
491
+ None
492
+ catch
493
+ case e : Exception =>
494
+ Some (e)
495
+
496
+ result.isDefined shouldBe true
497
+ result.get.getMessage.contains(" Cannot convert" ) shouldBe true
498
+ }
499
+
362
500
end WeaverTest
0 commit comments