X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/e91150b266bbd768905258166601fdf333d3d987..553d59fec08fd9102b21fd0dc83ba708862a6090:/t/t-bytes.py diff --git a/t/t-bytes.py b/t/t-bytes.py new file mode 100644 index 0000000..6755e96 --- /dev/null +++ b/t/t-bytes.py @@ -0,0 +1,162 @@ +### -*- mode: python, coding: utf-8 -*- +### +### Test `ByteString' +### +### (c) 2019 Straylight/Edgeware +### + +###----- Licensing notice --------------------------------------------------- +### +### This file is part of the Python interface to Catacomb. +### +### Catacomb/Python is free software: you can redistribute it and/or +### modify it under the terms of the GNU General Public License as +### published by the Free Software Foundation; either version 2 of the +### License, or (at your option) any later version. +### +### Catacomb/Python is distributed in the hope that it will be useful, but +### WITHOUT ANY WARRANTY; without even the implied warranty of +### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +### General Public License for more details. +### +### You should have received a copy of the GNU General Public License +### along with Catacomb/Python. If not, write to the Free Software +### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +### USA. + +###-------------------------------------------------------------------------- +### Imported modules. + +import sys as SYS +import catacomb as C +import unittest as U +import testutils as T + +###-------------------------------------------------------------------------- +class TestByteString (U.TestCase): + + def test_create(me): + + ## Create a string and make sure it looks right. + x = C.ByteString(T.bin("abcde")) + me.assertEqual(x, T.bin("abcde")) + me.assertEqual(x, C.bytes("6162636465")) + me.assertEqual(len(x), 5) + + def test_index(me): + + x = C.ByteString(T.bin("once upon a time there was a string")) + + ## Check that simple indexing works. + me.assertEqual(x[3], 'e') + me.assertEqual(x[-5], 't') + + ## Check out-of-range detection. + x[34]; me.assertRaises(IndexError, lambda: x[35]) + x[-35]; me.assertRaises(IndexError, lambda: x[-36]) + + ## Check slicing. + me.assertEqual(x[7:17], T.bin("on a time ")) + + ## Complex slicing is also supported. + me.assertEqual(x[5:23:3], C.bytes("756e206d7472")) + + def test_compare(me): + """ + Test byte string comparison. + + This is rather important, since we override it and many of the other + tests assume that comparison works. + """ + + def check(big, small): + """Check comparisons between BIG and SMALL strings.""" + + ## Equality. + me.assertTrue(big == big) + me.assertFalse(big == small) + + ## Inequality. + me.assertFalse(big != big) + me.assertTrue(big != small) + + ## Strict less-than. + me.assertFalse(big < big) + me.assertFalse(big < small) + me.assertTrue(small < big) + + ## Non-strict less-than. + me.assertTrue(big <= big) + me.assertFalse(big <= small) + me.assertTrue(small <= big) + + ## Non-strict greater-than. + me.assertTrue(big >= big) + me.assertTrue(big >= small) + me.assertFalse(small >= big) + + ## Strict greater-than. + me.assertFalse(big > big) + me.assertTrue(big > small) + me.assertFalse(small > big) + + ## Strings with equal length. + check(C.ByteString(T.bin("a string which is unlike the second")), + C.ByteString(T.bin("a string that is not like the first"))) + + ## A string and a prefix of it. + check(C.ByteString(T.bin("short strings order before longer ones")), + C.ByteString(T.bin("short string"))) + + ## The `ctstreq' function. + x = T.bin("special test string") + y = T.bin("my different string") + me.assertTrue(C.ctstreq(x, x)) + me.assertFalse(C.ctstreq(x, y)) + + def test_operators(me): + + ## Some example strings. + x = C.bytes("03a5fc") + y = C.bytes("5fac30") + z = C.bytes("00000000") + + ## Operands of a binary operator must have equal lengths. + me.assertRaises(ValueError, lambda: x&z) + me.assertRaises(ValueError, lambda: x|z) + me.assertRaises(ValueError, lambda: x^z) + + ## Bitwise AND. + me.assertEqual(type(x&y), C.ByteString) + me.assertEqual(x&y, C.bytes("03a430")) + + ## Bitwise OR. + me.assertEqual(type(x | y), C.ByteString) + me.assertEqual(x | y, C.bytes("5fadfc")) + + # Bitwise XOR. + me.assertEqual(type(x ^ y), C.ByteString) + me.assertEqual(x ^ y, C.bytes("5c09cc")) + + # Bitwise NOT. + me.assertEqual(type(~x), C.ByteString) + me.assertEqual(~x, C.bytes("fc5a03")) + + ## Concatenation. + me.assertEqual(x + y, C.bytes("03a5fc5fac30")) + + ## Replication (asymmetric but commutative). + me.assertEqual(3*x, C.bytes("03a5fc03a5fc03a5fc")) + me.assertEqual(x*3, C.bytes("03a5fc03a5fc03a5fc")) + + ## Replication by zero (regression test). + me.assertEqual(0*x, C.ByteString(T.bin(""))) + me.assertEqual(x*0, C.ByteString(T.bin(""))) + + def test_zero(me): + me.assertEqual(C.ByteString.zero(7), T.bin(7*"\0")) + me.assertEqual(C.ByteString.zero(0), T.bin("")) + +###----- That's all, folks -------------------------------------------------- + +if __name__ == "__main__": U.main()