KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_unconnected_pins.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 <connection_graph.h>
25#include <erc/erc.h>
26#include <erc/erc_settings.h>
27#include <locale_io.h>
28#include <sch_marker.h>
29#include <sch_pin.h>
30#include <sch_symbol.h>
31#include <schematic.h>
33#include <map>
34#include <set>
35#include <scoped_set_reset.h>
36
37
38BOOST_AUTO_TEST_CASE( ERCUnconnectedPinsUsePublishedConnectivity )
39{
40 LOCALE_IO locale;
41 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
42 SCOPED_SET_RESET restore( enabled, enabled );
43 const std::vector<wxString> fixtures = {
44 "NoConnectOnPin", "NoConnectOnLine", "NoConnectOnLineWithLabel",
45 "NoConnectPinsConnectedByLine", "NoConnectPinsConnectedByLabel", "ground_pin_test_ok",
46 "issue6588", "netlists/multinetclasses/multinetclasses", "issue23840/BusAndVectors"
47 };
48
49 for( const wxString& fixture : fixtures )
50 {
51 BOOST_TEST_CONTEXT( fixture.ToStdString() )
52 {
53 enabled = false;
54 SETTINGS_MANAGER settings;
55 std::unique_ptr<SCHEMATIC> schematic;
56 KI_TEST::LoadSchematic( settings, fixture, schematic );
57
58 for( auto& [code, severity] : schematic->ErcSettings().m_ERCSeverities )
59 severity = RPT_SEVERITY_IGNORE;
60
61 schematic->ErcSettings().m_ERCSeverities[ERCE_PIN_NOT_CONNECTED] = RPT_SEVERITY_ERROR;
62 schematic->ConnectionGraph()->RunERC();
63
64 if( fixture == "issue6588" )
65 {
66 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
67 {
68 for( SCH_ITEM* item : path.LastScreen()->Items().OfType( SCH_MARKER_T ) )
69 static_cast<SCH_MARKER*>( item )->SetExcluded( true, "Retained stacked-pin exclusion" );
70 }
71
72 schematic->RecordERCExclusions();
73 }
74 using DIAGNOSTICS = std::map<std::pair<KIID_PATH, KIID>, VECTOR2I>;
75 const auto collect = [&]()
76 {
77 DIAGNOSTICS diagnostics;
78 std::set<SCH_SCREEN*> screens;
79
80 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
81 screens.insert( path.LastScreen() );
82
83 for( SCH_SCREEN* screen : screens )
84 {
85 std::vector<SCH_MARKER*> markers;
86
87 for( SCH_ITEM* item : screen->Items().OfType( SCH_MARKER_T ) )
88 {
89 auto* marker = static_cast<SCH_MARKER*>( item );
90 markers.push_back( marker );
91 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() );
92 auto* pin = dynamic_cast<SCH_PIN*>( schematic->ResolveItem( error->GetMainItemID(), nullptr,
93 true ) );
94
95 if( !pin )
96 continue;
97
98 if( pin->GetParentSymbol()->IsPower() && pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_OUT )
99 continue;
100
101 if( fixture == "issue6588" )
102 {
103 BOOST_CHECK( marker->IsExcluded() );
104 BOOST_CHECK_EQUAL( marker->GetComment(), wxString( "Retained stacked-pin exclusion" ) );
105 }
106
107 BOOST_CHECK_EQUAL( error->GetErrorCode(), ERCE_PIN_NOT_CONNECTED );
108 BOOST_CHECK( error->MainItemHasSheetPath() );
109 BOOST_CHECK( !error->AuxItemHasSheetPath() );
110 BOOST_CHECK_EQUAL( error->GetIDs().size(), 1 );
111 const auto key = std::make_pair( error->GetSpecificSheetPath().PathRef(), pin->m_Uuid );
112 BOOST_CHECK( diagnostics.emplace( key, marker->GetPosition() ).second );
113 }
114
115 for( SCH_MARKER* marker : markers )
116 screen->DeleteItem( marker );
117 }
118
119 return diagnostics;
120 };
121 auto expected = collect();
122 const size_t expectedCount = fixture == "issue6588" ? 1
123 : fixture == "netlists/multinetclasses/multinetclasses" ? 12 : 0;
124 BOOST_REQUIRE_EQUAL( expected.size(), expectedCount );
125
126 if( fixture == "issue6588" )
127 {
128 // The legacy graph can select either stacked pin; the new witness must be visible
129 auto key = expected.begin()->first;
130 key.second = KIID( "c1301314-4db8-4c8f-a374-c89403debfd3" );
131 const auto* witness = dynamic_cast<SCH_PIN*>( schematic->ResolveItem( key.second, nullptr, true ) );
132 BOOST_REQUIRE( witness );
133 BOOST_CHECK( witness->IsVisible() );
134 BOOST_CHECK( witness->GetPosition() == expected.begin()->second );
135 expected.clear();
136 expected.emplace( key, witness->GetPosition() );
137 }
138
139 enabled = true;
140 schematic->RebuildConnectivity();
141 schematic->ConnectionGraph()->Reset();
143 schematic->ResolveERCExclusionsPostUpdate();
144 const auto actual = collect();
145
146 if( actual != expected )
147 {
148 for( const auto& [key, position] : expected )
149 {
150 if( !actual.contains( key ) )
151 BOOST_TEST_MESSAGE( "Missing pin " << key.second.AsString().ToStdString()
152 << " on " << key.first.AsString().ToStdString() );
153 }
154
155 for( const auto& [key, position] : actual )
156 {
157 if( !expected.contains( key ) )
158 BOOST_TEST_MESSAGE( "Extra pin " << key.second.AsString().ToStdString()
159 << " on " << key.first.AsString().ToStdString() );
160 }
161 }
162
163 BOOST_CHECK( actual == expected );
164 schematic->ErcSettings().m_ERCSeverities[ERCE_PIN_NOT_CONNECTED] = RPT_SEVERITY_IGNORE;
166 BOOST_CHECK( collect().empty() );
167 }
168 }
169}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
static int TestConnectivity(SCHEMATIC &aSchematic)
Definition erc.cpp:2215
Definition kiid.h:46
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.
static bool empty(const wxTextEntryBase *aCtrl)
@ ERCE_PIN_NOT_CONNECTED
Pin not connected and not no connect symbol.
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
Definition pin_type.h:43
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
BOOST_AUTO_TEST_CASE(ERCUnconnectedPinsUsePublishedConnectivity)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string path
KIBIS_PIN * pin
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
int actual
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_MARKER_T
Definition typeinfo.h:154
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683