@@ -11,6 +11,7 @@ import {
1111 MicrobitSensorState ,
1212 splitMessages ,
1313 processPeriodicMessage ,
14+ processResponseMessage ,
1415} from '../script/microbit-interfacing/serialProtocol' ;
1516
1617describe ( 'splitMessages' , ( ) => {
@@ -51,12 +52,49 @@ describe('splitMessages', () => {
5152 expect ( msgs . remainingInput ) . toEqual ( message3 ) ;
5253 } ) ;
5354
55+ it ( 'sets the remainingInput from incomplete message' , ( ) => {
56+ const message1 = 'R[0]INCOMPLETE' ;
57+
58+ const msgs = splitMessages ( message1 ) ;
59+
60+ expect ( msgs . messages . length ) . toEqual ( 0 ) ;
61+ expect ( msgs . remainingInput ) . toEqual ( message1 ) ;
62+ } ) ;
63+
5464 it ( 'processes empty input correctly' , ( ) => {
5565 const msgs = splitMessages ( '' ) ;
5666
5767 expect ( msgs . messages . length ) . toEqual ( 0 ) ;
5868 expect ( msgs . remainingInput ) . toEqual ( '' ) ;
5969 } ) ;
70+
71+ it ( 'throws away empty lines correctly' , ( ) => {
72+ const msgs = splitMessages ( '\n\n\n' ) ;
73+
74+ expect ( msgs . messages . length ) . toEqual ( 0 ) ;
75+ expect ( msgs . remainingInput ) . toEqual ( '' ) ;
76+ } ) ;
77+
78+ it ( 'throws away remainingInput of invalid type' , ( ) => {
79+ const message1 = 'R[0]START[]' ;
80+ const message_invalid_start = 'NOT_A_VALID_MSG_START' ;
81+
82+ const msgs = splitMessages ( message1 + '\n' + message_invalid_start ) ;
83+
84+ expect ( msgs . messages . length ) . toEqual ( 1 ) ;
85+ expect ( msgs . messages [ 0 ] ) . toEqual ( message1 ) ;
86+ expect ( msgs . remainingInput ) . toEqual ( '' ) ;
87+ } ) ;
88+
89+ it ( 'throws messages of invalid type' , ( ) => {
90+ const msgs = splitMessages ( 'P00\nC11\nR22\nX33\n' ) ;
91+
92+ expect ( msgs . messages . length ) . toEqual ( 3 ) ;
93+ expect ( msgs . messages [ 0 ] ) . toEqual ( 'P00' ) ;
94+ expect ( msgs . messages [ 1 ] ) . toEqual ( 'C11' ) ;
95+ expect ( msgs . messages [ 2 ] ) . toEqual ( 'R22' ) ;
96+ expect ( msgs . remainingInput ) . toEqual ( '' ) ;
97+ } ) ;
6098} ) ;
6199
62100describe ( 'processPeriodicMessage' , ( ) => {
@@ -141,3 +179,193 @@ describe('processPeriodicMessage', () => {
141179 expect ( got1 ) . toBeUndefined ( ) ;
142180 } ) ;
143181} ) ;
182+
183+ describe ( 'processResponseMessage' , ( ) => {
184+ it ( 'processes valid Handshake responses' , ( ) => {
185+ const message1 = 'R[0]HS[1]' ;
186+ const message2 = 'R[1122aabb]HS[255]' ;
187+ const message3 = 'R[FFFFFFFF]HS[-1000]' ;
188+
189+ const got1 = processResponseMessage ( message1 ) ;
190+ const got2 = processResponseMessage ( message2 ) ;
191+ const got3 = processResponseMessage ( message3 ) ;
192+
193+ expect ( got1 ) . toEqual ( {
194+ message : message1 ,
195+ messageId : 0 ,
196+ cmdType : 'HS' ,
197+ value : 1 ,
198+ } ) ;
199+ expect ( got2 ) . toEqual ( {
200+ message : message2 ,
201+ messageId : 0x1122aabb ,
202+ cmdType : 'HS' ,
203+ value : 255 ,
204+ } ) ;
205+ expect ( got3 ) . toEqual ( {
206+ message : message3 ,
207+ messageId : 0xffffffff ,
208+ cmdType : 'HS' ,
209+ value : - 1000 ,
210+ } ) ;
211+ } ) ;
212+
213+ it ( 'processes valid Radio Frequency response' , ( ) => {
214+ const message = 'R[1234]RF[42]' ;
215+
216+ const got = processResponseMessage ( message ) ;
217+
218+ expect ( got ) . toEqual ( {
219+ message : message ,
220+ messageId : 0x1234 ,
221+ cmdType : 'RF' ,
222+ value : 42 ,
223+ } ) ;
224+ } ) ;
225+
226+ it ( 'processes valid Software Versions responses' , ( ) => {
227+ const message1 = 'R[1234]SWVER[0.0.0]' ;
228+ const message2 = 'R[1234]SWVER[99.99.99]' ;
229+ const message3 = 'R[1234]SWVER[1.2.3]' ;
230+
231+ const got1 = processResponseMessage ( message1 ) ;
232+ const got2 = processResponseMessage ( message2 ) ;
233+ const got3 = processResponseMessage ( message3 ) ;
234+
235+ expect ( got1 ) . toEqual ( {
236+ message : message1 ,
237+ messageId : 0x1234 ,
238+ cmdType : 'SWVER' ,
239+ value : '0.0.0' ,
240+ } ) ;
241+ expect ( got2 ) . toEqual ( {
242+ message : message2 ,
243+ messageId : 0x1234 ,
244+ cmdType : 'SWVER' ,
245+ value : '99.99.99' ,
246+ } ) ;
247+ expect ( got3 ) . toEqual ( {
248+ message : message3 ,
249+ messageId : 0x1234 ,
250+ cmdType : 'SWVER' ,
251+ value : '1.2.3' ,
252+ } ) ;
253+ } ) ;
254+
255+ it ( 'processes valid Hardware Versions responses' , ( ) => {
256+ const message1 = 'R[1234]HWVER[0]' ;
257+ const message2 = 'R[1234]HWVER[9999]' ;
258+
259+ const got1 = processResponseMessage ( message1 ) ;
260+ const got2 = processResponseMessage ( message2 ) ;
261+
262+ expect ( got1 ) . toEqual ( {
263+ message : message1 ,
264+ messageId : 0x1234 ,
265+ cmdType : 'HWVER' ,
266+ value : 0 ,
267+ } ) ;
268+ expect ( got2 ) . toEqual ( {
269+ message : message2 ,
270+ messageId : 0x1234 ,
271+ cmdType : 'HWVER' ,
272+ value : 9999 ,
273+ } ) ;
274+ } ) ;
275+
276+ it ( 'processes valid Zstart response' , ( ) => {
277+ const message = 'R[1234]ZSTART[]' ;
278+
279+ const got = processResponseMessage ( message ) ;
280+
281+ expect ( got ) . toEqual ( {
282+ message : message ,
283+ messageId : 0x1234 ,
284+ cmdType : 'ZSTART' ,
285+ value : '' ,
286+ } ) ;
287+ } ) ;
288+
289+ it ( 'processes valid Stop response' , ( ) => {
290+ const message = 'R[1234]STOP[]' ;
291+
292+ const got = processResponseMessage ( message ) ;
293+
294+ expect ( got ) . toEqual ( {
295+ message : message ,
296+ messageId : 0x1234 ,
297+ cmdType : 'STOP' ,
298+ value : '' ,
299+ } ) ;
300+ } ) ;
301+
302+ it ( 'throws away messages that are not a response' , ( ) => {
303+ // First a valid response to stablish a baseline
304+ expect ( processResponseMessage ( 'R[0]STOP[]' ) ) . not . toBeUndefined ( ) ;
305+ // Now non-response messages types
306+ expect ( processResponseMessage ( 'C[0]STOP[]' ) ) . toBeUndefined ( ) ;
307+ expect ( processResponseMessage ( 'P[0]STOP[]' ) ) . toBeUndefined ( ) ;
308+ expect ( processResponseMessage ( 'P0E80495C4341' ) ) . toBeUndefined ( ) ;
309+ // Invalid message types
310+ expect ( processResponseMessage ( 'Z[0]STOP[]' ) ) . toBeUndefined ( ) ;
311+ expect ( processResponseMessage ( '9[0]STOP[]' ) ) . toBeUndefined ( ) ;
312+ } ) ;
313+
314+ it ( 'throws away response messages with invalid IDs' , ( ) => {
315+ // First a valid response to stablish a baseline
316+ expect ( processResponseMessage ( 'R[0]STOP[]' ) ) . not . toBeUndefined ( ) ;
317+ // Now invalid IDs
318+ expect ( processResponseMessage ( 'R[]STOP[]' ) ) . toBeUndefined ( ) ;
319+ expect ( processResponseMessage ( 'R[123456789]STOP[]' ) ) . toBeUndefined ( ) ;
320+ expect ( processResponseMessage ( 'R[12G]STOP[]' ) ) . toBeUndefined ( ) ;
321+ expect ( processResponseMessage ( 'R[-1]STOP[]' ) ) . toBeUndefined ( ) ;
322+ expect ( processResponseMessage ( 'R[1.1]STOP[]' ) ) . toBeUndefined ( ) ;
323+ expect ( processResponseMessage ( 'R[word]STOP[]' ) ) . toBeUndefined ( ) ;
324+ } ) ;
325+
326+ it ( 'throws away response messages with invalid number values' , ( ) => {
327+ // First valid messages to stablish a baseline
328+ expect ( processResponseMessage ( 'R[0]RF[10000]' ) ) . not . toBeUndefined ( ) ;
329+ expect ( processResponseMessage ( 'R[0]RF[-1]' ) ) . not . toBeUndefined ( ) ;
330+ // Now invalid values
331+ expect ( processResponseMessage ( 'R[0]RF[1-2]' ) ) . toBeUndefined ( ) ;
332+ expect ( processResponseMessage ( 'R[0]RF[1,2]' ) ) . toBeUndefined ( ) ;
333+ expect ( processResponseMessage ( 'R[0]RF[1F]' ) ) . toBeUndefined ( ) ;
334+ expect ( processResponseMessage ( 'R[0]RF[word]' ) ) . toBeUndefined ( ) ;
335+ } ) ;
336+
337+ it ( 'throws away response messages with invalid version values' , ( ) => {
338+ // First valid messages to stablish a baseline
339+ expect ( processResponseMessage ( 'R[0]SWVER[1.1.1]' ) ) . not . toBeUndefined ( ) ;
340+ // Now invalid values
341+ expect ( processResponseMessage ( 'R[0]SWVER[1]' ) ) . toBeUndefined ( ) ;
342+ expect ( processResponseMessage ( 'R[0]SWVER[1.1]' ) ) . toBeUndefined ( ) ;
343+ expect ( processResponseMessage ( 'R[0]SWVER[123.1.1]' ) ) . toBeUndefined ( ) ;
344+ expect ( processResponseMessage ( 'R[0]SWVER[1.123.1]' ) ) . toBeUndefined ( ) ;
345+ expect ( processResponseMessage ( 'R[0]SWVER[1.1.123]' ) ) . toBeUndefined ( ) ;
346+ expect ( processResponseMessage ( 'R[0]SWVER[11.22.AA]' ) ) . toBeUndefined ( ) ;
347+ expect ( processResponseMessage ( 'R[0]SWVER[word]' ) ) . toBeUndefined ( ) ;
348+ } ) ;
349+
350+ it ( 'throws away response messages with invalid empty value' , ( ) => {
351+ // First a valid response to stablish a baseline
352+ expect ( processResponseMessage ( 'R[0]STOP[]' ) ) . not . toBeUndefined ( ) ;
353+ // Now non-response messages types
354+ expect ( processResponseMessage ( 'R[0]STOP[0]' ) ) . toBeUndefined ( ) ;
355+ expect ( processResponseMessage ( 'R[0]STOP[-1]' ) ) . toBeUndefined ( ) ;
356+ expect ( processResponseMessage ( 'R[0]STOP[a]' ) ) . toBeUndefined ( ) ;
357+ } ) ;
358+
359+ it ( 'throws away other types of invalid responses' , ( ) => {
360+ expect ( processResponseMessage ( 'R0STOP[]' ) ) . toBeUndefined ( ) ;
361+ expect ( processResponseMessage ( '[0]STOP[]' ) ) . toBeUndefined ( ) ;
362+ expect ( processResponseMessage ( 'R[0]STOP' ) ) . toBeUndefined ( ) ;
363+ expect ( processResponseMessage ( 'R[0][]' ) ) . toBeUndefined ( ) ;
364+ expect ( processResponseMessage ( 'R[0]' ) ) . toBeUndefined ( ) ;
365+ expect ( processResponseMessage ( 'R[0]STOP[]STOP[]' ) ) . toBeUndefined ( ) ;
366+ expect ( processResponseMessage ( 'R[0]R[1]STOP[]' ) ) . toBeUndefined ( ) ;
367+ expect ( processResponseMessage ( 'R[0]STOP[]S' ) ) . toBeUndefined ( ) ;
368+ expect ( processResponseMessage ( 'R[0]RF[1' ) ) . toBeUndefined ( ) ;
369+ expect ( processResponseMessage ( 'R[0]RF1]' ) ) . toBeUndefined ( ) ;
370+ } ) ;
371+ } ) ;
0 commit comments