comparison trunk/external/oscpack/tests/OscUnitTests.cpp @ 570:4b37b53105a3

Add support for outputting featutes using OSC (for use with the Wekinator, etc).
author tomwalters@google.com
date Fri, 22 Jun 2012 12:22:08 +0000
parents
children
comparison
equal deleted inserted replaced
569:16a590fbc0ba 570:4b37b53105a3
1 /*
2 oscpack -- Open Sound Control packet manipulation library
3 http://www.audiomulch.com/~rossb/oscpack
4
5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files
9 (the "Software"), to deal in the Software without restriction,
10 including without limitation the rights to use, copy, modify, merge,
11 publish, distribute, sublicense, and/or sell copies of the Software,
12 and to permit persons to whom the Software is furnished to do so,
13 subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 Any person wishing to distribute modifications to the Software is
19 requested to send the modifications to the original developer so that
20 they can be incorporated into the canonical version.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 */
30 #include "OscUnitTests.h"
31
32 #include <iostream>
33 #include <iomanip>
34
35 #include "osc/OscReceivedElements.h"
36 #include "osc/OscPrintReceivedElements.h"
37 #include "osc/OscOutboundPacketStream.h"
38
39
40 namespace osc{
41
42 static int passCount_=0, failCount_=0;
43
44 void PrintTestSummary()
45 {
46 std::cout << (passCount_+failCount_) << " tests run, " << passCount_ << " passed, " << failCount_ << " failed.\n";
47 }
48
49 void pass_equality( const char *slhs, const char *srhs, const char *file, int line )
50 {
51 ++passCount_;
52 std::cout << file << "(" << line << "): PASSED : " << slhs << " == " << srhs << "\n";
53 }
54
55 void fail_equality( const char *slhs, const char *srhs, const char *file, int line )
56 {
57 ++failCount_;
58 std::cout << file << "(" << line << "): FAILED : " << slhs << " != " << srhs << "\n";
59 }
60
61 template <typename T>
62 void assertEqual_( const T& lhs, const T& rhs, const char *slhs, const char *srhs, const char *file, int line )
63 {
64 if( lhs == rhs )
65 pass_equality( slhs, srhs, file, line );
66 else
67 fail_equality( slhs, srhs, file, line );
68 }
69
70 template <typename T>
71 void assertEqual_( const T* lhs, const T* rhs, const char *slhs, const char *srhs, const char *file, int line )
72 {
73 if( lhs == rhs )
74 pass_equality( slhs, srhs, file, line );
75 else
76 fail_equality( slhs, srhs, file, line );
77 }
78
79 template <>
80 void assertEqual_( const char* lhs, const char* rhs, const char *slhs, const char *srhs, const char *file, int line )
81 {
82 if( strcmp( lhs, rhs ) == 0 )
83 pass_equality( slhs, srhs, file, line );
84 else
85 fail_equality( slhs, srhs, file, line );
86 }
87
88
89 #define assertEqual( a, b ) assertEqual_( (a), (b), #a, #b, __FILE__, __LINE__ )
90
91 //---------------------------------------------------------------------------
92 char * AllocateAligned4( unsigned long size )
93 {
94 char *s = new char[ size + 4 ]; //allocate on stack to get 4 byte alignment
95 return (char*)((long)(s-1) & (~0x03L)) + 4;
96 }
97
98 // allocate a 4 byte aligned copy of s
99 char * NewMessageBuffer( const char *s, unsigned long length )
100 {
101 char *p = AllocateAligned4( length );
102 memcpy( p, s, length );
103 return p;
104 }
105
106 void test1()
107 {
108 const char s[] = "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A";
109 char *buffer = NewMessageBuffer( s, sizeof(s)-1 );
110
111 // test argument iterator interface
112 bool unexpectedExceptionCaught = false;
113 try{
114 ReceivedMessage m( ReceivedPacket(buffer, sizeof(s)-1) );
115
116 assertEqual( strcmp( m.AddressPattern(), "/test" ), 0 );
117 assertEqual( strcmp( m.TypeTags(), "fiT" ), 0 );
118
119 ReceivedMessage::const_iterator i = m.ArgumentsBegin();
120 ++i;
121 ++i;
122 ++i;
123 assertEqual( i, m.ArgumentsEnd() );
124
125 i = m.ArgumentsBegin();
126 float f = (i++)->AsFloat();
127 (void)f;
128 int n = (i++)->AsInt32();
129 (void)n;
130 bool b = (i++)->AsBool();
131 (void)b;
132
133 i = m.ArgumentsBegin();
134 bool exceptionThrown = false;
135 try{
136 int n = (i++)->AsInt32();
137 (void)n;
138 }catch( Exception& ){
139 exceptionThrown = true;
140 }
141 assertEqual( exceptionThrown, true );
142
143 }catch( Exception& e ){
144 std::cout << "unexpected exception: " << e.what() << "\n";
145 unexpectedExceptionCaught = true;
146 }
147 assertEqual( unexpectedExceptionCaught, false );
148
149
150 // test argument stream interface
151 unexpectedExceptionCaught = false;
152 try{
153 ReceivedMessage m( ReceivedPacket(buffer, sizeof(s)-1) );
154 ReceivedMessageArgumentStream args = m.ArgumentStream();
155 assertEqual( args.Eos(), false );
156
157 float f;
158 long n;
159 bool b;
160 args >> f >> n >> b;
161
162 (void) f;
163 (void) n;
164 (void) b;
165
166 assertEqual( args.Eos(), true );
167
168 }catch( Exception& e ){
169 std::cout << "unexpected exception: " << e.what() << "\n";
170 unexpectedExceptionCaught = true;
171 }
172 assertEqual( unexpectedExceptionCaught, false );
173 }
174
175 //---------------------------------------------------------------------------
176
177
178 #define TEST2_PRINT( ss )\
179 {\
180 const char s[] = ss;\
181 ReceivedPacket p( NewMessageBuffer( s, sizeof(s)-1 ), sizeof(s)-1 ); \
182 ReceivedMessage m( p );\
183 std::cout << m << "\n";\
184 }
185
186 void test2()
187 {
188 bool unexpectedExceptionCaught = false;
189 try{
190 // 012301230 1 2 3
191 TEST2_PRINT( "/no_args\0\0\0\0" );
192
193 // 012301230 1 2 3 01 2 3
194 TEST2_PRINT( "/no_args\0\0\0\0,\0\0\0" );
195
196 // 01230123 012 3 0 1 2 3
197 TEST2_PRINT( "/an_int\0,i\0\0\0\0\0A" );
198 // 012301230 1 2 3 012 3 0 1 2 3
199 TEST2_PRINT( "/a_float\0\0\0\0,f\0\0\0\0\0\0" );
200 // 0123012301 2 3 012 3 012301230123
201 TEST2_PRINT( "/a_string\0\0\0,s\0\0hello world\0" );
202 // 01230123 012 3 0 1 2 3 0 1 2 3
203 TEST2_PRINT( "/a_blob\0,b\0\0\0\0\0\x4\x0\x1\x2\x3" );
204
205 // 0123012301 2 3 012 3 0 1 2 3 0 1 2 3
206 TEST2_PRINT( "/an_int64\0\0\0,h\0\0\0\0\0\0\0\0\0\x1" );
207 // 01230123012 3 012 3 0 1 2 3 0 1 2 3
208 TEST2_PRINT( "/a_timetag\0\0,t\0\0\0\0\0\0\0\0\0\x1" );
209 // 0123012301 2 3 012 3 0 1 2 3 0 1 2 3
210 TEST2_PRINT( "/a_double\0\0\0,d\0\0\0\0\0\0\0\0\0\0" );
211 // 0123012301 2 3 012 3 012301230123
212 TEST2_PRINT( "/a_symbol\0\0\0,S\0\0hello world\0" );
213 // 01230123 012 3 0 1 2 3
214 TEST2_PRINT( "/a_char\0,c\0\0\0\0\0A" );
215 // 012301230 1 2 3 012 3 0 1 2 3
216 TEST2_PRINT( "/a_color\0\0\0\0,r\0\0\0\0\0\0" );
217 // 012301230123012 3 012 3 0 1 2 3
218 TEST2_PRINT( "/a_midimessage\0\0,m\0\0\0\0\0\0" );
219 // 01230123 012 3
220 TEST2_PRINT( "/a_bool\0,T\0\0" );
221 // 01230123 012 3
222 TEST2_PRINT( "/a_bool\0,F\0\0" );
223 // 01230 1 2 3 012 3
224 TEST2_PRINT( "/Nil\0\0\0\0,N\0\0" );
225 // 01230 1 2 3 012 3
226 TEST2_PRINT( "/Inf\0\0\0\0,I\0\0" );
227
228 TEST2_PRINT( "/test\0\0\0,fiT\0\0\0\0\0\0\0\0\0\0\0A" );
229
230 bool exceptionThrown = false;
231 try{
232 TEST2_PRINT( "/a_char\0,x\0\0\0\0\0A" ); // unknown type tag 'x'
233 }catch( Exception& ){
234 exceptionThrown = true;
235 }
236 assertEqual( exceptionThrown, true );
237
238 }catch( Exception& e ){
239 std::cout << "unexpected exception: " << e.what() << "\n";
240 unexpectedExceptionCaught = true;
241 }
242 assertEqual( unexpectedExceptionCaught, false );
243 }
244
245 //-----------------------------------------------------------------------
246
247 // pack a message and then unpack it and check that the result is the same
248 // also print each message
249 // repeat the process inside a bundle
250
251 #define TEST_PACK_UNPACK0( addressPattern, argument, value, recieveGetter ) \
252 { \
253 memset( buffer, 0x74, bufferSize ); \
254 OutboundPacketStream ps( buffer, bufferSize ); \
255 ps << BeginMessage( addressPattern ) \
256 << argument \
257 << EndMessage;\
258 assertEqual( ps.IsReady(), true );\
259 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
260 std::cout << m << "\n";\
261 assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
262 } \
263 { \
264 memset( buffer, 0x74, bufferSize ); \
265 OutboundPacketStream ps( buffer, bufferSize ); \
266 ps << BeginBundle( 1234 ) \
267 << BeginMessage( addressPattern ) \
268 << argument \
269 << EndMessage \
270 << EndBundle;\
271 assertEqual( ps.IsReady(), true );\
272 ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
273 ReceivedMessage m( *b.ElementsBegin() );\
274 std::cout << m << "\n";\
275 assertEqual( m.ArgumentsBegin()-> recieveGetter () , value );\
276 }
277
278 #define TEST_PACK_UNPACK( addressPattern, argument, type, recieveGetter ) \
279 { \
280 memset( buffer, 0x74, bufferSize ); \
281 OutboundPacketStream ps( buffer, bufferSize ); \
282 ps << BeginMessage( addressPattern ) \
283 << argument \
284 << EndMessage;\
285 assertEqual( ps.IsReady(), true );\
286 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );\
287 std::cout << m << "\n";\
288 assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
289 } \
290 { \
291 memset( buffer, 0x74, bufferSize ); \
292 OutboundPacketStream ps( buffer, bufferSize ); \
293 ps << BeginBundle( 1234 ) \
294 << BeginMessage( addressPattern ) \
295 << argument \
296 << EndMessage \
297 << EndBundle;\
298 assertEqual( ps.IsReady(), true );\
299 ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );\
300 ReceivedMessage m( *b.ElementsBegin() );\
301 std::cout << m << "\n";\
302 assertEqual( m.ArgumentsBegin()-> recieveGetter () , ( type ) argument );\
303 }
304
305 void test3()
306 {
307 int bufferSize = 1000;
308 char *buffer = AllocateAligned4( bufferSize );
309
310 // single message tests
311 // empty message
312 {
313 memset( buffer, 0x74, bufferSize );
314 OutboundPacketStream ps( buffer, bufferSize );
315 ps << BeginMessage( "/no_arguments" )
316 << EndMessage;
317 assertEqual( ps.IsReady(), true );
318 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );
319 std::cout << m << "\n";\
320 }
321
322 TEST_PACK_UNPACK( "/a_bool", true, bool, AsBool );
323 TEST_PACK_UNPACK( "/a_bool", false, bool, AsBool );
324 TEST_PACK_UNPACK( "/a_bool", (bool)1, bool, AsBool );
325
326 TEST_PACK_UNPACK0( "/nil", Nil, true, IsNil );
327 TEST_PACK_UNPACK0( "/inf", Infinitum, true, IsInfinitum );
328
329 TEST_PACK_UNPACK( "/an_int", (int32)1234, int32, AsInt32 );
330
331 TEST_PACK_UNPACK( "/a_float", 3.1415926f, float, AsFloat );
332
333 TEST_PACK_UNPACK( "/a_char", 'c', char, AsChar );
334
335 TEST_PACK_UNPACK( "/an_rgba_color", RgbaColor(0x22334455), uint32, AsRgbaColor );
336
337 TEST_PACK_UNPACK( "/a_midi_message", MidiMessage(0x7F), uint32, AsMidiMessage );
338
339 TEST_PACK_UNPACK( "/an_int64", (int64)(0xFFFFFFFF), int64, AsInt64 );
340
341 TEST_PACK_UNPACK( "/a_time_tag", TimeTag(0xFFFFFFFF), uint64, AsTimeTag );
342
343 TEST_PACK_UNPACK( "/a_double", (double)3.1415926, double, AsDouble );
344
345 // blob
346 {
347 char blobData[] = "abcd";
348 memset( buffer, 0x74, bufferSize );
349 OutboundPacketStream ps( buffer, bufferSize );
350 ps << BeginMessage( "/a_blob" )
351 << Blob( blobData, 4 )
352 << EndMessage;
353 assertEqual( ps.IsReady(), true );
354 ReceivedMessage m( ReceivedPacket(ps.Data(), ps.Size()) );
355 std::cout << m << "\n";
356
357 const void *value;
358 unsigned long size;
359 m.ArgumentsBegin()->AsBlob( value, size );
360 assertEqual( size, (unsigned long)4 );
361 assertEqual( (memcmp( value, blobData, 4 ) == 0), true );
362 }
363
364
365 TEST_PACK_UNPACK( "/a_string", "hello world", const char*, AsString );
366
367 TEST_PACK_UNPACK( "/a_symbol", Symbol("foobar"), const char*, AsSymbol );
368
369
370 // nested bundles, and multiple messages in bundles...
371
372 {
373 memset( buffer, 0x74, bufferSize );
374 OutboundPacketStream ps( buffer, bufferSize );
375 ps << BeginBundle()
376 << BeginMessage( "/message_one" ) << 1 << 2 << 3 << 4 << EndMessage
377 << BeginMessage( "/message_two" ) << 1 << 2 << 3 << 4 << EndMessage
378 << BeginMessage( "/message_three" ) << 1 << 2 << 3 << 4 << EndMessage
379 << BeginMessage( "/message_four" ) << 1 << 2 << 3 << 4 << EndMessage
380 << EndBundle;
381 assertEqual( ps.IsReady(), true );
382 ReceivedBundle b( ReceivedPacket(ps.Data(), ps.Size()) );
383 std::cout << b << "\n";
384 }
385 }
386
387
388 void RunUnitTests()
389 {
390 test1();
391 test2();
392 test3();
393 PrintTestSummary();
394 }
395
396 } // namespace osc
397
398
399 #ifndef NO_OSC_TEST_MAIN
400
401 int main(int argc, char* argv[])
402 {
403 (void)argc;
404 (void)argv;
405
406 osc::RunUnitTests();
407 }
408
409 #endif