1 | #!/usr/bin/env python3 |
||
2 | |||
3 | """Tests for the starstruct class""" |
||
4 | |||
5 | import enum |
||
6 | import struct |
||
7 | import unittest |
||
8 | |||
9 | import pytest |
||
10 | |||
11 | from starstruct.message import Message |
||
12 | # from starstruct.modes import Mode |
||
13 | |||
14 | |||
15 | class SimpleEnum(enum.Enum): |
||
16 | """Simple enum class for testing message pack/unpack""" |
||
17 | one = 1 |
||
18 | two = 2 |
||
19 | three = 3 |
||
20 | |||
21 | |||
22 | # pylint: disable=line-too-long,invalid-name |
||
23 | class TestStarStruct(unittest.TestCase): |
||
24 | """StarStruct module tests""" |
||
25 | |||
26 | VarTest = Message('VarTest', [ |
||
27 | ('x', 'B'), |
||
28 | ('y', 'B'), |
||
29 | ]) |
||
30 | |||
31 | Repeated = Message('Repeated', [ |
||
32 | ('x', 'B'), |
||
33 | ('z', 'H'), |
||
34 | ]) |
||
35 | |||
36 | def test_no_data(self): |
||
37 | num_repeats = 4 |
||
38 | |||
39 | TestStruct = Message('TestStruct', [ |
||
40 | ('length', 'H', 'vardata'), |
||
41 | ('vardata', self.VarTest, 'length'), |
||
42 | ('repeated_data', self.Repeated, num_repeats), |
||
43 | ]) |
||
44 | test_data_no_data = { |
||
45 | 'length': 0, |
||
46 | 'vardata': [], |
||
47 | 'repeated_data': [ |
||
48 | ], |
||
49 | } |
||
50 | |||
51 | made = TestStruct.make(test_data_no_data) |
||
52 | assert made.length == 0 |
||
53 | assert made.vardata == [] |
||
54 | assert made.repeated_data == [] |
||
55 | |||
56 | packed = TestStruct.pack(test_data_no_data) |
||
57 | assert packed == struct.pack('H', 0) + (struct.pack('B', 0) + struct.pack('H', 0)) * num_repeats |
||
58 | |||
59 | View Code Duplication | def test_some_data(self): |
|
0 ignored issues
–
show
Duplication
introduced
by
![]() |
|||
60 | num_repeats = 3 |
||
61 | |||
62 | TestStruct = Message('TestStruct', [ |
||
63 | ('length', 'H', 'vardata'), |
||
64 | ('vardata', self.VarTest, 'length'), |
||
65 | ('repeated_data', self.Repeated, num_repeats), |
||
66 | ]) |
||
67 | |||
68 | test_data = { |
||
69 | 'length': 2, |
||
70 | 'vardata': [ |
||
71 | {'x': 1, 'y': 2}, |
||
72 | {'x': 3, 'y': 4}, |
||
73 | ], |
||
74 | 'repeated_data': [ |
||
75 | {'x': 7, 'z': 13}, |
||
76 | {'x': 2, 'z': 27}, |
||
77 | {'x': 6, 'z': 11}, |
||
78 | ], |
||
79 | } |
||
80 | |||
81 | made = TestStruct.make(test_data) |
||
82 | assert made.length == 2 |
||
83 | assert len(made.vardata) == 2 |
||
84 | assert len(made.repeated_data) == 3 |
||
85 | |||
86 | packed = TestStruct.pack(test_data) |
||
87 | assert packed == struct.pack('H', 2) + \ |
||
88 | struct.pack('BB', 1, 2) + \ |
||
89 | struct.pack('BB', 3, 4) + \ |
||
90 | (struct.pack('B', 7) + struct.pack('H', 13)) + \ |
||
91 | (struct.pack('B', 2) + struct.pack('H', 27)) + \ |
||
92 | (struct.pack('B', 6) + struct.pack('H', 11)) |
||
93 | |||
94 | View Code Duplication | def test_not_all_fixed_data(self): |
|
0 ignored issues
–
show
|
|||
95 | num_repeats = 5 |
||
96 | |||
97 | TestStruct = Message('TestStruct', [ |
||
98 | ('length', 'H', 'vardata'), |
||
99 | ('vardata', self.VarTest, 'length'), |
||
100 | ('repeated_data', self.Repeated, num_repeats), |
||
101 | ]) |
||
102 | |||
103 | test_data = { |
||
104 | 'length': 1, |
||
105 | 'vardata': [ |
||
106 | {'x': 255, 'y': 127}, |
||
107 | ], |
||
108 | 'repeated_data': [ |
||
109 | {'x': 6, 'z': 12}, |
||
110 | {'x': 1, 'z': 26}, |
||
111 | {'x': 5, 'z': 10}, |
||
112 | ], |
||
113 | } |
||
114 | |||
115 | made = TestStruct.make(test_data) |
||
116 | assert made.length == 1 |
||
117 | assert len(made.vardata) == 1 |
||
118 | assert len(made.repeated_data) == 3 |
||
119 | |||
120 | packed = TestStruct.pack(test_data) |
||
121 | assert packed == struct.pack('H', 1) + \ |
||
122 | struct.pack('BB', 255, 127) + \ |
||
123 | (struct.pack('B', 6) + struct.pack('H', 12)) + \ |
||
124 | (struct.pack('B', 1) + struct.pack('H', 26)) + \ |
||
125 | (struct.pack('B', 5) + struct.pack('H', 10)) + \ |
||
126 | (struct.pack('B', 0) + struct.pack('H', 0)) * 2 |
||
127 | |||
128 | View Code Duplication | def test_byte_length_no_data(self): |
|
0 ignored issues
–
show
|
|||
129 | TestStruct = Message('TestStruct', [ |
||
130 | ('length_in_objects', 'H', 'vardata'), |
||
131 | ('vardata', self.VarTest, 'length_in_objects'), |
||
132 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
133 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
134 | |||
135 | ]) |
||
136 | test_data_no_data = { |
||
137 | 'length_in_objects': 0, |
||
138 | 'vardata': [], |
||
139 | 'length_in_bytes': 0, |
||
140 | 'bytesdata': [], |
||
141 | } |
||
142 | |||
143 | made = TestStruct.make(test_data_no_data) |
||
144 | assert made.length_in_objects == 0 |
||
145 | assert made.vardata == [] |
||
146 | assert made.length_in_bytes == 0 |
||
147 | assert made.bytesdata == [] |
||
148 | |||
149 | packed = TestStruct.pack(test_data_no_data) |
||
150 | assert packed == \ |
||
151 | struct.pack('H', 0) + \ |
||
152 | struct.pack('H', 0) |
||
153 | |||
154 | View Code Duplication | def test_byte_length_some_data(self): |
|
0 ignored issues
–
show
|
|||
155 | TestStruct = Message('TestStruct', [ |
||
156 | ('length_in_objects', 'H', 'vardata'), |
||
157 | ('vardata', self.VarTest, 'length_in_objects'), |
||
158 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
159 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
160 | |||
161 | ]) |
||
162 | test_data_no_data = { |
||
163 | 'length_in_objects': 1, |
||
164 | 'vardata': [ |
||
165 | {'x': 255, 'y': 127}, |
||
166 | ], |
||
167 | 'length_in_bytes': 2, |
||
168 | 'bytesdata': [ |
||
169 | {'x': 254, 'y': 126}, |
||
170 | ], |
||
171 | } |
||
172 | |||
173 | made = TestStruct.make(test_data_no_data) |
||
174 | assert made.length_in_objects == 1 |
||
175 | assert made.vardata == [ |
||
176 | self.VarTest.make( |
||
177 | {'x': 255, 'y': 127} |
||
178 | )] |
||
179 | assert made.length_in_bytes == 2 |
||
180 | assert made.bytesdata == [ |
||
181 | self.VarTest.make( |
||
182 | {'x': 254, 'y': 126} |
||
183 | )] |
||
184 | |||
185 | packed = TestStruct.pack(test_data_no_data) |
||
186 | assert packed == \ |
||
187 | struct.pack('H', 1) + \ |
||
188 | struct.pack('BB', 255, 127) + \ |
||
189 | struct.pack('H', 2) + \ |
||
190 | struct.pack('BB', 254, 126) |
||
191 | |||
192 | def test_byte_length_more_data(self): |
||
193 | TestStruct = Message('TestStruct', [ |
||
194 | ('length_in_objects', 'H', 'vardata'), |
||
195 | ('vardata', self.VarTest, 'length_in_objects'), |
||
196 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
197 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
198 | |||
199 | ]) |
||
200 | |||
201 | test_data_no_data = { |
||
202 | 'length_in_objects': 1, |
||
203 | 'vardata': [ |
||
204 | {'x': 255, 'y': 127}, |
||
205 | ], |
||
206 | 'length_in_bytes': 10, |
||
207 | 'bytesdata': [ |
||
208 | {'x': 254, 'y': 126}, |
||
209 | {'x': 25, 'y': 16}, |
||
210 | {'x': 24, 'y': 26}, |
||
211 | {'x': 54, 'y': 17}, |
||
212 | {'x': 25, 'y': 12}, |
||
213 | ], |
||
214 | } |
||
215 | |||
216 | made = TestStruct.make(test_data_no_data) |
||
217 | assert made.length_in_objects == 1 |
||
218 | assert made.vardata == [ |
||
219 | self.VarTest.make( |
||
220 | {'x': 255, 'y': 127} |
||
221 | )] |
||
222 | assert made.length_in_bytes == 10 |
||
223 | assert made.bytesdata == [ |
||
224 | self.VarTest.make( |
||
225 | {'x': 254, 'y': 126} |
||
226 | ), |
||
227 | self.VarTest.make( |
||
228 | {'x': 25, 'y': 16}, |
||
229 | ), |
||
230 | self.VarTest.make( |
||
231 | {'x': 24, 'y': 26}, |
||
232 | ), |
||
233 | self.VarTest.make( |
||
234 | {'x': 54, 'y': 17}, |
||
235 | ), |
||
236 | self.VarTest.make( |
||
237 | {'x': 25, 'y': 12}, |
||
238 | ), |
||
239 | ] |
||
240 | |||
241 | packed = TestStruct.pack(test_data_no_data) |
||
242 | assert packed == \ |
||
243 | struct.pack('H', 1) + \ |
||
244 | struct.pack('BB', 255, 127) + \ |
||
245 | struct.pack('H', 10) + \ |
||
246 | struct.pack('BB', 254, 126) + \ |
||
247 | struct.pack('BB', 25, 16) + \ |
||
248 | struct.pack('BB', 24, 26) + \ |
||
249 | struct.pack('BB', 54, 17) + \ |
||
250 | struct.pack('BB', 25, 12) |
||
251 | |||
252 | def test_unpacking_of_correct_size(self): |
||
253 | packed_element = \ |
||
254 | struct.pack('H', 1) + \ |
||
255 | struct.pack('BB', 255, 127) + \ |
||
256 | struct.pack('H', 10) + \ |
||
257 | struct.pack('BB', 254, 126) + \ |
||
258 | struct.pack('BB', 25, 16) + \ |
||
259 | struct.pack('BB', 24, 26) + \ |
||
260 | struct.pack('BB', 54, 17) + \ |
||
261 | struct.pack('BB', 25, 12) |
||
262 | |||
263 | TestStruct = Message('TestStruct', [ |
||
264 | ('length_in_objects', 'H', 'vardata'), |
||
265 | ('vardata', self.VarTest, 'length_in_objects'), |
||
266 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
267 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
268 | ]) |
||
269 | |||
270 | unpacked = TestStruct.unpack(packed_element) |
||
271 | |||
272 | assert unpacked |
||
273 | assert unpacked.length_in_objects == 1 |
||
274 | assert unpacked.length_in_bytes == 10 |
||
275 | |||
276 | def test_unpacking_of_too_little_bytes(self): |
||
277 | # Only pack four elements, instead of the five |
||
278 | packed_element = \ |
||
279 | struct.pack('H', 1) + \ |
||
280 | struct.pack('BB', 255, 127) + \ |
||
281 | struct.pack('H', 10) + \ |
||
282 | struct.pack('BB', 254, 126) + \ |
||
283 | struct.pack('BB', 25, 16) + \ |
||
284 | struct.pack('BB', 24, 26) + \ |
||
285 | struct.pack('BB', 54, 17) |
||
286 | |||
287 | TestStruct = Message('TestStruct', [ |
||
288 | ('length_in_objects', 'H', 'vardata'), |
||
289 | ('vardata', self.VarTest, 'length_in_objects'), |
||
290 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
291 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
292 | ]) |
||
293 | |||
294 | with pytest.raises(struct.error): |
||
295 | unpacked = TestStruct.unpack(packed_element) |
||
296 | assert unpacked |
||
297 | |||
298 | def test_unpacking_of_too_many_bytes(self): |
||
299 | packed_element = \ |
||
300 | struct.pack('H', 1) + \ |
||
301 | struct.pack('BB', 255, 127) + \ |
||
302 | struct.pack('H', 10) + \ |
||
303 | struct.pack('BB', 254, 126) + \ |
||
304 | struct.pack('BB', 25, 16) + \ |
||
305 | struct.pack('BB', 24, 26) + \ |
||
306 | struct.pack('BB', 24, 26) + \ |
||
307 | struct.pack('BB', 24, 26) + \ |
||
308 | struct.pack('BB', 24, 26) + \ |
||
309 | struct.pack('BB', 24, 26) + \ |
||
310 | struct.pack('BB', 24, 26) + \ |
||
311 | struct.pack('BB', 54, 17) |
||
312 | |||
313 | TestStruct = Message('TestStruct', [ |
||
314 | ('length_in_objects', 'H', 'vardata'), |
||
315 | ('vardata', self.VarTest, 'length_in_objects'), |
||
316 | (b'length_in_bytes', 'H', 'bytesdata'), |
||
317 | ('bytesdata', self.VarTest, b'length_in_bytes'), |
||
318 | ]) |
||
319 | |||
320 | with pytest.raises(ValueError): |
||
321 | unpacked = TestStruct.unpack(packed_element) |
||
322 | assert unpacked |
||
323 | |||
324 | View Code Duplication | def test_single_element(self): |
|
0 ignored issues
–
show
|
|||
325 | TestStruct = Message('TestStruct', [ |
||
326 | ('length_in_objects', 'H', 'vardata'), |
||
327 | ('vardata', self.VarTest, 'length_in_objects'), |
||
328 | ('single_data', self.VarTest), |
||
329 | ]) |
||
330 | |||
331 | test_data = { |
||
332 | 'length': 2, |
||
333 | 'vardata': [ |
||
334 | {'x': 1, 'y': 2}, |
||
335 | {'x': 3, 'y': 4}, |
||
336 | ], |
||
337 | 'single_data': [ |
||
338 | {'x': 6, 'y': 11}, |
||
339 | ], |
||
340 | } |
||
341 | |||
342 | made = TestStruct.make(test_data) |
||
343 | assert len(made.vardata) == 2 |
||
344 | assert made.single_data.x == 6 |
||
345 | assert made.single_data.y == 11 |
||
346 | |||
347 | View Code Duplication | def test_single_element_2(self): |
|
0 ignored issues
–
show
|
|||
348 | TestStruct = Message('TestStruct', [ |
||
349 | ('length_in_objects', 'H', 'vardata'), |
||
350 | ('vardata', self.VarTest, 'length_in_objects'), |
||
351 | ('single_data', self.VarTest), |
||
352 | ]) |
||
353 | |||
354 | test_data = { |
||
355 | 'length': 2, |
||
356 | 'vardata': [ |
||
357 | {'x': 1, 'y': 2}, |
||
358 | {'x': 3, 'y': 4}, |
||
359 | ], |
||
360 | 'single_data': {'x': 6, 'y': 11}, |
||
361 | } |
||
362 | |||
363 | made = TestStruct.make(test_data) |
||
364 | assert len(made.vardata) == 2 |
||
365 | assert made.single_data.x == 6 |
||
366 | assert made.single_data.y == 11 |
||
367 | |||
368 | @pytest.mark.skip('Not implemented. Might not be possible') |
||
369 | def test_length_after_item(self): |
||
370 | num_repeats = 3 |
||
371 | |||
372 | TestStruct = Message('TestStruct', [ |
||
373 | ('vardata', self.VarTest, 'length'), |
||
374 | ('length', 'H', 'vardata'), |
||
375 | ('repeated_data', self.Repeated, num_repeats), |
||
376 | ]) |
||
377 | |||
378 | test_data = { |
||
379 | 'length': 2, |
||
380 | 'vardata': [ |
||
381 | {'x': 1, 'y': 2}, |
||
382 | {'x': 3, 'y': 4}, |
||
383 | ], |
||
384 | 'repeated_data': [ |
||
385 | {'x': 7, 'z': 13}, |
||
386 | {'x': 2, 'z': 27}, |
||
387 | {'x': 6, 'z': 11}, |
||
388 | ], |
||
389 | } |
||
390 | |||
391 | made = TestStruct.make(test_data) |
||
392 | assert made.length == 2 |
||
393 | assert made.vardata[0].x == 1 |
||
394 | assert made.vardata[0].y == 2 |
||
395 | |||
396 | packed = TestStruct.pack(test_data) |
||
397 | unpacked = TestStruct.unpack(packed) |
||
398 | assert unpacked |
||
399 |