bits/tests/test_bits.py

233 lines
9.2 KiB
Python

from unittest import TestCase
from .context import Bit, Bits, Bytes
class TestBits(TestCase):
def setUp(self):
self.testObjects = [
{"bytes": b'\x7f',
"str": "01111111",
"int": 127,
"hex": "7f",
"reverse": 254,
"bitsObject": Bits(127),
"list": [Bit(0),
Bit(1),
Bit(1),
Bit(1),
Bit(1),
Bit(1),
Bit(1),
Bit(1)
]
},
{"bytes": b'\xcf',
"str": "11001111",
"int": 207,
"hex": "cf",
"reverse": 243,
"bitsObject": Bits(207),
"list": [1, 1, 0, 0, 1, 1, 1, 1]
},
{"bytes": b'{',
"str": "01111011",
"int": 123,
"hex": "7b",
"reverse": 222,
"bitsObject": Bits(123),
"list": ["0", "1", "1", "1", "1", "0", "1", "1"]
},
{"bytes": b'<',
"str": "00111100",
"int": 60,
"hex": "3c",
"reverse": 60,
"bitsObject": Bits(60),
"list": [False,
False,
True,
True,
True,
True,
False,
False
]
},
{"bytes": b'>',
"str": "00111110",
"int": 62,
"hex": "3e",
"reverse": 124,
"bitsObject": Bits(62),
"list": [0,
False,
"1",
1,
Bit("1"),
Bit(True),
Bit(1),
Bit(False)
]
},
{"bytes": b'=',
"str": "00111101",
"int": 61,
"hex": "3d",
"reverse": 188,
"bitsObject": Bits(61),
"list": [True, 1, 1, True, Bit(0), Bit(1)]
}
]
def test_class(self):
"""Test various class features"""
with self.subTest("Reject values > 255"):
self.assertRaises(ValueError, Bits, 256)
with self.subTest("Reject values < 0"):
self.assertRaises(ValueError, Bits, -1)
with self.subTest("Reject binary strings longer than 8 characters"):
self.assertRaises(TypeError, Bits, '1100110011')
with self.subTest("Index errors"):
with self.assertRaises(IndexError):
Bits(127)[9]
with self.subTest("Test length"):
self.assertEqual(len(Bits(0)), 8)
def test_bytes(self):
"""Test conversion to bytes objects"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
self.assertEqual(bytes(testcase["bitsObject"]),
testcase["bytes"])
def test_int(self):
"""Test integer conversion"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
self.assertEqual(int(testcase["bitsObject"]), testcase["int"])
def test_hex(self):
"""Test conversion to hex"""
for testcase in self.testObjects:
with self.subTest("testcase[\"hex\"]: " + str(testcase["hex"])):
self.assertEqual(testcase["bitsObject"].hex(), testcase["hex"])
def test_str(self):
"""Test string representation"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
s = str(testcase["bitsObject"])
self.assertEqual(s, testcase["str"])
def test_list(self):
"""Test list conversion"""
for testcase in self.testObjects:
with self.subTest("testcase[\"list\"]: " + str(testcase["list"])):
self.assertEqual(testcase["bytes"],
bytes(Bits(testcase["list"])))
def test_bits(self):
"""Test bit representation"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
self.assertEqual(testcase["bitsObject"].bin(),
testcase["str"])
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [without leading zeros]"):
self.assertEqual(testcase["bitsObject"].bin(pad=False),
testcase["str"].lstrip("0"))
def test_reverse(self):
"""Test the reverse function changes the object bitorder and value"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
testcase["bitsObject"].reverse()
self.assertEqual(testcase["bitsObject"].bin(),
testcase["str"][::-1])
def test_membership_operators(self):
"""Test the membership operator (x in y)"""
with self.subTest("should all be True"):
for i in range(1, 256):
self.assertTrue(i in Bits(255), f"Bits({i}) in Bits(255) fail")
with self.subTest("should all be False"):
for i in range(1, 256):
self.assertFalse(i in Bits(0), f"Bits({i}) in Bits(0) fail")
with self.subTest("should pass"):
self.assertIn(1, Bits("00100111"), "1 in Bits(39)")
self.assertIn(2, Bits(39), "2 in Bits(39)")
self.assertIn(4, Bits(39), "4 in Bits(39)")
self.assertNotIn(8, Bits(39), "8 in Bits(39)")
self.assertNotIn(16, Bits(39), "16 in Bits(39)")
self.assertIn(32, Bits(39), "32 in Bits(39)")
self.assertNotIn(64, Bits(39), "64 in Bits(39)")
self.assertNotIn(128, Bits(39), "128 in Bits(39)")
def test_binary_operations(self):
self.assertEqual((Bits("00000100") << 3), Bits("00100000"),
"Bits(4) << 3 == Bits(32)")
self.assertEqual((Bits("00100000") << 1), Bits("01000000"),
"Bits(32) << 1 == Bits(64)")
self.assertEqual((Bits(64) >> 2), Bits(16),
"Bits(64) >> 2 == Bits(16)")
self.assertEqual(( 2 << Bits(6)), Bits(128),
"2 << Bits(6) == Bits(128)")
self.assertEqual((Bits(255) & Bits(64)), Bits(64),
"Bits(255) and Bits(64) == Bits(64)")
self.assertNotEqual((Bits(32) & Bits(64)), Bits(64),
"Bits(32) and Bits(64) != Bits(64)")
self.assertEqual((Bits(2) | Bits(32)), 34,
"Bits(2) or Bits(32) == 34")
self.assertEqual((Bits(80) | Bits(64)), Bits(80),
"Bits(80) or Bits(64) == Bits(80)")
self.assertEqual((Bits(80) ^ Bits(64)), Bits(16),
"Bits(80) xor Bits(64) == Bits(16)")
self.assertEqual((Bits(80) & Bits(64)), Bits(64),
"Bits(80) and Bits(64) == Bits(64)")
def test_comparisons(self):
"""Test the comparison operators"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [==]"):
self.assertEqual(testcase["bitsObject"],
Bits(testcase["int"]))
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [!=]"):
# Toggle bit 3
testobj = Bits(testcase["int"])
testobj[3] = not testobj[3]
self.assertNotEqual(testobj, testcase["bitsObject"])
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [<]"):
if testcase["int"] < 255:
self.assertLess(testcase["bitsObject"],
Bits(255))
else:
self.skipTest("value is MAX")
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [<=]"):
if testcase["int"] < 255:
self.assertLessEqual(testcase["bitsObject"], Bits(255))
self.assertLessEqual(testcase["bitsObject"],
Bits(testcase["int"]))
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [>]"):
if testcase["int"] > 0:
self.assertGreater(testcase["bitsObject"], Bits(0))
else:
self.skipTest("value is MIN")
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [>=]"):
if testcase["int"] > 0:
self.assertGreaterEqual(testcase["bitsObject"], Bits(0))
self.assertLessEqual(testcase["bitsObject"],
Bits(testcase["int"]))