From f97beb15b844476077b4e0b09f79ac8cdc71ef01 Mon Sep 17 00:00:00 2001 From: Roberto Fernandez Bautista Date: Sun, 19 Mar 2023 15:27:42 +0100 Subject: [PATCH] QA: std::optional testing + re-enable cadstar parts parser qa test --- .../qa_utils/wx_utils/unit_test_utils.h | 61 ++++++++++---- .../cadstar/test_cadstar_parts_parser.cpp | 82 ++++++++----------- 2 files changed, 80 insertions(+), 63 deletions(-) diff --git a/qa/qa_utils/include/qa_utils/wx_utils/unit_test_utils.h b/qa/qa_utils/include/qa_utils/wx_utils/unit_test_utils.h index e697cf35fd..767d0643fb 100644 --- a/qa/qa_utils/include/qa_utils/wx_utils/unit_test_utils.h +++ b/qa/qa_utils/include/qa_utils/wx_utils/unit_test_utils.h @@ -138,6 +138,52 @@ BOOST_TEST_PRINT_NAMESPACE_CLOSE #endif +template +struct PRINTABLE_OPT +{ + PRINTABLE_OPT( const std::optional& aOpt ) : m_Opt( aOpt ){}; + PRINTABLE_OPT( const T& aVal ) : m_Opt( aVal ){}; + + std::optional m_Opt; +}; + + +/** + * Work around to allow printing std::optional types + */ +#define KI_CHECK_OPT_EQUAL( lhs, rhs ) \ + BOOST_CHECK_EQUAL( PRINTABLE_OPT( lhs ), PRINTABLE_OPT( rhs ) ) + + +template +inline std::ostream& operator<<( std::ostream& aOs, const PRINTABLE_OPT& aOptional ) +{ + if( aOptional.m_Opt.has_value() ) + aOs << *aOptional.m_Opt; + else + aOs << "nullopt"; + + return aOs; +} + + +template +inline bool operator==( const PRINTABLE_OPT& aLhs, const PRINTABLE_OPT& aRhs ) +{ + if( !aLhs.m_Opt.has_value() && !aRhs.m_Opt.has_value() ) + return true; // both nullopt + + return aLhs.m_Opt.has_value() && aRhs.m_Opt.has_value() && *aLhs.m_Opt == *aRhs.m_Opt; +} + + +template +inline bool operator!=( const PRINTABLE_OPT& aLhs, const PRINTABLE_OPT& aRhs ) +{ + return !( aLhs == aRhs ); +} + + namespace BOOST_TEST_PRINT_NAMESPACE_OPEN { @@ -161,21 +207,6 @@ struct print_log_value> } }; -/** - * Boost print helper for std::optional - */ -template -struct print_log_value> -{ - inline void operator()( std::ostream& os, std::optional const& aOptional ) - { - if( aOptional.has_value() ) - print_log_value()( os, aOptional.value() ); - else - os << "nullopt"; - } -}; - /** * Boost print helper for wxPoint. Note operator<< for this type doesn't * exist in non-DEBUG builds. diff --git a/qa/unittests/common/plugins/cadstar/test_cadstar_parts_parser.cpp b/qa/unittests/common/plugins/cadstar/test_cadstar_parts_parser.cpp index b50eb216a6..11e007eb08 100644 --- a/qa/unittests/common/plugins/cadstar/test_cadstar_parts_parser.cpp +++ b/qa/unittests/common/plugins/cadstar/test_cadstar_parts_parser.cpp @@ -31,19 +31,6 @@ #include -//Todo: move somewhere else? -template -std::ostream& operator<<( std::ostream& aOs, const std::optional& aOptional ) -{ - if( aOptional.has_value() ) - aOs << aOptional.value(); - else - aOs << "nullopt"; - - return aOs; -} - - BOOST_AUTO_TEST_SUITE( CadstarPartParser ); @@ -64,7 +51,7 @@ BOOST_AUTO_TEST_CASE( AnalyzeGrammar ) BOOST_CHECK_EQUAL( headerIssues, 0 ); } -/* + struct CHECK_HEADER_CASE { std::string m_CaseName; @@ -118,33 +105,33 @@ BOOST_AUTO_TEST_CASE( ReadFile ) // Test a programatically generated file (see writeCadstarFile.py) auto ret = p.ReadFile( getCadstarTestFile( "cadstarDummy.lib" ) ); - BOOST_CHECK_EQUAL( ret.m_FormatNumber, 32 ); + KI_CHECK_OPT_EQUAL( ret.m_FormatNumber, 32 ); BOOST_CHECK_EQUAL( ret.m_PartEntries.size(), 100 ); int i = 0; for( CADSTAR_PART_ENTRY& partEntry : ret.m_PartEntries ) { - // Part header + // Part header KI_CHECK_OPT_EQUAL BOOST_CHECK_EQUAL( partEntry.m_Name, "PartName" + std::to_string( i ) ); - BOOST_CHECK_EQUAL( partEntry.m_Number, std::to_string( i * 5 ) ); - BOOST_CHECK_EQUAL( partEntry.m_Version, std::to_string( 2 ) ); - BOOST_CHECK_EQUAL( partEntry.m_Description, + KI_CHECK_OPT_EQUAL( partEntry.m_Number, std::to_string( i * 5 ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_Version, std::to_string( 2 ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_Description, "Part " + std::to_string( i ) + " Description" ); BOOST_CHECK_EQUAL( partEntry.m_Pcb_component, "FOOTPRINT" + std::to_string( i ) ); - BOOST_CHECK_EQUAL( partEntry.m_Pcb_alternate, "variant" + std::to_string( i * 5 ) ); - BOOST_CHECK_EQUAL( partEntry.m_Value, std::to_string( i ) + " uH" ); + KI_CHECK_OPT_EQUAL( partEntry.m_Pcb_alternate, "variant" + std::to_string( i * 5 ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_Value, std::to_string( i ) + " uH" ); BOOST_CHECK_EQUAL( partEntry.m_ComponentStem, "L" ); - BOOST_CHECK_EQUAL( partEntry.m_MaxPinCount, i + 10 ); + KI_CHECK_OPT_EQUAL( partEntry.m_MaxPinCount, i + 10 ); BOOST_CHECK_EQUAL( partEntry.m_GateSwappingAllowed, i % 10 != 1 ); BOOST_CHECK_EQUAL( partEntry.m_PinsVisible, i % 5 != 1 ); - BOOST_CHECK_EQUAL( partEntry.m_SpicePartName, "PartName" + std::to_string( i ) ); - BOOST_CHECK_EQUAL( partEntry.m_SpiceModel, std::to_string( i ) + "uH" ); + KI_CHECK_OPT_EQUAL( partEntry.m_SpicePartName, "PartName" + std::to_string( i ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_SpiceModel, std::to_string( i ) + "uH" ); - BOOST_CHECK_EQUAL( partEntry.m_AcceptancePartName, "PartName" + std::to_string( i ) ); - BOOST_CHECK_EQUAL( partEntry.m_AcceptanceText, "Acceptance" + std::to_string( i ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_AcceptancePartName, "PartName" + std::to_string( i ) ); + KI_CHECK_OPT_EQUAL( partEntry.m_AcceptanceText, "Acceptance" + std::to_string( i ) ); // User part attributes (* lines) BOOST_CHECK_EQUAL( partEntry.m_UserAttributes["UserFieldpartNo"], @@ -187,7 +174,7 @@ BOOST_AUTO_TEST_CASE( ReadFile ) // Check symbol name and pins BOOST_REQUIRE_EQUAL( partEntry.m_Symbols.size(), 1 ); BOOST_CHECK_EQUAL( partEntry.m_Symbols[0].m_SymbolName, "Symbol" + std::to_string( i ) ); - BOOST_CHECK_EQUAL( partEntry.m_Symbols[0].m_SymbolAlternateName, + KI_CHECK_OPT_EQUAL( partEntry.m_Symbols[0].m_SymbolAlternateName, std::optional() ); BOOST_REQUIRE_EQUAL( partEntry.m_Symbols[0].m_Pins.size(), 2 ); BOOST_CHECK_EQUAL( partEntry.m_Symbols[0].m_Pins[0].m_Identifier, 1 ); @@ -258,20 +245,18 @@ BOOST_AUTO_TEST_CASE( ReadContent ) CADSTAR_PARTS_LIB_PARSER csParser; CADSTAR_PARTS_LIB_MODEL result = csParser.ReadContent( test ); - std::optional nullOptString; - - BOOST_CHECK_EQUAL( result.m_FormatNumber, 32 ); + KI_CHECK_OPT_EQUAL( result.m_FormatNumber, 32 ); BOOST_REQUIRE_EQUAL( result.m_HierarchyNodes.size(), 2 ); // root and subnode BOOST_REQUIRE_EQUAL( result.m_PartEntries.size(), 1 ); BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Name, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Number, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Version, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Description, "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Number.value(), "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Version.value(), "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Description.value(), "" ); BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Pcb_component, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Pcb_alternate, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Value, "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Pcb_alternate.value(), "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_Value.value(), "" ); // Check pin names (*PNM) BOOST_REQUIRE_EQUAL( result.m_PartEntries[0].m_PinNamesMap.size(), 6 ); @@ -315,7 +300,7 @@ BOOST_AUTO_TEST_CASE( ReadContent ) // Check internal swap groups equivalences (*INT) BOOST_REQUIRE_EQUAL( result.m_PartEntries[0].m_InternalSwapGroup.size(), 1 ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_InternalSwapGroup[0].m_Name, "Group1" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_InternalSwapGroup[0].m_Name.value(), "Group1" ); std::vector>& intgates = result.m_PartEntries[0].m_InternalSwapGroup[0].m_Gates; @@ -331,7 +316,7 @@ BOOST_AUTO_TEST_CASE( ReadContent ) // Check external swap groups equivalences (*EXT) BOOST_REQUIRE_EQUAL( result.m_PartEntries[0].m_ExternalSwapGroup.size(), 1 ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_ExternalSwapGroup[0].m_Name, "Group2" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_ExternalSwapGroup[0].m_Name.value(), "Group2" ); std::vector>& extgates = result.m_PartEntries[0].m_ExternalSwapGroup[0].m_Gates; @@ -345,7 +330,7 @@ BOOST_AUTO_TEST_CASE( ReadContent ) BOOST_CHECK_EQUAL( extgates[1][1], 7 ); // Check part Definition - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_PartDefinitionName, "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_PartDefinitionName.value(), "" ); // Check *NGS BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_GateSwappingAllowed, false ); @@ -357,15 +342,15 @@ BOOST_AUTO_TEST_CASE( ReadContent ) BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_ComponentStem, "" ); // Check *MXP - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_MaxPinCount, 32 ); + KI_CHECK_OPT_EQUAL( result.m_PartEntries[0].m_MaxPinCount, 32 ); // Check *SPI - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_SpicePartName, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_SpiceModel, " " ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_SpicePartName.value(), "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_SpiceModel.value(), " " ); // Check *PAC - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_AcceptancePartName, "" ); - BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_AcceptanceText, "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_AcceptancePartName.value(), "" ); + BOOST_CHECK_EQUAL( result.m_PartEntries[0].m_AcceptanceText.value(), "" ); // Check user attributes (* lines) BOOST_REQUIRE_EQUAL( result.m_PartEntries[0].m_UserAttributes.size(), 2 ); @@ -461,10 +446,11 @@ BOOST_AUTO_TEST_CASE( ReadContent ) while( itA != symbols.end() || itB != expectedSymbols.end() ) { BOOST_TEST_CONTEXT( "With symbol = " << itB->m_SymbolName - << " Alternate = " << itB->m_SymbolAlternateName ) + << " Alternate = " + << itB->m_SymbolAlternateName.value_or( "[nullopt]" ) ) { BOOST_CHECK_EQUAL( itA->m_SymbolName, itB->m_SymbolName ); - BOOST_CHECK_EQUAL( itA->m_SymbolAlternateName, itB->m_SymbolAlternateName ); + KI_CHECK_OPT_EQUAL( itA->m_SymbolAlternateName, itB->m_SymbolAlternateName ); BOOST_REQUIRE_EQUAL( itA->m_Pins.size(), itB->m_Pins.size() ); @@ -478,7 +464,7 @@ BOOST_AUTO_TEST_CASE( ReadContent ) BOOST_CHECK_EQUAL( itPinsA->m_Identifier, itPinsB->m_Identifier ); BOOST_CHECK( itPinsA->m_Position == itPinsB->m_Position ); BOOST_CHECK( itPinsA->m_Type == itPinsB->m_Type ); - BOOST_CHECK_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading ); + KI_CHECK_OPT_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading ); } ++itPinsA; @@ -530,7 +516,7 @@ BOOST_AUTO_TEST_CASE( ReadContent ) BOOST_CHECK_EQUAL( itPinsA->m_Identifier, itPinsB->m_Identifier ); BOOST_CHECK( itPinsA->m_Position == itPinsB->m_Position ); BOOST_CHECK( itPinsA->m_Type == itPinsB->m_Type ); - BOOST_CHECK_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading ); + KI_CHECK_OPT_EQUAL( itPinsA->m_Loading, itPinsB->m_Loading ); ++itPinsA; ++itPinsB; @@ -541,6 +527,6 @@ BOOST_AUTO_TEST_CASE( ReadContent ) ++itEntryB; } } -*/ + BOOST_AUTO_TEST_SUITE_END()