KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_drc_courtyard_invalid.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.TXT for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
21
23#include <board.h>
25#include <footprint.h>
26#include <pcb_marker.h>
27#include <drc/drc_engine.h>
28#include <drc/drc_item.h>
29#include <widgets/ui_common.h>
30
31
32
33BOOST_AUTO_TEST_SUITE( DrcCourtyardInvalid )
34
35
37{
38 std::string m_refdes;
40};
41
42
43std::ostream& operator<<( std::ostream& os, const COURTYARD_INVALID_INFO& aInvalid )
44{
45 os << "COURTYARD_INVALID_INFO[ " << aInvalid.m_refdes;
46 os << ", code: " << aInvalid.m_drc_error_code << "]";
47 return os;
48}
49
50
52{
53 std::string m_board_name; // Fixture under drc_courtyard/invalid/
54 std::vector<COURTYARD_INVALID_INFO> m_exp_errors;
55};
56
57
58// clang-format off
59static const std::vector<COURTYARD_INVALID_CASE> courtyard_invalid_cases =
60{
61 {
62 // Empty board has no footprints to be invalid
63 "empty_board",
64 {},
65 },
66 {
67 "single_footprint_no_courtyard",
68 { // one error: the footprint has no courtyard
69 {
70 "U1",
72 },
73 },
74 },
75 {
76 "single_footprint_unclosed_courtyard",
77 { // one error: the footprint has malformed courtyard
78 {
79 "U1",
81 },
82 },
83 },
84 {
85 "single_footprint_disjoint_courtyard",
86 { // one error: the footprint has malformed courtyard
87 {
88 "U1",
90 },
91 },
92 },
93 {
94 "two_footprints_one_malformed",
95 { // one error: the second footprint has malformed courtyard
96 {
97 "U2",
99 },
100 },
101 },
102};
103// clang-format on
104
105
109static bool InvalidMatchesExpected( BOARD& aBoard, const PCB_MARKER& aMarker,
110 const COURTYARD_INVALID_INFO& aInvalid )
111{
112 auto reporter = std::static_pointer_cast<DRC_ITEM>( aMarker.GetRCItem() );
113 const FOOTPRINT* item_a = dynamic_cast<FOOTPRINT*>( aBoard.ResolveItem( reporter->GetMainItemID() ) );
114
115 // This one is more than just a mismatch!
116 if( reporter->GetAuxItemID() != niluuid )
117 {
118 BOOST_WARN_MESSAGE( false, "Expected no auxiliary item for invalid courtyard DRC." );
119 return false;
120 }
121
122 if( item_a == nullptr )
123 {
124 BOOST_ERROR( "Could not get board DRC item." );
125 return false;
126 }
127
128 if( item_a->GetReference() != aInvalid.m_refdes )
129 return false;
130
131 if( reporter->GetErrorCode() != aInvalid.m_drc_error_code )
132 return false;
133
134 return true;
135}
136
137
146 const std::vector<std::unique_ptr<PCB_MARKER>>& aMarkers,
147 const std::vector<COURTYARD_INVALID_INFO>& aExpInvalids )
148{
149 KI_TEST::CheckUnorderedMatches( aExpInvalids, aMarkers,
150 [&]( const COURTYARD_INVALID_INFO& aInvalid,
151 const std::unique_ptr<PCB_MARKER>& aMarker )
152 {
153 return InvalidMatchesExpected( aBoard, *aMarker, aInvalid );
154 } );
155}
156
157
159{
160 const std::string path = KI_TEST::GetPcbnewTestDataDir() + "drc_courtyard/invalid/"
161 + aCase.m_board_name + ".kicad_pcb";
162
163 std::unique_ptr<BOARD> board = KI_TEST::ReadBoardFromFileOrStream( path );
164
165 BOOST_REQUIRE( board );
166
167 BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
168
169 // do the overlap tests - that's a different test, but if not set,
170 // the invalid courtyard checks don't run either
172
173 // we will also check for missing courtyards here
175
176 // list of markers to collect
177 std::vector<std::unique_ptr<PCB_MARKER>> markers;
178
179 DRC_ENGINE drcEngine( board.get(), &board->GetDesignSettings() );
180
181 drcEngine.InitEngine( wxFileName() );
182
183 drcEngine.SetViolationHandler(
184 [&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, int aLayer,
185 const std::function<void( PCB_MARKER* )>& aPathGenerator )
186 {
187 if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS
188 || aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD
189 || aItem->GetErrorCode() == DRCE_MISSING_COURTYARD )
190 {
191 markers.push_back( std::make_unique<PCB_MARKER>( aItem, aPos ) );
192 }
193 } );
194
195 drcEngine.RunTests( EDA_UNITS::MM, true, false );
196
197 CheckInvalidsMatchExpected( *board, markers, aCase.m_exp_errors );
198}
199
200
201BOOST_AUTO_TEST_CASE( InvalidCases )
202{
203 for( const auto& c : courtyard_invalid_cases )
204 {
205 BOOST_TEST_CONTEXT( c.m_board_name )
206 {
208 }
209 }
210}
211
General utilities for PCB file IO for QA programs.
Container for design settings for a BOARD object.
std::map< int, SEVERITY > m_DRCSeverities
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:409
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition board.cpp:2116
Design Rule Checker object that performs all the DRC tests.
Definition drc_engine.h:129
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void SetViolationHandler(DRC_VIOLATION_HANDLER aHandler)
Set an optional DRC violation handler (receives DRC_ITEMs and positions).
Definition drc_engine.h:164
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
const wxString & GetReference() const
Definition footprint.h:901
std::shared_ptr< RC_ITEM > GetRCItem() const
@ DRCE_OVERLAPPING_FOOTPRINTS
Definition drc_item.h:68
@ DRCE_MISSING_COURTYARD
Definition drc_item.h:69
@ DRCE_MALFORMED_COURTYARD
Definition drc_item.h:70
KIID niluuid(0)
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
void CheckUnorderedMatches(const EXP_CONT &aExpected, const FOUND_CONT &aFound, MATCH_PRED aMatchPredicate)
Check that a container of "found" objects matches a container of "expected" objects.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
@ RPT_SEVERITY_ERROR
std::vector< COURTYARD_INVALID_INFO > m_exp_errors
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static const std::vector< COURTYARD_INVALID_CASE > courtyard_invalid_cases
static bool InvalidMatchesExpected(BOARD &aBoard, const PCB_MARKER &aMarker, const COURTYARD_INVALID_INFO &aInvalid)
Check if a PCB_MARKER is described by a particular COURTYARD_INVALID_INFO object.
std::ostream & operator<<(std::ostream &os, const COURTYARD_INVALID_INFO &aInvalid)
static void CheckInvalidsMatchExpected(BOARD &aBoard, const std::vector< std::unique_ptr< PCB_MARKER > > &aMarkers, const std::vector< COURTYARD_INVALID_INFO > &aExpInvalids)
Check that the produced markers match the expected.
void DoCourtyardInvalidTest(const COURTYARD_INVALID_CASE &aCase)
BOOST_AUTO_TEST_CASE(InvalidCases)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
IbisParser parser & reporter
BOOST_TEST_CONTEXT("Test Clearance")
Functions to provide common constants and other functions to assist in making a consistent UI.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683