29#include <wx/filename.h>
31#include <boost/test/unit_test.hpp>
49#define CHECK_ENUM_CLASS_EQUAL( L, R ) \
50 BOOST_CHECK_EQUAL( static_cast<int>( L ), static_cast<int>( R ) )
63 os <<
"UNKNOWN_VIA_TYPE(" <<
static_cast<int>( aViaType ) <<
")";
84 auto path = std::filesystem::temp_directory_path() / aName;
93 std::unique_ptr<BOARD>& aBoard )
97 aBoard->SetProject(
nullptr );
102 wxFileName projectFile( absPath +
".kicad_pro" );
103 wxFileName legacyProject( absPath +
".pro" );
104 std::string boardPath = absPath +
".kicad_pcb";
105 wxFileName rulesFile( absPath +
".kicad_dru" );
107 if( projectFile.Exists() )
109 aSettingsManager.
LoadProject( projectFile.GetFullPath() );
112 else if( legacyProject.Exists() )
114 aSettingsManager.
LoadProject( legacyProject.GetFullPath() );
127 BOOST_TEST_ERROR( ioe.
What() );
130 BOOST_REQUIRE_MESSAGE( aBoard,
"aBoard is null or invalid" );
132 if( projectFile.Exists() || legacyProject.Exists() )
133 aBoard->SetProject( &aSettingsManager.
Prj() );
135 auto m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard.get(), &aBoard->GetDesignSettings() );
137 BOOST_TEST_CHECKPOINT(
"Init drc engine" );
139 if( rulesFile.Exists() )
140 m_DRCEngine->InitEngine( rulesFile );
142 m_DRCEngine->InitEngine( wxFileName() );
144 aBoard->GetDesignSettings().m_DRCEngine = m_DRCEngine;
146 BOOST_TEST_CHECKPOINT(
"Build list of nets" );
149 aBoard->BuildListOfNets();
151 catch(
const std::exception& e )
153 BOOST_TEST_ERROR(
"Exception in BuildListOfNets: " << e.what() );
157 BOOST_TEST_CHECKPOINT(
"Build connectivity" );
160 aBoard->BuildConnectivity();
162 catch(
const std::exception& e )
164 BOOST_TEST_ERROR(
"Exception in BuildConnectivity: " << e.what() );
168 BOOST_TEST_CHECKPOINT(
"Synchronize Tuning Profile Properties" );
171 aBoard->GetLengthCalculation()->SynchronizeTuningProfileProperties();
173 catch(
const std::exception& e )
175 BOOST_TEST_ERROR(
"Exception in SynchronizeTimeDomainProperties: " << e.what() );
179 if( aBoard->GetProject() )
181 std::unordered_set<wxString>
dummy;
182 BOOST_TEST_CHECKPOINT(
"Synchronize Component Classes" );
185 aBoard->SynchronizeComponentClasses(
dummy );
187 catch(
const std::exception& e )
189 BOOST_TEST_ERROR(
"Exception in SynchronizeComponentClasses: " << e.what() );
193 BOOST_TEST_CHECKPOINT(
"Run DRC cache generator" );
198 cacheGenerator.
Run();
200 catch(
const std::exception& e )
202 BOOST_TEST_ERROR(
"Exception in DRC cache generator: " << e.what() );
214 BOOST_REQUIRE_EQUAL( item->
Type(), aItemType );
237 m_path = std::filesystem::temp_directory_path()
238 / ( aNamePrefix + std::to_string( i ) + aSuffix );
240 if( !std::filesystem::exists(
m_path ) )
246 wxASSERT( !std::filesystem::exists(
m_path ) );
247 std::filesystem::create_directories(
m_path );
260 std::function<
void(
BOARD& )> aBoardTestFunction,
261 std::optional<int> aExpectedBoardVersion )
263 const std::string absBoardPath =
273 aBoardTestFunction( *board1 );
277 if( aExpectedBoardVersion )
279 BOOST_CHECK_EQUAL( board1->GetFileFormatVersionAtLoad(), *aExpectedBoardVersion );
286 const auto savePath = tempLib.
GetPath() / ( aRelativePath.ToStdString() +
".kicad_pcb" );
295 aBoardTestFunction( *board2 );
302 std::function<
void(
FOOTPRINT& )> aFootprintTestFunction,
303 std::optional<int> aExpectedFootprintVersion )
306 + aLibRelativePath.ToStdString() +
"/"
307 + aFpName.ToStdString() +
".kicad_mod";
316 aFootprintTestFunction( *fp1 );
320 if( aExpectedFootprintVersion )
322 BOOST_CHECK_EQUAL( fp1->GetFileFormatVersionAtLoad(), *aExpectedFootprintVersion );
333 const wxString fpFilename = fp1->GetFPID().GetLibItemName() + wxString(
".kicad_mod" );
339 const auto fp2Path = tempLib.
GetPath() / fpFilename.ToStdString();
349 aFootprintTestFunction( *fp2 );
356 BOOST_TEST_CHECKPOINT(
"Filling zones" );
359 toolMgr.
SetEnvironment( m_board,
nullptr,
nullptr,
nullptr,
nullptr );
366 std::vector<ZONE*> toFill;
369 toFill.push_back( zone );
371 if( filler.
Fill( toFill,
false,
nullptr ) )
374 BOOST_TEST_CHECKPOINT(
"Building connectivity (after zone fill)" );
379#define TEST( a, b ) \
384#define TEST_PT( a, b ) \
413 return fp_comp( itemA, itemB );
443 std::set<PAD*, FOOTPRINT::cmp_pads> expectedPads(
expected->Pads().begin(),
445 std::set<PAD*, FOOTPRINT::cmp_pads> fpPads( fp->
Pads().begin(), fp->
Pads().end() );
447 for(
auto itExpected = expectedPads.begin(), itFp = fpPads.begin();
448 itExpected != expectedPads.end() && itFp != fpPads.end(); itExpected++, itFp++ )
453 std::set<BOARD_ITEM*, kitest_cmp_drawings> expectedGraphicalItems(
expected->GraphicalItems().begin(),
455 std::set<BOARD_ITEM*, kitest_cmp_drawings> fpGraphicalItems( fp->
GraphicalItems().begin(),
458 for(
auto itExpected = expectedGraphicalItems.begin(), itFp = fpGraphicalItems.begin();
459 itExpected != expectedGraphicalItems.end() && itFp != fpGraphicalItems.end();
460 itExpected++, itFp++ )
464 switch( ( *itExpected )->Type() )
497 BOOST_ERROR(
"KICAD_T not known" );
502 std::set<ZONE*, FOOTPRINT::cmp_zones> expectedZones(
expected->Zones().begin(),
504 std::set<ZONE*, FOOTPRINT::cmp_zones> fpZones( fp->
Zones().begin(), fp->
Zones().end() );
506 for(
auto itExpected = expectedZones.begin(), itFp = fpZones.begin();
507 itExpected != expectedZones.end() && itFp != fpZones.end(); itExpected++, itFp++ )
519 BOOST_REQUIRE_MESSAGE(
false, reporter.
GetMessages() );
557 pad->GetLocalSolderMaskMargin().value_or( 0 ) );
559 pad->GetLocalSolderPasteMargin().value_or( 0 ) );
561 pad->GetLocalSolderPasteMarginRatio().value_or( 0 ) );
563 pad->GetLocalClearance().value_or( 0 ) );
566 pad->GetLocalThermalSpokeWidthOverride().value_or( 0 ) );
582 pad->GetCustomShapeInZoneOpt() );
735 for(
int i = 0; i <
expected->OutlineCount(); ++i )
748 for(
int j = 0; j <
expected->Outline( i ).PointCount(); ++j )
773 switch( track->Type() )
787 for(
PAD*
pad : fp->Pads() )
796 std::ostringstream ss;
797 ss <<
"\n=== Board Statistics: " << aBoardName <<
" ===\n"
800 <<
" Footprints: " << aBoard->
Footprints().size() <<
"\n"
801 <<
" Tracks: " << trackCount <<
"\n"
802 <<
" Vias: " << viaCount <<
"\n"
803 <<
" Arcs: " << arcCount <<
"\n"
804 <<
" SMD Pads: " << smdPadCount <<
"\n"
805 <<
" TH Pads: " << thPadCount <<
"\n"
806 <<
" Zones: " << aBoard->
Zones().size();
845 const char* severityStr =
"???";
847 switch( msg.severity )
854 default: severityStr =
" ";
break;
864 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
871 aIoPlugin.
LoadBoard( aFilePath, board.get(),
nullptr,
nullptr );
880 catch(
const std::exception& e )
913 return it->second.get();
916 BOARD* raw = board.get();
#define SKIP_CONNECTIVITY
General utilities for PCB file IO for QA programs.
std::ostream & boost_test_print_type(std::ostream &os, const VIATYPE &aViaType)
#define CHECK_ENUM_CLASS_EQUAL(L, R)
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
bool IsLocked() const override
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Information pertinent to a Pcbnew printed circuit board.
const ZONES & Zones() const
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
int GetCopperLayerCount() const
const FOOTPRINTS & Footprints() const
const TRACKS & Tracks() const
unsigned GetNetCount() const
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
void SetDRCEngine(DRC_ENGINE *engine)
KICAD_T Type() const
Returns the type of object.
const VECTOR2I & GetBezierC2() const
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
VECTOR2I GetArcMid() const
const EDA_ANGLE & GetTextAngle() const
virtual void SetReporter(REPORTER *aReporter)
Set an optional reporter for warnings/errors.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const char * what() const override
std::exception interface, returned as UTF-8
void DumpBoardToFile(BOARD &aBoard, const std::string &aName) const
std::map< std::string, std::unique_ptr< BOARD > > m_boardCache
BOARD * getCachedBoard(PCB_IO &aIoPlugin, const std::string &aFilePath, bool aForceReload, REPORTER *aReporter)
BOARD * LoadAndCache(const std::string &aFilePath, REPORTER *aReporter)
Load (or reload) board for the given file path and send the load messages to the given reporter.
BOARD * GetCachedBoard(const std::string &aFilePath)
Get a cached board for the given file path, or load it if not already cached, without forcing a reloa...
void PrintAllMessages(const std::string &aContext) const
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
std::vector< MESSAGE > m_messages
A temporary directory that will be deleted when it goes out of scope.
const std::filesystem::path & GetPath() const
TEMPORARY_DIRECTORY(const std::string &aNamePrefix, const std::string aSuffix)
Create a temporary directory with a given prefix and suffix.
std::filesystem::path m_path
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
A base class that BOARD loading and saving plugins should derive from.
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into either ...
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
STROKE_PARAMS GetStroke() const override
VECTOR2I GetPosition() const override
virtual VECTOR2I GetPosition() const override
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
virtual const VECTOR2I GetPoint(int aIndex) const override
int PointCount() const
Return the number of points (vertices) in this line chain.
Represent a set of closed polygons.
int TotalVertices() const
Return total number of vertices stored in the set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
LINE_STYLE GetLineStyle() const
A wrapper for reporting to a wxString object.
const wxString & GetMessages() const
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Handle a list of polygons defining a copper zone.
int GetHatchBorderAlgorithm() const
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
std::optional< int > GetLocalClearance() const override
bool GetDoNotAllowVias() const
bool GetDoNotAllowPads() const
bool GetDoNotAllowTracks() const
ISLAND_REMOVAL_MODE GetIslandRemovalMode() const
SHAPE_POLY_SET * Outline()
long long int GetMinIslandArea() const
const wxString & GetZoneName() const
int GetMinThickness() const
ZONE_CONNECTION GetPadConnection() const
int GetHatchThickness() const
double GetHatchHoleMinArea() const
int GetThermalReliefSpokeWidth() const
EDA_ANGLE GetHatchOrientation() const
bool GetDoNotAllowFootprints() const
ZONE_FILL_MODE GetFillMode() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
TEARDROP_TYPE GetTeardropAreaType() const
double GetHatchSmoothingValue() const
bool GetDoNotAllowZoneFills() const
int GetHatchSmoothingLevel() const
unsigned int GetCornerRadius() const
int GetCornerSmoothingType() const
int GetThermalReliefGap() const
unsigned GetAssignedPriority() const
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
void CheckFootprint(const FOOTPRINT *expected, const FOOTPRINT *fp)
Helper method to check if two footprints are semantically the same.
void PrintBoardStats(const BOARD *aBoard, const std::string &aBoardName)
Print detailed board statistics for debugging using test-framework logging.
void FillZones(BOARD *m_board)
std::unique_ptr< BOARD > LoadBoardWithCapture(PCB_IO &aIoPlugin, const std::string &aFilePath, REPORTER *aReporter)
Attempt to load an board with a given IO plugin, capturing all reporter messages.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
void CheckFpShape(const PCB_SHAPE *expected, const PCB_SHAPE *shape)
std::unique_ptr< FOOTPRINT > ReadFootprintFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
void LoadAndTestFootprintFile(const wxString &aLibRelativePath, const wxString &aFpName, bool aRoundtrip, std::function< void(FOOTPRINT &)> aFootprintTestFunction, std::optional< int > aExpectedFootprintVersion)
Same as LoadAndTestBoardFile, but for footprints.
void DumpBoardToFile(BOARD &board, const std::string &aFilename)
Utility function to simply write a Board out to a file.
void CheckFpPad(const PAD *expected, const PAD *pad)
void CheckFpZone(const ZONE *expected, const ZONE *zone)
void CheckFpText(const PCB_TEXT *expected, const PCB_TEXT *text)
void DumpFootprintToFile(const FOOTPRINT &aFootprint, const std::string &aLibraryPath)
Same as DumpBoardToFile, but for footprints.
void LoadAndTestBoardFile(const wxString aRelativePath, bool aRoundtrip, std::function< void(BOARD &)> aBoardTestFunction, std::optional< int > aExpectedBoardVersion)
Perform "some test" on a board file loaded from the path, then optionally save and reload and run the...
void CheckShapePolySet(const SHAPE_POLY_SET *expected, const SHAPE_POLY_SET *polyset)
BOARD_ITEM & RequireBoardItemWithTypeAndId(const BOARD &aBoard, KICAD_T aItemType, const KIID &aID)
Get an item from the given board with a certain type and UUID.
@ SMD
Smd pad, appears on the solder paste layer (default)
std::vector< FAB_LAYER_COLOR > dummy
FOOTPRINT::cmp_drawings fp_comp
bool operator()(const BOARD_ITEM *itemA, const BOARD_ITEM *itemB) const
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension