KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_sch_pin.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 2
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// Code under test
24#include <lib_symbol.h>
25#include <pin_type.h>
26#include <sch_pin.h>
27#include <sch_symbol.h>
28
29
31{
32public:
34 {
35 m_parent_part = new LIB_SYMBOL( "parent_part", nullptr );
36
38 m_parent_part->AddDrawItem( m_lib_pin );
39
40 // give the pin some kind of data we can use to test
41 m_lib_pin->SetNumber( "42" );
42 m_lib_pin->SetName( "pinname" );
44 m_lib_pin->SetPosition( VECTOR2I( 1, 2 ) );
45
47 m_parent_symbol = new SCH_SYMBOL( *m_parent_part, m_parent_part->GetLibId(), &path, 0, 0,
48 VECTOR2I( 1, 2 ) );
49 m_parent_symbol->SetRef( &path, "U2" );
50 m_parent_symbol->UpdatePins();
51
52 m_sch_pin = m_parent_symbol->GetPins( &path )[0];
53 }
54
56 {
57 delete m_parent_symbol;
58 delete m_parent_part;
59 }
60
63
65 SCH_PIN* m_sch_pin; // owned by m_parent_symbol, not us
66};
67
68
72BOOST_FIXTURE_TEST_SUITE( SchPin, TEST_SCH_PIN_FIXTURE )
73
74
77BOOST_AUTO_TEST_CASE( DefaultProperties )
78{
79 BOOST_CHECK_EQUAL( m_sch_pin->GetParentSymbol(), m_parent_symbol );
80
81 BOOST_CHECK_EQUAL( m_sch_pin->GetLocalPosition(), VECTOR2I( 1, 2 ) );
82 BOOST_CHECK_EQUAL( m_sch_pin->GetPosition(), VECTOR2I( 2, 4 ) );
83
84 BOOST_CHECK_EQUAL( m_sch_pin->IsVisible(), m_lib_pin->IsVisible() );
85 BOOST_CHECK_EQUAL( m_sch_pin->GetName(), m_lib_pin->GetName() );
86 BOOST_CHECK_EQUAL( m_sch_pin->GetNumber(), m_lib_pin->GetNumber() );
87
88 BOOST_CHECK( ( m_sch_pin->GetType() == m_lib_pin->GetType() ) );
89
90 BOOST_CHECK_EQUAL( m_sch_pin->IsGlobalPower(), m_lib_pin->IsGlobalPower() );
91 BOOST_CHECK_EQUAL( m_sch_pin->IsLocalPower(), m_lib_pin->IsLocalPower() );
92}
93
98{
99 SCH_PIN assigned = *m_sch_pin;
100
101 BOOST_CHECK_EQUAL( assigned.GetParentSymbol(), m_parent_symbol );
102 BOOST_CHECK_EQUAL( assigned.GetNumber(), m_lib_pin->GetNumber() );
103}
104
109{
110 SCH_PIN copied( *m_sch_pin );
111
112 BOOST_CHECK_EQUAL( copied.GetParentSymbol(), m_parent_symbol );
113 BOOST_CHECK_EQUAL( copied.GetNumber(), m_lib_pin->GetNumber() );
114 BOOST_CHECK_EQUAL( copied.GetAlt(), wxEmptyString );
115
116 SCH_PIN::ALT alt;
117 alt.m_Name = wxS( "alt" );
120 copied.GetAlternates()[ wxS( "alt" ) ] = alt;
121
122 // Set some non-default values
123 copied.SetAlt( "alt" );
124
125 SCH_PIN copied2( copied );
126 BOOST_CHECK_EQUAL( copied2.GetAlt(), "alt" );
127}
128
133{
134 // dangles by default
135 BOOST_CHECK_EQUAL( m_sch_pin->IsDangling(), true );
136
137 // all you have to do to un-dangle is say so
138 m_sch_pin->SetIsDangling( false );
139 BOOST_CHECK_EQUAL( m_sch_pin->IsDangling(), false );
140
141 // and the same to re-dangle
142 m_sch_pin->SetIsDangling( true );
143 BOOST_CHECK_EQUAL( m_sch_pin->IsDangling(), true );
144}
145
149BOOST_AUTO_TEST_CASE( PinNumbering )
150{
152
153 const wxString name = m_sch_pin->GetDefaultNetName( path );
154 BOOST_CHECK_EQUAL( name, "Net-(U2-pinname)" );
155
156 // do it again: this should now (transparently) go though the net name map
157 // can't really check directly, but coverage tools should see this
158 const wxString map_name = m_sch_pin->GetDefaultNetName( path );
159 BOOST_CHECK_EQUAL( map_name, name );
160}
161
165BOOST_AUTO_TEST_CASE( PinNumberingPower )
166{
167 // but if we set isPower...
168 m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
169 m_parent_part->SetGlobalPower();
170 BOOST_CHECK_EQUAL( m_lib_pin->IsGlobalPower(), true );
171
172 // and update symbol from library...
174 delete m_parent_symbol;
175 m_parent_symbol = new SCH_SYMBOL( *m_parent_part, m_parent_part->GetLibId(), &path, 0, 0,
176 VECTOR2I( 1, 2 ) );
177 m_parent_symbol->SetRef( &path, "U2" );
178 m_parent_symbol->SetValueFieldText( "voltage_value" );
179 m_parent_symbol->UpdatePins();
180
181 m_sch_pin = m_parent_symbol->GetPins( &path )[0];
182
183 // ... then the name is just the pin name
184 const wxString pwr_name = m_sch_pin->GetDefaultNetName( path );
185 BOOST_CHECK_EQUAL( pwr_name, "voltage_value" );
186}
187
188BOOST_AUTO_TEST_CASE( AlternatePinRenameUpdates )
189{
190 SCH_PIN::ALT alt;
191 alt.m_Name = wxS( "ALT1" );
194 m_lib_pin->GetAlternates()[ wxS( "ALT1" ) ] = alt;
195
196 m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
197 m_sch_pin = m_parent_symbol->GetPins()[0];
198 m_sch_pin->SetAlt( wxS( "ALT1" ) );
199
200 SCH_PIN::ALT altNew = alt;
201 m_lib_pin->GetAlternates().erase( wxS( "ALT1" ) );
202 altNew.m_Name = wxS( "ALT1_NEW" );
203 m_lib_pin->GetAlternates()[ wxS( "ALT1_NEW" ) ] = altNew;
204
205 m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
206
207 SCH_PIN* updatedPin = m_parent_symbol->GetPins()[0];
208
209 BOOST_CHECK_EQUAL( updatedPin->GetAlt(), "ALT1_NEW" );
210 BOOST_CHECK( updatedPin->GetAlternates().count( wxS( "ALT1" ) ) == 0 );
211}
212
213
217BOOST_AUTO_TEST_CASE( AlternatePinTypeReturnsCorrectType )
218{
219 // Set the library pin's default type to no_connect
220 m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
221
222 // Add an alternate with a different type (power_in)
223 SCH_PIN::ALT powerAlt;
224 powerAlt.m_Name = wxS( "8.pow" );
227 m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
228
229 // Flatten and update the symbol to get a fresh schematic pin
230 m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
231 m_sch_pin = m_parent_symbol->GetPins()[0];
232
233 // Before selecting alternate, type should be the default (NC)
234 BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_NC );
235
236 // Select the alternate
237 m_sch_pin->SetAlt( wxS( "8.pow" ) );
238
239 // After selecting alternate, type should be the alternate's type (POWER_IN)
240 BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
241 BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
242
243 // Also verify shape changed
244 BOOST_CHECK( m_sch_pin->GetShape() == GRAPHIC_PINSHAPE::LINE );
245}
246
247
253BOOST_AUTO_TEST_CASE( AlternatePinTypePersistsThroughSymbolUpdate )
254{
255 // Set the library pin's default type to no_connect
256 m_lib_pin->SetType( ELECTRICAL_PINTYPE::PT_NC );
257
258 // Add an alternate with a different type (power_in)
259 SCH_PIN::ALT powerAlt;
260 powerAlt.m_Name = wxS( "8.pow" );
263 m_lib_pin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
264
265 // First flatten to set up the symbol
266 m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
267 m_sch_pin = m_parent_symbol->GetPins()[0];
268
269 // Set the alternate on the schematic pin (like the parser would)
270 m_sch_pin->SetAlt( wxS( "8.pow" ) );
271 BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
272 BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
273
274 // Now simulate what happens when the library symbol is re-resolved
275 // This is similar to what happens after loading a schematic from file
276 m_parent_symbol->SetLibSymbol( m_parent_part->Flatten().release() );
277 m_sch_pin = m_parent_symbol->GetPins()[0];
278
279 // After the symbol update, the alternate should still be set
280 BOOST_CHECK_EQUAL( m_sch_pin->GetAlt(), "8.pow" );
281
282 // And GetType() should return the alternate's type
283 BOOST_CHECK( m_sch_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
284}
285
286
292BOOST_AUTO_TEST_CASE( ParserCreatedPinWithAlternate )
293{
294 // Create a library symbol with a pin that has alternates
295 LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
296
297 SCH_PIN* libPin = new SCH_PIN( libSymbol );
298 libPin->SetNumber( "8" );
299 libPin->SetName( "PIN8" );
300 libPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC
301 libPin->SetPosition( VECTOR2I( 0, 0 ) );
302
303 // Add an alternate with power_in type
304 SCH_PIN::ALT powerAlt;
305 powerAlt.m_Name = wxS( "8.pow" );
308 libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
309
310 libSymbol->AddDrawItem( libPin );
311
312 // Create a schematic symbol
314 SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
315 VECTOR2I( 0, 0 ) );
316 symbol->SetRef( &path, "J1" );
317
318 // Simulate what the parser does: create a raw pin with alternate set
319 // This bypasses SetAlt() validation by using the constructor directly
320 symbol->GetRawPins().clear(); // Remove auto-created pins
321 symbol->GetRawPins().emplace_back(
322 std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
323
324 SCH_PIN* parserPin = symbol->GetRawPins()[0].get();
325
326 // At this point, m_alt is set but m_libPin is nullptr
327 BOOST_CHECK_EQUAL( parserPin->GetAlt(), "8.pow" );
328 BOOST_CHECK( parserPin->GetLibPin() == nullptr );
329
330 // GetType() should return PT_UNSPECIFIED when m_libPin is null
331 BOOST_CHECK( parserPin->GetType() == ELECTRICAL_PINTYPE::PT_UNSPECIFIED );
332
333 // Now simulate SetLibSymbol() which calls UpdatePins()
334 symbol->SetLibSymbol( libSymbol->Flatten().release() );
335
336 // Verify the flattened library symbol has pins with alternates
337 BOOST_CHECK( symbol->GetLibSymbolRef() != nullptr );
338 std::vector<SCH_PIN*> libPins = symbol->GetLibSymbolRef()->GetGraphicalPins( 0, 0 );
339 BOOST_CHECK_EQUAL( libPins.size(), 1 );
340
341 if( !libPins.empty() )
342 {
343 SCH_PIN* flattenedLibPin = libPins[0];
344 BOOST_CHECK( !flattenedLibPin->GetAlternates().empty() );
345 BOOST_CHECK( flattenedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 );
346 }
347
348 // Get the pin after the update
349 SCH_PIN* updatedPin = symbol->GetPins( &path )[0];
350
351 // The alternate should still be set
352 BOOST_CHECK_EQUAL( updatedPin->GetAlt(), "8.pow" );
353
354 // m_libPin should now be set
355 BOOST_CHECK( updatedPin->GetLibPin() != nullptr );
356
357 // GetType() should return the alternate's type (PT_POWER_IN)
358 BOOST_CHECK( updatedPin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
359
360 delete symbol;
361 delete libSymbol;
362}
363
364
370BOOST_AUTO_TEST_CASE( LibraryPinAlternatesPreservedThroughCopy )
371{
372 // Create original library symbol with pin that has alternates
373 LIB_SYMBOL* origLibSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
374
375 SCH_PIN* origLibPin = new SCH_PIN( origLibSymbol );
376 origLibPin->SetNumber( "8" );
377 origLibPin->SetName( "8" ); // Default name matches number
378 origLibPin->SetType( ELECTRICAL_PINTYPE::PT_NC ); // Default type is NC
379 origLibPin->SetPosition( VECTOR2I( 0, 0 ) );
380
381 // Add alternate with power_in type
382 SCH_PIN::ALT powerAlt;
383 powerAlt.m_Name = wxS( "8.pow" );
386 origLibPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
387
388 origLibSymbol->AddDrawItem( origLibPin );
389
390 // Verify original has alternates
391 BOOST_CHECK( !origLibPin->GetAlternates().empty() );
392 BOOST_CHECK( origLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 );
393
394 // Simulate what happens during loading:
395 // 1. Library symbol is stored in m_libSymbols (just keep the original)
396 // 2. Create a COPY of the library symbol (like UpdateLocalLibSymbolLinks does)
397 LIB_SYMBOL* copiedLibSymbol = new LIB_SYMBOL( *origLibSymbol );
398
399 // Verify the copied library symbol has pins with alternates
400 std::vector<SCH_PIN*> copiedLibPins = copiedLibSymbol->GetGraphicalPins( 0, 0 );
401 BOOST_CHECK_EQUAL( copiedLibPins.size(), 1 );
402
403 if( !copiedLibPins.empty() )
404 {
405 SCH_PIN* copiedLibPin = copiedLibPins[0];
406
407 // This is the critical check - does the copied lib pin have alternates?
408 BOOST_CHECK_MESSAGE( !copiedLibPin->GetAlternates().empty(),
409 "Copied library pin should have alternates" );
410 BOOST_CHECK_MESSAGE( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0,
411 "Copied library pin should have '8.pow' alternate" );
412
413 // Check if the alternate has the correct type
414 if( copiedLibPin->GetAlternates().count( wxS( "8.pow" ) ) > 0 )
415 {
416 BOOST_CHECK( copiedLibPin->GetAlternates().at( wxS( "8.pow" ) ).m_Type
418 }
419 }
420
421 // Now create a schematic symbol with parser-created raw pins
423 SCH_SYMBOL* symbol = new SCH_SYMBOL( *origLibSymbol, origLibSymbol->GetLibId(), &path, 0, 0,
424 VECTOR2I( 0, 0 ) );
425 symbol->SetRef( &path, "J1" );
426
427 // Clear auto-created pins and add parser-style raw pin
428 symbol->GetRawPins().clear();
429 symbol->GetRawPins().emplace_back(
430 std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
431
432 // Verify raw pin state before SetLibSymbol
433 SCH_PIN* rawPin = symbol->GetRawPins()[0].get();
434 BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" );
435 BOOST_CHECK( rawPin->GetLibPin() == nullptr );
436
437 // Call SetLibSymbol with the COPIED library symbol (like UpdateLocalLibSymbolLinks does)
438 symbol->SetLibSymbol( copiedLibSymbol ); // Takes ownership
439
440 // Get the pin after UpdatePins() was called
441 std::vector<SCH_PIN*> schPins = symbol->GetPins( &path );
442 BOOST_CHECK_EQUAL( schPins.size(), 1 );
443
444 if( !schPins.empty() )
445 {
446 SCH_PIN* schPin = schPins[0];
447
448 // Check that m_libPin is set
449 BOOST_CHECK_MESSAGE( schPin->GetLibPin() != nullptr,
450 "Schematic pin should have m_libPin set after UpdatePins" );
451
452 // Check that the alternate is still set
453 BOOST_CHECK_MESSAGE( schPin->GetAlt() == "8.pow",
454 "Alternate should be preserved as '8.pow'" );
455
456 // Check that GetType() returns the alternate's type
458 "GetType() should return alternate's type (PT_POWER_IN)" );
459
460 // Additional diagnostic: check the library pin's alternates
461 if( schPin->GetLibPin() )
462 {
463 BOOST_CHECK_MESSAGE( !schPin->GetLibPin()->GetAlternates().empty(),
464 "Library pin pointed to by schematic pin should have alternates" );
465 BOOST_CHECK_MESSAGE( schPin->GetLibPin()->GetAlternates().count( wxS( "8.pow" ) ) > 0,
466 "Library pin should have '8.pow' in its alternates map" );
467 }
468 }
469
470 delete symbol;
471 delete origLibSymbol;
472}
473
474
480BOOST_AUTO_TEST_CASE( GetTypeBeforeLibPinSet )
481{
482 // Create a schematic symbol with parser-created raw pin
484 LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
485
486 SCH_PIN* libPin = new SCH_PIN( libSymbol );
487 libPin->SetNumber( "8" );
488 libPin->SetName( "8" );
490 libPin->SetPosition( VECTOR2I( 0, 0 ) );
491
492 SCH_PIN::ALT powerAlt;
493 powerAlt.m_Name = wxS( "8.pow" );
496 libPin->GetAlternates()[ wxS( "8.pow" ) ] = powerAlt;
497 libSymbol->AddDrawItem( libPin );
498
499 // Create symbol using default constructor (like parser does)
500 SCH_SYMBOL* symbol = new SCH_SYMBOL();
501 symbol->SetLibId( libSymbol->GetLibId() );
502
503 // Add parser-style raw pin with alternate set but no m_libPin
504 symbol->GetRawPins().emplace_back(
505 std::make_unique<SCH_PIN>( symbol, wxS( "8" ), wxS( "8.pow" ), KIID() ) );
506
507 SCH_PIN* rawPin = symbol->GetRawPins()[0].get();
508
509 // At this point: m_alt is set, m_libPin is nullptr, m_type is PT_INHERIT
510 BOOST_CHECK_EQUAL( rawPin->GetAlt(), "8.pow" );
511 BOOST_CHECK( rawPin->GetLibPin() == nullptr );
512
513 // GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED
514 // per the code in GetType()
516 "GetType() with m_alt set but m_libPin=nullptr should return PT_UNSPECIFIED" );
517
518 // GetShownName() should still return the alternate name
519 BOOST_CHECK_EQUAL( rawPin->GetShownName(), "8.pow" );
520
521 // Now set the library symbol which triggers UpdatePins()
522 symbol->SetLibSymbol( new LIB_SYMBOL( *libSymbol ) );
523
524 // After UpdatePins(), pin should have correct type
525 std::vector<SCH_PIN*> schPins = symbol->GetPins( &path );
526 BOOST_CHECK_EQUAL( schPins.size(), 1 );
527
528 if( !schPins.empty() )
529 {
530 SCH_PIN* schPin = schPins[0];
531 BOOST_CHECK_EQUAL( schPin->GetAlt(), "8.pow" );
532 BOOST_CHECK( schPin->GetLibPin() != nullptr );
534 "After SetLibSymbol, GetType() should return PT_POWER_IN" );
535 }
536
537 delete symbol;
538 delete libSymbol;
539}
540
541
545BOOST_AUTO_TEST_CASE( ChangeSymbolFewerPinsNoCrash )
546{
547 // Create a symbol with multiple pins (pins 1, 2, 3)
548 LIB_SYMBOL* multiPinPart = new LIB_SYMBOL( "multi_pin_part", nullptr );
549
550 SCH_PIN* pin1 = new SCH_PIN( multiPinPart );
551 pin1->SetNumber( "1" );
552 pin1->SetName( "PIN1" );
554 pin1->SetPosition( VECTOR2I( 0, 0 ) );
555 multiPinPart->AddDrawItem( pin1 );
556
557 SCH_PIN* pin2 = new SCH_PIN( multiPinPart );
558 pin2->SetNumber( "2" );
559 pin2->SetName( "PIN2" );
561 pin2->SetPosition( VECTOR2I( 100, 0 ) );
562 multiPinPart->AddDrawItem( pin2 );
563
564 SCH_PIN* pin3 = new SCH_PIN( multiPinPart );
565 pin3->SetNumber( "3" );
566 pin3->SetName( "PIN3" );
568 pin3->SetPosition( VECTOR2I( 200, 0 ) );
569 multiPinPart->AddDrawItem( pin3 );
570
572 SCH_SYMBOL* symbol = new SCH_SYMBOL( *multiPinPart, multiPinPart->GetLibId(), &path, 0, 0,
573 VECTOR2I( 0, 0 ) );
574 symbol->SetRef( &path, "U1" );
575 symbol->UpdatePins();
576
577 BOOST_CHECK_EQUAL( symbol->GetPins( &path ).size(), 3 );
578
579 // Create a symbol with only one pin (pin 1)
580 LIB_SYMBOL* singlePinPart = new LIB_SYMBOL( "single_pin_part", nullptr );
581
582 SCH_PIN* newPin1 = new SCH_PIN( singlePinPart );
583 newPin1->SetNumber( "1" );
584 newPin1->SetName( "NEW_PIN1" );
586 newPin1->SetPosition( VECTOR2I( 0, 0 ) );
587 singlePinPart->AddDrawItem( newPin1 );
588
589 // Change to the single-pin symbol - this should not crash
590 symbol->SetLibSymbol( singlePinPart->Flatten().release() );
591
592 // Verify the symbol now has only one pin
593 BOOST_CHECK_EQUAL( symbol->GetPins( &path ).size(), 1 );
594
595 // Verify GetPin returns the correct pin for the new lib pin
596 std::vector<SCH_PIN*> libPins = symbol->GetLibSymbolRef()->GetGraphicalPins( 0, 0 );
597 BOOST_CHECK_EQUAL( libPins.size(), 1 );
598
599 SCH_PIN* schPin = symbol->GetPin( libPins[0] );
600 BOOST_CHECK( schPin != nullptr );
601
602 if( schPin )
603 {
604 BOOST_CHECK_EQUAL( schPin->GetNumber(), "1" );
605 }
606
607 delete symbol;
608 delete multiPinPart;
609 delete singlePinPart;
610}
611
617BOOST_AUTO_TEST_CASE( HasConnectivityChangesForPowerPinVisibility )
618{
619 // Create a library symbol with a hidden power pin
620 LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "power_symbol", nullptr );
621
622 SCH_PIN* libPin = new SCH_PIN( libSymbol );
623 libPin->SetNumber( "1" );
624 libPin->SetName( "VCC" );
626 libPin->SetPosition( VECTOR2I( 0, 0 ) );
627 libPin->SetVisible( false ); // Hidden power pin
628 libSymbol->AddDrawItem( libPin );
629
630 // Create a schematic symbol
632 SCH_SYMBOL* symbol1 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
633 VECTOR2I( 0, 0 ) );
634 symbol1->SetRef( &path, "U1" );
635 symbol1->UpdatePins();
636
637 SCH_PIN* schPin1 = symbol1->GetPins( &path )[0];
638
639 // Verify initial state - should be a global power pin
640 BOOST_CHECK( schPin1->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
641 BOOST_CHECK( !schPin1->IsVisible() );
642 BOOST_CHECK( schPin1->IsGlobalPower() );
643
644 // Create a second symbol with the same pin made visible
645 libPin->SetVisible( true ); // Make pin visible
646 SCH_SYMBOL* symbol2 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
647 VECTOR2I( 0, 0 ) );
648 symbol2->SetRef( &path, "U2" );
649 symbol2->UpdatePins();
650
651 SCH_PIN* schPin2 = symbol2->GetPins( &path )[0];
652
653 // Verify second state - should NOT be a global power pin (visible power pins aren't global)
654 BOOST_CHECK( schPin2->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
655 BOOST_CHECK( schPin2->IsVisible() );
656 BOOST_CHECK( !schPin2->IsGlobalPower() );
657
658 // HasConnectivityChanges should detect the visibility difference for power pins
659 BOOST_CHECK_MESSAGE( schPin1->HasConnectivityChanges( schPin2, &path ),
660 "HasConnectivityChanges should detect visibility change for power input pins" );
661
662 BOOST_CHECK_MESSAGE( schPin2->HasConnectivityChanges( schPin1, &path ),
663 "HasConnectivityChanges should detect visibility change for power input pins (reverse)" );
664
665 // Verify that regular (non-power) pins don't trigger connectivity changes on visibility change
666 libPin->SetType( ELECTRICAL_PINTYPE::PT_INPUT ); // Change to regular input
667 libPin->SetVisible( false );
668
669 SCH_SYMBOL* symbol3 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
670 VECTOR2I( 0, 0 ) );
671 symbol3->SetRef( &path, "U3" );
672 symbol3->UpdatePins();
673 SCH_PIN* schPin3 = symbol3->GetPins( &path )[0];
674
675 libPin->SetVisible( true ); // Change visibility
676
677 SCH_SYMBOL* symbol4 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
678 VECTOR2I( 0, 0 ) );
679 symbol4->SetRef( &path, "U4" );
680 symbol4->UpdatePins();
681 SCH_PIN* schPin4 = symbol4->GetPins( &path )[0];
682
683 // Regular pins shouldn't trigger connectivity changes on visibility change
684 BOOST_CHECK_MESSAGE( !schPin3->HasConnectivityChanges( schPin4, &path ),
685 "HasConnectivityChanges should NOT detect visibility change for regular input pins" );
686
687 delete symbol1;
688 delete symbol2;
689 delete symbol3;
690 delete symbol4;
691 delete libSymbol;
692}
693
694
699BOOST_AUTO_TEST_CASE( HasConnectivityChangesForPinTypeChange )
700{
701 // Create a library symbol with a regular pin
702 LIB_SYMBOL* libSymbol = new LIB_SYMBOL( "test_symbol", nullptr );
703
704 SCH_PIN* libPin = new SCH_PIN( libSymbol );
705 libPin->SetNumber( "1" );
706 libPin->SetName( "PIN1" );
708 libPin->SetPosition( VECTOR2I( 0, 0 ) );
709 libSymbol->AddDrawItem( libPin );
710
711 // Create first schematic symbol with regular input pin
713 SCH_SYMBOL* symbol1 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
714 VECTOR2I( 0, 0 ) );
715 symbol1->SetRef( &path, "U1" );
716 symbol1->UpdatePins();
717 SCH_PIN* schPin1 = symbol1->GetPins( &path )[0];
718
719 // Change pin type to power input
721
722 SCH_SYMBOL* symbol2 = new SCH_SYMBOL( *libSymbol, libSymbol->GetLibId(), &path, 0, 0,
723 VECTOR2I( 0, 0 ) );
724 symbol2->SetRef( &path, "U2" );
725 symbol2->UpdatePins();
726 SCH_PIN* schPin2 = symbol2->GetPins( &path )[0];
727
728 // Changing to/from PT_POWER_IN should trigger connectivity changes
729 BOOST_CHECK_MESSAGE( schPin1->HasConnectivityChanges( schPin2, &path ),
730 "HasConnectivityChanges should detect change from INPUT to POWER_IN" );
731
732 BOOST_CHECK_MESSAGE( schPin2->HasConnectivityChanges( schPin1, &path ),
733 "HasConnectivityChanges should detect change from POWER_IN to INPUT" );
734
735 delete symbol1;
736 delete symbol2;
737 delete libSymbol;
738}
739
740
const char * name
Definition kiid.h:44
Define a library symbol object.
Definition lib_symbol.h:79
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:148
std::vector< const SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
std::unique_ptr< LIB_SYMBOL > Flatten() const
Return a flattened symbol inheritance to the caller.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:274
const std::map< wxString, ALT > & GetAlternates() const
Definition sch_pin.h:163
void SetNumber(const wxString &aNumber)
Definition sch_pin.cpp:734
void SetVisible(bool aVisible)
Definition sch_pin.h:117
ALT GetAlt(const wxString &aAlt)
Definition sch_pin.h:177
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
Definition sch_pin.cpp:1689
void SetName(const wxString &aName)
Definition sch_pin.cpp:512
bool IsGlobalPower() const
Return whether this pin forms a global power connection: i.e., is part of a power symbol and of type ...
Definition sch_pin.cpp:448
bool IsVisible() const
Definition sch_pin.cpp:480
SCH_PIN * GetLibPin() const
Definition sch_pin.h:92
void SetPosition(const VECTOR2I &aPos) override
Definition sch_pin.h:254
const wxString & GetShownName() const
Definition sch_pin.cpp:671
void SetType(ELECTRICAL_PINTYPE aType)
Definition sch_pin.cpp:422
const wxString & GetNumber() const
Definition sch_pin.h:127
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:402
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:69
void SetLibId(const LIB_ID &aName)
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
Definition sch_symbol.h:661
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 UpdatePins()
Updates the cache of SCH_PIN objects for each pin.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
SCH_PIN * GetPin(const wxString &number) const
Find a symbol pin by number.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
Definition sch_symbol.h:177
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
SCH_SYMBOL * m_parent_symbol
LIB_SYMBOL * m_parent_part
@ PT_INPUT
usual pin input: must be connected
Definition pin_type.h:33
@ PT_NC
not connected (must be left open)
Definition pin_type.h:46
@ PT_OUTPUT
usual output
Definition pin_type.h:34
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
Definition pin_type.h:42
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
Definition pin_type.h:41
wxString m_Name
Definition sch_pin.h:45
GRAPHIC_PINSHAPE m_Shape
Definition sch_pin.h:46
ELECTRICAL_PINTYPE m_Type
Definition sch_pin.h:47
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
bool copied
KIBIS_PIN * pin3
std::string path
KIBIS_PIN * pin1
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_AUTO_TEST_CASE(DefaultProperties)
Declare the test suite.
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683