20#include <boost/test/unit_test.hpp>
49static const char*
BOARD_FILE =
"net_chains/stub_length.kicad_pcb";
54static const char*
DRU_TEXT = R
"KICAD((version 1)
57 (condition "A.NetClass == 'Default'")
58 (constraint stub_length (min 0mm) (max 5mm))
68 namespace fs = std::filesystem;
70 fs::path tmpDir = fs::temp_directory_path() /
"kicad_drc_stub_length";
71 fs::create_directories( tmpDir );
73 fs::path druPath = tmpDir /
"stub_length.kicad_dru";
76 std::ofstream druOut( druPath );
81 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
83 board->BuildConnectivity();
85 NETINFO_ITEM* netA = board->FindNet( wxS(
"/TRUNK_A" ) );
87 NETINFO_ITEM* netC = board->FindNet( wxS(
"/TRUNK_C" ) );
100 for(
FOOTPRINT* fp : board->Footprints() )
102 for(
PAD*
pad : fp->Pads() )
120 auto drcEngine = std::make_shared<DRC_ENGINE>( board.get(), &bds );
121 wxFileName ruleFile( druPath.string() );
122 drcEngine->InitEngine( ruleFile );
133 std::vector<wxString> stubMessages;
135 drcEngine->SetViolationHandler(
136 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I&,
int,
140 stubMessages.push_back( aItem->GetErrorMessage(
false ) );
145 auto matchesNet = [&](
const wxString& netName )
147 for(
const wxString& msg : stubMessages )
149 if( msg.Contains( wxString::Format( wxS(
"'%s'" ), netName ) ) )
156 bool aFlagged = matchesNet( netA->
GetNetname() );
157 bool bFlagged = matchesNet( netB->
GetNetname() );
158 bool cFlagged = matchesNet( netC->
GetNetname() );
160 BOOST_CHECK_MESSAGE( bFlagged,
161 "Intermediate stub net MID_B should fire stub_length violation" );
162 BOOST_CHECK_MESSAGE( !aFlagged,
163 "Trunk endpoint net TRUNK_A (owns terminal_pad_0) must not fire" );
164 BOOST_CHECK_MESSAGE( !cFlagged,
165 "Trunk endpoint net TRUNK_C (owns terminal_pad_1) must not fire" );
168 fs::remove( druPath, ec );
174 namespace fs = std::filesystem;
176 fs::path tmpDir = fs::temp_directory_path() /
"kicad_drc_stub_length";
177 fs::create_directories( tmpDir );
179 fs::path druPath = tmpDir /
"stub_length_2net.kicad_dru";
184 static const char* TWO_NET_BOARD_FILE =
"net_chains/stub_length_two_net.kicad_pcb";
186 static const char* TWO_NET_DRU = R
"KICAD((version 1)
189 (condition "A.NetClass == 'Default'")
190 (constraint stub_length (min 0mm) (max 5mm))
195 std::ofstream druOut( druPath );
196 druOut << TWO_NET_DRU;
200 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
202 board->BuildConnectivity();
216 for(
FOOTPRINT* fp : board->Footprints() )
218 for(
PAD*
pad : fp->Pads() )
236 auto drcEngine = std::make_shared<DRC_ENGINE>( board.get(), &bds );
237 wxFileName ruleFile( druPath.string() );
238 drcEngine->InitEngine( ruleFile );
251 drcEngine->SetViolationHandler(
252 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I&,
int,
261 BOOST_CHECK_MESSAGE( stubCount == 0,
262 "Two-net chain with both ends owning terminal pads must not "
263 "fire any stub_length violation, got "
267 fs::remove( druPath, ec );
273 namespace fs = std::filesystem;
275 fs::path tmpDir = fs::temp_directory_path() /
"kicad_drc_stub_length";
276 fs::create_directories( tmpDir );
278 fs::path druPath = tmpDir /
"stub_length_pad_to_die.kicad_dru";
284 static const char* PAD_TO_DIE_BOARD_FILE =
"net_chains/stub_length_pad_to_die.kicad_pcb";
286 static const char* PAD_TO_DIE_DRU = R
"KICAD((version 1)
289 (condition "A.NetClass == 'Default'")
290 (constraint stub_length (min 0mm) (max 5mm))
295 std::ofstream druOut( druPath );
296 druOut << PAD_TO_DIE_DRU;
300 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
303 NETINFO_ITEM* netA = board->FindNet( wxS( "/TRUNK_A" ) );
305 NETINFO_ITEM* netC = board->FindNet( wxS(
"/TRUNK_C" ) );
319 for(
FOOTPRINT* fp : board->Footprints() )
321 for(
PAD*
pad : fp->Pads() )
345 board->BuildConnectivity();
349 auto drcEngine = std::make_shared<DRC_ENGINE>( board.get(), &bds );
350 wxFileName ruleFile( druPath.string() );
351 drcEngine->InitEngine( ruleFile );
362 std::vector<wxString> stubMessages;
364 drcEngine->SetViolationHandler(
365 [&](
const std::shared_ptr<DRC_ITEM>& aItem,
const VECTOR2I&,
int,
369 stubMessages.push_back( aItem->GetErrorMessage(
false ) );
374 auto matchesNet = [&](
const wxString& netName )
376 for(
const wxString& msg : stubMessages )
378 if( msg.Contains( wxString::Format( wxS(
"'%s'" ), netName ) ) )
385 BOOST_CHECK_MESSAGE( matchesNet( netB->
GetNetname() ),
386 "Stub net MID_B with 2 mm route + 10 mm pad-to-die must violate "
387 "the 5 mm stub_length budget" );
390 fs::remove( druPath, ec );
401 const wxString DRU_TIME = wxS(
403 "(rule \"StubBudgetTime\"\n"
404 " (condition \"A.NetClass == 'Default'\")\n"
405 " (constraint stub_length (max 100ps))\n"
411 std::vector<std::shared_ptr<DRC_RULE>> rules;
416 "stub_length with ps units must parse without error, got: "
417 <<
reporter.GetMessages().ToStdString() );
419 BOOST_REQUIRE_EQUAL( rules.size(), 1u );
421 std::optional<DRC_CONSTRAINT> stubConstraint =
440 const wxString DRU_LAYER = wxS(
442 "(rule \"GoodReturnPath\"\n"
443 " (condition \"A.NetClass == 'Default'\")\n"
444 " (constraint return_path (layer \"B.Cu\"))\n"
450 std::vector<std::shared_ptr<DRC_RULE>> rules;
455 "return_path with a layer must parse without error, got: "
456 <<
reporter.GetMessages().ToStdString() );
458 BOOST_REQUIRE_EQUAL( rules.size(), 1u );
460 std::optional<DRC_CONSTRAINT> rpConstraint =
constexpr EDA_IU_SCALE pcbIUScale
General utilities for PCB file IO for QA programs.
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
std::shared_ptr< DRC_ENGINE > m_DRCEngine
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
Handle the data for a net.
const wxString & GetNetname() const
void SetNetChain(const wxString &aNetChain)
void SetTerminalPad(int aIndex, PAD *aPad)
void SetPadToDieLength(int aLength)
A #PLUGIN derivation for saving and loading Pcbnew s-expression formatted files.
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
A wrapper for reporting to a wxString object.
@ DRCE_LIB_FOOTPRINT_ISSUES
@ DRCE_NET_CHAIN_STUB_TOO_LONG
@ DRCE_DRILL_OUT_OF_RANGE
@ DRCE_LIB_FOOTPRINT_MISMATCH
@ NET_CHAIN_STUB_LENGTH_CONSTRAINT
@ NET_CHAIN_RETURN_PATH_CONSTRAINT
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static const char * BOARD_FILE
static const char * DRU_TEXT
BOOST_AUTO_TEST_CASE(StubLengthFiresOnIntermediateNetOnly)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
IbisParser parser & reporter
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I