# The contents of this file are subject to the Mozilla Public License # (MPL) Version 1.1 (the "License"); you may not use this file except # in compliance with the License. You may obtain a copy of the License # at http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and # limitations under the License. # # The Original Code is LEPL (http://www.acooke.org/lepl) # The Initial Developer of the Original Code is Andrew Cooke. # Portions created by the Initial Developer are Copyright (C) 2009-2010 # Andrew Cooke (andrew@acooke.org). All Rights Reserved. # # Alternatively, the contents of this file may be used under the terms # of the LGPL license (the GNU Lesser General Public License, # http://www.gnu.org/licenses/lgpl.html), in which case the provisions # of the LGPL License are applicable instead of those above. # # If you wish to allow use of your version of this file only under the # terms of the LGPL License and not to allow others to use your version # of this file under the MPL, indicate your decision by deleting the # provisions above and replace them with the notice and other provisions # required by the LGPL License. If you do not delete the provisions # above, a recipient may use your version of this file under either the # MPL or the LGPL License. ''' Tests for the lepl.bin.bits module. ''' if bytes is str: print('Binary parsing unsupported in this Python version') else: #from logging import basicConfig, DEBUG from unittest import TestCase from lepl.bin import * # pylint: disable-msg=C0103, C0111, C0301, W0702, C0324 # (dude this is just a test) class IntTest(TestCase): def test_int(self): one = Int(1, 1) assert type(one) == Int assert 1 == one assert len(one) == 1 assert str(one) == '1' assert repr(one) == 'Int(1,1)' assert 3 * one == 3 class BitStringTest(TestCase): def test_lengths(self): assert 0 == unpack_length(0), unpack_length(0) assert 1 == unpack_length(1), unpack_length(1) assert 7 == unpack_length(7), unpack_length(7) assert 8 == unpack_length(8), unpack_length(8) assert 9 == unpack_length(9), unpack_length(9) assert 0 == unpack_length(0.), unpack_length(0.) assert 1 == unpack_length(0.1), unpack_length(0.1) assert 7 == unpack_length(0.7), unpack_length(0.7) assert 8 == unpack_length(1.), unpack_length(1.) assert 8 == unpack_length(1.0), unpack_length(1.0) assert 9 == unpack_length(1.1), unpack_length(1.1) assert 15 == unpack_length(1.7), unpack_length(1.7) assert 16 == unpack_length(2.), unpack_length(2.) self.assert_error(lambda: unpack_length(0.8)) def assert_error(self, thunk): try: thunk() assert False, 'expected error' except: pass def assert_length_value(self, length, value, b): assert len(b) == length, (len(b), length) assert b.to_bytes() == value, (b.to_bytes(), value, b) def test_from_byte(self): self.assert_error(lambda: BitString.from_byte(-1)) self.assert_length_value(8, b'\x00', BitString.from_byte(0)) self.assert_length_value(8, b'\x01', BitString.from_byte(1)) self.assert_length_value(8, b'\xff', BitString.from_byte(255)) self.assert_error(lambda: BitString.from_byte(256)) def test_from_bytearray(self): self.assert_length_value(8, b'\x00', BitString.from_bytearray(b'\x00')) self.assert_length_value(16, b'ab', BitString.from_bytearray(b'ab')) self.assert_length_value(16, b'ab', BitString.from_bytearray(bytearray(b'ab'))) def test_from_int(self): self.assert_length_value(3, b'\x00', BitString.from_int('0o0')) self.assert_error(lambda: BitString.from_int('1o0')) self.assert_error(lambda: BitString.from_int('00o0')) self.assert_error(lambda: BitString.from_int('100o0')) self.assert_error(lambda: BitString.from_int('777o0')) self.assert_length_value(9, b'\x40\x00', BitString.from_int('0o100')) self.assert_length_value(9, b'\xfe\x01', BitString.from_int('0o776')) self.assert_length_value(12, b'\xff\x03', BitString.from_int('0x3ff')) self.assert_length_value(12, b'\xff\x03', BitString.from_int('0o1777')) self.assert_length_value(16, b'\x03\xff', BitString.from_int('03ffx0')) self.assert_length_value(3, b'\x04', BitString.from_int('0b100')) self.assert_length_value(1, b'\x01', BitString.from_int('1b0')) self.assert_length_value(2, b'\x02', BitString.from_int('01b0')) self.assert_length_value(9, b'\x00\x01', BitString.from_int('000000001b0')) self.assert_length_value(9, b'\x01\x01', BitString.from_int('100000001b0')) self.assert_length_value(16, b'\x0f\x33', BitString.from_int('1111000011001100b0')) def test_from_sequence(self): self.assert_length_value(8, b'\x01', BitString.from_sequence([1], BitString.from_byte)) self.assert_error(lambda: BitString.from_sequence([256], BitString.from_byte)) self.assert_length_value(16, b'\x01\x02', BitString.from_sequence([1,2], BitString.from_byte)) def test_from_int_with_length(self): self.assert_error(lambda: BitString.from_int(1, 0)) self.assert_error(lambda: BitString.from_int(0, 1)) self.assert_error(lambda: BitString.from_int(0, 7)) self.assert_length_value(8, b'\x00', BitString.from_int(0, 8)) self.assert_error(lambda: BitString.from_int(0, 0.1)) self.assert_length_value(8, b'\x00', BitString.from_int(0, 1.)) self.assert_length_value(1, b'\x00', BitString.from_int('0x0', 1)) self.assert_length_value(7, b'\x00', BitString.from_int('0x0', 7)) self.assert_length_value(8, b'\x00', BitString.from_int('0x0', 8)) self.assert_length_value(1, b'\x00', BitString.from_int('0x0', 0.1)) self.assert_length_value(8, b'\x00', BitString.from_int('0x0', 1.)) self.assert_length_value(16, b'\x34\x12', BitString.from_int(0x1234, 16)) self.assert_length_value(16, b'\x34\x12', BitString.from_int('0x1234', 16)) self.assert_length_value(16, b'\x12\x34', BitString.from_int('1234x0', 16)) self.assert_length_value(16, b'\x34\x12', BitString.from_int('4660', 16)) self.assert_length_value(16, b'\x34\x12', BitString.from_int('0d4660', 16)) self.assert_length_value(16, b'\x12\x34', BitString.from_int('4660d0', 16)) def test_str(self): b = BitString.from_int32(0xabcd1234) assert str(b) == '00101100 01001000 10110011 11010101b0/32', str(b) b = BitString.from_int('0b110') assert str(b) == '011b0/3', str(b) def test_invert(self): #basicConfig(level=DEBUG) self.assert_length_value(12, b'\x00\x0c', ~BitString.from_int('0x3ff')) def test_add(self): acc = BitString() for i in range(8): acc += BitString.from_int('0o' + str(i)) # >>> hex(0o76543210) # '0xfac688' self.assert_length_value(24, b'\x88\xc6\xfa', acc) acc = BitString() for i in range(7): acc += BitString.from_int('0o' + str(i)) self.assert_length_value(21, b'\x88\xc6\x1a', acc) def test_get_item(self): a = BitString.from_int('01001100011100001111b0') b = a[:] assert a == b, (a, b) b = a[0:] assert a == b, (a, b) b = a[-1::-1] assert BitString.from_int('11110000111000110010b0') == b, b b = a[0] assert BitString.from_int('0b0') == b, (b, str(b), BitString.from_int('0b0')) b = a[1] assert BitString.from_int('1b0') == b, b b = a[0:2] assert BitString.from_int('01b0') == b, b b = a[0:2] assert BitString.from_int('0b10') == b, b b = a[-5:] assert BitString.from_int('01111b0') == b, b b = a[-1:-6:-1] assert BitString.from_int('11110b0') == b, b b = a[1:-1] assert BitString.from_int('100110001110000111b0') == b, b def assert_round_trip(self, start, stop=None, length=None): if stop == None: stop = start result = BitString.from_int(start, length=length).to_int() assert result == stop, (result, stop) if length is not None: assert len(result) == length, (result, length) def test_to_int(self): self.assert_round_trip(0) self.assert_round_trip(1) self.assert_round_trip(1, length=1) self.assert_round_trip(467) self.assert_round_trip(467, length=16) self.assert_round_trip(467, length=19) class SwapTableTest(TestCase): def test_swap(self): table = swap_table() assert table[0x0f] == 0xf0, hex(table[0x0f]) assert table[0xff] == 0xff assert table[0] == 0 assert table[10] == 80, table[10]