KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue16915_bus_netclass.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 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
30
33
36
37
40
41
42BOOST_FIXTURE_TEST_SUITE( Issue16915BusNetclass, TEST_ISSUE16915_FIXTURE )
43
44
45
48BOOST_AUTO_TEST_CASE( ForEachBusMemberExpansion )
49{
50 std::vector<wxString> collected;
51
52 // Test vector bus expansion
53 collected.clear();
54 NET_SETTINGS::ForEachBusMember( wxS( "DATA[0..3]" ),
55 [&]( const wxString& member )
56 {
57 collected.push_back( member );
58 } );
59
60 std::vector<wxString> expected = { wxS( "DATA0" ), wxS( "DATA1" ), wxS( "DATA2" ),
61 wxS( "DATA3" ) };
62
63 BOOST_CHECK_EQUAL_COLLECTIONS( collected.begin(), collected.end(), expected.begin(),
64 expected.end() );
65
66 // Test bus group with nested vector buses
67 collected.clear();
68 NET_SETTINGS::ForEachBusMember( wxS( "BUS{A[0..1] B[2..3]}" ),
69 [&]( const wxString& member )
70 {
71 collected.push_back( member );
72 } );
73
74 expected = { wxS( "A0" ), wxS( "A1" ), wxS( "B2" ), wxS( "B3" ) };
75 BOOST_CHECK_EQUAL_COLLECTIONS( collected.begin(), collected.end(), expected.begin(),
76 expected.end() );
77
78 // Test non-bus pattern (should return as-is)
79 collected.clear();
80 NET_SETTINGS::ForEachBusMember( wxS( "SIMPLE_NET" ),
81 [&]( const wxString& member )
82 {
83 collected.push_back( member );
84 } );
85
86 expected = { wxS( "SIMPLE_NET" ) };
87 BOOST_CHECK_EQUAL_COLLECTIONS( collected.begin(), collected.end(), expected.begin(),
88 expected.end() );
89}
90
91
95BOOST_AUTO_TEST_CASE( ParseBusVectorExpansion )
96{
97 wxString name;
98 std::vector<wxString> members;
99
100 // Test basic vector bus pattern
101 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "IN[0..7]" ), &name, &members ) );
102 BOOST_CHECK_EQUAL( name, wxS( "IN" ) );
103 BOOST_CHECK_EQUAL( members.size(), 8 );
104
105 std::vector<wxString> expected = { wxS( "IN0" ), wxS( "IN1" ), wxS( "IN2" ), wxS( "IN3" ),
106 wxS( "IN4" ), wxS( "IN5" ), wxS( "IN6" ), wxS( "IN7" ) };
107
108 BOOST_CHECK_EQUAL_COLLECTIONS( members.begin(), members.end(), expected.begin(), expected.end() );
109
110 // Test with path prefix
111 members.clear();
112 BOOST_CHECK( NET_SETTINGS::ParseBusVector( wxS( "/IN[0..7]" ), &name, &members ) );
113 BOOST_CHECK_EQUAL( name, wxS( "/IN" ) );
114 BOOST_CHECK_EQUAL( members.size(), 8 );
115}
116
117
124BOOST_AUTO_TEST_CASE( BusPatternMatchesBusMembers )
125{
126 LoadSchematic( SchematicQAPath( "issue16915" ) );
127
128 std::shared_ptr<NET_SETTINGS>& netSettings =
129 m_schematic->Project().GetProjectFile().m_NetSettings;
130
131 // The project has patterns:
132 // "/IN[0..7]" -> "Input" netclass
133 // "/OUT[7..0]" -> "Output" netclass
134
135 // Test that individual bus member nets get the correct netclass
136 // Input bus members should get "Input" netclass
137 for( int i = 0; i <= 7; i++ )
138 {
139 wxString netName = wxString::Format( "/IN%d", i );
140 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( netName );
141
142 BOOST_TEST_INFO( "Checking netclass for " << netName );
143 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
144 }
145
146 // Output bus members should get "Output" netclass
147 for( int i = 0; i <= 7; i++ )
148 {
149 wxString netName = wxString::Format( "/OUT%d", i );
150 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( netName );
151
152 BOOST_TEST_INFO( "Checking netclass for " << netName );
153 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Output" ) );
154 }
155}
156
157
164BOOST_AUTO_TEST_CASE( BusMemberNetclassHasCorrectColor )
165{
166 LoadSchematic( SchematicQAPath( "issue16915" ) );
167
168 std::shared_ptr<NET_SETTINGS>& netSettings =
169 m_schematic->Project().GetProjectFile().m_NetSettings;
170
171 // Check that the Input netclass has the expected color (magenta: rgb(255, 0, 255))
172 std::shared_ptr<NETCLASS> inputNc = netSettings->GetEffectiveNetClass( "/IN0" );
173 KIGFX::COLOR4D inputColor = inputNc->GetSchematicColor();
174
175 // The project defines Input netclass with schematic_color "rgb(255, 0, 255)"
176 BOOST_CHECK_EQUAL( inputColor.r, 1.0 );
177 BOOST_CHECK_EQUAL( inputColor.g, 0.0 );
178 BOOST_CHECK_EQUAL( inputColor.b, 1.0 );
179
180 // Check that the Output netclass has the expected color (orange: rgb(255, 153, 0))
181 std::shared_ptr<NETCLASS> outputNc = netSettings->GetEffectiveNetClass( "/OUT0" );
182 KIGFX::COLOR4D outputColor = outputNc->GetSchematicColor();
183
184 // The project defines Output netclass with schematic_color "rgb(255, 153, 0)"
185 BOOST_CHECK_EQUAL( outputColor.r, 1.0 );
186 BOOST_CHECK_CLOSE( outputColor.g, 0.6, 1.0 ); // 153/255 ≈ 0.6
187 BOOST_CHECK_EQUAL( outputColor.b, 0.0 );
188}
189
190
198BOOST_AUTO_TEST_CASE( BusWireInheritsNetclassFromMembers )
199{
200 LoadSchematic( SchematicQAPath( "issue16915" ) );
201
202 std::shared_ptr<NET_SETTINGS>& netSettings =
203 m_schematic->Project().GetProjectFile().m_NetSettings;
204
205 // The bus "/IN[0..7]" should inherit the "Input" netclass since all its members
206 // (/IN0, /IN1, ..., /IN7) have the "Input" netclass assigned via the pattern.
207 std::shared_ptr<NETCLASS> busNc = netSettings->GetEffectiveNetClass( "/IN[0..7]" );
208 BOOST_CHECK_EQUAL( busNc->GetName(), wxS( "Input" ) );
209
210 // Verify the bus has the correct color (magenta)
211 KIGFX::COLOR4D busColor = busNc->GetSchematicColor();
212 BOOST_CHECK_EQUAL( busColor.r, 1.0 );
213 BOOST_CHECK_EQUAL( busColor.g, 0.0 );
214 BOOST_CHECK_EQUAL( busColor.b, 1.0 );
215
216 // Similarly, "/OUT[7..0]" should inherit the "Output" netclass
217 busNc = netSettings->GetEffectiveNetClass( "/OUT[7..0]" );
218 BOOST_CHECK_EQUAL( busNc->GetName(), wxS( "Output" ) );
219
220 // Verify the bus has the correct color (orange)
221 busColor = busNc->GetSchematicColor();
222 BOOST_CHECK_EQUAL( busColor.r, 1.0 );
223 BOOST_CHECK_CLOSE( busColor.g, 0.6, 1.0 ); // 153/255 ≈ 0.6
224 BOOST_CHECK_EQUAL( busColor.b, 0.0 );
225}
226
227
234BOOST_AUTO_TEST_CASE( BusGroupPatternExpansion )
235{
236 LoadSchematic( SchematicQAPath( "issue16915" ) );
237
238 std::shared_ptr<NET_SETTINGS>& netSettings =
239 m_schematic->Project().GetProjectFile().m_NetSettings;
240
241 // Add a bus group pattern - members are vector buses that need expansion
242 netSettings->SetNetclassPatternAssignment( wxS( "PCI{North[0..2] South[3..5]}" ),
243 wxS( "Input" ) );
244
245 // Check that individual member nets from the expanded group get the netclass
246 // North[0..2] should expand to North0, North1, North2
247 for( int i = 0; i <= 2; i++ )
248 {
249 wxString netName = wxString::Format( "North%d", i );
250 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( netName );
251
252 BOOST_TEST_INFO( "Checking netclass for " << netName );
253 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
254 }
255
256 // South[3..5] should expand to South3, South4, South5
257 for( int i = 3; i <= 5; i++ )
258 {
259 wxString netName = wxString::Format( "South%d", i );
260 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( netName );
261
262 BOOST_TEST_INFO( "Checking netclass for " << netName );
263 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
264 }
265}
266
267
273BOOST_AUTO_TEST_CASE( BusWithMixedNetclassesFallsBackToDefault )
274{
275 LoadSchematic( SchematicQAPath( "issue16915" ) );
276
277 std::shared_ptr<NET_SETTINGS>& netSettings =
278 m_schematic->Project().GetProjectFile().m_NetSettings;
279
280 // Assign only some members of a test bus to a netclass
281 netSettings->SetNetclassPatternAssignment( wxS( "MIXED0" ), wxS( "Input" ) );
282 netSettings->SetNetclassPatternAssignment( wxS( "MIXED1" ), wxS( "Output" ) );
283
284 // The bus "MIXED[0..1]" has members with different netclasses, so it should
285 // fall back to the default netclass
286 std::shared_ptr<NETCLASS> busNc = netSettings->GetEffectiveNetClass( "MIXED[0..1]" );
287 BOOST_CHECK_EQUAL( busNc->GetName(), wxS( "Default" ) );
288}
289
290
296BOOST_AUTO_TEST_CASE( NonBusPatternsStillWork )
297{
298 LoadSchematic( SchematicQAPath( "issue16915" ) );
299
300 std::shared_ptr<NET_SETTINGS>& netSettings =
301 m_schematic->Project().GetProjectFile().m_NetSettings;
302
303 // Add a simple wildcard pattern for testing
304 netSettings->SetNetclassPatternAssignment( wxS( "/TEST*" ), wxS( "Input" ) );
305
306 // The wildcard pattern should still work
307 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( "/TEST_NET" );
308 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
309
310 nc = netSettings->GetEffectiveNetClass( "/TESTXYZ" );
311 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
312}
313
314
322BOOST_AUTO_TEST_CASE( NetclassCacheInvalidation )
323{
324 LoadSchematic( SchematicQAPath( "issue16915" ) );
325
326 std::shared_ptr<NET_SETTINGS>& netSettings =
327 m_schematic->Project().GetProjectFile().m_NetSettings;
328
329 // Initial lookup - should get "Input" netclass from the pattern "/IN[0..7]"
330 std::shared_ptr<NETCLASS> nc = netSettings->GetEffectiveNetClass( "/IN0" );
331 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
332
333 // Verify the lookup is cached
334 BOOST_CHECK( netSettings->HasEffectiveNetClass( "/IN0" ) );
335
336 // Clear the cache for this specific net
337 netSettings->ClearCacheForNet( "/IN0" );
338
339 // Cache should be cleared
340 BOOST_CHECK( !netSettings->HasEffectiveNetClass( "/IN0" ) );
341
342 // Looking up again should still return "Input" (pattern still matches)
343 nc = netSettings->GetEffectiveNetClass( "/IN0" );
344 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
345
346 // Now add a pattern that matches a renamed net
347 // Simulate: net was "/OLD_NET", now it's "/NEW_NET"
348 netSettings->SetNetclassPatternAssignment( wxS( "/OLD_NET" ), wxS( "Input" ) );
349 netSettings->SetNetclassPatternAssignment( wxS( "/NEW_NET" ), wxS( "Output" ) );
350
351 // Look up both - they should get different netclasses
352 nc = netSettings->GetEffectiveNetClass( "/OLD_NET" );
353 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
354
355 nc = netSettings->GetEffectiveNetClass( "/NEW_NET" );
356 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Output" ) );
357
358 // Clear all caches (simulating what happens on major connectivity changes)
359 netSettings->ClearAllCaches();
360
361 // Both should be recalculated correctly
362 nc = netSettings->GetEffectiveNetClass( "/OLD_NET" );
363 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Input" ) );
364
365 nc = netSettings->GetEffectiveNetClass( "/NEW_NET" );
366 BOOST_CHECK_EQUAL( nc->GetName(), wxS( "Output" ) );
367}
368
369
const char * name
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:105
double r
Red component.
Definition color4d.h:393
double g
Green component.
Definition color4d.h:394
double b
Blue component.
Definition color4d.h:395
A generic fixture for loading schematics and associated settings for qa tests.
static bool ParseBusVector(const wxString &aBus, wxString *aName, std::vector< wxString > *aMemberList)
Parse a bus vector (e.g.
static void ForEachBusMember(const wxString &aBusPattern, const std::function< void(const wxString &)> &aFunction)
Call a function for each member of an expanded bus pattern.
static void LoadSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ForEachBusMemberExpansion)
Test that ForEachBusMember correctly expands bus patterns.
BOOST_TEST_INFO("Parsed: "<< path)
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_EQUAL(result, "25.4")