chiark / gitweb /
t/t-bytes.py: Check that indexing, slicing, etc. return `C.ByteString'.
[catacomb-python] / t / t-bytes.py
CommitLineData
553d59fe
MW
1### -*- mode: python, coding: utf-8 -*-
2###
3### Test `ByteString'
4###
5### (c) 2019 Straylight/Edgeware
6###
7
8###----- Licensing notice ---------------------------------------------------
9###
10### This file is part of the Python interface to Catacomb.
11###
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.
16###
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.
21###
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,
25### USA.
26
27###--------------------------------------------------------------------------
28### Imported modules.
29
30import sys as SYS
31import catacomb as C
32import unittest as U
33import testutils as T
34
35###--------------------------------------------------------------------------
36class TestByteString (U.TestCase):
37
38 def test_create(me):
39
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)
45
46 def test_index(me):
47
48 x = C.ByteString(T.bin("once upon a time there was a string"))
49
50 ## Check that simple indexing works.
49e3a113 51 me.assertEqual(type(x[3]), C.ByteString)
553d59fe
MW
52 me.assertEqual(x[3], 'e')
53 me.assertEqual(x[-5], 't')
54
55 ## Check out-of-range detection.
56 x[34]; me.assertRaises(IndexError, lambda: x[35])
57 x[-35]; me.assertRaises(IndexError, lambda: x[-36])
58
49e3a113
MW
59 ## Check slicing. This should always give us bytes.
60 me.assertEqual(type(x[7:17]), C.ByteString)
553d59fe
MW
61 me.assertEqual(x[7:17], T.bin("on a time "))
62
63 ## Complex slicing is also supported.
64 me.assertEqual(x[5:23:3], C.bytes("756e206d7472"))
65
66 def test_compare(me):
67 """
68 Test byte string comparison.
69
70 This is rather important, since we override it and many of the other
71 tests assume that comparison works.
72 """
73
74 def check(big, small):
75 """Check comparisons between BIG and SMALL strings."""
76
77 ## Equality.
78 me.assertTrue(big == big)
79 me.assertFalse(big == small)
80
81 ## Inequality.
82 me.assertFalse(big != big)
83 me.assertTrue(big != small)
84
85 ## Strict less-than.
86 me.assertFalse(big < big)
87 me.assertFalse(big < small)
88 me.assertTrue(small < big)
89
90 ## Non-strict less-than.
91 me.assertTrue(big <= big)
92 me.assertFalse(big <= small)
93 me.assertTrue(small <= big)
94
95 ## Non-strict greater-than.
96 me.assertTrue(big >= big)
97 me.assertTrue(big >= small)
98 me.assertFalse(small >= big)
99
100 ## Strict greater-than.
101 me.assertFalse(big > big)
102 me.assertTrue(big > small)
103 me.assertFalse(small > big)
104
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")))
108
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")))
112
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))
118
119 def test_operators(me):
120
121 ## Some example strings.
122 x = C.bytes("03a5fc")
123 y = C.bytes("5fac30")
124 z = C.bytes("00000000")
125
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)
130
131 ## Bitwise AND.
132 me.assertEqual(type(x&y), C.ByteString)
133 me.assertEqual(x&y, C.bytes("03a430"))
134
135 ## Bitwise OR.
136 me.assertEqual(type(x | y), C.ByteString)
137 me.assertEqual(x | y, C.bytes("5fadfc"))
138
139 # Bitwise XOR.
140 me.assertEqual(type(x ^ y), C.ByteString)
141 me.assertEqual(x ^ y, C.bytes("5c09cc"))
142
143 # Bitwise NOT.
144 me.assertEqual(type(~x), C.ByteString)
145 me.assertEqual(~x, C.bytes("fc5a03"))
146
147 ## Concatenation.
49e3a113 148 me.assertEqual(type(x + y), C.ByteString)
553d59fe
MW
149 me.assertEqual(x + y, C.bytes("03a5fc5fac30"))
150
151 ## Replication (asymmetric but commutative).
49e3a113
MW
152 me.assertEqual(type(3*x), C.ByteString)
153 me.assertEqual(type(x*3), C.ByteString)
553d59fe
MW
154 me.assertEqual(3*x, C.bytes("03a5fc03a5fc03a5fc"))
155 me.assertEqual(x*3, C.bytes("03a5fc03a5fc03a5fc"))
156
157 ## Replication by zero (regression test).
49e3a113
MW
158 me.assertEqual(type(0*x), C.ByteString)
159 me.assertEqual(type(x*0), C.ByteString)
553d59fe
MW
160 me.assertEqual(0*x, C.ByteString(T.bin("")))
161 me.assertEqual(x*0, C.ByteString(T.bin("")))
162
163 def test_zero(me):
164 me.assertEqual(C.ByteString.zero(7), T.bin(7*"\0"))
165 me.assertEqual(C.ByteString.zero(0), T.bin(""))
166
167###----- That's all, folks --------------------------------------------------
168
169if __name__ == "__main__": U.main()