QA: LIB_TABLE tests
Some basic tests on LIB_TABLE and LIB_TABLE_ROW that demonstrate the behaviour of fallbacks and various access methods. Also add a few LIB_TABLE_BASE comments and changed some NULLs to nullptr.
This commit is contained in:
parent
e6a6266f3d
commit
84d79ec10d
|
@ -306,7 +306,7 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName ) const
|
||||||
// not found, search fall back table(s), if any
|
// not found, search fall back table(s), if any
|
||||||
} while( ( cur = cur->fallBack ) != 0 );
|
} while( ( cur = cur->fallBack ) != 0 );
|
||||||
|
|
||||||
return NULL; // not found
|
return nullptr; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,7 +328,7 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName )
|
||||||
// not found, search fall back table(s), if any
|
// not found, search fall back table(s), if any
|
||||||
} while( ( cur = cur->fallBack ) != 0 );
|
} while( ( cur = cur->fallBack ) != 0 );
|
||||||
|
|
||||||
return NULL; // not found
|
return nullptr; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ const LIB_TABLE_ROW* LIB_TABLE::FindRowByURI( const wxString& aURI )
|
||||||
// not found, search fall back table(s), if any
|
// not found, search fall back table(s), if any
|
||||||
} while( ( cur = cur->fallBack ) != 0 );
|
} while( ( cur = cur->fallBack ) != 0 );
|
||||||
|
|
||||||
return NULL; // not found
|
return nullptr; // not found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ PROPERTIES* LIB_TABLE::ParseOptions( const std::string& aOptionsList )
|
||||||
return new PROPERTIES( props );
|
return new PROPERTIES( props );
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ public:
|
||||||
* a row is not found in this table. No ownership is
|
* a row is not found in this table. No ownership is
|
||||||
* taken of aFallBackTable.
|
* taken of aFallBackTable.
|
||||||
*/
|
*/
|
||||||
LIB_TABLE( LIB_TABLE* aFallBackTable = NULL );
|
LIB_TABLE( LIB_TABLE* aFallBackTable = nullptr );
|
||||||
|
|
||||||
virtual ~LIB_TABLE();
|
virtual ~LIB_TABLE();
|
||||||
|
|
||||||
|
@ -315,6 +315,12 @@ public:
|
||||||
nickIndex.clear();
|
nickIndex.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares this table against another.
|
||||||
|
*
|
||||||
|
* This compares the row *contents* against each other.
|
||||||
|
* Any fallback tables are not checked.
|
||||||
|
*/
|
||||||
bool operator==( const LIB_TABLE& r ) const
|
bool operator==( const LIB_TABLE& r ) const
|
||||||
{
|
{
|
||||||
if( rows.size() == r.rows.size() )
|
if( rows.size() == r.rows.size() )
|
||||||
|
@ -333,9 +339,23 @@ public:
|
||||||
|
|
||||||
bool operator!=( const LIB_TABLE& r ) const { return !( *this == r ); }
|
bool operator!=( const LIB_TABLE& r ) const { return !( *this == r ); }
|
||||||
|
|
||||||
int GetCount() { return rows.size(); }
|
/**
|
||||||
|
* Get the number of rows contained in the table
|
||||||
|
*/
|
||||||
|
int GetCount()
|
||||||
|
{
|
||||||
|
return rows.size();
|
||||||
|
}
|
||||||
|
|
||||||
LIB_TABLE_ROW* At( int aIndex ) { return &rows[aIndex]; }
|
/**
|
||||||
|
* Get the row at the given index.
|
||||||
|
* @param aIndex row index (must exist)
|
||||||
|
* @return pointer to the row
|
||||||
|
*/
|
||||||
|
LIB_TABLE_ROW* At( int aIndex )
|
||||||
|
{
|
||||||
|
return &rows[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the table is empty.
|
* Return true if the table is empty.
|
||||||
|
|
|
@ -41,6 +41,7 @@ set( common_srcs
|
||||||
test_coroutine.cpp
|
test_coroutine.cpp
|
||||||
test_format_units.cpp
|
test_format_units.cpp
|
||||||
test_hotkey_store.cpp
|
test_hotkey_store.cpp
|
||||||
|
test_lib_table.cpp
|
||||||
test_kicad_string.cpp
|
test_kicad_string.cpp
|
||||||
test_refdes_utils.cpp
|
test_refdes_utils.cpp
|
||||||
test_title_block.cpp
|
test_title_block.cpp
|
||||||
|
|
|
@ -0,0 +1,364 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Test suite for LIB_TABLE_BASE
|
||||||
|
*
|
||||||
|
* This test is of a abstract class, so we will implement a cut-down
|
||||||
|
* version and only test the core logic. Tests of the concrete implementations's
|
||||||
|
* own logic should be done in the relevant tests.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unit_test_utils/unit_test_utils.h>
|
||||||
|
|
||||||
|
// Code under test
|
||||||
|
#include <lib_table_base.h>
|
||||||
|
|
||||||
|
#include <make_unique.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A concrete implementation of #LIB_TABLE_ROW that implements
|
||||||
|
* the minimum interface.
|
||||||
|
*/
|
||||||
|
class TEST_LIB_TABLE_ROW : public LIB_TABLE_ROW
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TEST_LIB_TABLE_ROW( const wxString& aNick, const wxString& aURI, const wxString& aOptions,
|
||||||
|
const wxString& aDescr )
|
||||||
|
: LIB_TABLE_ROW( aNick, aURI, aOptions, aDescr )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const wxString GetType() const override
|
||||||
|
{
|
||||||
|
return m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetType( const wxString& aType ) override
|
||||||
|
{
|
||||||
|
m_type = aType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
LIB_TABLE_ROW* do_clone() const override
|
||||||
|
{
|
||||||
|
return new TEST_LIB_TABLE_ROW( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A concrete implementation of #LIB_TABLE that implements
|
||||||
|
* the minimum interface for testing.
|
||||||
|
*
|
||||||
|
* Notably, the Parse/Format functions are not used, as there is no "real"
|
||||||
|
* format to read/write.
|
||||||
|
*/
|
||||||
|
class TEST_LIB_TABLE : public LIB_TABLE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TEST_LIB_TABLE( LIB_TABLE* aFallback = nullptr ) : LIB_TABLE( aFallback )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
KICAD_T Type() override // from _ELEM
|
||||||
|
{
|
||||||
|
// Doesn't really matter what this is
|
||||||
|
return FP_LIB_TABLE_T;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Parse( LIB_TABLE_LEXER* aLexer ) override
|
||||||
|
{
|
||||||
|
// Do nothing, we won't parse anything. Parse testing of actual data
|
||||||
|
// will happen in the relevant other tests.
|
||||||
|
}
|
||||||
|
|
||||||
|
void Format( OUTPUTFORMATTER* aOutput, int aIndentLevel ) const override
|
||||||
|
{
|
||||||
|
// do nothing, we don't need to test this function
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple structure to contain data to set up a single #TEST_LIB_TABLE_ROW
|
||||||
|
*/
|
||||||
|
struct LIB_ROW_DEFINITION
|
||||||
|
{
|
||||||
|
std::string m_nickname;
|
||||||
|
std::string m_uri;
|
||||||
|
std::string m_description;
|
||||||
|
bool m_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
/**
|
||||||
|
* Set-up data for the re-used library row definitions.
|
||||||
|
*/
|
||||||
|
static const std::vector<LIB_ROW_DEFINITION> main_lib_defs = {
|
||||||
|
{
|
||||||
|
"Lib1",
|
||||||
|
"://lib/1",
|
||||||
|
"The first library",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Lib2",
|
||||||
|
"://lib/2",
|
||||||
|
"The second library",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Lib3",
|
||||||
|
"://lib/3",
|
||||||
|
"The third library",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const std::vector<LIB_ROW_DEFINITION> fallback_lib_defs = {
|
||||||
|
{
|
||||||
|
"FallbackLib1",
|
||||||
|
"://lib/fb1",
|
||||||
|
"The first fallback library",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"FallbackLib2",
|
||||||
|
"://lib/fb2",
|
||||||
|
"The second fallback library",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reusable test fixture with some basic pre-filled tables.
|
||||||
|
*/
|
||||||
|
struct LIB_TABLE_TEST_FIXTURE
|
||||||
|
{
|
||||||
|
LIB_TABLE_TEST_FIXTURE() : m_mainTableWithFb( &m_fallbackTable )
|
||||||
|
{
|
||||||
|
for( const auto& lib : main_lib_defs )
|
||||||
|
{
|
||||||
|
m_mainTableNoFb.InsertRow( makeRowFromDef( lib ).release() );
|
||||||
|
m_mainTableWithFb.InsertRow( makeRowFromDef( lib ).release() );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const auto& lib : fallback_lib_defs )
|
||||||
|
{
|
||||||
|
m_fallbackTable.InsertRow( makeRowFromDef( lib ).release() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to construct a new #TEST_LIB_TABLE_ROW from a definition struct
|
||||||
|
*/
|
||||||
|
std::unique_ptr<TEST_LIB_TABLE_ROW> makeRowFromDef( const LIB_ROW_DEFINITION& aDef )
|
||||||
|
{
|
||||||
|
auto row = std::make_unique<TEST_LIB_TABLE_ROW>(
|
||||||
|
aDef.m_nickname, aDef.m_uri, "", aDef.m_description );
|
||||||
|
|
||||||
|
row->SetEnabled( aDef.m_enabled );
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Table with some enabled and disabled libs, no fallback provided
|
||||||
|
TEST_LIB_TABLE m_mainTableNoFb;
|
||||||
|
|
||||||
|
/// Identical to m_mainTableNoFb, but with a fallback
|
||||||
|
TEST_LIB_TABLE m_mainTableWithFb;
|
||||||
|
|
||||||
|
/// The table that m_mainTableWithFb falls back to.
|
||||||
|
TEST_LIB_TABLE m_fallbackTable;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare the test suite
|
||||||
|
*/
|
||||||
|
BOOST_FIXTURE_TEST_SUITE( LibTable, LIB_TABLE_TEST_FIXTURE )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an empty table behaves correctly
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Empty )
|
||||||
|
{
|
||||||
|
TEST_LIB_TABLE table;
|
||||||
|
|
||||||
|
// Tables start out empty
|
||||||
|
BOOST_CHECK_EQUAL( table.GetCount(), 0 );
|
||||||
|
BOOST_CHECK_EQUAL( true, table.IsEmpty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check size and emptiness on tables with fallback
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( EmptyWithFallback )
|
||||||
|
{
|
||||||
|
// Fall back though another empty table to the real fallback
|
||||||
|
TEST_LIB_TABLE interposer_table( &m_fallbackTable );
|
||||||
|
TEST_LIB_TABLE table( &interposer_table );
|
||||||
|
|
||||||
|
// Table has no elements...
|
||||||
|
BOOST_CHECK_EQUAL( table.GetCount(), 0 );
|
||||||
|
|
||||||
|
// But it's not empty if we include the fallback
|
||||||
|
BOOST_CHECK_EQUAL( false, table.IsEmpty( true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check table clearing function
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Clear )
|
||||||
|
{
|
||||||
|
m_mainTableNoFb.Clear();
|
||||||
|
|
||||||
|
// Tables start out empty
|
||||||
|
BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 0 );
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb.IsEmpty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check table equality function
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Equal )
|
||||||
|
{
|
||||||
|
// writing a boot print is a bit of faff, so just use BOOST_CHECK_EQUAL and bools
|
||||||
|
|
||||||
|
// These two are identical, except the fallback (which isn't checked)
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb == m_mainTableWithFb );
|
||||||
|
BOOST_CHECK_EQUAL( false, m_mainTableNoFb != m_mainTableWithFb );
|
||||||
|
|
||||||
|
// Modify one of them
|
||||||
|
m_mainTableWithFb.At( 1 )->SetNickName( "NewNickname" );
|
||||||
|
BOOST_CHECK_EQUAL( false, m_mainTableNoFb == m_mainTableWithFb );
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb != m_mainTableWithFb );
|
||||||
|
|
||||||
|
// And check unequal (against empty)
|
||||||
|
TEST_LIB_TABLE empty_table;
|
||||||
|
BOOST_CHECK_EQUAL( false, m_mainTableNoFb == empty_table );
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb != empty_table );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test indexing into the main table
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Indexing )
|
||||||
|
{
|
||||||
|
// Filled with the right row count
|
||||||
|
BOOST_CHECK_EQUAL( m_mainTableNoFb.GetCount(), 3 );
|
||||||
|
|
||||||
|
const auto* row0 = m_mainTableNoFb.At( 0 );
|
||||||
|
BOOST_CHECK_EQUAL( row0->GetNickName(), "Lib1" );
|
||||||
|
|
||||||
|
const auto* row1 = m_mainTableNoFb.At( 1 );
|
||||||
|
BOOST_CHECK_EQUAL( row1->GetNickName(), "Lib2" );
|
||||||
|
|
||||||
|
// disable, but still in the index
|
||||||
|
const auto* row2 = m_mainTableNoFb.At( 2 );
|
||||||
|
BOOST_CHECK_EQUAL( row2->GetNickName(), "Lib3" );
|
||||||
|
|
||||||
|
// check correct handling of out-of-bounds
|
||||||
|
// TODO: this doesn't work with boost::ptr_vector - that only asserts
|
||||||
|
// BOOST_CHECK_THROW( m_mainTableNoFb.At( 3 ), std::out_of_range );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test retrieval of libs by nickname
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( HasLibrary )
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib1" ) );
|
||||||
|
|
||||||
|
// disabled lib can be "not found" if checkEnabled is set
|
||||||
|
BOOST_CHECK_EQUAL( true, m_mainTableNoFb.HasLibrary( "Lib3" ) );
|
||||||
|
BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "Lib3", true ) );
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( false, m_mainTableNoFb.HasLibrary( "NotPresent" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test retrieval of libs by nickname
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Descriptions )
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL( "The first library", m_mainTableNoFb.GetDescription( "Lib1" ) );
|
||||||
|
|
||||||
|
// disabled lib works
|
||||||
|
BOOST_CHECK_EQUAL( "The third library", m_mainTableNoFb.GetDescription( "Lib3" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test retrieval of libs by URI
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( URIs )
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL( "://lib/1", m_mainTableNoFb.GetFullURI( "Lib1" ) );
|
||||||
|
|
||||||
|
const auto* row = m_mainTableNoFb.FindRowByURI( "://lib/1" );
|
||||||
|
|
||||||
|
// should be found
|
||||||
|
BOOST_CHECK_NE( nullptr, row );
|
||||||
|
|
||||||
|
if( row )
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL( "Lib1", row->GetNickName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
row = m_mainTableNoFb.FindRowByURI( "this_uri_is_not_found" );
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( nullptr, row );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test retrieval of the logical libs function
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( LogicalLibs )
|
||||||
|
{
|
||||||
|
auto logical_libs = m_mainTableNoFb.GetLogicalLibs();
|
||||||
|
|
||||||
|
// The enabled library nicknames
|
||||||
|
const std::vector<wxString> exp_libs = {
|
||||||
|
"Lib1",
|
||||||
|
"Lib2",
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL_COLLECTIONS(
|
||||||
|
logical_libs.begin(), logical_libs.end(), exp_libs.begin(), exp_libs.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
Loading…
Reference in New Issue