Skip to content

Commit

Permalink
add modifications to Checker for repetitions support (and unit test)
Browse files Browse the repository at this point in the history
issue #33
  • Loading branch information
Valentin Noel committed Dec 12, 2013
1 parent 5b71710 commit df8f29c
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 21 deletions.
67 changes: 46 additions & 21 deletions libraries/ElementChecker/src/ElementChecker/Checker/Checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,22 @@ void Checker::check( const ShPtrElement element )
status = eStatusSkip;
}

if( status == eStatusInvalid && ! element->_repetExpr.empty() )
if( ! element->_repetExpr.empty() )
{
LOG_TRACE( "[checker] " << element->_id << " : check repetitions" );
status = eStatusSkip;
std::string errorMessage;
ShPtrElement previous = element->getPrevious();
if( ! isIterationValid( previous, errorMessage ) )
{
LOG_ERROR( errorMessage << " (" << element->_id << " )" );
element->_error.push_back( errorMessage );
if( status == eStatusValid && ! continueRepetition( element ) )
status = eStatusInvalid;
if( status == eStatusInvalid )
{
status = eStatusSkip;
ShPtrElement previous = element->getPrevious();
if( ! isIterationValid( previous, errorMessage ) )
{
LOG_ERROR( errorMessage << " (" << element->_id << " )" );
element->_error.push_back( errorMessage );
status = eStatusInvalid;
}
}
}

Expand All @@ -159,20 +164,6 @@ void Checker::check( const ShPtrElement element )
LOG_TRACE( "[checker] " << element->_id << " : return status = " << statusMap.at( status ) );
}

void Checker::setParentGroupSize( const ShPtrElement element )
{
ShPtrElement parent = element->getParent();

if( parent == nullptr ||
element->getPrevious() == nullptr ||
element->getSpecNode()->next() != nullptr ||
parent->_groupSizeExpr.empty() )
return;

parent->_specGroupSize = _exprParser->getExpressionResult< size_t >( parent->_groupSizeExpr );
LOG_TRACE( "[checker] set " << element->_id << "'s parent (" << parent->_id << ") groupSize (" << parent->_groupSizeExpr << "): " << parent->_specGroupSize );
}

size_t Checker::getSize( const ShPtrElement element )
{
try
Expand Down Expand Up @@ -218,6 +209,40 @@ size_t Checker::getSize( const ShPtrElement element )
}
}

void Checker::setParentGroupSize( const ShPtrElement element )
{
ShPtrElement parent = element->getParent();

if( parent == nullptr ||
element->getPrevious() == nullptr ||
element->getSpecNode()->next() != nullptr ||
parent->_groupSizeExpr.empty() )
return;

parent->_specGroupSize = _exprParser->getExpressionResult< size_t >( parent->_groupSizeExpr );
LOG_TRACE( "[checker] set " << element->_id << "'s parent (" << parent->_id << ") groupSize (" << parent->_groupSizeExpr << "): " << parent->_specGroupSize );
}

bool Checker::continueRepetition( const ShPtrElement element )
{
if( element->_repetExpr.empty() )
return true;
size_t repetMax = 0;
for( std::pair< std::string, std::string > repetPair : element->_repetExpr )
{
if( repetPair.first != repetPair.second )
continue;
repetMax = std::max( _exprParser->getExpressionResult< size_t >( repetPair.first ), repetMax );
}

if( repetMax != 0 && element->_iteration > repetMax )
{
LOG_TRACE( "[checker] repetition : " << element->_iteration << " / " << repetMax << ": continue...");
return false;
}
return true;
}

bool Checker::isIterationValid( const ShPtrElement element, std::string& errorMessage )
{
if( element->_repetExpr.empty() )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Checker
size_t getSize( const ShPtrElement element );
private:
void setParentGroupSize ( const ShPtrElement element );
bool continueRepetition ( const ShPtrElement element );
bool isIterationValid ( const ShPtrElement element, std::string& errorMessage );
bool isRequirementValid ( const ShPtrElement element );
void checkLastUnorderedElement( const ShPtrElement element );
Expand Down
127 changes: 127 additions & 0 deletions libraries/ElementChecker/test/checkerTestRepetitions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,133 @@ BOOST_AUTO_TEST_CASE( element_checker_checker_repetition )
}
}

BOOST_AUTO_TEST_CASE( element_checker_checker_repetition_limited )
{
std::string jsonStringBegin = R"*(
{
"content": [
{
"id": "value1",
"label": "Value1",
"type": "uint16",
"repetition": )*";


std::string jsonStringEnd = R"*(
},
{
"id": "valueEnd",
"label": "Value End",
"type": "ascii",
"values": "END"
}
]
}
)*";

std::vector< char > buff1 { 0x00, 0x01 };
std::vector< char > buff2 { 0x00, 0x02 };
std::vector< char > buff3 { 0x00, 0x03 };
std::vector< char > buff4 { 'E', 'N', 'D' };

LOG_INFO( "\n>>> element_checker_checker_repetition_limited <<<" );
{
std::string jsonStringRepetition = R"*("3")*";

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

Checker checker;

std::shared_ptr< basic_element::Element > elem1( new basic_element::Element( node ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusUnknown );
elem1->set( buff1, 2 );
checker.check( elem1 );
LOG_FATAL( elem1->_id << " | " << typeStringMap.at( elem1->_type ) << " | " << statusMap.at( elem1->_status ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem2( new basic_element::Element( elem1->next(), elem1 ) );
elem2->set( buff2, 2 );
checker.check( elem2 );
LOG_FATAL( elem2->_id << " | " << typeStringMap.at( elem2->_type ) << " | " << statusMap.at( elem2->_status ) );
BOOST_CHECK_EQUAL( elem2->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem3( new basic_element::Element( elem2->next(), elem2 ) );
elem3->set( buff3, 2 );
checker.check( elem3 );
LOG_FATAL( elem3->_id << " | " << typeStringMap.at( elem3->_type ) << " | " << statusMap.at( elem3->_status ) );
BOOST_CHECK_EQUAL( elem3->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem4( new basic_element::Element( elem3->next(), elem3 ) );
elem4->set( buff4, 2 );
checker.check( elem4 );
LOG_FATAL( elem4->_id << " | " << typeStringMap.at( elem4->_type ) << " | " << statusMap.at( elem4->_status ) );
BOOST_CHECK_EQUAL( elem4->_status, eStatusSkip );
BOOST_CHECK( elem4->_error.empty() );

std::shared_ptr< basic_element::Element > elem5( new basic_element::Element( elem4->next(), elem4 ) );
elem5->set( buff4, 3 );
checker.check( elem5 );
BOOST_CHECK_EQUAL( elem5->_status, eStatusValid );
LOG_FATAL( elem5->_id << " | " << typeStringMap.at( elem5->_type ) << " | " << statusMap.at( elem5->_status ) );

BOOST_CHECK( elem5->next() == nullptr );
}
LOG_INFO( "\n>>> element_checker_checker_repetition_limited suite <<<" );
{
std::string jsonStringRepetition = R"*( [
1, 2, 3
] )*";

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

Checker checker;

std::shared_ptr< basic_element::Element > elem1( new basic_element::Element( node ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusUnknown );
elem1->set( buff1, 2 );
checker.check( elem1 );
LOG_FATAL( elem1->_id << " | " << typeStringMap.at( elem1->_type ) << " | " << statusMap.at( elem1->_status ) );
BOOST_CHECK_EQUAL( elem1->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem2( new basic_element::Element( elem1->next(), elem1 ) );
elem2->set( buff2, 2 );
checker.check( elem2 );
LOG_FATAL( elem2->_id << " | " << typeStringMap.at( elem2->_type ) << " | " << statusMap.at( elem2->_status ) );
BOOST_CHECK_EQUAL( elem2->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem3( new basic_element::Element( elem2->next(), elem2 ) );
elem3->set( buff3, 2 );
checker.check( elem3 );
LOG_FATAL( elem3->_id << " | " << typeStringMap.at( elem3->_type ) << " | " << statusMap.at( elem3->_status ) );
BOOST_CHECK_EQUAL( elem3->_status, eStatusValid );

std::shared_ptr< basic_element::Element > elem4( new basic_element::Element( elem3->next(), elem3 ) );
elem4->set( buff4, 2 );
checker.check( elem4 );
LOG_FATAL( elem4->_id << " | " << typeStringMap.at( elem4->_type ) << " | " << statusMap.at( elem4->_status ) );
BOOST_CHECK_EQUAL( elem4->_status, eStatusSkip );
BOOST_CHECK( elem4->_error.empty() );

std::shared_ptr< basic_element::Element > elem5( new basic_element::Element( elem4->next(), elem4 ) );
elem5->set( buff4, 3 );
checker.check( elem5 );
BOOST_CHECK_EQUAL( elem5->_status, eStatusValid );
LOG_FATAL( elem5->_id << " | " << typeStringMap.at( elem5->_type ) << " | " << statusMap.at( elem5->_status ) );

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

BOOST_AUTO_TEST_CASE( element_checker_checker_repetition_invalid )
{
std::string jsonStringBegin = R"*(
Expand Down

0 comments on commit df8f29c

Please sign in to comment.