예제 #1
0
 def test_array(self):
     # invalid length
     with self.assertRaises(DecoderException):
         ubjloadb(ARRAY_START + CONTAINER_COUNT + ubjdumpb(-5))
     # unencodable type within
     with self.assertRaises(EncoderException):
         ubjdumpb([type(None)])
     for sequence in list, tuple:
         self.assertEqual(ubjdumpb(sequence()), ARRAY_START + ARRAY_END)
     self.assertEqual(ubjdumpb((None,), container_count=True), (ARRAY_START + CONTAINER_COUNT + TYPE_UINT8 +
                                                                b'\x01' + TYPE_NULL))
     obj = [123,
            1.25,
            43121609.5543,
            12345.44e40,
            Decimal('10e15'),
            'a',
            'here is a string',
            None,
            True,
            False,
            [[1, 2], 3, [4, 5, 6], 7],
            {'a dict': 456}]
     for opts in ({'container_count': False}, {'container_count': True}):
         self.check_enc_dec(obj, **opts)
예제 #2
0
    def test_circular(self):
        sequence = [1, 2, 3]
        sequence.append(sequence)
        mapping = {'a': 1, 'b': 2}
        mapping['c'] = mapping

        for container in (sequence, mapping):
            with self.assertRaises(EncoderException):
                ubjdumpb(container)

        # Refering to the same container multiple times is valid however
        sequence = [1, 2, 3]
        mapping = {'a': 1, 'b': 2}
        self.check_enc_dec([sequence, mapping, sequence, mapping])
예제 #3
0
    def test_float(self):
        # insufficient length
        for float_type in (TYPE_FLOAT32, TYPE_FLOAT64):
            with self.assertRaises(DecoderException):
                ubjloadb(float_type + b'\x01')

        self.check_enc_dec(0.0, 5, expected_type=TYPE_FLOAT32)

        for type_, value, total_size in (
                (TYPE_FLOAT32, 1.18e-38, 5),
                (TYPE_FLOAT32, 3.4e38, 5),
                (TYPE_FLOAT64, 2.23e-308, 9),
                (TYPE_FLOAT64, 12345.44e40, 9),
                (TYPE_FLOAT64, 1.8e307, 9)):
            self.check_enc_dec(value,
                               total_size,
                               approximate=True,
                               expected_type=type_,
                               no_float32=False)
            # using only float64 (default)
            self.check_enc_dec(value,
                               9 if type_ == TYPE_FLOAT32 else total_size,
                               approximate=True,
                               expected_type=(TYPE_FLOAT64 if type_ == TYPE_FLOAT32 else type_))
        for value in ('nan', '-inf', 'inf'):
            for no_float32 in (True, False):
                self.assertEqual(ubjloadb(ubjdumpb(float(value), no_float32=no_float32)), None)
        # value which results in high_prec usage
        for no_float32 in (True, False):
            self.check_enc_dec(2.22e-308, 4, expected_type=TYPE_HIGH_PREC, length_greater_or_equal=True,
                               no_float32=no_float32)
예제 #4
0
 def test_bytes(self):
     # insufficient length
     with self.assertRaises(DecoderException):
         ubjloadb(ARRAY_START + CONTAINER_TYPE + TYPE_UINT8 + CONTAINER_COUNT + TYPE_UINT8 + b'\x02' + b'\x01')
     self.check_enc_dec(b'')
     self.check_enc_dec(b'\x01' * 4)
     self.assertEqual(ubjloadb(ubjdumpb(b'\x04' * 4), no_bytes=True), [4] * 4)
     self.check_enc_dec(b'largebinary' * 100)
예제 #5
0
 def test_char(self):
     self.assertEqual(ubjdumpb(u('a')), TYPE_CHAR + 'a'.encode('utf-8'))
     # no char, char invalid utf-8
     for suffix in (b'', b'\xfe'):
         with self.assertRaises(DecoderException):
             ubjloadb(TYPE_CHAR + suffix)
     for char in (u('a'), u('\0'), u('~')):
         self.check_enc_dec(char, 2)
예제 #6
0
    def test_high_precision(self):
        self.assertEqual(ubjdumpb(Decimal(-1.5)),
                         TYPE_HIGH_PREC + TYPE_UINT8 + b'\x04' + '-1.5'.encode('utf-8'))
        # insufficient length, invalid utf-8, invalid decimal value
        for suffix in (b'n', b'\xfe\xfe', b'na'):
            with self.assertRaises(DecoderException):
                ubjloadb(TYPE_HIGH_PREC + TYPE_UINT8 + b'\x02' + suffix)

        self.check_enc_dec('1.8e315')
        for value in (
                '0.0',
                '2.5',
                '10e30',
                '-1.2345e67890'):
            # minimum length because: marker + length marker + length + value
            self.check_enc_dec(Decimal(value), 4, length_greater_or_equal=True)
        # cannot compare equality, so test separately (since these evaluate to "NULL"
        for value in ('nan', '-inf', 'inf'):
            self.assertEqual(ubjloadb(ubjdumpb(Decimal(value))), None)
예제 #7
0
 def test_string(self):
     self.assertEqual(ubjdumpb(u('ab')), TYPE_STRING + TYPE_UINT8 + b'\x02' + 'ab'.encode('utf-8'))
     self.check_enc_dec(u(''), 3)
     # invalid string size, string too short, string invalid utf-8
     for suffix in (b'\x81', b'\x01', b'\x01' + b'\xfe'):
         with self.assertRaises(DecoderException):
             ubjloadb(TYPE_STRING + TYPE_INT8 + suffix)
     # Note: In Python 2 plain str type is encoded as byte array
     for string in ('some ascii', u(r'\u00a9 with extended\u2122'), u('long string') * 100):
         self.check_enc_dec(string, 4, length_greater_or_equal=True)
예제 #8
0
    def test_load_all(self):
        test_data = [{
            "an int": 1234,
            "a float": 1.234,
            "some text": "Hello World!"
        }, {
            "an array of text!": ["abc", "def"],
            "A very large number": 123456789101112
        }]

        with open("ubj_multi_object_test.ubj", "wb") as f:
            for item in test_data:
                f.write(ubjdumpb(item))
                curr_file_pos = f.tell()
                f.seek(curr_file_pos + 200)
                f.write(b'\x00')

        with open("ubj_multi_object_test.ubj", "rb") as f:
            output = ubjload_all(f)

        self.assertEqual(test_data, output)
예제 #9
0
 def check_enc_dec(self, obj,
                   # total length of encoded object
                   length=None,
                   # total length is at least the given number of bytes
                   length_greater_or_equal=False,
                   # approximate comparison (e.g. for float)
                   approximate=False,
                   # type marker expected at start of encoded output
                   expected_type=None,
                   # additional arguments to pass to encoder
                   **kwargs):
     """Black-box test to check whether the provided object is the same once encoded and subsequently decoded."""
     encoded = ubjdumpb(obj, **kwargs)
     if expected_type is not None:
         self.type_check(encoded[0], expected_type)
     if length is not None:
         assert_func = self.assertGreaterEqual if length_greater_or_equal else self.assertEqual
         assert_func(len(encoded), length, self.__format_in_out(obj, encoded))
     if approximate:
         self.assertTrue(self.numbers_close(ubjloadb(encoded), obj), msg=self.__format_in_out(obj, encoded))
     else:
         self.assertEqual(ubjloadb(encoded), obj, self.__format_in_out(obj, encoded))
예제 #10
0
    def test_int(self):
        self.assertEqual(ubjdumpb(Decimal(-1.5)),
                         TYPE_HIGH_PREC + TYPE_UINT8 + b'\x04' + '-1.5'.encode('utf-8'))
        # insufficient length
        with self.assertRaises(DecoderException):
            ubjloadb(TYPE_INT16 + b'\x01')

        for type_, value, total_size in (
                (TYPE_UINT8, 0, 2),
                (TYPE_UINT8, 255, 2),
                (TYPE_INT8, -128, 2),
                (TYPE_INT16, -32768, 3),
                (TYPE_INT16, 32767, 3),
                (TYPE_INT32, 2147483647, 5),
                (TYPE_INT32, -2147483648, 5),
                (TYPE_INT64, 9223372036854775807, 9),
                (TYPE_INT64, -9223372036854775808, 9),
                # HIGH_PREC (marker + length marker + length + value)
                (TYPE_HIGH_PREC, 9223372036854775808, 22),
                (TYPE_HIGH_PREC, -9223372036854775809, 23),
                (TYPE_HIGH_PREC, 9999999999999999999999999999999999999, 40)):
            self.check_enc_dec(value, total_size, expected_type=type_)
예제 #11
0
 def ubjdumpb(obj, *args, **kwargs):
     return ubjdumpb(obj, *args, **kwargs)
예제 #12
0
 def __save(self):
     with self.__lock:
         with open(self.__fn, 'wb') as f:
             f.write(ubjdumpb(self.__data))
예제 #13
0
 def test_unencodable(self):
     with self.assertRaises(EncoderException):
         ubjdumpb(type(None))
예제 #14
0
    def test_object(self):
        self.assertEqual(ubjdumpb({}), OBJECT_START + OBJECT_END)
        self.assertEqual(ubjdumpb({'a': None}, container_count=True), (OBJECT_START + CONTAINER_COUNT + TYPE_UINT8 +
                                                                       b'\x01' + TYPE_UINT8 + b'\x01' +
                                                                       'a'.encode('utf-8') + TYPE_NULL))
        self.check_enc_dec({})
        # negative length
        with self.assertRaises(DecoderException):
            ubjloadb(OBJECT_START + CONTAINER_COUNT + ubjdumpb(-1))
        with self.assertRaises(EncoderException):
            ubjdumpb({123: 'non-string key'})
        with self.assertRaises(EncoderException):
            ubjdumpb({'fish': type(list)})
        # invalid key size type
        with self.assertRaises(DecoderException):
            ubjloadb(OBJECT_START + TYPE_NULL)
        # invalid key size, key too short, key invalid utf-8, no value
        for suffix in (b'\x81', b'\x01', b'\x01' + b'\xfe', b'\x0101'):
            with self.assertRaises(DecoderException):
                ubjloadb(OBJECT_START + TYPE_INT8 + suffix)
        self.check_enc_dec({'longkey1' * 65: 1})
        self.check_enc_dec({'longkey2' * 4096: 1})

        obj = {'int': 123,
               'longint': 9223372036854775807,
               'float': 1.25,
               'hp': Decimal('10e15'),
               'char': 'a',
               'str': 'here is a string',
               'unicode': u(r'\u00a9 with extended\u2122'),
               '': 'empty key',
               u(r'\u00a9 with extended\u2122'): 'unicode-key',
               'null': None,
               'true': True,
               'false': False,
               'array': [1, 2, 3],
               'bytes_array': b'1234',
               'object': {'another one': 456, 'yet another': {'abc': True}}}
        for opts in ({'container_count': False}, {'container_count': True}):
            self.check_enc_dec(obj, **opts)

        # dictionary key sorting
        obj1 = OrderedDict.fromkeys('abcdefghijkl')
        obj2 = OrderedDict.fromkeys('abcdefghijkl'[::-1])
        self.assertNotEqual(ubjdumpb(obj1), ubjdumpb(obj2))
        self.assertEqual(ubjdumpb(obj1, sort_keys=True), ubjdumpb(obj2, sort_keys=True))

        # custom mapping class
        with self.assertRaises(TypeError):
            ubjloadb(TYPE_NULL, object_pairs_hook=list)
        self.assertEqual(ubjloadb(ubjdumpb(obj1), object_pairs_hook=OrderedDict), obj1)
예제 #15
0
 def test_null(self):
     self.assertEqual(ubjdumpb(None), TYPE_NULL)
     self.check_enc_dec(None, 1)
예제 #16
0
 def test_bool(self):
     self.assertEqual(ubjdumpb(True), TYPE_BOOL_TRUE)
     self.assertEqual(ubjdumpb(False), TYPE_BOOL_FALSE)
     self.check_enc_dec(True, 1)
     self.check_enc_dec(False, 1)