Skip to content

Commit

Permalink
add count expressions support (and unit tests)
Browse files Browse the repository at this point in the history
issue #33
  • Loading branch information
Valentin Noel committed Nov 6, 2013
1 parent 2546e8f commit 1e57022
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 13 deletions.
37 changes: 24 additions & 13 deletions libraries/ElementChecker/src/ElementChecker/Checker/Checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Checker::Checker()

void Checker::check( const std::shared_ptr< basic_element::Element > element )
{
if( element->_size == 0 ) // @todo: parse count expression
if( element->_size == 0 && element->_countExpr.empty() ) // @todo: parse count expression
LOG_WARNING( element->_id << ": Null data size !" );

// if nothing to compare
Expand Down Expand Up @@ -141,12 +141,12 @@ void Checker::check( const std::shared_ptr< basic_element::Element > element )
// end of unordered group : check iterations
if( element->getParent() != nullptr && ! element->getParent()->_isOrdered && status == eStatusInvalid )
{
LOG_FATAL( "CHECKER: " << element->_id << ": Unordered group" );
LOG_ERROR( "CHECKER: " << element->_id << ": Unordered group" );
element->_status = eStatusInvalidButSkip;

if( element->getSpecNode()->next() == nullptr )
{
LOG_FATAL( "CHECKER: " << element->_id << ": Last element" );
LOG_ERROR( "CHECKER: " << element->_id << ": Last element" );
// create a list with the children IDs
std::set< std::string > childIds = element->getParent()->getSpecNode()->getChildrenNodes();
// if the previous element exists (the current element is not the first)
Expand All @@ -163,12 +163,12 @@ void Checker::check( const std::shared_ptr< basic_element::Element > element )
// if the previous element's ID is equal to one ID of the list
if( prev->_id == id && prev->_status == eStatusValid )
{
LOG_FATAL( " >>> childIds: " << id );
LOG_ERROR( "CHECKER: >>> childIds: " << id );
// erase this ID from the list if repetitions ok !
std::string errorMessage;
if( ! prev->_repetExpr.empty() && ! isIterationValid( prev, errorMessage ) )
{
LOG_ERROR( prev->_id << ": " << errorMessage );
LOG_ERROR( "(" << prev->_id << ") " << errorMessage );
prev->_error += errorMessage;
_elementList.push_back( prev );
prev->getParent()->_status = eStatusInvalidGroupForIteration;
Expand All @@ -179,17 +179,17 @@ void Checker::check( const std::shared_ptr< basic_element::Element > element )
// go to the previous element of the previous, etc..
prev = prev->getPrevious();
}
LOG_FATAL( "CHECKER: " << element->_id << ": End of unordered group, remaining children: " << childIds.size() );
LOG_ERROR( "CHECKER: " << element->_id << ": End of unordered group, remaining children: " << childIds.size() );
// if it remains some IDs in the list
if( childIds.size() != 0 )
{
LOG_FATAL( "CHECKER: " << element->getParent()->_id );
LOG_FATAL( "CHECKER: " << &*element->getParent() );
LOG_ERROR( "CHECKER: " << element->getParent()->_id );
LOG_ERROR( "CHECKER: " << &*element->getParent() );
// every nodes haven't been checked : the parent is not valid
element->getParent()->_status = eStatusInvalidForUnordered;
}
}
LOG_FATAL( "CHECKER: " << element->_id << "'s status: " << element->_status );
LOG_ERROR( "CHECKER: " << element->_id << "'s status: " << element->_status );
return;
}

Expand All @@ -205,14 +205,25 @@ void Checker::check( const std::shared_ptr< basic_element::Element > element )
element->_error += errorMessage;
_elementList.push_back( element );
}
LOG_FATAL( "CHECKER: " << element->_id << "'s status: eStatusInvalid" );
LOG_ERROR( "CHECKER: " << element->_id << "'s status: eStatusInvalid" );
return;
}

LOG_FATAL( "CHECKER: " << element->_id << "'s status: " << status );
LOG_ERROR( "CHECKER: " << element->_id << "'s status: " << status );
_elementList.push_back( element );
}

size_t Checker::getSize( const std::shared_ptr< basic_element::Element > element )
{
if( ! element->_countExpr.empty() )
{
ExpressionParser sizeParser( _elementList );
element->_size = sizeParser.getExpressionResult< size_t >( element->_countExpr );
LOG_FATAL( "COUNT: " << element->_id << "'s size: " << element->_size );
}
return element->_size;
}

bool Checker::isIterationValid( const std::shared_ptr< basic_element::Element > element, std::string& errorMessage )
{
if( element->_repetExpr.empty() )
Expand All @@ -225,7 +236,7 @@ bool Checker::isIterationValid( const std::shared_ptr< basic_element::Element >
{
ExpressionParser repetParser( _elementList );
size_t repetNumber = repetParser.getExpressionResult< size_t >( repetPair.first );
LOG_FATAL( "////// REPETITION : " << element->_iteration << " / " << repetNumber );
LOG_ERROR( "CHECKER: repetition : " << element->_iteration << " / " << repetNumber );
if( element->_iteration == repetNumber )
return true;
error << element->_iteration << " / " << repetNumber;
Expand All @@ -241,7 +252,7 @@ bool Checker::isIterationValid( const std::shared_ptr< basic_element::Element >
if( ! repetPair.second.empty() )
repetMax = repetParser.getExpressionResult< size_t >( repetPair.second );

LOG_FATAL( "////// REPETITIONS : " << element->_iteration << " / [" << repetMin << ", " << repetMax << "]" );
LOG_ERROR( "CHECKER: repetitions : " << element->_iteration << " / [" << repetMin << ", " << repetMax << "]" );
if( repetMin <= element->_iteration )
if( repetMax == 0 || repetMax >= element->_iteration )
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Checker
Checker();

void check( const std::shared_ptr< basic_element::Element > element );
size_t getSize( const std::shared_ptr< basic_element::Element > element );
std::vector< std::shared_ptr< basic_element::Element > > getElementList() { return _elementList; }
private:
bool isIterationValid( const std::shared_ptr< basic_element::Element > element, std::string& errorMessage );
Expand Down
116 changes: 116 additions & 0 deletions libraries/ElementChecker/test/checkerTestCount.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

BOOST_AUTO_TEST_SUITE( element_checker_test_checker_count )

BOOST_AUTO_TEST_CASE( element_checker_checker_count )
{
std::string jsonStringBegin = R"*(
{
"header": [
{
"id": "value1",
"label": "Value1",
"type": "uint32"
},
{
"id": "value2",
"label": "Value2",
"type": "raw",
"count": )*";

std::string jsonStringEnd = R"*(
},
{
"id": "value3",
"label": "Value3",
"type": "ascii",
"values": "WAVE3"
}
]
}
)*";

const char buff1[4] { 0x00, 0x00, 0x00, 0x05 };
const char buff2[5] { 'W', 'A', 'V', 'E', '2' };
const char buff3[5] { 'W', 'A', 'V', 'E', '3' };

LOG_INFO( "\n>>> element_checker_checker_count <<<" );
{
std::string jsonStringCount = R"*( "5" )*";

spec_reader::Specification spec;
spec.setFromString( jsonStringBegin + jsonStringCount + jsonStringEnd );
std::shared_ptr< spec_reader::SpecNode > node = spec.getFirstNode();
BOOST_CHECK_EQUAL( node->getId(), "value1" );
BOOST_CHECK_EQUAL( node->next()->getId(), "value2" );
BOOST_CHECK_EQUAL( node->next()->next()->getId(), "value3" );
BOOST_CHECK( node->next()->next()->next() == nullptr );

Checker checker;

std::shared_ptr< basic_element::Element > elem1( new basic_element::Element( node ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusNotChecked );
BOOST_CHECK_EQUAL( elem1->_size, 4 );
BOOST_CHECK_EQUAL( checker.getSize( elem1 ), 4 );
elem1->set( (const char*)&buff1, checker.getSize( elem1 ) );
checker.check( elem1 );
BOOST_CHECK_EQUAL( elem1->_status, eStatusPassOver );

std::shared_ptr< basic_element::Element > elem2( new basic_element::Element( elem1->next(), elem1 ) );
BOOST_CHECK_EQUAL( elem2->_size, 0 );
BOOST_CHECK_EQUAL( checker.getSize( elem2 ), 5 );
elem2->set( (const char*)&buff2, checker.getSize( elem2 ) );
checker.check( elem2 );
BOOST_CHECK_EQUAL( elem2->_size, 5 );
BOOST_CHECK_EQUAL( elem2->_status, eStatusPassOver );

std::shared_ptr< basic_element::Element > elem3( new basic_element::Element( elem2->next(), elem2 ) );
BOOST_CHECK_EQUAL( elem3->_size, 5 );
BOOST_CHECK_EQUAL( checker.getSize( elem3 ), 5 );
elem3->set( (const char*)&buff3, checker.getSize( elem3 ) );
checker.check( elem3 );
BOOST_CHECK_EQUAL( elem3->_status, eStatusValid );

BOOST_CHECK( elem3->next() == nullptr );
}
LOG_INFO( "\n>>> element_checker_checker_count suite <<<" );
{
std::string jsonStringCount = R"*( "value1 - 2" )*";

spec_reader::Specification spec;
spec.setFromString( jsonStringBegin + jsonStringCount + jsonStringEnd );
std::shared_ptr< spec_reader::SpecNode > node = spec.getFirstNode();
BOOST_CHECK_EQUAL( node->getId(), "value1" );
BOOST_CHECK_EQUAL( node->next()->getId(), "value2" );
BOOST_CHECK_EQUAL( node->next()->next()->getId(), "value3" );
BOOST_CHECK( node->next()->next()->next() == nullptr );

Checker checker;

std::shared_ptr< basic_element::Element > elem1( new basic_element::Element( node ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusNotChecked );
BOOST_CHECK_EQUAL( elem1->_size, 4 );
BOOST_CHECK_EQUAL( checker.getSize( elem1 ), 4 );
elem1->set( (const char*)&buff1, checker.getSize( elem1 ) );
checker.check( elem1 );
BOOST_CHECK_EQUAL( elem1->_status, eStatusPassOver );

std::shared_ptr< basic_element::Element > elem2( new basic_element::Element( elem1->next(), elem1 ) );
BOOST_CHECK_EQUAL( elem2->_size, 0 );
BOOST_CHECK_EQUAL( checker.getSize( elem2 ), 3 );
elem2->set( (const char*)&buff2, checker.getSize( elem2 ) );
checker.check( elem2 );
BOOST_CHECK_EQUAL( elem2->_size, 3 );
BOOST_CHECK_EQUAL( elem2->_status, eStatusPassOver );

std::shared_ptr< basic_element::Element > elem3( new basic_element::Element( elem2->next(), elem2 ) );
BOOST_CHECK_EQUAL( elem3->_size, 5 );
BOOST_CHECK_EQUAL( checker.getSize( elem3 ), 5 );
elem3->set( (const char*)&buff3, checker.getSize( elem3 ) );
checker.check( elem3 );
BOOST_CHECK_EQUAL( elem3->_status, eStatusValid );

BOOST_CHECK( elem3->next() == nullptr );
}
}

BOOST_AUTO_TEST_SUITE_END()
1 change: 1 addition & 0 deletions libraries/ElementChecker/test/elementCheckerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ BOOST_AUTO_TEST_SUITE_END()
#include "checkerTest.hpp"
#include "checkerTestRepetitions.hpp"
#include "checkerTestUnordered.hpp"
#include "checkerTestCount.hpp"

0 comments on commit 1e57022

Please sign in to comment.