def test_valid_creation(self): """ Test that we can create an encoder object from valid data. """ for good_data in [[1, 2, 3], 1, b"string", b"12", {b"key": 3}]: with self.subTest(msg=f"Good data {good_data}."): self.assertIsInstance(bencode.Encoder(good_data), bencode.Encoder)
def test_invalid_creation(self): """ Test that we cannot create an encoder object from invalid data. """ for bad_data in [None, [], bytes(), OrderedDict(), 0]: with self.subTest(msg=f"No/empty data {bad_data}."): with self.assertRaises(bencode.EncodeError): bencode.Encoder(bad_data)
def test__encode_int(self): """ Tests the encoder's integer encoding """ valid_int = [(12, b"i12e"), (0, b"i0e"), (-100, b"i-100e")] encoder = bencode.Encoder([1, 2, 3]) # bogus data for t in valid_int: with self.subTest(smg=f"Valid int {t[0]}"): self.assertEqual(encoder._encode_int(t[0]), t[1])
def test__encode_bytestr(self): """ Tests the encoder's bytestring encoding """ valid_strings = [(b"value", b"5:value"), (b"", b"0:")] encoder = bencode.Encoder([1, 2, 3]) # bogus data for t in valid_strings: with self.subTest(msg=f"Valid string {t[0]}"): self.assertEqual(encoder._encode_bytestr(t[0]), t[1])
def test__encode_list(self): """ Tests the implementation of list bencoding. """ valid_lists = [([1, 2, 3], b"li1ei2ei3ee"), ([[1], [], [1]], b"lli1eeleli1eee"), ([b"val", OrderedDict({"key": b"val"}), [[]]], b"l3:vald3:key3:valelleee")] encoder = bencode.Encoder([1, 2, 3]) # bogus data for case in valid_lists: with self.subTest(msg=f"Valid list {case[0]}"): self.assertEqual(encoder._encode_list(case[0]), case[1])
def test__encode(self): """ Tests that _encode functions properly. """ empty_vals = {b"de": dict(), b"le": list(), b"0:": bytes()} encoder = bencode.Encoder([1, 2, 3]) # bogus data for k, v in empty_vals.items(): with self.subTest(msg=f"Empty value {v}."): self.assertEqual(encoder._encode(v), k) invalid_vals = [True, set(), TestCase] for v in invalid_vals: with self.subTest(msg=f"Invalid value {v}."): with self.assertRaises(bencode.EncodeError): encoder._encode(v)
def test__encode_dict(self): """ Tests the implementation of dictionary bencoding. """ encoder = bencode.Encoder([1, 2, 3]) # bogus data with self.subTest(msg="Invalid dict key."): with self.assertRaises(bencode.EncodeError): data = OrderedDict({1: b"val"}) encoder._encode_dict(data) with self.subTest(msg="Unsorted keys."): with self.assertRaises(bencode.EncodeError): data = OrderedDict({"b": b"val", "a": b"val"}) encoder._encode_dict(data) with self.subTest(msg="Valid dictionary."): data = OrderedDict({"a": OrderedDict({"b": [1, 2, 3]})}) self.assertEqual(encoder._encode_dict(data), b"d1:ad1:bli1ei2ei3eeee")
def test_decode_recode_compare(self): """ This should probably live in test_bencode.py, but resides here now since this class creates a .torrent metainfo file with an external program. TODO: move this test to a more proper location """ file_copy = os.path.abspath( os.path.join(os.path.dirname(__file__), "copy.torrent")) with open(self.external_torrent_path, 'rb') as f: data = f.read() unencoded_data = bencode.Decoder(data).decode() with open(file_copy, 'wb+') as ff: encoded_data = bencode.Encoder(unencoded_data).encode() ff.write(encoded_data) self.assertTrue(cmp(self.external_torrent_path, file_copy)) os.remove(file_copy)