1 ### -*- mode: python, coding: utf-8 -*-
5 ### (c) 2019 Straylight/Edgeware
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the Python interface to Catacomb.
12 ### Catacomb/Python is free software: you can redistribute it and/or
13 ### modify it under the terms of the GNU General Public License as
14 ### published by the Free Software Foundation; either version 2 of the
15 ### License, or (at your option) any later version.
17 ### Catacomb/Python is distributed in the hope that it will be useful, but
18 ### WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ### General Public License for more details.
22 ### You should have received a copy of the GNU General Public License
23 ### along with Catacomb/Python. If not, write to the Free Software
24 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
27 ###--------------------------------------------------------------------------
35 ###--------------------------------------------------------------------------
36 class TestByteString (U.TestCase):
40 ## Create a string and make sure it looks right.
41 x = C.ByteString(T.bin("abcde"))
42 me.assertEqual(x, T.bin("abcde"))
43 me.assertEqual(x, C.bytes("6162636465"))
44 me.assertEqual(len(x), 5)
48 x = C.ByteString(T.bin("once upon a time there was a string"))
50 ## Check that simple indexing works.
51 me.assertEqual(type(x[3]), C.ByteString)
52 me.assertEqual(x[3], 'e')
53 me.assertEqual(x[-5], 't')
55 ## Check out-of-range detection.
56 x[34]; me.assertRaises(IndexError, lambda: x[35])
57 x[-35]; me.assertRaises(IndexError, lambda: x[-36])
59 ## Check slicing. This should always give us bytes.
60 me.assertEqual(type(x[7:17]), C.ByteString)
61 me.assertEqual(x[7:17], T.bin("on a time "))
63 ## Complex slicing is also supported.
64 me.assertEqual(x[5:23:3], C.bytes("756e206d7472"))
68 Test byte string comparison.
70 This is rather important, since we override it and many of the other
71 tests assume that comparison works.
74 def check(big, small):
75 """Check comparisons between BIG and SMALL strings."""
78 me.assertTrue(big == big)
79 me.assertFalse(big == small)
82 me.assertFalse(big != big)
83 me.assertTrue(big != small)
86 me.assertFalse(big < big)
87 me.assertFalse(big < small)
88 me.assertTrue(small < big)
90 ## Non-strict less-than.
91 me.assertTrue(big <= big)
92 me.assertFalse(big <= small)
93 me.assertTrue(small <= big)
95 ## Non-strict greater-than.
96 me.assertTrue(big >= big)
97 me.assertTrue(big >= small)
98 me.assertFalse(small >= big)
100 ## Strict greater-than.
101 me.assertFalse(big > big)
102 me.assertTrue(big > small)
103 me.assertFalse(small > big)
105 ## Strings with equal length.
106 check(C.ByteString(T.bin("a string which is unlike the second")),
107 C.ByteString(T.bin("a string that is not like the first")))
109 ## A string and a prefix of it.
110 check(C.ByteString(T.bin("short strings order before longer ones")),
111 C.ByteString(T.bin("short string")))
113 ## The `ctstreq' function.
114 x = T.bin("special test string")
115 y = T.bin("my different string")
116 me.assertTrue(C.ctstreq(x, x))
117 me.assertFalse(C.ctstreq(x, y))
119 def test_operators(me):
121 ## Some example strings.
122 x = C.bytes("03a5fc")
123 y = C.bytes("5fac30")
124 z = C.bytes("00000000")
126 ## Operands of a binary operator must have equal lengths.
127 me.assertRaises(ValueError, lambda: x&z)
128 me.assertRaises(ValueError, lambda: x|z)
129 me.assertRaises(ValueError, lambda: x^z)
132 me.assertEqual(type(x&y), C.ByteString)
133 me.assertEqual(x&y, C.bytes("03a430"))
136 me.assertEqual(type(x | y), C.ByteString)
137 me.assertEqual(x | y, C.bytes("5fadfc"))
140 me.assertEqual(type(x ^ y), C.ByteString)
141 me.assertEqual(x ^ y, C.bytes("5c09cc"))
144 me.assertEqual(type(~x), C.ByteString)
145 me.assertEqual(~x, C.bytes("fc5a03"))
148 me.assertEqual(type(x + y), C.ByteString)
149 me.assertEqual(x + y, C.bytes("03a5fc5fac30"))
151 ## Replication (asymmetric but commutative).
152 me.assertEqual(type(3*x), C.ByteString)
153 me.assertEqual(type(x*3), C.ByteString)
154 me.assertEqual(3*x, C.bytes("03a5fc03a5fc03a5fc"))
155 me.assertEqual(x*3, C.bytes("03a5fc03a5fc03a5fc"))
157 ## Replication by zero (regression test).
158 me.assertEqual(type(0*x), C.ByteString)
159 me.assertEqual(type(x*0), C.ByteString)
160 me.assertEqual(0*x, C.ByteString(T.bin("")))
161 me.assertEqual(x*0, C.ByteString(T.bin("")))
164 me.assertEqual(C.ByteString.zero(7), T.bin(7*"\0"))
165 me.assertEqual(C.ByteString.zero(0), T.bin(""))
167 ###----- That's all, folks --------------------------------------------------
169 if __name__ == "__main__": U.main()