qa: more tests for libeval_compiler
This commit is contained in:
parent
4e00ad9ca9
commit
6bddc4bdd6
|
@ -24,34 +24,16 @@
|
||||||
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
||||||
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
||||||
|
|
||||||
find_program(LEMON lemon)
|
|
||||||
|
|
||||||
if( LEMON )
|
|
||||||
|
|
||||||
macro( generate_lemon_grammar TGT_NAME GRAMMAR_LEMON GRAMMAR_C )
|
|
||||||
add_custom_target( ${TGT_NAME}
|
|
||||||
DEPENDS ${GRAMMAR_LEMON}
|
|
||||||
COMMAND ${LEMON} -q ${GRAMMAR_LEMON}
|
|
||||||
COMMENT "Running Lemon on ${GRAMMAR_LEMON} -> ${GRAMMAR_C}"
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
)
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
generate_lemon_grammar( libeval_grammar2 grammar.lemon grammar.c )
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW)
|
add_definitions(-DBOOST_TEST_DYN_LINK -DPCBNEW)
|
||||||
|
|
||||||
if( BUILD_GITHUB_PLUGIN )
|
if( BUILD_GITHUB_PLUGIN )
|
||||||
set( GITHUB_PLUGIN_LIBRARIES github_plugin )
|
set( GITHUB_PLUGIN_LIBRARIES github_plugin )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_dependencies( pnsrouter pcbcommon pcad2kicadpcb libeval_grammar2 ${GITHUB_PLUGIN_LIBRARIES} )
|
add_dependencies( pnsrouter pcbcommon pcad2kicadpcb ${GITHUB_PLUGIN_LIBRARIES} )
|
||||||
|
|
||||||
add_executable( libeval_compiler_test
|
add_executable( libeval_compiler_test
|
||||||
libeval_compiler_test.cpp
|
libeval_compiler_test.cpp
|
||||||
libeval_compiler.cpp
|
|
||||||
../qa_utils/mocks.cpp
|
../qa_utils/mocks.cpp
|
||||||
../../common/base_units.cpp
|
../../common/base_units.cpp
|
||||||
../../3d-viewer/3d_viewer/3d_viewer_settings.cpp
|
../../3d-viewer/3d_viewer/3d_viewer_settings.cpp
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
#include "class_board.h"
|
#include "class_board.h"
|
||||||
#include "class_track.h"
|
#include "class_track.h"
|
||||||
#include "libeval_compiler.h"
|
|
||||||
|
|
||||||
|
#include <pcb_expr_evaluator.h>
|
||||||
|
|
||||||
#include <io_mgr.h>
|
#include <io_mgr.h>
|
||||||
#include <kicad_plugin.h>
|
#include <kicad_plugin.h>
|
||||||
|
@ -13,182 +13,6 @@
|
||||||
|
|
||||||
#include <profile.h>
|
#include <profile.h>
|
||||||
|
|
||||||
class PCB_EXPR_VAR_REF;
|
|
||||||
|
|
||||||
class PCB_EXPR_UCODE : public LIBEVAL::UCODE
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
virtual VAR_REF *createVarRef( const std::string &var, const std::string &field ) override;
|
|
||||||
|
|
||||||
void SetItems( BOARD_ITEM *a, BOARD_ITEM* b )
|
|
||||||
{
|
|
||||||
m_items[0] = a;
|
|
||||||
m_items[1] = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOARD_ITEM *GetItem( int index ) const
|
|
||||||
{
|
|
||||||
return m_items[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BOARD_ITEM *m_items[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PCB_EXPR_VAR_REF : public LIBEVAL::UCODE::VAR_REF
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PCB_EXPR_VAR_REF ( int aItemIndex )
|
|
||||||
: m_itemIndex(aItemIndex)
|
|
||||||
{
|
|
||||||
//printf("*** createVarRef %p %d\n", this, aItemIndex );
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetType( LIBEVAL::VAR_TYPE_T type )
|
|
||||||
{
|
|
||||||
m_type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddAllowedClass ( TYPE_ID type_hash, PROPERTY_BASE *prop )
|
|
||||||
{
|
|
||||||
m_matchingTypes[type_hash] = prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual LIBEVAL::VAR_TYPE_T GetType( const LIBEVAL::UCODE* aUcode ) const override
|
|
||||||
{
|
|
||||||
return m_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual LIBEVAL::VALUE GetValue( const LIBEVAL::UCODE* aUcode ) const override
|
|
||||||
{
|
|
||||||
auto ucode = static_cast<const PCB_EXPR_UCODE*> (aUcode);
|
|
||||||
auto item = ucode->GetItem( m_itemIndex );
|
|
||||||
|
|
||||||
auto it = m_matchingTypes.find( TYPE_HASH( *item ) );
|
|
||||||
|
|
||||||
if( it == m_matchingTypes.end() )
|
|
||||||
{
|
|
||||||
printf("Null field!\n");
|
|
||||||
return LIBEVAL::VALUE(0.0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( m_type == LIBEVAL::VT_NUMERIC )
|
|
||||||
return LIBEVAL::VALUE( (double) item->Get<int>( it->second ) );
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxString str = item->Get<wxString>( it->second );
|
|
||||||
//printf("item %p GetStr '%s'\n", item, (const char*) str.c_str());
|
|
||||||
return LIBEVAL::VALUE( (const char*) str.c_str() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::unordered_map<TYPE_ID, PROPERTY_BASE*> m_matchingTypes;
|
|
||||||
int m_itemIndex;
|
|
||||||
LIBEVAL::VAR_TYPE_T m_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
LIBEVAL::UCODE::VAR_REF *PCB_EXPR_UCODE::createVarRef( const std::string &var, const std::string &field )
|
|
||||||
{
|
|
||||||
PCB_EXPR_VAR_REF *rv;
|
|
||||||
|
|
||||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
|
||||||
|
|
||||||
auto classes = propMgr.GetAllClasses();
|
|
||||||
auto vref = new PCB_EXPR_VAR_REF( var == "A" ? 0 : 1 );
|
|
||||||
|
|
||||||
for ( auto cls : classes )
|
|
||||||
{
|
|
||||||
if( propMgr.IsOfType( cls.type, TYPE_HASH( BOARD_ITEM ) ) )
|
|
||||||
{
|
|
||||||
PROPERTY_BASE* prop = propMgr.GetProperty( cls.type, field );
|
|
||||||
if( prop )
|
|
||||||
{
|
|
||||||
//printf("Field '%s' class %s ptr %p\n", field.c_str(), (const char *) cls.name.c_str(), prop );
|
|
||||||
vref->AddAllowedClass( cls.type, prop );
|
|
||||||
if ( prop->TypeHash() == TYPE_HASH(int) )
|
|
||||||
vref->SetType( LIBEVAL::VT_NUMERIC );
|
|
||||||
else if ( prop->TypeHash() == TYPE_HASH(wxString) )
|
|
||||||
vref->SetType( LIBEVAL::VT_STRING );
|
|
||||||
else {
|
|
||||||
printf("Unknown property type\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vref;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOARD* loadBoard( const std::string& filename )
|
|
||||||
{
|
|
||||||
PLUGIN::RELEASER pi( new PCB_IO );
|
|
||||||
BOARD* brd = nullptr;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
brd = pi->Load( wxString( filename.c_str() ), NULL, NULL );
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& ioe )
|
|
||||||
{
|
|
||||||
wxString msg = wxString::Format( _( "Error loading board.\n%s" ),
|
|
||||||
ioe.Problem() );
|
|
||||||
|
|
||||||
printf( "%s\n", (const char*) msg.mb_str() );
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return brd;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class PCB_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~PCB_UNIT_RESOLVER()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const std::vector<std::string>& GetSupportedUnits() const override
|
|
||||||
{
|
|
||||||
static const std::vector<std::string> pcbUnits = {"mil", "mm", "in"};
|
|
||||||
|
|
||||||
return pcbUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual double Convert( const std::string aString, int unitId ) const override
|
|
||||||
{
|
|
||||||
double v = atof(aString.c_str());
|
|
||||||
switch(unitId)
|
|
||||||
{
|
|
||||||
case 0 :
|
|
||||||
return Mils2iu( v );
|
|
||||||
case 1:
|
|
||||||
return Millimeter2iu( v );
|
|
||||||
case 2:
|
|
||||||
return Mils2iu( v * 1000.0 );
|
|
||||||
default:
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PCB_EXPR_COMPILER()
|
|
||||||
{
|
|
||||||
m_unitResolver.reset( new PCB_UNIT_RESOLVER );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool testEvalExpr( const std::string expr, LIBEVAL::VALUE expectedResult, bool expectError = false, BOARD_ITEM* itemA = nullptr, BOARD_ITEM* itemB = nullptr )
|
bool testEvalExpr( const std::string expr, LIBEVAL::VALUE expectedResult, bool expectError = false, BOARD_ITEM* itemA = nullptr, BOARD_ITEM* itemB = nullptr )
|
||||||
{
|
{
|
||||||
PCB_EXPR_COMPILER compiler;
|
PCB_EXPR_COMPILER compiler;
|
||||||
|
@ -207,7 +31,7 @@ bool testEvalExpr( const std::string expr, LIBEVAL::VALUE expectedResult, bool e
|
||||||
ok = true;
|
ok = true;
|
||||||
return ok;
|
return ok;
|
||||||
} else {
|
} else {
|
||||||
printf("result: FAIL (unexpected parse error)\n");
|
printf("result: FAIL: %s\n", compiler.GetErrorStatus().Format().c_str() );
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,24 +68,6 @@ bool EvaluatePCBExpression( const std::string& aExpr, int& aResult )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PCB_EXPR_EVALUATOR
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PCB_EXPR_EVALUATOR();
|
|
||||||
~PCB_EXPR_EVALUATOR();
|
|
||||||
|
|
||||||
bool Evaluate( const wxString& aExpr );
|
|
||||||
int Result() const { return m_result; }
|
|
||||||
wxString GetErrorString();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_error;
|
|
||||||
int m_result;
|
|
||||||
|
|
||||||
PCB_EXPR_COMPILER m_compiler;
|
|
||||||
PCB_EXPR_UCODE m_ucode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main( int argc, char *argv[] )
|
int main( int argc, char *argv[] )
|
||||||
{
|
{
|
||||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||||
|
@ -307,18 +113,25 @@ int main( int argc, char *argv[] )
|
||||||
trackA.SetNet( net1info );
|
trackA.SetNet( net1info );
|
||||||
trackB.SetNet( net2info );
|
trackB.SetNet( net2info );
|
||||||
|
|
||||||
|
trackB.SetLayer( F_Cu );
|
||||||
|
|
||||||
trackA.SetWidth( Mils2iu( 10 ));
|
trackA.SetWidth( Mils2iu( 10 ));
|
||||||
trackB.SetWidth( Mils2iu( 20 ));
|
trackB.SetWidth( Mils2iu( 20 ));
|
||||||
|
|
||||||
printf("TrkA %p netclass '%s'\n", &trackA, (const char*) trackA.GetNetClassName().c_str() );
|
printf("TrkA %p netclass '%s'\n", &trackA, (const char*) trackA.GetNetClassName().c_str() );
|
||||||
printf("TrkB %p netclass '%s'\n", &trackB, (const char*) trackB.GetNetClassName().c_str() );
|
printf("TrkB %p netclass '%s'\n", &trackB, (const char*) trackB.GetNetClassName().c_str() );
|
||||||
|
|
||||||
|
// testEvalExpr( "A.onlayer(\"F.Cu\") || A.onlayer(\"B.Cu\")", VAL(1.0), false, &trackA, &trackB );
|
||||||
|
testEvalExpr( "A.type == \"Pad\" && B.type == \"Pad\" && (A.onLayer(\"F.Cu\"))",VAL(0.0), false, &trackA, &trackB );
|
||||||
|
return 0;
|
||||||
testEvalExpr( "A.Width > B.Width", VAL(0.0), false, &trackA, &trackB );
|
testEvalExpr( "A.Width > B.Width", VAL(0.0), false, &trackA, &trackB );
|
||||||
testEvalExpr( "A.Width + B.Width", VAL(Mils2iu(10) + Mils2iu(20)), false, &trackA, &trackB );
|
testEvalExpr( "A.Width + B.Width", VAL(Mils2iu(10) + Mils2iu(20)), false, &trackA, &trackB );
|
||||||
|
|
||||||
testEvalExpr( "A.Netclass", VAL( (const char*) trackA.GetNetClassName().c_str() ), false, &trackA, &trackB );
|
testEvalExpr( "A.Netclass", VAL( (const char*) trackA.GetNetClassName().c_str() ), false, &trackA, &trackB );
|
||||||
testEvalExpr( "A.Netclass == \"HV\" && B.netclass == \"otherClass\"", VAL( 1.0 ), false, &trackA, &trackB );
|
testEvalExpr( "(A.Netclass == \"HV\") && (B.netclass == \"otherClass\") && (B.netclass != \"F.Cu\")", VAL( 1.0 ), false, &trackA, &trackB );
|
||||||
testEvalExpr( "A.Netclass + 1.0", VAL( 1.0 ), false, &trackA, &trackB );
|
testEvalExpr( "A.Netclass + 1.0", VAL( 1.0 ), false, &trackA, &trackB );
|
||||||
|
testEvalExpr( "A.type == \"Track\" && B.type == \"Track\" && A.layer == \"F.Cu\"", VAL(0.0), false, &trackA, &trackB );
|
||||||
|
testEvalExpr( "(A.type == \"Track\") && (B.type == \"Track\") && (A.layer == \"F.Cu\")", VAL(0.0), false, &trackA, &trackB );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue