corelib/tests/srd-bin-reader.cc

559 lines
14 KiB
C++

#include <ebcl/SRDBinary.hh>
#include <ebcl/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
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 ] );
}
}