#include #include #include using namespace ebcl; #define V1PROLOGUE_ \ 0xce , 0xa1 , 0x7c , 0xea , \ 0x00 , 0xee , 0xff , 0xc0 class SRDBinReaderTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( SRDBinReaderTest ); CPPUNIT_TEST( testEmptyInput ); CPPUNIT_TEST( testIncompleteMagic ); CPPUNIT_TEST( testBadMagic ); CPPUNIT_TEST( testMissingVersion ); CPPUNIT_TEST( testIncompleteVersion ); CPPUNIT_TEST( testBadVersion ); CPPUNIT_TEST( testPrologueOnly ); CPPUNIT_TEST( testEmpty ); CPPUNIT_TEST( testList ); CPPUNIT_TEST( testIncompleteList ); CPPUNIT_TEST( testString ); CPPUNIT_TEST( testComment ); CPPUNIT_TEST( testWordUnknown ); CPPUNIT_TEST( testWordEmpty ); CPPUNIT_TEST( testWordInvalid ); CPPUNIT_TEST( testWordDup ); CPPUNIT_TEST( testWordKnown ); CPPUNIT_TEST( testWordBadID ); CPPUNIT_TEST( testSpuriousVar ); CPPUNIT_TEST( testVarUnknownWord ); CPPUNIT_TEST( testVarKnownWord ); CPPUNIT_TEST( testInt32 ); CPPUNIT_TEST( testInt64 ); CPPUNIT_TEST( testFloat ); CPPUNIT_TEST( testBinaryEmpty ); CPPUNIT_TEST( testBinarySizeOnly ); CPPUNIT_TEST( testBinaryData ); CPPUNIT_TEST_SUITE_END( ); T_String location = T_String( "test" ); public: void testEmptyInput( ); void testIncompleteMagic( ); void testBadMagic( ); void testMissingVersion( ); void testIncompleteVersion( ); void testBadVersion( ); void testPrologueOnly( ); void testEmpty( ); void testList( ); void testIncompleteList( ); void testString( ); void testComment( ); void testWordUnknown( ); void testWordEmpty( ); void testWordInvalid( ); void testWordDup( ); void testWordKnown( ); void testWordBadID( ); void testSpuriousVar( ); void testVarUnknownWord( ); void testVarKnownWord( ); void testInt32( ); void testInt64( ); void testFloat( ); void testBinaryEmpty( ); void testBinarySizeOnly( ); void testBinaryData( ); }; CPPUNIT_TEST_SUITE_REGISTRATION( SRDBinReaderTest ); /*----------------------------------------------------------------------------*/ // Helper macros #define M_CKLS_(SIZE) \ CPPUNIT_ASSERT_EQUAL( uint32_t( SIZE ) , list.size( ) ) #define M_CKTOK_(ITEM,TYPE,POS) \ do { \ CPPUNIT_ASSERT( E_SRDTokenType::TYPE == \ list[ ITEM ].type( ) ); \ CPPUNIT_ASSERT( list[ ITEM ].hasLocation( ) ); \ CPPUNIT_ASSERT( location == \ list[ ITEM ].location( ).source( ) ); \ CPPUNIT_ASSERT_EQUAL( size_t( POS ) , \ list[ ITEM ].location( ).byte( ) ); \ } while ( 0 ) #define M_CKERRS_( x ) \ CPPUNIT_ASSERT_EQUAL( uint32_t( x ) , e.errors.size( ) ) #define M_CKERR_(IDX,STR,POS) \ do { \ auto const& _e( e.errors[ IDX ] ); \ CPPUNIT_ASSERT( T_String( STR ) == _e.error( ) ); \ CPPUNIT_ASSERT( location == _e.location( ).source( ) ); \ CPPUNIT_ASSERT_EQUAL( size_t( POS ) , \ _e.location( ).byte( ) ); \ } while ( 0 ) #define M_PRINTERR_(IDX) \ do { \ char err[ e.errors[ IDX ].error( ).size( ) + 1 ]; \ err[ sizeof( err ) - 1 ] = 0; \ memcpy( err , e.errors[ IDX ].error( ).data( ) , \ sizeof( err ) - 1 ); \ printf( "ERR %s @ %d\n" , err , int( \ e.errors[ IDX ].location( ).byte( ) ) ); \ } while ( 0 ) /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testEmptyInput( ) { T_MemoryInputStream stream( nullptr , 0 ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "missing magic" , 0 ); } } void SRDBinReaderTest::testIncompleteMagic( ) { const uint8_t data[] = { 0xce , 0xa1 , 0x7c }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "missing magic" , 3 ); } } void SRDBinReaderTest::testBadMagic( ) { const uint8_t data[] = { 0xce , 0xa1 , 0x7c , 0xfa }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "invalid magic number" , 0 ); } } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testMissingVersion( ) { const uint8_t data[] = { 0xce , 0xa1 , 0x7c , 0xea }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "missing version ID" , 4 ); } } void SRDBinReaderTest::testIncompleteVersion( ) { const uint8_t data[] = { 0xce , 0xa1 , 0x7c , 0xea , 0x00 , 0xee , 0xff }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "missing version ID" , 7 ); } } void SRDBinReaderTest::testBadVersion( ) { const uint8_t data[] = { 0xce , 0xa1 , 0x7c , 0xea , 0xc0 , 0xff , 0xee , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "invalid version ID" , 4 ); } } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testPrologueOnly( ) { const uint8_t data[] = { V1PROLOGUE_ }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "unexpected end of file" , 8 ); } } void SRDBinReaderTest::testEmpty( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 0 ); } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testList( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x01 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 2 ); M_CKTOK_( 0 , START , 8 ); M_CKTOK_( 1 , END , 9 ); } void SRDBinReaderTest::testIncompleteList( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x01 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "unexpected end of file" , 10 ); } } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testString( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x05 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , STRING , 8 ); CPPUNIT_ASSERT( list[ 0 ].stringValue( ) == T_String( "test" ) ); } void SRDBinReaderTest::testComment( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x09 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , COMMENT , 8 ); CPPUNIT_ASSERT( list[ 0 ].stringValue( ) == T_String( "test" ) ); } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testWordUnknown( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , WORD , 8 ); CPPUNIT_ASSERT( list[ 0 ].stringValue( ) == T_String( "test" ) ); } void SRDBinReaderTest::testWordEmpty( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "empty word" , 9 ); } } void SRDBinReaderTest::testWordInvalid( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , ' ' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "invalid word" , 9 ); } } void SRDBinReaderTest::testWordDup( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "duplicate word" , 18 ); } } void SRDBinReaderTest::testWordKnown( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 2 ); M_CKTOK_( 1 , WORD , 17 ); CPPUNIT_ASSERT( list[ 1 ].stringValue( ) == T_String( "test" ) ); } void SRDBinReaderTest::testWordBadID( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "unregistered word" , 9 ); } } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testSpuriousVar( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x04 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); try { SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "spurious variable tag" , 8 ); } } void SRDBinReaderTest::testVarUnknownWord( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x04 , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , VAR , 8 ); CPPUNIT_ASSERT( list[ 0 ].stringValue( ) == T_String( "test" ) ); } void SRDBinReaderTest::testVarKnownWord( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x02 , 0x04 , 0x00 , 0x00 , 0x00 , 't' , 'e' , 's' , 't' , 0x04 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 2 ); M_CKTOK_( 1 , VAR , 17 ); CPPUNIT_ASSERT( list[ 1 ].stringValue( ) == T_String( "test" ) ); } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testInt32( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x06 , 0x04 , 0x03 , 0x02 , 0x01 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , INT , 8 ); CPPUNIT_ASSERT_EQUAL( int64_t( 0x01020304 ) , list[ 0 ].longValue( ) ); } void SRDBinReaderTest::testInt64( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x07 , 0x04 , 0x03 , 0x02 , 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , LONG , 8 ); CPPUNIT_ASSERT_EQUAL( int64_t( 0x01020304 ) , list[ 0 ].longValue( ) ); } void SRDBinReaderTest::testFloat( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x08 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xf0 , 0x3f , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , FLOAT , 8 ); CPPUNIT_ASSERT_EQUAL( 1.0 , list[ 0 ].floatValue( ) ); } /*----------------------------------------------------------------------------*/ void SRDBinReaderTest::testBinaryEmpty( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , BINARY , 8 ); CPPUNIT_ASSERT_EQUAL( size_t( 0 ) , list[ 0 ].binary( ).size( ) ); } void SRDBinReaderTest::testBinarySizeOnly( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x0a , 0x08 , 0x00 , 0x00 , 0x00 , }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list; try { list = SRDBinaryReadFrom( location , stream , false ); CPPUNIT_FAIL( "X_SRDErrors exception expected" ); } catch ( X_SRDErrors & e ) { M_CKERRS_( 1 ); M_CKERR_( 0 , "unexpected end of file" , 13 ); } } void SRDBinReaderTest::testBinaryData( ) { const uint8_t data[] = { V1PROLOGUE_ , 0x0a , 0x08 , 0x00 , 0x00 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x00 }; T_MemoryInputStream stream( data , sizeof( data ) ); T_SRDList list( SRDBinaryReadFrom( location , stream , false ) ); M_CKLS_( 1 ); M_CKTOK_( 0 , BINARY , 8 ); CPPUNIT_ASSERT_EQUAL( size_t( 8 ) , list[ 0 ].binary( ).size( ) ); for ( uint8_t i = 0 ; i < 8 ; i ++ ) { CPPUNIT_ASSERT_EQUAL( uint8_t( i + 1 ) , list[ 0 ].binary( )[ i ] ); } }