#include "srd-preproc-cmd-common.hh"


class SRDPreprocCmdIntrospectTest : public CppUnit::TestFixture
{
	CPPUNIT_TEST_SUITE( SRDPreprocCmdIntrospectTest );

	CPPUNIT_TEST( testIsSetMissingArgs );
	CPPUNIT_TEST( testIsSetExtraArgs );
	CPPUNIT_TEST( testIsSetBadArg );
	CPPUNIT_TEST( testIsSetTrue );
	CPPUNIT_TEST( testIsSetFalse );

	CPPUNIT_TEST( testIsMacroMissingArgs );
	CPPUNIT_TEST( testIsMacroExtraArgs );
	CPPUNIT_TEST( testIsMacroBadArg );
	CPPUNIT_TEST( testIsMacroTrue );
	CPPUNIT_TEST( testIsMacroFalse );

	CPPUNIT_TEST( testIsBlessedMissingArgs );
	CPPUNIT_TEST( testIsBlessedExtraArgs );
	CPPUNIT_TEST( testIsBlessedBadArg );
	CPPUNIT_TEST( testIsBlessedUnset );
	CPPUNIT_TEST( testIsBlessedUnblessed );
	CPPUNIT_TEST( testIsBlessedTrue );

	CPPUNIT_TEST( testTypeOfMissingArg );
	CPPUNIT_TEST( testTypeOfExtraArgs );
	CPPUNIT_TEST( testTypeOfList );
	CPPUNIT_TEST( testTypeOfWord );
	CPPUNIT_TEST( testTypeOfString );
	CPPUNIT_TEST( testTypeOfInt );
	CPPUNIT_TEST( testTypeOfLong );
	CPPUNIT_TEST( testTypeOfReal );
	CPPUNIT_TEST( testTypeOfVar );
	CPPUNIT_TEST( testTypeOfBinary );
	CPPUNIT_TEST( testTypeOfComment );

	CPPUNIT_TEST_SUITE_END( );

   public:
	void testIsSetMissingArgs( );
	void testIsSetExtraArgs( );
	void testIsSetBadArg( );
	void testIsSetTrue( );
	void testIsSetFalse( );

	void testIsMacroMissingArgs( );
	void testIsMacroExtraArgs( );
	void testIsMacroBadArg( );
	void testIsMacroTrue( );
	void testIsMacroFalse( );

	void testIsBlessedMissingArgs( );
	void testIsBlessedExtraArgs( );
	void testIsBlessedBadArg( );
	void testIsBlessedUnset( );
	void testIsBlessedUnblessed( );
	void testIsBlessedTrue( );

	void testTypeOfMissingArg( );
	void testTypeOfExtraArgs( );
	void testTypeOfList( );
	void testTypeOfWord( );
	void testTypeOfString( );
	void testTypeOfInt( );
	void testTypeOfLong( );
	void testTypeOfReal( );
	void testTypeOfVar( );
	void testTypeOfBinary( );
	void testTypeOfComment( );
};
CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdIntrospectTest );

/*----------------------------------------------------------------------------*/

void SRDPreprocCmdIntrospectTest::testIsSetMissingArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-set )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "not enough arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 11 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsSetExtraArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-set a b c )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "too many arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 13 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsSetBadArg( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-set 1 )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "word expected" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 11 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsSetTrue( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "(-set x 1)( -is-set x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "1" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsSetFalse( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-set x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

/*----------------------------------------------------------------------------*/

void SRDPreprocCmdIntrospectTest::testIsMacroMissingArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-macro )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "not enough arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 13 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsMacroExtraArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-macro a b c )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "too many arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 15 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsMacroBadArg( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-macro 1 )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "word expected" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 13 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsMacroTrue( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "(-set-macro x (()))( -is-macro x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "1" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsMacroFalse( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-macro x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

/*----------------------------------------------------------------------------*/

void SRDPreprocCmdIntrospectTest::testIsBlessedMissingArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-blessed )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "not enough arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 15 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsBlessedExtraArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-blessed a b c )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "too many arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 17 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsBlessedBadArg( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-blessed 1 )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "word expected" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 15 );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsBlessedUnset( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -is-blessed x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsBlessedUnblessed( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "(-set x 1)( -is-blessed x )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "0" , output ) );
}

void SRDPreprocCmdIntrospectTest::testIsBlessedTrue( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -set x (()) )\n"
				"( -bless x )\n"
				"( -is-blessed x )" ,
				errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "1" , output ) );
}

/*----------------------------------------------------------------------------*/

void SRDPreprocCmdIntrospectTest::testTypeOfMissingArg( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "not enough arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 12 );
	CPPUNIT_ASSERT( check( "none" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfExtraArgs( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of a b c )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) );
	M_CKERR_( 0 , "too many arguments" , 1 , 3 );
	M_CKERR_( 1 , "previous error cause" , 1 , 14 );
	CPPUNIT_ASSERT( check( "word" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfList( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of ( ) )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "list" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfWord( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of w )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "word" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfString( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of \"w\" )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "string" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfInt( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of 0 )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "int" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfLong( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of 12123456789 )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "long" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfReal( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of 0. )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "real" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfVar( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of ( -raw $x ) )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "var" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfBinary( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of [] )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "binary" , output ) );
}

void SRDPreprocCmdIntrospectTest::testTypeOfComment( )
{
	T_SRDErrors errors;
	T_SRDList output( process( "( -type-of (-from-source \"{x}\") )" , errors ) );
	CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) );
	CPPUNIT_ASSERT( check( "comment" , output ) );
}