def test_serialize_sequence(self):
     Seq = typing.Sequence[st.uint16]
     self.assertEqual(bcs.serialize([], Seq), b"\x00")
     self.assertEqual(bcs.serialize([0, 1], Seq), b"\x02\x00\x00\x01\x00")
     self.assertEqual(bcs.serialize([256] * 128, Seq),
                      b"\x80\x01" + b"\x00\x01" * 128)
     self.assertEqual(bcs.deserialize(b"\x01\x03\x00", Seq), ([3], b""))
    def test_serialize_bytes(self):
        self.assertEqual(bcs.serialize(b"", bytes), b"\x00")
        self.assertEqual(bcs.serialize(b"\x00\x00", bytes), b"\x02\x00\x00")
        self.assertEqual(bcs.serialize(b"\x00" * 128, bytes),
                         b"\x80\x01" + b"\x00" * 128)

        self.assertEqual(bcs.deserialize(b"\x00", bytes), (b"", b""))
 def test_bcs_bool(self):
     self.assertEqual(bcs.serialize(False, st.bool), b"\x00")
     self.assertEqual(bcs.serialize(True, st.bool), b"\x01")
     self.assertEqual(bcs.deserialize(b"\x00", st.bool), (False, b""))
     self.assertEqual(bcs.deserialize(b"\x01", st.bool), (True, b""))
     with self.assertRaises(st.DeserializationError):
         bcs.deserialize(b"\x02", st.bool)
     with self.assertRaises(st.DeserializationError):
         bcs.deserialize(b"", st.bool)
 def test_serialize_option(self):
     T = typing.Optional[st.uint16]
     self.assertEqual(bcs.serialize(None, T), b"\x00")
     self.assertEqual(bcs.serialize(6, T), b"\x01\x06\x00")
     self.assertEqual(bcs.deserialize(b"\x00", T), (None, b""))
     self.assertEqual(bcs.deserialize(b"\x01\x02\x00", T), (2, b""))
     with self.assertRaisesRegex(st.DeserializationError, "Wrong tag.*"):
         # Must enforce canonical encoding.
         bcs.deserialize(b"\x02\x06\x00", T)
 def test_serialize_map(self):
     Map = typing.Dict[st.uint16, st.uint8]
     m = OrderedDict([(1, 5), (256, 3)])
     e = bcs.serialize(m, Map)
     self.assertEqual(e, b"\x02\x00\x01\x03\x01\x00\x05")
     self.assertEqual((m, b""),
                      bcs.deserialize(b"\x02\x00\x01\x03\x01\x00\x05", Map))
     m2 = OrderedDict([(256, 3), (1, 5)])
     e2 = bcs.serialize(m2, Map)
     self.assertEqual(e2, e)
     with self.assertRaises(st.DeserializationError):
         # Must enforce canonical encoding.
         bcs.deserialize(b"\x02\x01\x00\x05\x00\x01\x03", Map)
 def test_bcs_u64(self):
     self.assertEqual(
         bcs.serialize(0x0102030405060708, st.uint64),
         b"\x08\x07\x06\x05\x04\x03\x02\x01",
     )
     self.assertEqual(bcs.deserialize(b"\xff" * 8, st.uint64),
                      ((1 << 64) - 1, b""))
 def test_serialize_str(self):
     self.assertEqual(bcs.serialize("ABC\u0394", str), b"\x05ABC\xce\x94")
     self.assertEqual(bcs.deserialize(b"\x05ABC\xce\x94A", str),
                      ("ABC\u0394", b"A"))
     with self.assertRaises(st.DeserializationError):
         bcs.deserialize(b"\x03AB", str)
     with self.assertRaises(st.DeserializationError):
         bcs.deserialize(b"\x03\x80ab", str)
 def test_struct(self):
     self.assertEqual(
         bcs.serialize(BcsTestCase.Foo(x=0, y=1), BcsTestCase.Foo),
         b"\x00\x01\x00")
     self.assertEqual(
         bcs.deserialize(b"\x02\x01\x00", BcsTestCase.Foo),
         (BcsTestCase.Foo(x=2, y=1), b""),
     )
 def test_bcs_i128(self):
     self.assertEqual(
         bcs.serialize(st.int128(0x0102030405060708090A0B0C0D0E0F10),
                       st.int128),
         b"\x10\x0f\x0e\r\x0c\x0b\n\t\x08\x07\x06\x05\x04\x03\x02\x01",
     )
     self.assertEqual(bcs.deserialize(b"\xff" * 16, st.int128),
                      (st.int128(-1), b""))
 def test_enum(self):
     self.assertEqual(
         bcs.serialize(BcsTestCase.Bar1(x=0, y=1), BcsTestCase.Bar),
         b"\x01\x00\x01\x00",
     )
     self.assertEqual(
         bcs.deserialize(b"\x01\x02\x01\x00", BcsTestCase.Bar),
         (BcsTestCase.Bar1(x=2, y=1), b""),
     )
 def test_serialize_set(self):
     Set = typing.Dict[st.uint16, st.unit]
     m = {256: None, 1: None}
     e = bcs.serialize(m, Set)
     self.assertEqual(e, b"\x02\x00\x01\x01\x00")
     self.assertEqual((m, b""), bcs.deserialize(b"\x02\x00\x01\x01\x00",
                                                Set))
     with self.assertRaises(st.DeserializationError):
         # Must enforce canonical encoding.
         bcs.deserialize(b"\x02\x01\x00\x00\x01", Set)
 def test_bcs_i32(self):
     self.assertEqual(bcs.serialize(0x01020304, st.int32),
                      b"\x04\x03\x02\x01")
     self.assertEqual(bcs.deserialize(b"\xff\xff\xff\xff", st.int32),
                      (-1, b""))
 def test_bcs_i16(self):
     self.assertEqual(bcs.serialize(0x0102, st.int16), b"\x02\x01")
     self.assertEqual(bcs.deserialize(b"\xff\xff", st.int16), (-1, b""))
 def test_bcs_i8(self):
     self.assertEqual(bcs.serialize(4, st.int8), b"\x04")
     self.assertEqual(bcs.serialize(-2, st.int8), b"\xfe")
     self.assertEqual(bcs.deserialize(b"\xff", st.int8), (-1, b""))
 def test_deserialize_long_sequence(self):
     Seq = typing.Sequence[st.uint16]
     five = st.uint16(5)
     v = [five] * 1000000
     b = bcs.serialize(v, Seq)
     self.assertEqual(bcs.deserialize(b, Seq), (v, b""))
 def test_bcs_u32(self):
     self.assertEqual(bcs.serialize(0x01020304, st.uint32),
                      b"\x04\x03\x02\x01")
     self.assertEqual(bcs.deserialize(b"\xff\xff\xff\xff", st.uint32),
                      (4294967295, b""))
 def test_bcs_u8(self):
     self.assertEqual(bcs.serialize(0x1, st.uint8), b"\x01")
     self.assertEqual(bcs.deserialize(b"\xff", st.uint8), (255, b""))
    def test_max_container_depth(self):
        # Required to avoid RecursionError's in python.
        sys.setrecursionlimit(bcs.MAX_CONTAINER_DEPTH * 5)

        l1 = BcsTestCase.List.integers(4)
        b1 = bcs.serialize(l1, BcsTestCase.List)
        self.assertEqual(
            b1,
            bytes([
                # fmt: off
                1,
                3,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                1,
                2,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                1,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0
            ]),
        )
        self.assertEqual(bcs.deserialize(b1, BcsTestCase.List), (l1, b""))

        l2 = BcsTestCase.List.integers(bcs.MAX_CONTAINER_DEPTH - 1)
        b2 = bcs.serialize(l2, BcsTestCase.List)
        self.assertEqual(bcs.deserialize(b2, BcsTestCase.List), (l2, b""))

        l3 = BcsTestCase.List.integers(bcs.MAX_CONTAINER_DEPTH)
        with self.assertRaises(st.SerializationError):
            bcs.serialize(l3, BcsTestCase.List)

        b3 = bytes([1, 243, 1, 0, 0, 0, 0, 0, 0]) + b2
        with self.assertRaisesRegex(st.DeserializationError,
                                    "Exceeded maximum container depth.*"):
            self.assertEqual(bcs.deserialize(b3, BcsTestCase.List))

        # Pairs don't count in "container depth".
        P = typing.Tuple[BcsTestCase.List, BcsTestCase.List]
        self.assertEqual(bcs.deserialize(b2 + b2, P), ((l2, l2), b""))
        with self.assertRaisesRegex(st.DeserializationError,
                                    "Exceeded maximum container depth.*"):
            bcs.deserialize(b2 + b3, P)
 def test_serialize_tuple(self):
     T = typing.Tuple[st.uint8, st.uint16]
     self.assertEqual(bcs.serialize((0, 1), T), b"\x00\x01\x00")
     self.assertEqual(bcs.deserialize(b"\x02\x01\x00", T), ((2, 1), b""))