KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_erc_pin_map_capture.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 <set>
24#include <advanced_config.h>
25#include <erc/erc.h>
26#include <kiface_ids.h>
27#include <kiway.h>
28#include <lib_symbol.h>
29#include <locale_io.h>
30#include <sch_marker.h>
31#include <sch_pin.h>
32#include <sch_sheet.h>
33#include <sch_symbol.h>
34#include <schematic.h>
36#include <scoped_set_reset.h>
37
38BOOST_AUTO_TEST_CASE( ERCUnmappedPinsBindSharedInstancePaths )
39{
40 struct FOOTPRINT_FACE : KIFACE
41 {
42 bool OnKifaceStart( PGM_BASE*, int, KIWAY* ) override { return true; }
43 void OnKifaceEnd() override {}
44 void Reset() override {}
45 wxWindow* CreateKiWindow( wxWindow*, int, KIWAY*, int ) override { return nullptr; }
46 void GetActions( std::vector<TOOL_ACTION*>& ) const override {}
47
48 static void Pads( const wxString& aFootprint, PROJECT*, std::set<wxString>& aPads )
49 {
50 if( aFootprint == "Acceptance:3" )
51 aPads = { "1", "2" };
52 else if( aFootprint == "Acceptance:2" )
53 aPads = { "NO_NATIVE_PIN" };
54 }
55
56 void* IfaceOrAddress( int aId ) override
57 {
58 BOOST_REQUIRE_EQUAL( aId, KIFACE_FOOTPRINT_PAD_NUMBERS );
59 return reinterpret_cast<void*>( &Pads );
60 }
61 } face;
62
63 LOCALE_IO locale;
64 auto& enabled = const_cast<ADVANCED_CFG&>( ADVANCED_CFG::GetCfg() ).m_ConnectivityEngine;
65 SCOPED_SET_RESET restore( enabled, enabled );
66 SETTINGS_MANAGER settings;
67 std::unique_ptr<SCHEMATIC> schematic;
68 KI_TEST::LoadSchematic( settings, "legacy_hierarchy/legacy_hierarchy", schematic );
69 std::vector<SCH_SHEET_PATH> paths;
70
71 for( const SCH_SHEET_PATH& path : schematic->Hierarchy() )
72 {
73 if( path.LastScreen()->GetFileName().EndsWith( "ampli_ht.kicad_sch" ) )
74 paths.push_back( path );
75 }
76
77 BOOST_REQUIRE_EQUAL( paths.size(), 2u );
78 SCH_SCREEN& screen = *paths[0].LastScreen();
79 BOOST_REQUIRE( &screen == paths[1].LastScreen() );
80 paths[0].SetPageNumber( "2" );
81 paths[1].SetPageNumber( "3" );
82 SCH_SYMBOL* symbol = nullptr;
83
84 for( SCH_ITEM* item : screen.Items().OfType( SCH_SYMBOL_T ) )
85 {
86 auto* candidate = static_cast<SCH_SYMBOL*>( item );
87
88 if( candidate->GetLibId().GetLibItemName() == "R" )
89 {
90 symbol = candidate;
91 break;
92 }
93 }
94
95 BOOST_REQUIRE( symbol );
96 LIB_ID footprint;
97 BOOST_REQUIRE_LT( footprint.Parse( "Acceptance:2", true ), 0 );
98 symbol->GetLibSymbolRef()->SetAssociatedFootprints( { { footprint, wxString() } } );
99 symbol->SetFootprintFieldText( "Acceptance:${#}" );
100 schematic->ErcSettings().SetSeverity( ERCE_PIN_MAP_UNMAPPED_PIN, RPT_SEVERITY_WARNING );
101 const auto pins = symbol->GetPins( &paths[0] );
102 BOOST_REQUIRE_EQUAL( pins.size(), 2u );
103 const std::set<KIID> expected{ pins[0]->m_Uuid, pins[1]->m_Uuid };
104
105 for( bool backend : { true, false } )
106 {
107 enabled = backend;
108 schematic->RebuildConnectivity();
109
110 for( const SCH_SHEET_PATH& displayed : paths )
111 {
112 BOOST_TEST_CONTEXT( "backend=" << backend << "; displayed=" << displayed.GetPageNumber() )
113 {
114 schematic->SetCurrentSheet( displayed );
115 ERC_TESTER tester( schematic.get() );
116 tester.TestPinMap( &face, &schematic->Project() );
117 std::set<KIID> found;
118 size_t count = 0;
119 std::vector<SCH_MARKER*> markers;
120
121 for( SCH_ITEM* item : screen.Items().OfType( SCH_MARKER_T ) )
122 {
123 auto* marker = static_cast<SCH_MARKER*>( item );
124 markers.push_back( marker );
125 const auto error = std::static_pointer_cast<ERC_ITEM>( marker->GetRCItem() );
126
127 if( error->GetErrorCode() != ERCE_PIN_MAP_UNMAPPED_PIN
128 || !expected.contains( error->GetMainItemID() ) )
129 {
130 continue;
131 }
132
133 ++count;
134 found.insert( error->GetMainItemID() );
135 BOOST_CHECK( error->IsSheetSpecific() );
136 BOOST_CHECK( error->MainItemHasSheetPath() );
137
138 if( error->IsSheetSpecific() && error->MainItemHasSheetPath() )
139 {
140 BOOST_CHECK( error->GetSpecificSheetPath().PathRef() == paths[0].PathRef() );
141 BOOST_CHECK( error->GetMainItemSheetPath().PathRef() == paths[0].PathRef() );
142 }
143 }
144
145 BOOST_CHECK_EQUAL( count, expected.size() );
146 BOOST_CHECK( found == expected );
147
148 for( SCH_MARKER* marker : markers )
149 screen.DeleteItem( marker );
150 }
151 }
152 }
153
154 for( bool backend : { false, true } )
155 {
156 BOOST_TEST_CONTEXT( "removed sheet; backend=" << backend )
157 {
158 enabled = backend;
159 schematic->RebuildConnectivity();
160 SCH_SHEET* removed = paths[0].Last();
161 BOOST_REQUIRE( schematic->RootScreen()->Remove( removed ) );
162 schematic->RefreshHierarchy();
163 ERC_TESTER retained( schematic.get() );
164 BOOST_CHECK_NO_THROW( retained.TestPinMap( &face, &schematic->Project() ) );
165 schematic->RootScreen()->Append( removed );
166 schematic->RefreshHierarchy();
167 std::vector<SCH_MARKER*> markers;
168
169 for( SCH_ITEM* item : screen.Items().OfType( SCH_MARKER_T ) )
170 markers.push_back( static_cast<SCH_MARKER*>( item ) );
171
172 for( SCH_MARKER* marker : markers )
173 screen.DeleteItem( marker );
174 }
175 }
176}
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:248
Runs the electrical rules checks and adds a SCH_MARKER for each violation.
Definition erc.h:60
int TestPinMap(KIFACE *aCvPcb, PROJECT *aProject)
Check pin-to-pad maps (issue #2282): stale pin references, duplicate pad targets, bad pads and unmapp...
Definition erc.cpp:417
A minimalistic software bus for communications between various DLLs/DSOs (DSOs) within the same KiCad...
Definition kiway.h:340
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
void SetAssociatedFootprints(std::vector< ASSOCIATED_FOOTPRINT > aList)
Definition lib_symbol.h:267
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Container for data for KiCad programs.
Definition pgm_base.h:101
Container for project specific data.
Definition project.h:63
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:122
void DeleteItem(SCH_ITEM *aItem)
Remove aItem from the linked list and deletes the object.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:48
Schematic symbol object.
Definition sch_symbol.h:74
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
void SetFootprintFieldText(const wxString &aFootprint)
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:182
RAII class that sets an value at construction and resets it to the original value at destruction.
@ ERCE_PIN_MAP_UNMAPPED_PIN
A connected pin resolves to no footprint pad.
@ KIFACE_FOOTPRINT_PAD_NUMBERS
Function pointer type: void (*)( const wxString& aFootprint, PROJECT* aProject, std::set<wxString>& a...
Definition kiface_ids.h:62
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ RPT_SEVERITY_WARNING
Implement a participant in the KIWAY alchemy.
Definition kiway.h:153
virtual wxWindow * CreateKiWindow(wxWindow *aParent, int aClassId, KIWAY *aKIWAY, int aCtlBits=0)=0
Create a wxWindow for the current project.
virtual bool OnKifaceStart(PGM_BASE *aProgram, int aCtlBits, KIWAY *aKiway)=0
Called just once shortly after the DSO is loaded.
virtual void OnKifaceEnd()=0
Called just once just before the DSO is to be unloaded.
virtual void * IfaceOrAddress(int aDataId)=0
Return pointer to the requested object.
virtual void Reset()=0
Reloads global state.
virtual void GetActions(std::vector< TOOL_ACTION * > &aActions) const =0
Append this Kiface's registered actions to the given list.
BOOST_AUTO_TEST_CASE(ERCUnmappedPinsBindSharedInstancePaths)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string path
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_MARKER_T
Definition typeinfo.h:154