bits/tests/test_bits.py

193 lines
7.6 KiB
Python
Raw Normal View History

2020-10-03 20:35:46 -05:00
from unittest import TestCase
2020-10-06 23:29:55 -05:00
from .context import Bits, Bytes
2020-10-03 20:35:46 -05:00
2020-10-06 23:29:55 -05:00
class TestBits(TestCase):
2020-10-03 20:35:46 -05:00
def setUp(self):
self.testObjects = [
2020-10-06 23:29:55 -05:00
{"bytes": b'\x7f',
"bits": "01111111",
"int": 127,
"reverse": 254,
"bitsObject": Bits(127)
},
{"bytes": b'\xcf',
"bits": "11001111",
"int": 207,
"reverse": 243,
"bitsObject": Bits(207)
},
{"bytes": b'{',
"bits": "01111011",
"int": 123,
"reverse": 222,
"bitsObject": Bits(123)
},
{"bytes": b'<',
"bits": "00111100",
"int": 60,
"reverse": 60,
"bitsObject": Bits(60)
},
{"bytes": b'>',
"bits": "00111110",
"int": 62,
"reverse": 124,
"bitsObject": Bits(62)
2020-10-03 20:35:46 -05:00
}
]
2020-10-06 23:29:55 -05:00
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)
2020-10-03 20:35:46 -05:00
def test_bytes(self):
2020-10-06 23:29:55 -05:00
"""
Test conversion to bytes object
"""
2020-10-03 20:35:46 -05:00
for testcase in self.testObjects:
2020-10-06 23:29:55 -05:00
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
self.assertEqual(bytes(testcase["bitsObject"]),
testcase["bytes"])
2020-10-03 20:35:46 -05:00
def test_int(self):
2020-10-06 23:29:55 -05:00
"""
Test integer conversion
"""
2020-10-03 20:35:46 -05:00
for testcase in self.testObjects:
2020-10-06 23:29:55 -05:00
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
self.assertEqual(int(testcase["bitsObject"]), testcase["int"])
2020-10-03 20:35:46 -05:00
def test_str(self):
2020-10-06 23:29:55 -05:00
"""
Test string representation
"""
for testcase in self.testObjects:
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
s = str(testcase["bitsObject"])
self.assertEqual(s, testcase["bits"])
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["bits"])
with self.subTest("testcase[\"int\"]: " + str(testcase["int"]) \
+ " [without leading zeros]"):
self.assertEqual(testcase["bitsObject"].bin(pad=False),
2020-10-13 01:32:50 -05:00
testcase["bits"].lstrip("0"))
2020-10-06 23:29:55 -05:00
def test_reverse(self):
"""
Test the reverse function changes the object bitorder and value
"""
2020-10-04 13:11:46 -05:00
for testcase in self.testObjects:
2020-10-06 23:29:55 -05:00
with self.subTest("testcase[\"int\"]: " + str(testcase["int"])):
testcase["bitsObject"].reverse()
self.assertEqual(testcase["bitsObject"].bin(),
testcase["bits"][::-1])
2020-10-03 20:35:46 -05:00
2020-10-13 01:32:50 -05:00
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)")
2020-10-06 23:29:55 -05:00
def test_comparisons(self):
"""
Test the comparison operators
"""
2020-10-04 13:11:46 -05:00
for testcase in self.testObjects:
2020-10-06 23:29:55 -05:00
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"]))
2020-10-03 20:35:46 -05:00