QA eeschema: add some tests
This adds a few tests on: * LIB_PART * SCH_PIN * SCH_SHEET * SCH_SHEET_PATH These tests exercise some of the basic code paths in these classes and show some of the expected behaviours. None of these tests are particularly ground-breaking, but they provide a starting point to build out further tests, and to ensure the already-covered behaviour is stable. It does expose some places where SCH_SHEET could probably use const.
This commit is contained in:
parent
0617bffce0
commit
840e08fa78
|
@ -130,6 +130,15 @@ the triggering of a bug prior to fixing it. This is advantageous, not only from
|
|||
a "project history" perspective, but also to ensure that the test you write to
|
||||
catch the bug in question does, in fact, catch the bug in the first place.
|
||||
|
||||
### Assertions {#test-assertions}
|
||||
|
||||
It is possible to check for assertions in unit tests. When running the unit
|
||||
tests, `wxASSERT` calls are caught and re-thrown as exceptions. You can then use
|
||||
the `CHECK_WX_ASSERT` macro to check this is called in Debug builds. In Release
|
||||
builds, the check is not run, as `wxASSERT` is disabled in these builds.
|
||||
|
||||
You can use this to ensure that code rejects invalid input correctly.
|
||||
|
||||
## Python modules {#python-tests}
|
||||
|
||||
The Pcbnew Python modules have some test programs in the `qa` directory.
|
||||
|
|
|
@ -32,12 +32,20 @@ add_executable( qa_eeschema
|
|||
../../common/colors.cpp
|
||||
../../common/observable.cpp
|
||||
|
||||
# need the mock Pgm for many functions
|
||||
mocks_eeschema.cpp
|
||||
|
||||
eeschema_test_utils.cpp
|
||||
timestamp_test_utils.cpp
|
||||
|
||||
# The main test entry points
|
||||
test_module.cpp
|
||||
|
||||
test_eagle_plugin.cpp
|
||||
test_lib_part.cpp
|
||||
test_sch_pin.cpp
|
||||
test_sch_sheet.cpp
|
||||
test_sch_sheet_path.cpp
|
||||
|
||||
# Older CMakes cannot link OBJECT libraries
|
||||
# https://cmake.org/pipermail/cmake/2013-November/056263.html
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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 utils (e.g. print helpers and test predicates for LIB_FIELD objects
|
||||
*/
|
||||
|
||||
#ifndef QA_EESCHEMA_LIB_FIELD_TEST_UTILS__H
|
||||
#define QA_EESCHEMA_LIB_FIELD_TEST_UTILS__H
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
#include <class_libentry.h>
|
||||
#include <template_fieldnames.h>
|
||||
|
||||
|
||||
BOOST_TEST_PRINT_NAMESPACE_OPEN
|
||||
{
|
||||
template <>
|
||||
struct print_log_value<LIB_FIELD>
|
||||
{
|
||||
inline void operator()( std::ostream& os, LIB_FIELD const& f )
|
||||
{
|
||||
os << "LIB_FIELD[ " << f.GetName() << " ]";
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct print_log_value<LIB_FIELDS>
|
||||
{
|
||||
inline void operator()( std::ostream& os, LIB_FIELDS const& f )
|
||||
{
|
||||
os << "LIB_FIELDS[ " << f.size() << " ]";
|
||||
}
|
||||
};
|
||||
}
|
||||
BOOST_TEST_PRINT_NAMESPACE_CLOSE
|
||||
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
|
||||
/**
|
||||
* Predicate to check a field name is as expected
|
||||
* @param aField LIB_FIELD to check the name
|
||||
* @param aExpectedName the expected field name
|
||||
* @param aExpectedId the expected field id
|
||||
* @return true if match
|
||||
*/
|
||||
bool FieldNameIdMatches(
|
||||
const LIB_FIELD& aField, const std::string& aExpectedName, int aExpectedId )
|
||||
{
|
||||
bool ok = true;
|
||||
const auto gotName = aField.GetName( false );
|
||||
|
||||
if( gotName != aExpectedName )
|
||||
{
|
||||
BOOST_TEST_INFO(
|
||||
"Field name mismatch: got '" << gotName << "', expected '" << aExpectedName );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
const int gotId = aField.GetId();
|
||||
|
||||
if( gotId != aExpectedId )
|
||||
{
|
||||
BOOST_TEST_INFO( "Field ID mismatch: got '" << gotId << "', expected '" << aExpectedId );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate to check that the mandatory fields in a LIB_FIELDS object look sensible
|
||||
* @param aFields the fields to check
|
||||
* @return true if valid
|
||||
*/
|
||||
bool AreDefaultFieldsCorrect( const LIB_FIELDS& aFields )
|
||||
{
|
||||
const unsigned expectedCount = NumFieldType::MANDATORY_FIELDS;
|
||||
if( aFields.size() < expectedCount )
|
||||
{
|
||||
BOOST_TEST_INFO(
|
||||
"Expected at least " << expectedCount << " fields, got " << aFields.size() );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= FieldNameIdMatches( aFields[0], "Reference", NumFieldType::REFERENCE );
|
||||
ok &= FieldNameIdMatches( aFields[1], "Value", NumFieldType::VALUE );
|
||||
ok &= FieldNameIdMatches( aFields[2], "Footprint", NumFieldType::FOOTPRINT );
|
||||
ok &= FieldNameIdMatches( aFields[3], "Datasheet", NumFieldType::DATASHEET );
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
} // namespace KI_TEST
|
||||
|
||||
#endif // QA_EESCHEMA_LIB_FIELD_TEST_UTILS__H
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
*/
|
||||
|
||||
#include <kiface_i.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
|
||||
// The main sheet of the project
|
||||
SCH_SHEET* g_RootSheet = nullptr;
|
||||
|
||||
// a transform matrix, to display components in lib editor
|
||||
TRANSFORM DefaultTransform = TRANSFORM( 1, 0, 0, -1 );
|
||||
|
||||
static struct IFACE : public KIFACE_I
|
||||
{
|
||||
// Of course all are overloads, implementations of the KIFACE.
|
||||
|
||||
IFACE( const char* aName, KIWAY::FACE_T aType ) : KIFACE_I( aName, aType )
|
||||
{
|
||||
}
|
||||
|
||||
bool OnKifaceStart( PGM_BASE* aProgram, int aCtlBits ) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnKifaceEnd() override
|
||||
{
|
||||
}
|
||||
|
||||
wxWindow* CreateWindow(
|
||||
wxWindow* aParent, int aClassId, KIWAY* aKiway, int aCtlBits = 0 ) override
|
||||
{
|
||||
assert( false );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function IfaceOrAddress
|
||||
* return a pointer to the requested object. The safest way to use this
|
||||
* is to retrieve a pointer to a static instance of an interface, similar to
|
||||
* how the KIFACE interface is exported. But if you know what you are doing
|
||||
* use it to retrieve anything you want.
|
||||
*
|
||||
* @param aDataId identifies which object you want the address of.
|
||||
*
|
||||
* @return void* - and must be cast into the know type.
|
||||
*/
|
||||
void* IfaceOrAddress( int aDataId ) override
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
} kiface( "mock_eeschema", KIWAY::FACE_SCH );
|
||||
|
||||
static struct PGM_MOCK_EESCHEMA_FRAME : public PGM_BASE
|
||||
{
|
||||
bool OnPgmInit();
|
||||
|
||||
void OnPgmExit()
|
||||
{
|
||||
Kiway.OnKiwayEnd();
|
||||
|
||||
// Destroy everything in PGM_BASE, especially wxSingleInstanceCheckerImpl
|
||||
// earlier than wxApp and earlier than static destruction would.
|
||||
PGM_BASE::Destroy();
|
||||
}
|
||||
|
||||
void MacOpenFile( const wxString& aFileName ) override
|
||||
{
|
||||
wxFileName filename( aFileName );
|
||||
|
||||
if( filename.FileExists() )
|
||||
{
|
||||
#if 0
|
||||
// this pulls in EDA_DRAW_FRAME type info, which we don't want in
|
||||
// the single_top link image.
|
||||
KIWAY_PLAYER* frame = dynamic_cast<KIWAY_PLAYER*>( App().GetTopWindow() );
|
||||
#else
|
||||
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
|
||||
#endif
|
||||
|
||||
if( frame )
|
||||
frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
|
||||
}
|
||||
}
|
||||
} program;
|
||||
|
||||
PGM_BASE& Pgm()
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
KIFACE_I& Kiface()
|
||||
{
|
||||
return kiface;
|
||||
}
|
||||
|
||||
|
||||
static COLOR4D s_layerColor[LAYER_ID_COUNT];
|
||||
|
||||
COLOR4D GetLayerColor( SCH_LAYER_ID aLayer )
|
||||
{
|
||||
unsigned layer = ( aLayer );
|
||||
wxASSERT( layer < arrayDim( s_layerColor ) );
|
||||
return s_layerColor[layer];
|
||||
}
|
||||
|
||||
void SetLayerColor( COLOR4D aColor, SCH_LAYER_ID aLayer )
|
||||
{
|
||||
// Do not allow non-background layers to be completely white.
|
||||
// This ensures the BW printing recognizes that the colors should be
|
||||
// printed black.
|
||||
if( aColor == COLOR4D::WHITE && aLayer != LAYER_SCHEMATIC_BACKGROUND )
|
||||
aColor.Darken( 0.01 );
|
||||
|
||||
unsigned layer = aLayer;
|
||||
wxASSERT( layer < arrayDim( s_layerColor ) );
|
||||
s_layerColor[layer] = aColor;
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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_PART
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
// Code under test
|
||||
#include <class_libentry.h>
|
||||
|
||||
#include "lib_field_test_utils.h"
|
||||
|
||||
class TEST_LIB_PART_FIXTURE
|
||||
{
|
||||
public:
|
||||
TEST_LIB_PART_FIXTURE() : m_part_no_data( "part_name", nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
///> Part with no extra data set
|
||||
LIB_PART m_part_no_data;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Declare the test suite
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( LibPart, TEST_LIB_PART_FIXTURE )
|
||||
|
||||
|
||||
/**
|
||||
* Check that we can get the basic properties out as expected
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( DefaultProperties )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetName(), "part_name" );
|
||||
|
||||
// Didn't set a library, so this is empty
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetLibraryName(), "" );
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetLib(), nullptr );
|
||||
|
||||
// only get the root
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetAliasCount(), 1 );
|
||||
|
||||
// no sub units
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetUnitCount(), 1 );
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.IsMulti(), false );
|
||||
|
||||
// no conversion
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.HasConversion(), false );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the drawings on a "blank" LIB_PART
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( DefaultDrawings )
|
||||
{
|
||||
// default drawings exist
|
||||
BOOST_CHECK_EQUAL( m_part_no_data.GetDrawItems().size(), 4 );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the default fields are present as expected
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( DefaultFields )
|
||||
{
|
||||
LIB_FIELDS fields;
|
||||
m_part_no_data.GetFields( fields );
|
||||
|
||||
// Should get the 4 default fields
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::AreDefaultFieldsCorrect, ( fields ) );
|
||||
|
||||
// but no more (we didn't set them)
|
||||
BOOST_CHECK_EQUAL( fields.size(), NumFieldType::MANDATORY_FIELDS );
|
||||
|
||||
// also check the default field accessors
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
|
||||
( m_part_no_data.GetReferenceField() )( "Reference" )( NumFieldType::REFERENCE ) );
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
|
||||
( m_part_no_data.GetValueField() )( "Value" )( NumFieldType::VALUE ) );
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
|
||||
( m_part_no_data.GetFootprintField() )( "Footprint" )( NumFieldType::FOOTPRINT ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test adding fields to a LIB_PART
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( AddedFields )
|
||||
{
|
||||
LIB_FIELDS fields;
|
||||
m_part_no_data.GetFields( fields );
|
||||
|
||||
// Ctor takes non-const ref (?!)
|
||||
const std::string newFieldName = "new_field";
|
||||
wxString nonConstNewFieldName = newFieldName;
|
||||
fields.push_back( LIB_FIELD( 42, nonConstNewFieldName ) );
|
||||
|
||||
// fairly roundabout way to add a field, but it is what it is
|
||||
m_part_no_data.SetFields( fields );
|
||||
|
||||
// Should get the 4 default fields
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::AreDefaultFieldsCorrect, ( fields ) );
|
||||
|
||||
// and our new one
|
||||
BOOST_REQUIRE_EQUAL( fields.size(), NumFieldType::MANDATORY_FIELDS + 1 );
|
||||
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
|
||||
( fields[NumFieldType::MANDATORY_FIELDS] )( newFieldName )( 42 ) );
|
||||
|
||||
// Check by-id lookup
|
||||
|
||||
LIB_FIELD* gotNewField = m_part_no_data.GetField( 42 );
|
||||
|
||||
BOOST_REQUIRE_NE( gotNewField, nullptr );
|
||||
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches, ( *gotNewField )( newFieldName )( 42 ) );
|
||||
|
||||
// Check by-name lookup
|
||||
|
||||
gotNewField = m_part_no_data.FindField( newFieldName );
|
||||
|
||||
BOOST_REQUIRE_NE( gotNewField, nullptr );
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches, ( *gotNewField )( newFieldName )( 42 ) );
|
||||
}
|
||||
|
||||
|
||||
struct TEST_LIB_PART_SUBREF_CASE
|
||||
{
|
||||
int m_index;
|
||||
bool m_addSep;
|
||||
std::string m_expSubRef;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test the subreference indexing
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( SubReference )
|
||||
{
|
||||
const std::vector<TEST_LIB_PART_SUBREF_CASE> cases = {
|
||||
{
|
||||
1,
|
||||
false,
|
||||
"A",
|
||||
},
|
||||
{
|
||||
2,
|
||||
false,
|
||||
"B",
|
||||
},
|
||||
{
|
||||
26,
|
||||
false,
|
||||
"Z",
|
||||
},
|
||||
{
|
||||
27,
|
||||
false,
|
||||
"AA",
|
||||
},
|
||||
{ // haven't configured a separator, so should be nothing
|
||||
1,
|
||||
true,
|
||||
"A",
|
||||
},
|
||||
};
|
||||
|
||||
for( const auto& c : cases )
|
||||
{
|
||||
BOOST_TEST_CONTEXT(
|
||||
"Subref: " << c.m_index << ", " << c.m_addSep << " -> '" << c.m_expSubRef << "'" )
|
||||
{
|
||||
const auto subref = m_part_no_data.SubReference( c.m_index, c.m_addSep );
|
||||
BOOST_CHECK_EQUAL( subref, c.m_expSubRef );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -30,11 +30,29 @@
|
|||
|
||||
#include <wx/init.h>
|
||||
|
||||
#include <unit_test_utils/wx_assert.h>
|
||||
|
||||
/*
|
||||
* Simple function to handle a WX assertion and throw a real exception.
|
||||
*
|
||||
* This is useful when you want to check assertions fire in unit tests.
|
||||
*/
|
||||
void wxAssertThrower( const wxString& aFile, int aLine, const wxString& aFunc,
|
||||
const wxString& aCond, const wxString& aMsg )
|
||||
{
|
||||
throw KI_TEST::WX_ASSERT_ERROR( aFile, aLine, aFunc, aCond, aMsg );
|
||||
}
|
||||
|
||||
|
||||
bool init_unit_test()
|
||||
{
|
||||
boost::unit_test::framework::master_test_suite().p_name.value = "Common Eeschema module tests";
|
||||
return wxInitialize();
|
||||
|
||||
bool ok = wxInitialize();
|
||||
|
||||
wxSetAssertHandler( &wxAssertThrower );
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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 SCH_PIM
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/geometry.h>
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
#include <unit_test_utils/wx_assert.h>
|
||||
|
||||
// Code under test
|
||||
#include <sch_pin.h>
|
||||
|
||||
#include <sch_component.h>
|
||||
|
||||
#include <eda_rect.h>
|
||||
|
||||
|
||||
class TEST_SCH_PIN_FIXTURE
|
||||
{
|
||||
public:
|
||||
TEST_SCH_PIN_FIXTURE()
|
||||
: m_parent_part( "parent_part", nullptr ),
|
||||
m_lib_pin( &m_parent_part ),
|
||||
m_parent_comp( wxPoint( 0, 0 ), nullptr ),
|
||||
m_sch_pin( &m_lib_pin, &m_parent_comp )
|
||||
{
|
||||
// give the pin some kind of data we can use to test
|
||||
m_lib_pin.SetNumber( "42" );
|
||||
m_lib_pin.SetName( "pinname" );
|
||||
m_lib_pin.SetType( ELECTRICAL_PINTYPE::PIN_INPUT );
|
||||
|
||||
SCH_SHEET_PATH path;
|
||||
m_parent_comp.SetRef( &path, "U2" );
|
||||
}
|
||||
|
||||
LIB_PART m_parent_part;
|
||||
LIB_PIN m_lib_pin;
|
||||
|
||||
SCH_COMPONENT m_parent_comp;
|
||||
SCH_PIN m_sch_pin;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Declare the test suite
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( SchPin, TEST_SCH_PIN_FIXTURE )
|
||||
|
||||
/**
|
||||
* Check basic properties of an un-modified SCH_PIN object
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( DefaultProperties )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetParentComponent(), &m_parent_comp );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetLibPin(), &m_lib_pin );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetPosition(), wxPoint( 0, 0 ) );
|
||||
|
||||
// These just forward to LIB_PIN for now, so this isn't very interesting
|
||||
// but later we will want to test these functions for SCH_PIN's own functionality
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.IsVisible(), m_lib_pin.IsVisible() );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetName(), m_lib_pin.GetName() );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetNumber(), m_lib_pin.GetNumber() );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.GetType(), m_lib_pin.GetType() );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.IsPowerConnection(), m_lib_pin.IsPowerConnection() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the assignment operator
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( Assign )
|
||||
{
|
||||
SCH_PIN assigned = m_sch_pin;
|
||||
|
||||
BOOST_CHECK_EQUAL( assigned.GetParentComponent(), &m_parent_comp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the copy ctor
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( Copy )
|
||||
{
|
||||
SCH_PIN copied( m_sch_pin );
|
||||
|
||||
BOOST_CHECK_EQUAL( copied.GetParentComponent(), &m_parent_comp );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the pin dangling flag
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( PinDangling )
|
||||
{
|
||||
// dangles by default
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.IsDangling(), true );
|
||||
|
||||
// all you have to do to un-dangle is say so
|
||||
m_sch_pin.SetIsDangling( false );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.IsDangling(), false );
|
||||
|
||||
// and the same to re-dangle
|
||||
m_sch_pin.SetIsDangling( true );
|
||||
BOOST_CHECK_EQUAL( m_sch_pin.IsDangling(), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the pin labelling
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( PinNumbering )
|
||||
{
|
||||
SCH_SHEET_PATH path;
|
||||
|
||||
const wxString name = m_sch_pin.GetDefaultNetName( path );
|
||||
BOOST_CHECK_EQUAL( name, "Net-(U2-Pad42)" );
|
||||
|
||||
// do it again: this should now (transparently) go though the net name map
|
||||
// can't really check directly, but coverage tools should see this
|
||||
const wxString map_name = m_sch_pin.GetDefaultNetName( path );
|
||||
BOOST_CHECK_EQUAL( map_name, name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the pin labelling when it's a power pin
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( PinNumberingPower )
|
||||
{
|
||||
// but if we set is power...
|
||||
m_lib_pin.SetType( ELECTRICAL_PINTYPE::PIN_POWER_IN );
|
||||
m_parent_part.SetPower();
|
||||
|
||||
// the name is just the pin name
|
||||
SCH_SHEET_PATH path;
|
||||
const wxString pwr_name = m_sch_pin.GetDefaultNetName( path );
|
||||
BOOST_CHECK_EQUAL( pwr_name, "pinname" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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 SCH_SHEET
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
// Code under test
|
||||
#include <sch_sheet.h>
|
||||
|
||||
#include "timestamp_test_utils.h"
|
||||
|
||||
#include <unit_test_utils/wx_assert.h>
|
||||
|
||||
class TEST_SCH_SHEET_FIXTURE
|
||||
{
|
||||
public:
|
||||
TEST_SCH_SHEET_FIXTURE() : m_sheet(), m_csheet( m_sheet )
|
||||
{
|
||||
}
|
||||
|
||||
SCH_SHEET m_sheet;
|
||||
|
||||
///> Can use when you need a const ref (lots of places need fixing here)
|
||||
const SCH_SHEET& m_csheet;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Print helper.
|
||||
* Not a print_log_value because old Boosts don't like that in BOOST_CHECK_EQUAL_COLLECTIONS
|
||||
*/
|
||||
std::ostream& operator<<( std::ostream& os, DANGLING_END_ITEM const& d )
|
||||
{
|
||||
os << "DANGLING_END_ITEM[ type " << d.GetType() << " @(" << d.GetPosition().x << ", "
|
||||
<< d.GetPosition().y << "), item " << d.GetItem() << ", parent " << d.GetParent() << " ]";
|
||||
return os;
|
||||
}
|
||||
|
||||
bool operator==( const DANGLING_END_ITEM& aA, const DANGLING_END_ITEM& aB )
|
||||
{
|
||||
return aA.GetItem() == aB.GetItem()
|
||||
&& aA.GetPosition() == aB.GetPosition()
|
||||
&& aA.GetType() == aB.GetType()
|
||||
&& aA.GetParent() == aB.GetParent();
|
||||
}
|
||||
|
||||
bool operator!=( const DANGLING_END_ITEM& aA, const DANGLING_END_ITEM& aB )
|
||||
{
|
||||
return !( aA == aB );
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare the test suite
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( SchSheet, TEST_SCH_SHEET_FIXTURE )
|
||||
|
||||
|
||||
/**
|
||||
* Check default properties
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( Default )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_csheet.GetPosition(), wxPoint( 0, 0 ) );
|
||||
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::EndsInTimestamp, ( m_csheet.GetName().ToStdString() ) );
|
||||
|
||||
// it is it's own root sheet
|
||||
BOOST_CHECK_EQUAL( m_sheet.GetRootSheet(), &m_sheet );
|
||||
BOOST_CHECK_EQUAL( m_sheet.CountSheets(), 1 );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_csheet.GetScreenCount(), 0 );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_sheet.ComponentCount(), 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding pins to a sheet
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( AddPins )
|
||||
{
|
||||
const wxPoint pinPos{ 42, 13 };
|
||||
|
||||
// we should catch null insertions
|
||||
CHECK_WX_ASSERT( m_sheet.AddPin( nullptr ) );
|
||||
|
||||
auto newPin = std::make_unique<SCH_SHEET_PIN>( &m_sheet, pinPos, "pinname" );
|
||||
|
||||
// can't be const because of RemovePin (?!)
|
||||
SCH_SHEET_PIN& pinRef = *newPin;
|
||||
|
||||
m_sheet.AddPin( newPin.release() );
|
||||
|
||||
// now we can find it in the list
|
||||
BOOST_CHECK_EQUAL( m_sheet.HasPins(), true );
|
||||
BOOST_CHECK_EQUAL( m_sheet.HasPin( "pinname" ), true );
|
||||
BOOST_CHECK_EQUAL( m_sheet.HasPin( "PINname" ), true );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_sheet.GetPin( pinPos ), &pinRef );
|
||||
|
||||
// check the actual list can be retrieved
|
||||
// this should be const...
|
||||
SCH_SHEET_PINS& pins = m_sheet.GetPins();
|
||||
BOOST_CHECK_EQUAL( &pins[0], &pinRef );
|
||||
|
||||
// catch the bad call
|
||||
CHECK_WX_ASSERT( m_sheet.RemovePin( nullptr ) );
|
||||
|
||||
m_sheet.RemovePin( &pinRef );
|
||||
|
||||
// and it's gone
|
||||
BOOST_CHECK_EQUAL( m_sheet.HasPins(), false );
|
||||
BOOST_CHECK_EQUAL( m_sheet.HasPin( "pinname" ), false );
|
||||
BOOST_CHECK_EQUAL( m_sheet.GetPin( pinPos ), nullptr );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that pins are added and renumbered to be unique
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( PinRenumbering )
|
||||
{
|
||||
for( int i = 0; i < 5; ++i )
|
||||
{
|
||||
auto pin = std::make_unique<SCH_SHEET_PIN>( &m_sheet, wxPoint{ i, i }, "name" );
|
||||
|
||||
// set the pins to have the same number going in
|
||||
pin->SetNumber( 2 );
|
||||
|
||||
m_sheet.AddPin( pin.release() );
|
||||
}
|
||||
|
||||
SCH_SHEET_PINS& pins = m_sheet.GetPins();
|
||||
|
||||
std::vector<int> numbers;
|
||||
|
||||
for( const auto& pin : pins )
|
||||
{
|
||||
numbers.push_back( pin.GetNumber() );
|
||||
}
|
||||
|
||||
// and now...they are all unique
|
||||
BOOST_CHECK_PREDICATE( KI_TEST::CollectionHasNoDuplicates<decltype( numbers )>, ( numbers ) );
|
||||
}
|
||||
|
||||
|
||||
struct TEST_END_CONN_PIN
|
||||
{
|
||||
std::string m_pin_name;
|
||||
wxPoint m_pos;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test the endpoint and connection point collections: we should be able to add pins, then
|
||||
* have them appear as endpoints.
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( EndconnectionPoints )
|
||||
{
|
||||
// x = zero because the pin is clamped to the left side by default
|
||||
const std::vector<TEST_END_CONN_PIN> pin_defs = {
|
||||
{
|
||||
"1name",
|
||||
{ 0, 13 },
|
||||
},
|
||||
{
|
||||
"2name",
|
||||
{ 0, 130 },
|
||||
},
|
||||
};
|
||||
|
||||
// Insert the pins into the sheet
|
||||
for( const auto& pin : pin_defs )
|
||||
{
|
||||
m_sheet.AddPin(
|
||||
std::make_unique<SCH_SHEET_PIN>( &m_sheet, pin.m_pos, pin.m_pin_name ).release() );
|
||||
}
|
||||
|
||||
SCH_SHEET_PINS& pins = m_sheet.GetPins();
|
||||
|
||||
// make sure the pins made it in
|
||||
BOOST_CHECK_EQUAL( pins.size(), pin_defs.size() );
|
||||
|
||||
// Check that the EndPoint getter gets the right things
|
||||
{
|
||||
std::vector<DANGLING_END_ITEM> expectedDangling;
|
||||
|
||||
// Construct expected from the pin, not defs, as we need the pin address
|
||||
for( auto& pin : pins )
|
||||
{
|
||||
expectedDangling.emplace_back(
|
||||
DANGLING_END_T::SHEET_LABEL_END, &pin, pin.GetPosition(), &pin );
|
||||
}
|
||||
|
||||
std::vector<DANGLING_END_ITEM> dangling;
|
||||
m_sheet.GetEndPoints( dangling );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( dangling.begin(), dangling.end(), expectedDangling.begin(),
|
||||
expectedDangling.end() );
|
||||
}
|
||||
|
||||
// And check the connection getter
|
||||
{
|
||||
std::vector<wxPoint> expectedConnections;
|
||||
|
||||
// we want to see every pin that we just added
|
||||
for( const auto& pin : pin_defs )
|
||||
{
|
||||
expectedConnections.push_back( pin.m_pos );
|
||||
}
|
||||
|
||||
std::vector<wxPoint> connections;
|
||||
m_sheet.GetConnectionPoints( connections );
|
||||
|
||||
BOOST_CHECK_EQUAL_COLLECTIONS( connections.begin(), connections.end(),
|
||||
expectedConnections.begin(), expectedConnections.end() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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 SCH_SHEET_PATH
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
// Code under test
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
#include "timestamp_test_utils.h"
|
||||
|
||||
#include <sch_sheet.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
class TEST_SCH_SHEET_PATH_FIXTURE
|
||||
{
|
||||
public:
|
||||
TEST_SCH_SHEET_PATH_FIXTURE()
|
||||
{
|
||||
for( unsigned i = 0; i < 4; ++i )
|
||||
{
|
||||
m_sheets.emplace_back( wxPoint( i, i ) );
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "Sheet" << i;
|
||||
m_sheets[i].SetName( ss.str() );
|
||||
}
|
||||
|
||||
// 0->1->2
|
||||
m_linear.push_back( &m_sheets[0] );
|
||||
m_linear.push_back( &m_sheets[1] );
|
||||
m_linear.push_back( &m_sheets[2] );
|
||||
}
|
||||
|
||||
SCH_SHEET_PATH m_empty_path;
|
||||
|
||||
/**
|
||||
* We look at sheet 2 in the hierarchy:
|
||||
* Sheets: 0 -> 1 -> 2
|
||||
*/
|
||||
SCH_SHEET_PATH m_linear;
|
||||
|
||||
/// handy store of SCH_SHEET objects
|
||||
std::vector<SCH_SHEET> m_sheets;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Declare the test suite
|
||||
*/
|
||||
BOOST_FIXTURE_TEST_SUITE( SchSheetPath, TEST_SCH_SHEET_PATH_FIXTURE )
|
||||
|
||||
|
||||
/**
|
||||
* Check properties of an empty SCH_SHEET_PATH
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( Empty )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_empty_path.size(), 0 );
|
||||
|
||||
BOOST_CHECK_THROW( m_empty_path.at( 0 ), std::out_of_range );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_empty_path.GetPageNumber(), 0 );
|
||||
|
||||
// These accessors return nullptr when empty (i.e. they don't crash)
|
||||
BOOST_CHECK_EQUAL( m_empty_path.Last(), nullptr );
|
||||
BOOST_CHECK_EQUAL( m_empty_path.LastScreen(), nullptr );
|
||||
BOOST_CHECK_EQUAL( m_empty_path.LastDrawList(), nullptr );
|
||||
BOOST_CHECK_EQUAL( m_empty_path.FirstDrawList(), nullptr );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_empty_path.Path(), "/" );
|
||||
BOOST_CHECK_EQUAL( m_empty_path.PathHumanReadable(), "/" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check properties of a non-empty SCH_SHEET_PATH
|
||||
*/
|
||||
BOOST_AUTO_TEST_CASE( NonEmpty )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_linear.size(), 3 );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_linear.at( 0 ), &m_sheets[0] );
|
||||
BOOST_CHECK_EQUAL( m_linear.at( 1 ), &m_sheets[1] );
|
||||
BOOST_CHECK_EQUAL( m_linear.at( 2 ), &m_sheets[2] );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), 0 );
|
||||
|
||||
BOOST_CHECK_EQUAL( m_linear.Last(), &m_sheets[2] );
|
||||
BOOST_CHECK_EQUAL( m_linear.LastScreen(), nullptr );
|
||||
BOOST_CHECK_EQUAL( m_linear.LastDrawList(), nullptr );
|
||||
BOOST_CHECK_EQUAL( m_linear.FirstDrawList(), nullptr );
|
||||
|
||||
// don't know what the timestamps will be, but we know the format: /<8 chars>/<8 chars>/
|
||||
BOOST_CHECK_PREDICATE(
|
||||
KI_TEST::IsTimestampStringWithLevels, ( m_linear.Path().ToStdString() )( 2 ) );
|
||||
|
||||
// Sheet0 is the root sheet and isn't in the path
|
||||
BOOST_CHECK_EQUAL( m_linear.PathHumanReadable(), "/Sheet1/Sheet2/" );
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( Compare )
|
||||
{
|
||||
SCH_SHEET_PATH otherEmpty;
|
||||
|
||||
BOOST_CHECK( m_empty_path == otherEmpty );
|
||||
|
||||
BOOST_CHECK( m_empty_path != m_linear );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
*/
|
||||
|
||||
#include "timestamp_test_utils.h"
|
||||
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
|
||||
bool EndsInTimestamp( const std::string& aStr )
|
||||
{
|
||||
if( aStr.size() < 8 )
|
||||
{
|
||||
BOOST_TEST_INFO( "Too short to be timestamp: " << aStr.size() );
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsTimeStampish( aStr.end() - 8, aStr.end() );
|
||||
}
|
||||
|
||||
bool IsTimestampStringWithLevels( const std::string& aStr, unsigned aLevels )
|
||||
{
|
||||
const unsigned tsLen = 8;
|
||||
const unsigned levelLen = tsLen + 1; // add the /
|
||||
|
||||
if( aStr.size() != aLevels * levelLen + 1 )
|
||||
{
|
||||
BOOST_TEST_INFO( "String is the wrong length for " << aLevels << " levels." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( aStr[0] != '/' )
|
||||
{
|
||||
BOOST_TEST_INFO( "Doesn't start with '/'" );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto tsBegin = aStr.begin() + 1;
|
||||
|
||||
for( unsigned i = 0; i < aLevels; i++ )
|
||||
{
|
||||
if( !IsTimeStampish( tsBegin, tsBegin + tsLen ) )
|
||||
{
|
||||
BOOST_TEST_INFO( "Not a timeStamp at level "
|
||||
<< i << ": " << std::string( tsBegin, tsBegin + tsLen ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( *( tsBegin + tsLen ) != '/' )
|
||||
{
|
||||
BOOST_TEST_INFO( "level doesn't end in '/'" );
|
||||
return false;
|
||||
}
|
||||
|
||||
tsBegin += levelLen;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace KI_TEST
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
*/
|
||||
|
||||
#ifndef QA_EESCHEMA_TIMESTAMP_TEST_UTILS__H
|
||||
#define QA_EESCHEMA_TIMESTAMP_TEST_UTILS__H
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Test utilities for timestamps
|
||||
*/
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
|
||||
/**
|
||||
* Predicate for checking a timestamp character
|
||||
* @param aChr the character
|
||||
* @return true if it's a valid timestamp char (0-9, A-F)
|
||||
*/
|
||||
inline bool IsTimeStampChar( char aChr )
|
||||
{
|
||||
return ( aChr >= 'A' && aChr <= 'F' ) || ( aChr >= '0' && aChr <= '9' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the string between the iterators looks like a timestamp (i.e. 8 hex digits)
|
||||
*/
|
||||
template <typename T>
|
||||
bool IsTimeStampish( const T& aBegin, const T& aEnd )
|
||||
{
|
||||
// Wrong length
|
||||
if( aEnd != aBegin + 8 )
|
||||
return false;
|
||||
|
||||
// Check all chars
|
||||
return std::all_of( aBegin, aEnd, IsTimeStampChar );
|
||||
}
|
||||
|
||||
/**
|
||||
* Predicate to check if a string look like it ends in a timestamp
|
||||
* @param aStr the string to check
|
||||
* @return true if it does
|
||||
*/
|
||||
bool EndsInTimestamp( const std::string& aStr );
|
||||
|
||||
/**
|
||||
* Predicate to check a string is a timestmap path format
|
||||
*
|
||||
* Eg. levels=2: /1234ABCD/9878DEFC/
|
||||
*
|
||||
* @param aStr candidate string
|
||||
* @param levels expected levels
|
||||
* @return true if format matches
|
||||
*/
|
||||
bool IsTimestampStringWithLevels( const std::string& aStr, unsigned aLevels );
|
||||
|
||||
} // namespace KI_TEST
|
||||
|
||||
#endif // QA_EESCHEMA_TIMESTAMP_TEST_UTILS__H
|
|
@ -29,6 +29,7 @@ find_package( Boost COMPONENTS unit_test_framework filesystem system REQUIRED )
|
|||
|
||||
set( SRCS
|
||||
unit_test_utils.cpp
|
||||
wx_assert.cpp
|
||||
)
|
||||
|
||||
add_library( unit_test_utils STATIC ${SRCS} )
|
||||
|
@ -37,6 +38,7 @@ target_link_libraries( unit_test_utils PUBLIC
|
|||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${wxWidgets_LIBRARIES}
|
||||
)
|
||||
|
||||
target_include_directories( unit_test_utils PUBLIC
|
||||
|
|
|
@ -27,9 +27,12 @@
|
|||
#include <boost/test/test_case_template.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <unit_test_utils/wx_assert.h>
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
#include <wx/gdicmn.h>
|
||||
/**
|
||||
* If HAVE_EXPECTED_FAILURES is defined, this means that
|
||||
* boost::unit_test::expected_failures is available.
|
||||
|
@ -130,6 +133,43 @@ BOOST_TEST_PRINT_NAMESPACE_CLOSE
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
BOOST_TEST_PRINT_NAMESPACE_OPEN
|
||||
{
|
||||
|
||||
/**
|
||||
* Boost print helper for generic vectors
|
||||
*/
|
||||
template <typename T>
|
||||
struct print_log_value<std::vector<T>>
|
||||
{
|
||||
inline void operator()( std::ostream& os, std::vector<T> const& aVec )
|
||||
{
|
||||
os << "std::vector size " << aVec.size() << "[";
|
||||
|
||||
for( const auto& i : aVec )
|
||||
{
|
||||
os << "\n ";
|
||||
print_log_value<T>()( os, i );
|
||||
}
|
||||
|
||||
os << "]";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Boost print helper for wxPoint. Note operator<< for this type doesn't
|
||||
* exist in non-DEBUG builds.
|
||||
*/
|
||||
template <>
|
||||
struct print_log_value<wxPoint>
|
||||
{
|
||||
void operator()( std::ostream& os, wxPoint const& aVec );
|
||||
};
|
||||
}
|
||||
BOOST_TEST_PRINT_NAMESPACE_CLOSE
|
||||
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
|
||||
|
@ -231,6 +271,19 @@ void CheckUnorderedMatches(
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Predicate to check a collection has no duplicate elements
|
||||
*/
|
||||
template <typename T>
|
||||
bool CollectionHasNoDuplicates( const T& aCollection )
|
||||
{
|
||||
T sorted = aCollection;
|
||||
std::sort( sorted.begin(), sorted.end() );
|
||||
|
||||
return std::adjacent_find( sorted.begin(), sorted.end() ) == sorted.end();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a simple string "aIn -> aOut".
|
||||
*
|
||||
|
@ -251,6 +304,18 @@ std::string InOutString( const IN& aIn, const OUT& aOut )
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* A test macro to check a wxASSERT is thrown.
|
||||
*
|
||||
* This only happens in DEBUG builds, so prevent test failures in Release builds
|
||||
* by using this macro.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define CHECK_WX_ASSERT( STATEMENT ) BOOST_CHECK_THROW( STATEMENT, KI_TEST::WX_ASSERT_ERROR );
|
||||
#else
|
||||
#define CHECK_WX_ASSERT( STATEMENT )
|
||||
#endif
|
||||
|
||||
} // namespace KI_TEST
|
||||
|
||||
#endif // UNIT_TEST_UTILS__H
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
*/
|
||||
|
||||
#ifndef UNIT_TEST_UTILS_WX_ASSERT__H
|
||||
#define UNIT_TEST_UTILS_WX_ASSERT__H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
|
||||
/**
|
||||
* An exception class to represent a WX assertion.
|
||||
*
|
||||
* In normal programs, this is popped as a dialog, but in unit tests, it
|
||||
* prints a fairly unhelpful stack trace and otherwise doesn't inform the
|
||||
* test runner.
|
||||
*
|
||||
* We want to raise a formal exception to allow us to catch it with
|
||||
* things like BOOST_CHECK_THROW if expected, or for the test case to fail if
|
||||
* not expected.
|
||||
*/
|
||||
class WX_ASSERT_ERROR : public std::exception
|
||||
{
|
||||
public:
|
||||
WX_ASSERT_ERROR( const wxString& aFile, int aLine, const wxString& aFunc, const wxString& aCond,
|
||||
const wxString& aMsg );
|
||||
|
||||
const char* what() const noexcept override;
|
||||
|
||||
// Public, so catchers can have a look (though be careful as the function
|
||||
// names can change over time!)
|
||||
std::string m_file;
|
||||
int m_line;
|
||||
std::string m_func;
|
||||
std::string m_cond;
|
||||
std::string m_msg;
|
||||
|
||||
std::string m_format_msg;
|
||||
};
|
||||
|
||||
} // namespace KI_TEST
|
||||
|
||||
#endif // UNIT_TEST_UTILS_WX_ASSERT__H
|
|
@ -21,6 +21,15 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Nothing here yet, but CMake requires *something*.
|
||||
*/
|
||||
#include <unit_test_utils/unit_test_utils.h>
|
||||
|
||||
BOOST_TEST_PRINT_NAMESPACE_OPEN
|
||||
{
|
||||
|
||||
void print_log_value<wxPoint>::operator()( std::ostream& os, wxPoint const& aPt )
|
||||
{
|
||||
os << "WXPOINT[ x=\"" << aPt.x << "\" y=\"" << aPt.y << "\" ]";
|
||||
}
|
||||
|
||||
}
|
||||
BOOST_TEST_PRINT_NAMESPACE_CLOSE
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
*/
|
||||
|
||||
#include <unit_test_utils/wx_assert.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace KI_TEST
|
||||
{
|
||||
WX_ASSERT_ERROR::WX_ASSERT_ERROR( const wxString& aFile, int aLine, const wxString& aFunc,
|
||||
const wxString& aCond, const wxString& aMsg )
|
||||
: m_file( aFile ), m_line( aLine ), m_func( aFunc ), m_cond( aCond ), m_msg( aMsg )
|
||||
{
|
||||
std::ostringstream ss;
|
||||
|
||||
ss << "WX assertion in " << m_file << ":" << m_line << "\n"
|
||||
<< "in function " << m_func << "\n"
|
||||
<< "failed condition: " << m_cond;
|
||||
|
||||
if( m_msg.size() )
|
||||
ss << "\n"
|
||||
<< "with message: " << m_msg;
|
||||
|
||||
m_format_msg = ss.str();
|
||||
}
|
||||
|
||||
const char* WX_ASSERT_ERROR::what() const noexcept
|
||||
{
|
||||
return m_format_msg.c_str();
|
||||
}
|
||||
|
||||
} // namespace KI_TEST
|
Loading…
Reference in New Issue