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 ) )
64 os <<
"UNKNOWN_VIA_TYPE(" <<
static_cast<int>( viaType ) <<
")";
83 auto path = std::filesystem::temp_directory_path() / aName;
92 std::unique_ptr<BOARD>& aBoard )
96 aBoard->SetProject(
nullptr );
101 wxFileName projectFile( absPath +
".kicad_pro" );
102 wxFileName legacyProject( absPath +
".pro" );
103 std::string boardPath = absPath +
".kicad_pcb";
104 wxFileName rulesFile( absPath +
".kicad_dru" );
106 if( projectFile.Exists() )
108 aSettingsManager.
LoadProject( projectFile.GetFullPath() );
111 else if( legacyProject.Exists() )
113 aSettingsManager.
LoadProject( legacyProject.GetFullPath() );
126 BOOST_TEST_ERROR( ioe.
What() );
129 BOOST_REQUIRE_MESSAGE( aBoard,
"aBoard is null or invalid" );
131 if( projectFile.Exists() || legacyProject.Exists() )
132 aBoard->SetProject( &aSettingsManager.
Prj() );
134 auto m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard.get(), &aBoard->GetDesignSettings() );
136 BOOST_TEST_CHECKPOINT(
"Init drc engine" );
138 if( rulesFile.Exists() )
139 m_DRCEngine->InitEngine( rulesFile );
141 m_DRCEngine->InitEngine( wxFileName() );
143 aBoard->GetDesignSettings().m_DRCEngine = m_DRCEngine;
145 BOOST_TEST_CHECKPOINT(
"Build list of nets" );
148 aBoard->BuildListOfNets();
150 catch(
const std::exception& e )
152 BOOST_TEST_ERROR(
"Exception in BuildListOfNets: " << e.what() );
156 BOOST_TEST_CHECKPOINT(
"Build connectivity" );
159 aBoard->BuildConnectivity();
161 catch(
const std::exception& e )
163 BOOST_TEST_ERROR(
"Exception in BuildConnectivity: " << e.what() );
167 BOOST_TEST_CHECKPOINT(
"Synchronize Tuning Profile Properties" );
170 aBoard->GetLengthCalculation()->SynchronizeTuningProfileProperties();
172 catch(
const std::exception& e )
174 BOOST_TEST_ERROR(
"Exception in SynchronizeTimeDomainProperties: " << e.what() );
178 if( aBoard->GetProject() )
180 std::unordered_set<wxString>
dummy;
181 BOOST_TEST_CHECKPOINT(
"Synchronize Component Classes" );
184 aBoard->SynchronizeComponentClasses(
dummy );
186 catch(
const std::exception& e )
188 BOOST_TEST_ERROR(
"Exception in SynchronizeComponentClasses: " << e.what() );
192 BOOST_TEST_CHECKPOINT(
"Run DRC cache generator" );
197 cacheGenerator.
Run();
199 catch(
const std::exception& e )
201 BOOST_TEST_ERROR(
"Exception in DRC cache generator: " << e.what() );
213 BOOST_REQUIRE_EQUAL( item->
Type(), aItemType );
236 m_path = std::filesystem::temp_directory_path()
237 / ( aNamePrefix + std::to_string( i ) + aSuffix );
239 if( !std::filesystem::exists(
m_path ) )
245 wxASSERT( !std::filesystem::exists(
m_path ) );
246 std::filesystem::create_directories(
m_path );
259 std::function<
void(
BOARD& )> aBoardTestFunction,
260 std::optional<int> aExpectedBoardVersion )
262 const std::string absBoardPath =
272 aBoardTestFunction( *board1 );
276 if( aExpectedBoardVersion )
278 BOOST_CHECK_EQUAL( board1->GetFileFormatVersionAtLoad(), *aExpectedBoardVersion );
285 const auto savePath = tempLib.
GetPath() / ( aRelativePath.ToStdString() +
".kicad_pcb" );
294 aBoardTestFunction( *board2 );
301 std::function<
void(
FOOTPRINT& )> aFootprintTestFunction,
302 std::optional<int> aExpectedFootprintVersion )
305 + aLibRelativePath.ToStdString() +
"/"
306 + aFpName.ToStdString() +
".kicad_mod";
315 aFootprintTestFunction( *fp1 );
319 if( aExpectedFootprintVersion )
321 BOOST_CHECK_EQUAL( fp1->GetFileFormatVersionAtLoad(), *aExpectedFootprintVersion );
332 const wxString fpFilename = fp1->GetFPID().GetLibItemName() + wxString(
".kicad_mod" );
338 const auto fp2Path = tempLib.
GetPath() / fpFilename.ToStdString();
348 aFootprintTestFunction( *fp2 );
355 BOOST_TEST_CHECKPOINT(
"Filling zones" );
358 toolMgr.
SetEnvironment( m_board,
nullptr,
nullptr,
nullptr,
nullptr );
365 std::vector<ZONE*> toFill;
368 toFill.push_back( zone );
370 if( filler.
Fill( toFill,
false,
nullptr ) )
373 BOOST_TEST_CHECKPOINT(
"Building connectivity (after zone fill)" );
378#define TEST( a, b ) \
383#define TEST_PT( a, b ) \
412 return fp_comp( itemA, itemB );
442 std::set<PAD*, FOOTPRINT::cmp_pads> expectedPads(
expected->Pads().begin(),
444 std::set<PAD*, FOOTPRINT::cmp_pads> fpPads( fp->
Pads().begin(), fp->
Pads().end() );
446 for(
auto itExpected = expectedPads.begin(), itFp = fpPads.begin();
447 itExpected != expectedPads.end() && itFp != fpPads.end(); itExpected++, itFp++ )
452 std::set<BOARD_ITEM*, kitest_cmp_drawings> expectedGraphicalItems(
expected->GraphicalItems().begin(),
454 std::set<BOARD_ITEM*, kitest_cmp_drawings> fpGraphicalItems( fp->
GraphicalItems().begin(),
457 for(
auto itExpected = expectedGraphicalItems.begin(), itFp = fpGraphicalItems.begin();
458 itExpected != expectedGraphicalItems.end() && itFp != fpGraphicalItems.end();
459 itExpected++, itFp++ )
463 switch( ( *itExpected )->Type() )
496 BOOST_ERROR(
"KICAD_T not known" );
501 std::set<ZONE*, FOOTPRINT::cmp_zones> expectedZones(
expected->Zones().begin(),
503 std::set<ZONE*, FOOTPRINT::cmp_zones> fpZones( fp->
Zones().begin(), fp->
Zones().end() );
505 for(
auto itExpected = expectedZones.begin(), itFp = fpZones.begin();
506 itExpected != expectedZones.end() && itFp != fpZones.end(); itExpected++, itFp++ )
518 BOOST_REQUIRE_MESSAGE(
false, reporter.
GetMessages() );
556 pad->GetLocalSolderMaskMargin().value_or( 0 ) );
558 pad->GetLocalSolderPasteMargin().value_or( 0 ) );
560 pad->GetLocalSolderPasteMarginRatio().value_or( 0 ) );
562 pad->GetLocalClearance().value_or( 0 ) );
565 pad->GetLocalThermalSpokeWidthOverride().value_or( 0 ) );
581 pad->GetCustomShapeInZoneOpt() );
734 for(
int i = 0; i <
expected->OutlineCount(); ++i )
747 for(
int j = 0; j <
expected->Outline( i ).PointCount(); ++j )
772 switch( track->Type() )
786 for(
PAD*
pad : fp->Pads() )
795 std::ostringstream ss;
796 ss <<
"\n=== Board Statistics: " << aBoardName <<
" ===\n"
799 <<
" Footprints: " << aBoard->
Footprints().size() <<
"\n"
800 <<
" Tracks: " << trackCount <<
"\n"
801 <<
" Vias: " << viaCount <<
"\n"
802 <<
" Arcs: " << arcCount <<
"\n"
803 <<
" SMD Pads: " << smdPadCount <<
"\n"
804 <<
" TH Pads: " << thPadCount <<
"\n"
805 <<
" Zones: " << aBoard->
Zones().size();
844 const char* severityStr =
"???";
846 switch( msg.severity )
853 default: severityStr =
" ";
break;
863 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
870 aIoPlugin.
LoadBoard( aFilePath, board.get(),
nullptr,
nullptr );
879 catch(
const std::exception& e )
912 return it->second.get();
915 BOARD* raw = board.get();
#define SKIP_CONNECTIVITY
General utilities for PCB file IO for QA programs.
#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