chiark / gitweb /
.gdbinit: Delete this obsolete file.
[catacomb-python] / t / t-bytes.py
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
30 import sys as SYS
31 import catacomb as C
32 import unittest as U
33 import testutils as T
34
35 ###--------------------------------------------------------------------------
36 class 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.
51     me.assertEqual(type(x[3]), C.ByteString)
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
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 "))
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.
148     me.assertEqual(type(x + y), C.ByteString)
149     me.assertEqual(x + y, C.bytes("03a5fc5fac30"))
150
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"))
156
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("")))
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
169 if __name__ == "__main__": U.main()