#include #include using namespace ebcl; class SyntaxTreeTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( SyntaxTreeTest ); CPPUNIT_TEST( testEmpty ); CPPUNIT_TEST( testSetData ); CPPUNIT_TEST( testUpdateData ); CPPUNIT_TEST( testAddChildren ); CPPUNIT_TEST( testVisit ); CPPUNIT_TEST( testLocation ); CPPUNIT_TEST_SUITE_END( ); public: void testEmpty( ); void testSetData( ); void testUpdateData( ); void testAddChildren( ); void testVisit( ); void testLocation( ); }; CPPUNIT_TEST_SUITE_REGISTRATION( SyntaxTreeTest ); /*----------------------------------------------------------------------------*/ enum class E_TestNode_ { ROOT , ADD , VALUE }; using T_Test_ = T_SyntaxTree< E_TestNode_ , uint32_t >; /*----------------------------------------------------------------------------*/ void SyntaxTreeTest::testEmpty( ) { T_Test_ st{ E_TestNode_::ROOT }; CPPUNIT_ASSERT( E_TestNode_::ROOT == st.typeOf( 0 ) ); CPPUNIT_ASSERT( st.childrenOf( 0 ).empty( ) ); CPPUNIT_ASSERT_EQUAL( 0u , st.parentOf( 0 ) ); CPPUNIT_ASSERT( !st.hasData( 0 ) ); } void SyntaxTreeTest::testSetData( ) { T_Test_ st{ E_TestNode_::ROOT }; CPPUNIT_ASSERT( E_TestNode_::ROOT == st.typeOf( 0 ) ); CPPUNIT_ASSERT( !st.hasData( 0 ) ); CPPUNIT_ASSERT_EQUAL( 12u , st.newData< uint32_t >( 0 , 12 ) ); CPPUNIT_ASSERT( st.hasData( 0 ) ); CPPUNIT_ASSERT_EQUAL( 12u , st.dataOf< uint32_t>( 0 ) ); } void SyntaxTreeTest::testUpdateData( ) { T_Test_ st{ E_TestNode_::ROOT }; st.newData< uint32_t >( 0 , 12 ); st.dataOf< uint32_t>( 0 ) = 42u; CPPUNIT_ASSERT_EQUAL( 42u , st.dataOf< uint32_t>( 0 ) ); } void SyntaxTreeTest::testAddChildren( ) { T_Test_ st{ E_TestNode_::ROOT }; const auto rc{ st.addChild( 0 , E_TestNode_::ADD ) }; CPPUNIT_ASSERT_EQUAL( 1u , rc ); CPPUNIT_ASSERT_EQUAL( 1u , st.childrenOf( 0 ).size( ) ); CPPUNIT_ASSERT_EQUAL( rc , st.childrenOf( 0 )[ 0 ] ); CPPUNIT_ASSERT_EQUAL( 0u , st.parentOf( rc ) ); CPPUNIT_ASSERT( E_TestNode_::ADD == st.typeOf( rc ) ); const auto cc{ st.addChild( rc , E_TestNode_::VALUE ) }; CPPUNIT_ASSERT_EQUAL( 2u , cc ); CPPUNIT_ASSERT_EQUAL( 1u , st.childrenOf( rc ).size( ) ); CPPUNIT_ASSERT_EQUAL( cc , st.childrenOf( rc )[ 0 ] ); CPPUNIT_ASSERT( E_TestNode_::VALUE == st.typeOf( cc ) ); } void SyntaxTreeTest::testVisit( ) { T_Test_ st{ E_TestNode_::ROOT }; const uint32_t c0{ st.addChild( 0 , E_TestNode_::ADD ) }; const uint32_t c1{ st.addChild( c0 , E_TestNode_::VALUE ) }; const uint32_t c2{ st.addChild( c0 , E_TestNode_::VALUE ) }; st.newData< uint32_t >( c1 , 12u ); st.newData< uint32_t >( c2 , 42u ); using T_Result_ = std::tuple< bool , uint32_t , T_Optional< uint32_t > >; T_Array< T_Result_ > visitData; st.visitor( ).visit( st.root( ) , [&visitData]( T_Test_::T_Node node , bool after ) { //fprintf( stderr , "NODE %d (%c)\n" , node.node , after ? 'O' : 'I' ); visitData.add( std::make_tuple( !after , node.node , node.tree.hasData( node.node ) ? T_Optional< uint32_t >( node.tree.dataOf< uint32_t >( node.node ) ) : T_Optional< uint32_t >() ) ); return true; } ); // ROOT <-- ADD <-- VALUE{12} // <-- VALUE{42} CPPUNIT_ASSERT_EQUAL( 8u , visitData.size( ) ); CPPUNIT_ASSERT( std::get< 0 >( visitData[ 0 ] ) ); CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 0 ] ) ); CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 0 ] ) ); CPPUNIT_ASSERT( std::get< 0 >( visitData[ 1 ] ) ); CPPUNIT_ASSERT_EQUAL( c0 , std::get< 1 >( visitData[ 1 ] ) ); CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 1 ] ) ); CPPUNIT_ASSERT( std::get< 0 >( visitData[ 2 ] ) ); CPPUNIT_ASSERT_EQUAL( c1 , std::get< 1 >( visitData[ 2 ] ) ); CPPUNIT_ASSERT( std::get< 2 >( visitData[ 2 ] ) ); CPPUNIT_ASSERT_EQUAL( 12u , *std::get< 2 >( visitData[ 2 ] ) ); CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 3 ] ) ); CPPUNIT_ASSERT_EQUAL( c1 , std::get< 1 >( visitData[ 3 ] ) ); CPPUNIT_ASSERT( std::get< 2 >( visitData[ 3 ] ) ); CPPUNIT_ASSERT_EQUAL( 12u , *std::get< 2 >( visitData[ 3 ] ) ); CPPUNIT_ASSERT( std::get< 0 >( visitData[ 4 ] ) ); CPPUNIT_ASSERT_EQUAL( c2 , std::get< 1 >( visitData[ 4 ] ) ); CPPUNIT_ASSERT( std::get< 2 >( visitData[ 4 ] ) ); CPPUNIT_ASSERT_EQUAL( 42u , *std::get< 2 >( visitData[ 4 ] ) ); CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 5 ] ) ); CPPUNIT_ASSERT_EQUAL( c2 , std::get< 1 >( visitData[ 5 ] ) ); CPPUNIT_ASSERT( std::get< 2 >( visitData[ 5 ] ) ); CPPUNIT_ASSERT_EQUAL( 42u , *std::get< 2 >( visitData[ 5 ] ) ); CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 6 ] ) ); CPPUNIT_ASSERT_EQUAL( c0 , std::get< 1 >( visitData[ 6 ] ) ); CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) ); CPPUNIT_ASSERT( !std::get< 0 >( visitData[ 7 ] ) ); CPPUNIT_ASSERT_EQUAL( 0u , std::get< 1 >( visitData[ 7 ] ) ); CPPUNIT_ASSERT( !std::get< 2 >( visitData[ 6 ] ) ); } void SyntaxTreeTest::testLocation( ) { T_Test_ st{ E_TestNode_::ROOT }; CPPUNIT_ASSERT_EQUAL( 0u , st.locationOf( 0 ) ); st.locationOf( 0 ) = 123; CPPUNIT_ASSERT_EQUAL( 123u , st.locationOf( 0 ) ); }