KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_import_net_names.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or
9 * (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#include <board.h>
24#include <eda_pattern_match.h>
27#include <footprint.h>
28#include <import_net_names.h>
31#include <netinfo.h>
32#include <pcb_field.h>
33#include <reporter.h>
35#include <set>
36#include <tuple>
37
39{
45
47 std::unique_ptr<BOARD> board;
48};
49
50BOOST_FIXTURE_TEST_SUITE( ImportedNetNames, IMPORT_NET_NAMES_FIXTURE )
51
52BOOST_AUTO_TEST_CASE( RenamePreservesConnectedItemsAndBothNetIndexes )
53{
54 const wxString original = wxS( "Net-(Q6-Pad2)" );
55 const wxString renamed = wxS( "Net-(Q6-B)" );
56 NETINFO_ITEM* net = board->FindNet( original );
57 BOOST_REQUIRE( net );
58 const int code = net->GetNetCode();
59 const unsigned netCount = board->GetNetInfo().GetNetCount();
60 std::vector<std::tuple<BOARD_CONNECTED_ITEM*, NETINFO_ITEM*, int, wxString>> before;
61 std::set<KICAD_T> renamedTypes;
62
63 for( BOARD_CONNECTED_ITEM* item : board->AllConnectedItems() )
64 {
65 before.emplace_back( item, item->GetNet(), item->GetNetCode(), item->GetNetname() );
66
67 if( item->GetNet() == net )
68 renamedTypes.insert( item->Type() );
69 }
70
71 BOOST_REQUIRE( renamedTypes.count( PCB_PAD_T ) );
72 BOOST_REQUIRE( renamedTypes.count( PCB_TRACE_T ) );
73 BOOST_REQUIRE( renamedTypes.count( PCB_ZONE_T ) );
76 { { original, renamed }, { wxS( "N999999999" ), wxS( "Net-(Absent-Pad1)" ) } }, reporter ) );
77 BOOST_CHECK( board->FindNet( original ) == nullptr );
78 BOOST_CHECK( board->FindNet( renamed ) == net );
79 BOOST_CHECK( board->FindNet( code ) == net );
80 BOOST_CHECK_EQUAL( board->GetNetInfo().GetNetCount(), netCount );
81 BOOST_CHECK( board->FindNet( wxS( "Net-(Absent-Pad1)" ) ) == nullptr );
82
83 for( const auto& [item, oldNet, oldCode, oldName] : before )
84 {
85 BOOST_CHECK( item->GetNet() == oldNet );
86 BOOST_CHECK_EQUAL( item->GetNetCode(), oldCode );
87 BOOST_CHECK_EQUAL( item->GetNetname(), oldNet == net ? renamed : oldName );
88 }
89}
90
91BOOST_AUTO_TEST_CASE( FootprintFieldsAreFilledNotOverwritten )
92{
93 FOOTPRINT* empty = board->FindFootprintByReference( wxS( "Q6" ) );
94 FOOTPRINT* held = board->FindFootprintByReference( wxS( "Q3" ) );
95 BOOST_REQUIRE( empty && held );
96
97 empty->SetValue( wxString() );
98 empty->GetField( wxS( "Description" ) )->SetText( wxString() );
99 held->SetValue( wxS( "KeepMe" ) );
100
102
103 for( const wxString& ref : { wxS( "Q6" ), wxS( "Q3" ) } )
104 {
105 COMPONENT* component = new COMPONENT( LIB_ID(), ref, wxS( "FromSchematic" ), KIID_PATH(), {} );
106 nlohmann::ordered_map<wxString, wxString> fields = { { wxS( "Reference" ), ref },
107 { wxS( "Value" ), wxS( "FromSchematic" ) },
108 { wxS( "Maker" ), wxS( "Acme" ) },
109 { wxS( "Description" ), wxS( "Resistor" ) } };
110
111 if( ref == wxS( "Q6" ) )
112 fields[wxS( "Serial" )] = wxString();
113
114 component->SetFields( fields );
115 netlist.AddComponent( component );
116 }
117
118 PCB_FIELD* maker = new PCB_FIELD( held, FIELD_T::USER );
119 held->Add( maker );
120 maker->SetName( wxS( "Maker" ) );
121 maker->SetText( wxS( "Board" ) );
122 held->GetField( wxS( "Description" ) )->SetText( wxS( "Mine" ) );
123
125 BOOST_CHECK_EQUAL( empty->GetValue(), wxS( "FromSchematic" ) );
126 BOOST_CHECK_EQUAL( empty->GetField( wxS( "Maker" ) )->GetText(), wxS( "Acme" ) );
127 BOOST_CHECK_EQUAL( empty->GetField( wxS( "Description" ) )->GetText(), wxS( "Resistor" ) );
128 BOOST_CHECK( empty->HasField( wxS( "Serial" ) ) );
129 BOOST_CHECK_EQUAL( held->GetValue(), wxS( "KeepMe" ) );
130 BOOST_CHECK_EQUAL( held->GetField( wxS( "Maker" ) )->GetText(), wxS( "Board" ) );
131 BOOST_CHECK_EQUAL( held->GetField( wxS( "Description" ) )->GetText(), wxS( "Mine" ) );
132}
133
134BOOST_AUTO_TEST_CASE( ReferencesTakeTheSchematicSpelling )
135{
136 FOOTPRINT* lowered = board->FindFootprintByReference( wxS( "Q6" ) );
137 FOOTPRINT* named = board->FindFootprintByReference( wxS( "Q3" ) );
138 BOOST_REQUIRE( lowered && named );
139
140 lowered->SetReference( wxS( "q6" ) );
141 named->SetReference( wxS( "UNKQ3" ) );
142
144
145 for( const wxString& ref : { wxS( "Q6" ), wxS( "Q3" ) } )
146 netlist.AddComponent( new COMPONENT( LIB_ID(), ref, wxS( "V" ), KIID_PATH(), {} ) );
147
148 // UNK prefixes only a reference that starts with a non-letter, so UNKQ3 is its own reference
150 BOOST_CHECK_EQUAL( lowered->GetReference(), wxS( "Q6" ) );
151 BOOST_CHECK_EQUAL( named->GetReference(), wxS( "UNKQ3" ) );
152}
153
154BOOST_AUTO_TEST_CASE( InvalidMappingsLeaveEveryNetUnchanged )
155{
156 const wxString first = wxS( "Net-(Q6-Pad2)" );
157 const wxString second = wxS( "Net-(Q6-Pad3)" );
158 BOOST_REQUIRE( board->FindNet( first ) );
159 BOOST_REQUIRE( board->FindNet( second ) );
160 BOOST_REQUIRE( board->FindNet( wxS( "GND" ) ) );
161 std::vector<std::tuple<NETINFO_ITEM*, int, wxString>> before;
162
163 for( NETINFO_ITEM* net : board->GetNetInfo() )
164 before.emplace_back( net, net->GetNetCode(), net->GetNetname() );
165
166 const std::vector<std::map<wxString, wxString>> invalid = {
167 { { first, wxS( "Net-(Q6-B)" ) }, { second, wxS( "GND" ) } },
168 { { first, wxS( "Net-(Q6-B)" ) }, { second, wxS( "Net-(Q6-B)" ) } },
169 { { first, wxS( "Net-(Q6-B)" ) }, { second, wxString() } },
170 { { wxString(), wxS( "Net-(Q6-B)" ) } }
171 };
172
173 for( const auto& names : invalid )
174 {
176 BOOST_CHECK( !ApplyImportedNetNameMap( *board, names, reporter ) );
177 BOOST_CHECK( !reporter.GetMessages().IsEmpty() );
178 BOOST_CHECK_EQUAL( board->GetNetInfo().GetNetCount(), before.size() );
179
180 for( const auto& [net, code, name] : before )
181 {
182 BOOST_CHECK_EQUAL( net->GetNetname(), name );
183 BOOST_CHECK_EQUAL( net->GetNetCode(), code );
184 BOOST_CHECK( board->FindNet( name ) == net );
185 BOOST_CHECK( board->FindNet( code ) == net );
186 }
187 }
188}
189
190BOOST_AUTO_TEST_CASE( SimultaneousNameSwapPreservesNetIdentity )
191{
192 const wxString first = wxS( "Net-(Q6-Pad2)" );
193 const wxString second = wxS( "Net-(Q6-Pad3)" );
194 NETINFO_ITEM* firstNet = board->FindNet( first );
195 NETINFO_ITEM* secondNet = board->FindNet( second );
196 BOOST_REQUIRE( firstNet && secondNet );
197 const int firstCode = firstNet->GetNetCode();
198 const int secondCode = secondNet->GetNetCode();
200 BOOST_REQUIRE( ApplyImportedNetNameMap( *board, { { first, second }, { second, first } }, reporter ) );
201 BOOST_CHECK( board->FindNet( first ) == secondNet );
202 BOOST_CHECK( board->FindNet( second ) == firstNet );
203 BOOST_CHECK( board->FindNet( firstCode ) == firstNet );
204 BOOST_CHECK( board->FindNet( secondCode ) == secondNet );
205}
206
207BOOST_AUTO_TEST_CASE( ExactNetclassAssignmentsFollowRenamedNets )
208{
209 const wxString original = wxS( "/ATN_IN" );
210 const wxString renamed = wxS( "/RENAMED_ATN_IN" );
211 NETINFO_ITEM* net = board->FindNet( original );
212 BOOST_REQUIRE( net );
213 auto settings = board->GetDesignSettings().m_NetSettings;
214 BOOST_REQUIRE( settings );
215 const auto assignedClass = settings->GetEffectiveNetClass( original );
216 BOOST_REQUIRE_EQUAL( assignedClass->GetName(), wxString( "HV" ) );
217 BOOST_REQUIRE( settings->GetEffectiveNetClass( renamed ) == settings->GetDefaultNetclass() );
218 const NETCLASS* netClass = net->GetNetClass();
219 std::vector<std::pair<wxString, wxString>> expectedPatterns;
220
221 for( const auto& [matcher, name] : settings->GetNetclassPatternAssignments() )
222 expectedPatterns.emplace_back( matcher->GetPattern() == original ? renamed : matcher->GetPattern(), name );
223
225 BOOST_REQUIRE( ApplyImportedNetNameMap( *board, { { original, renamed } }, reporter ) );
226 BOOST_CHECK( net->GetNetClass() == netClass );
227 BOOST_CHECK( settings->GetEffectiveNetClass( renamed ) == assignedClass );
228 BOOST_CHECK( settings->GetEffectiveNetClass( original ) == settings->GetDefaultNetclass() );
229 std::vector<std::pair<wxString, wxString>> actualPatterns;
230
231 for( const auto& [matcher, name] : settings->GetNetclassPatternAssignments() )
232 actualPatterns.emplace_back( matcher->GetPattern(), name );
233
234 BOOST_CHECK( actualPatterns == expectedPatterns );
235 settings->ClearAllCaches();
236 BOOST_CHECK( settings->GetEffectiveNetClass( renamed ) == assignedClass );
237}
238
239BOOST_AUTO_TEST_CASE( NetColorAssignmentsFollowRenamedNets )
240{
241 const wxString original = wxS( "/ATN_IN" );
242 const wxString renamed = wxS( "/RECOLOURED_ATN_IN" );
243 auto settings = board->GetDesignSettings().m_NetSettings;
244 BOOST_REQUIRE( settings );
245 const KIGFX::COLOR4D colour( 0.25, 0.5, 0.75, 1.0 );
246 settings->SetNetColorAssignment( original, colour );
247
249 BOOST_REQUIRE( ApplyImportedNetNameMap( *board, { { original, renamed } }, reporter ) );
250
251 const auto& colours = settings->GetNetColorAssignments();
252 BOOST_CHECK_EQUAL( colours.count( original ), 0 );
253 BOOST_REQUIRE_EQUAL( colours.count( renamed ), 1 );
254 BOOST_CHECK( colours.at( renamed ) == colour );
255}
256
257
const char * name
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
Store all of the related component information found in a netlist.
void SetFields(nlohmann::ordered_map< wxString, wxString > aFields)
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:236
PCB_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this footprint.
void SetReference(const wxString &aReference)
Definition footprint.h:799
void SetValue(const wxString &aValue)
Definition footprint.h:822
void Add(BOARD_ITEM *aItem, ADD_MODE aMode=ADD_MODE::INSERT, bool aSkipConnectivity=false) override
Adds an item to the container.
const wxString & GetValue() const
Definition footprint.h:817
const wxString & GetReference() const
Definition footprint.h:793
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
A collection of nets and the parameters used to route or test these nets.
Definition netclass.h:44
Handle the data for a net.
Definition netinfo.h:50
NETCLASS * GetNetClass()
Definition netinfo.h:101
int GetNetCode() const
Definition netinfo.h:104
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
void SetName(const wxString &aName)
Definition pcb_field.h:121
A wrapper for reporting to a wxString object.
Definition reporter.h:242
static bool empty(const wxTextEntryBase *aCtrl)
Abstract pattern-matching tool and implementations.
bool ApplyImportedNetNameMap(BOARD &aBoard, const std::map< wxString, wxString > &aNames, REPORTER &aReporter)
Apply caller-selected imported net names without changing net identity or connectivity.
int ReconcileImportedReferences(BOARD &aBoard, NETLIST &aNetlist)
Give an imported board footprint the reference its schematic symbol uses.
int FillImportedFootprintFields(BOARD &aBoard, NETLIST &aNetlist)
Copy what an imported board footprint lacks from the schematic symbol it is linked to.
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
std::unique_ptr< BOARD > board
@ USER
The field ID hasn't been set yet; field is invalid.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(RenamePreservesConnectedItemsAndBothNetIndexes)
std::string netlist
IbisParser parser & reporter
BOOST_CHECK_EQUAL(result, "25.4")
@ PCB_ZONE_T
class ZONE, a copper pour area
Definition typeinfo.h:100
@ PCB_PAD_T
class PAD, a pad in a footprint
Definition typeinfo.h:79
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:88