KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_no_connect.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 3
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
22
23#include <advanced_config.h>
24#include <scoped_set_reset.h>
25#include <sch_marker.h>
26#include <connection_graph.h>
27#include <schematic.h>
28#include <erc/erc_settings.h>
29#include <erc/erc.h>
30#include <erc/erc_report.h>
32#include <locale_io.h>
33#include <set>
34#include <tuple>
35
36
38{
41
43 std::unique_ptr<SCHEMATIC> m_schematic;
44};
45
46
48{
50 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
51 SCOPED_SET_RESET restore( enabled, enabled );
52
53 // Check for Errors related to no connect flag
54
55 std::vector<std::pair<wxString, int>> tests = {
56 { "NoConnectOnPin", 0 },
57 { "NoConnectOnLine", 0 },
58 { "NoConnectOnLineWithLabel", 1 },
59 { "NoConnectOnLineWithGlobalLabel", 1 },
60 { "NoConnectOnLineWithHierarchicalLabel", 3 },
61 { "NoConnectPinsConnectedByLine", 1 },
62 { "NoConnectPinsConnectedByLabel", 1 },
63 { "issue24201/issue24201", 0 },
64 { "issue24201_label/issue24201", 1 },
65 };
66
67 for( bool useEngine : { false, true } )
68 {
69 enabled = useEngine;
70
71 for( const std::pair<wxString, int>& test : tests )
72 {
73 BOOST_TEST_CONTEXT( test.first.ToStdString() << " engine=" << useEngine )
74 {
75 KI_TEST::LoadSchematic( m_settingsManager, test.first, m_schematic );
76
77 ERC_SETTINGS& settings = m_schematic->ErcSettings();
78 SHEETLIST_ERC_ITEMS_PROVIDER errors( m_schematic.get() );
79
80 // Skip the "Modified symbol" warning
83
84 m_schematic->ConnectionGraph()->RunERC();
85
86 ERC_TESTER tester( m_schematic.get() );
89 tester.TestNoConnectPins();
90 tester.TestPinToPin();
91 tester.TestSimilarLabels();
92
94
95 ERC_REPORT reportWriter( m_schematic.get(), EDA_UNITS::MM );
96
97 BOOST_CHECK_MESSAGE( errors.GetCount() == test.second,
98 "Expected " << test.second << " errors in " << test.first.ToStdString()
99 << " but got " << errors.GetCount() << "\n"
100 << reportWriter.GetTextReport() );
101 }
102 }
103 }
104}
105
106
107BOOST_AUTO_TEST_CASE( ERCNoConnectFlagsUsePublishedNets )
108{
109 LOCALE_IO locale;
110 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
111 SCOPED_SET_RESET restore( enabled, enabled );
112
113 const std::vector<wxString> fixtures = {
114 "NoConnectOnPin", "NoConnectOnLine", "NoConnectOnLineWithLabel",
115 "NoConnectOnLineWithGlobalLabel", "NoConnectOnLineWithHierarchicalLabel",
116 "NoConnectPinsConnectedByLine", "NoConnectPinsConnectedByLabel",
117 "issue24201/issue24201", "issue24201_label/issue24201", "NoConnectOnPin"
118 };
119
120 // The repeated NoConnectOnPin entry moves its flag off the pin to exercise the unconnected-flag check
121 const size_t movedFlagVariant = fixtures.size() - 1;
122
123 for( size_t variant = 0; variant < fixtures.size(); ++variant )
124 {
125 const wxString& fixture = fixtures[variant];
126
127 BOOST_TEST_CONTEXT( fixture.ToStdString() << " variant=" << variant )
128 {
129 enabled = false;
130 SETTINGS_MANAGER settings;
131 std::unique_ptr<SCHEMATIC> schematic;
132 KI_TEST::LoadSchematic( settings, fixture, schematic );
133
134 for( auto& [code, severity] : schematic->ErcSettings().m_ERCSeverities )
135 severity = RPT_SEVERITY_IGNORE;
136
137 schematic->ErcSettings().m_ERCSeverities[ERCE_NOCONNECT_CONNECTED] = RPT_SEVERITY_ERROR;
138 schematic->ErcSettings().m_ERCSeverities[ERCE_NOCONNECT_NOT_CONNECTED] = RPT_SEVERITY_ERROR;
139
140 if( variant == movedFlagVariant )
141 {
142 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
143 {
144 for( SCH_ITEM* flag : path.LastScreen()->Items().OfType( SCH_NO_CONNECT_T ) )
145 {
146 flag->Move( VECTOR2I( 10000000, 10000000 ) );
147 path.LastScreen()->Update( flag );
148 }
149 }
150
151 schematic->RebuildConnectivity();
152 }
153
154 schematic->ConnectionGraph()->RunERC();
155
156 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
157 {
158 for( SCH_ITEM* item : path.LastScreen()->Items().OfType( SCH_MARKER_T ) )
159 static_cast<SCH_MARKER*>( item )->SetExcluded( true, "Retained NC flag" );
160 }
161
162 schematic->RecordERCExclusions();
163 using DIAGNOSTIC = std::tuple<int, KIID_PATH, std::vector<KIID>, VECTOR2I>;
164 const auto collect = [&]()
165 {
166 std::vector<DIAGNOSTIC> result;
167 std::set<SCH_SCREEN*> screens;
168
169 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
170 screens.insert( path.LastScreen() );
171
172 for( SCH_SCREEN* screen : screens )
173 {
174 std::vector<SCH_MARKER*> markers;
175
176 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
177 {
178 auto* marker = static_cast<SCH_MARKER*>( item );
179 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() );
180 BOOST_CHECK( marker->IsExcluded() );
181 BOOST_CHECK_EQUAL( marker->GetComment(), wxString( "Retained NC flag" ) );
182 BOOST_CHECK( error->MainItemHasSheetPath() );
183 BOOST_CHECK( !error->AuxItemHasSheetPath() );
184 result.emplace_back( error->GetErrorCode(), error->GetSpecificSheetPath().PathRef(),
185 error->GetIDs(), marker->GetPosition() );
186 markers.push_back( marker );
187 }
188
189 for( SCH_MARKER* marker : markers )
190 screen->DeleteItem( marker );
191 }
192
193 std::sort( result.begin(), result.end() );
194 return result;
195 };
196 const auto expected = collect();
197
198 if( variant == movedFlagVariant )
199 {
200 BOOST_REQUIRE_EQUAL( expected.size(), 1 );
202 }
203
204 enabled = true;
205 schematic->RebuildConnectivity();
206 schematic->ConnectionGraph()->Reset();
208 schematic->ResolveERCExclusionsPostUpdate();
209 BOOST_CHECK( collect() == expected );
210 schematic->ErcSettings().m_ERCSeverities[ERCE_NOCONNECT_CONNECTED] = RPT_SEVERITY_IGNORE;
211 schematic->ErcSettings().m_ERCSeverities[ERCE_NOCONNECT_NOT_CONNECTED] = RPT_SEVERITY_IGNORE;
213 BOOST_CHECK( collect().empty() );
214 }
215 }
216}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
wxString GetTextReport()
Returns the ERC report in "text" (human readable) format in the C-locale.
Container for ERC settings.
std::map< int, SEVERITY > m_ERCSeverities
Runs the electrical rules checks and adds a SCH_MARKER for each violation.
Definition erc.h:60
int TestPinToPin()
Checks the full netlist against the pin-to-pin connectivity requirements.
Definition erc.cpp:1709
int TestSimilarLabels()
Checks for labels that differ only in capitalization.
Definition erc.cpp:2696
static int TestConnectivity(SCHEMATIC &aSchematic)
Definition erc.cpp:2260
int TestMultUnitPinConflicts()
Checks if shared pins on multi-unit symbols have been connected to different nets.
Definition erc.cpp:2145
int TestNoConnectPins()
In KiCad 5 and earlier, you could connect stuff up to pins with NC electrical type.
Definition erc.cpp:1288
int TestMultiunitFootprints()
Test if all units of each multiunit symbol have the same footprint assigned.
Definition erc.cpp:923
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
RAII class that sets an value at construction and resets it to the original value at destruction.
An implementation of the RC_ITEM_LIST interface which uses the global SHEETLIST to fulfill the contra...
int GetCount(int aSeverity=-1) const override
void SetSeverities(int aSeverities) override
static bool empty(const wxTextEntryBase *aCtrl)
@ ERCE_NOCONNECT_NOT_CONNECTED
A no connect symbol is not connected to anything.
@ ERCE_LIB_SYMBOL_MISMATCH
Symbol doesn't match copy in library.
@ ERCE_NOCONNECT_CONNECTED
A no connect symbol is connected to more than 1 pin.
@ ERCE_LIB_SYMBOL_ISSUES
Symbol not found in active libraries.
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
std::vector< FAB_LAYER_COLOR > dummy
std::unique_ptr< SCHEMATIC > m_schematic
BOOST_FIXTURE_TEST_CASE(ERCNoConnect, ERC_REGRESSION_TEST_FIXTURE)
BOOST_AUTO_TEST_CASE(ERCNoConnectFlagsUsePublishedNets)
std::string path
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_NO_CONNECT_T
Definition typeinfo.h:156
@ SCH_MARKER_T
Definition typeinfo.h:154
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708