@@ -597,6 +597,111 @@ def test_zero_length(self):
597597 assert ms .decode_row (b"" ) == {}
598598
599599
600+ class TestJSONBinaryCodec :
601+ def test_encode_requires_binary (self ):
602+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
603+ with pytest .raises (
604+ exceptions .MetadataEncodingError ,
605+ match = "requires top-level '_binary' bytes-like value" ,
606+ ):
607+ ms .validate_and_encode_row ({})
608+
609+ def test_zero_length_blob (self ):
610+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
611+ encoded = ms .validate_and_encode_row ({"_binary" : b"" })
612+ decoded = ms .decode_row (encoded )
613+ assert isinstance (decoded ["_binary" ], memoryview )
614+ assert len (decoded ["_binary" ]) == 0
615+ # JSON portion was empty
616+ assert set (decoded .keys ()) == {"_binary" }
617+
618+ def test_round_trip_with_blob_and_json (self ):
619+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
620+ blob = b"\x00 \x01 \x02 hello"
621+ row = {"label" : "alpha" , "count" : 7 , "_binary" : blob }
622+ encoded = ms .validate_and_encode_row (row )
623+ out = ms .decode_row (encoded )
624+ assert out ["label" ] == "alpha"
625+ assert out ["count" ] == 7
626+ assert isinstance (out ["_binary" ], memoryview )
627+ assert out ["_binary" ].tobytes () == blob
628+
629+ def test_decode_without_magic_errors (self ):
630+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
631+ # Plain JSON is not acceptable for this codec
632+ with pytest .raises (ValueError , match = "missing magic header" ):
633+ ms .decode_row (b"{}" )
634+
635+ def test_simple_default (self ):
636+ schema = {
637+ "codec" : "json+binary" ,
638+ "type" : "object" ,
639+ "properties" : {"number" : {"type" : "number" , "default" : 5 }},
640+ }
641+ ms = tskit .MetadataSchema (schema )
642+ # With json+binary, we need to provide _binary even for empty metadata
643+ assert ms .decode_row (ms .validate_and_encode_row ({"_binary" : b"" })) == {
644+ "number" : 5 ,
645+ "_binary" : memoryview (b"" ),
646+ }
647+ assert ms .decode_row (
648+ ms .validate_and_encode_row ({"_binary" : b"" , "number" : 42 })
649+ ) == {"number" : 42 , "_binary" : memoryview (b"" )}
650+
651+ def test_nested_default_error (self ):
652+ schema = {
653+ "codec" : "json+binary" ,
654+ "type" : "object" ,
655+ "properties" : {
656+ "obj" : {
657+ "type" : "object" ,
658+ "properties" : {
659+ "nested_obj_no_default" : {
660+ "type" : "object" ,
661+ "properties" : {},
662+ },
663+ "nested_obj" : {
664+ "type" : "object" ,
665+ "properties" : {},
666+ "default" : {"foo" : "bar" },
667+ },
668+ },
669+ }
670+ },
671+ }
672+ with pytest .raises (
673+ tskit .MetadataSchemaValidationError ,
674+ match = "Defaults can only be specified at the top level for JSON codec" ,
675+ ):
676+ tskit .MetadataSchema (schema )
677+
678+ def test_bad_type_error (self ):
679+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
680+ # json+binary first checks for _binary key, so we need a dict with _binary
681+ # but other fields that can't be JSON encoded
682+ with pytest .raises (
683+ exceptions .MetadataEncodingError ,
684+ match = "Could not encode metadata of type TableCollection" ,
685+ ):
686+ ms .validate_and_encode_row (
687+ {"_binary" : b"" , "bad_field" : tskit .TableCollection (1 )}
688+ )
689+
690+ def test_skip_validation (self ):
691+ ms = tskit .MetadataSchema ({"codec" : "json+binary" })
692+ assert ms ._bypass_validation
693+ with patch .object (ms , "_validate_row" , return_value = True ) as mocked_validate :
694+ ms .validate_and_encode_row ({"_binary" : b"" })
695+ assert mocked_validate .call_count == 0
696+
697+ def test_dont_skip_validation (self ):
698+ ms = tskit .MetadataSchema ({"codec" : "json+binary" , "properties" : {"foo" : {}}})
699+ assert not ms ._bypass_validation
700+ with patch .object (ms , "_validate_row" , return_value = True ) as mocked_validate :
701+ ms .validate_and_encode_row ({"_binary" : b"" })
702+ assert mocked_validate .call_count == 1
703+
704+
600705class TestStructCodec :
601706 def encode_decode (self , method_name , sub_schema , obj , buffer ):
602707 assert (
0 commit comments