chiark / gitweb /
ec.c: Fix length type which should have been `Py_ssize_t'.
[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(x[3], 'e')
52     me.assertEqual(x[-5], 't')
53
54     ## Check out-of-range detection.
55     x[34]; me.assertRaises(IndexError, lambda: x[35])
56     x[-35]; me.assertRaises(IndexError, lambda: x[-36])
57
58     ## Check slicing.
59     me.assertEqual(x[7:17], T.bin("on a time "))
60
61     ## Complex slicing is also supported.
62     me.assertEqual(x[5:23:3], C.bytes("756e206d7472"))
63
64   def test_compare(me):
65     """
66     Test byte string comparison.
67
68     This is rather important, since we override it and many of the other
69     tests assume that comparison works.
70     """
71
72     def check(big, small):
73       """Check comparisons between BIG and SMALL strings."""
74
75       ## Equality.
76       me.assertTrue(big == big)
77       me.assertFalse(big == small)
78
79       ## Inequality.
80       me.assertFalse(big != big)
81       me.assertTrue(big != small)
82
83       ## Strict less-than.
84       me.assertFalse(big < big)
85       me.assertFalse(big < small)
86       me.assertTrue(small < big)
87
88       ## Non-strict less-than.
89       me.assertTrue(big <= big)
90       me.assertFalse(big <= small)
91       me.assertTrue(small <= big)
92
93       ## Non-strict greater-than.
94       me.assertTrue(big >= big)
95       me.assertTrue(big >= small)
96       me.assertFalse(small >= big)
97
98       ## Strict greater-than.
99       me.assertFalse(big > big)
100       me.assertTrue(big > small)
101       me.assertFalse(small > big)
102
103     ## Strings with equal length.
104     check(C.ByteString(T.bin("a string which is unlike the second")),
105           C.ByteString(T.bin("a string that is not like the first")))
106
107     ## A string and a prefix of it.
108     check(C.ByteString(T.bin("short strings order before longer ones")),
109           C.ByteString(T.bin("short string")))
110
111     ## The `ctstreq' function.
112     x = T.bin("special test string")
113     y = T.bin("my different string")
114     me.assertTrue(C.ctstreq(x, x))
115     me.assertFalse(C.ctstreq(x, y))
116
117   def test_operators(me):
118
119     ## Some example strings.
120     x = C.bytes("03a5fc")
121     y = C.bytes("5fac30")
122     z = C.bytes("00000000")
123
124     ## Operands of a binary operator must have equal lengths.
125     me.assertRaises(ValueError, lambda: x&z)
126     me.assertRaises(ValueError, lambda: x|z)
127     me.assertRaises(ValueError, lambda: x^z)
128
129     ## Bitwise AND.
130     me.assertEqual(type(x&y), C.ByteString)
131     me.assertEqual(x&y, C.bytes("03a430"))
132
133     ## Bitwise OR.
134     me.assertEqual(type(x | y), C.ByteString)
135     me.assertEqual(x | y, C.bytes("5fadfc"))
136
137     # Bitwise XOR.
138     me.assertEqual(type(x ^ y), C.ByteString)
139     me.assertEqual(x ^ y, C.bytes("5c09cc"))
140
141     # Bitwise NOT.
142     me.assertEqual(type(~x), C.ByteString)
143     me.assertEqual(~x, C.bytes("fc5a03"))
144
145     ## Concatenation.
146     me.assertEqual(x + y, C.bytes("03a5fc5fac30"))
147
148     ## Replication (asymmetric but commutative).
149     me.assertEqual(3*x, C.bytes("03a5fc03a5fc03a5fc"))
150     me.assertEqual(x*3, C.bytes("03a5fc03a5fc03a5fc"))
151
152     ## Replication by zero (regression test).
153     me.assertEqual(0*x, C.ByteString(T.bin("")))
154     me.assertEqual(x*0, C.ByteString(T.bin("")))
155
156   def test_zero(me):
157     me.assertEqual(C.ByteString.zero(7), T.bin(7*"\0"))
158     me.assertEqual(C.ByteString.zero(0), T.bin(""))
159
160 ###----- That's all, folks --------------------------------------------------
161
162 if __name__ == "__main__": U.main()