KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_pin_map_resolver.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
21
22#include <memory>
23#include <set>
24
25#include <pin_map.h>
26#include <lib_symbol.h>
27#include <sch_pin.h>
28#include <sch_symbol.h>
29#include <sch_sheet_path.h>
30
31
33
34
35namespace
36{
37LIB_ID makeFp( const wxString& aLibNick, const wxString& aName )
38{
39 LIB_ID id;
40 id.SetLibNickname( aLibNick );
41 id.SetLibItemName( aName );
42 return id;
43}
44
45
46SCH_PIN* addPin( LIB_SYMBOL& aSymbol, const wxString& aNumber )
47{
48 SCH_PIN* pin = new SCH_PIN( &aSymbol );
49 pin->SetNumber( aNumber );
51 aSymbol.AddDrawItem( pin );
52 return pin;
53}
54} // namespace
55
56
58{
60 {
61 m_dfn = makeFp( wxS( "Package_DFN_QFN" ), wxS( "DFN-8-1EP" ) );
62
63 m_lib = std::make_unique<LIB_SYMBOL>( wxS( "LM358" ), nullptr );
64 addPin( *m_lib, wxS( "1" ) ); // identity in DFN
65 addPin( *m_lib, wxS( "4" ) ); // mapped to [4,9]
66 addPin( *m_lib, wxS( "8" ) ); // not mapped, no pad -> UNMAPPED
67
68 PIN_MAP map( wxS( "DFN-8-EP" ) );
69 map.SetEntry( wxS( "4" ), wxS( "[4,9]" ) );
70 m_lib->PinMaps().AddOrReplace( map );
71 m_lib->SetAssociatedFootprints( { { m_dfn, wxS( "DFN-8-EP" ) } } );
72
73 m_symbol = std::make_unique<SCH_SYMBOL>( *m_lib, m_lib->GetLibId(), nullptr, 0, 0,
74 VECTOR2I( 0, 0 ) );
75 m_symbol->UpdatePins();
76 }
77
78 SCH_PIN* pin( const wxString& aNumber ) const { return m_symbol->GetPin( aNumber ); }
79
81 std::unique_ptr<LIB_SYMBOL> m_lib;
82 std::unique_ptr<SCH_SYMBOL> m_symbol;
83 SCH_SHEET_PATH m_sheet; // empty path; no variant means base override
84};
85
86
87BOOST_FIXTURE_TEST_SUITE( PinMapResolver, PIN_MAP_RESOLVER_FIXTURE )
88
89
90BOOST_AUTO_TEST_CASE( ThreeResolutionStates )
91{
92 std::set<wxString> dfnPads = { wxS( "1" ), wxS( "2" ), wxS( "3" ), wxS( "4" ),
93 wxS( "5" ), wxS( "6" ), wxS( "7" ), wxS( "9" ) };
94
95 PAD_RESOLUTION state;
96
97 // MAPPED: pin 4 -> [4,9] via the library map (no footprint needed for MAPPED).
98 BOOST_CHECK_EQUAL( pin( wxS( "4" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
99 &dfnPads, &state ),
100 wxS( "[4,9]" ) );
101 BOOST_CHECK( state == PAD_RESOLUTION::MAPPED );
102
103 // IDENTITY: pin 1 has no entry but pad 1 exists on the footprint.
104 BOOST_CHECK_EQUAL( pin( wxS( "1" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
105 &dfnPads, &state ),
106 wxS( "1" ) );
107 BOOST_CHECK( state == PAD_RESOLUTION::IDENTITY );
108
109 // UNMAPPED: pin 8 has no entry and pad 8 is absent (set has 1-7 and 9).
110 BOOST_CHECK( pin( wxS( "8" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn, &dfnPads,
111 &state ).IsEmpty() );
112 BOOST_CHECK( state == PAD_RESOLUTION::UNMAPPED );
113}
114
115
116BOOST_AUTO_TEST_CASE( NoFootprintPathAssumesIdentity )
117{
118 PAD_RESOLUTION state;
119
120 // MAPPED entries still resolve with no footprint.
121 BOOST_CHECK_EQUAL( pin( wxS( "4" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
122 nullptr, &state ),
123 wxS( "[4,9]" ) );
124 BOOST_CHECK( state == PAD_RESOLUTION::MAPPED );
125
126 // Everything unmapped is assumed identity (returns the pin number) on the painter path.
127 BOOST_CHECK_EQUAL( pin( wxS( "8" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
128 nullptr, &state ),
129 wxS( "8" ) );
130 BOOST_CHECK( state == PAD_RESOLUTION::IDENTITY );
131}
132
133
134BOOST_AUTO_TEST_CASE( OverridePrecedence )
135{
136 PAD_RESOLUTION state;
137
138 // FORCE_IDENTITY ignores the library map: pin 4 falls through to identity/unmapped.
139 PIN_MAP_INSTANCE_OVERRIDE forceIdentity;
141 m_symbol->SetPinMapOverride( forceIdentity );
142
143 std::set<wxString> pads = { wxS( "4" ) };
144 BOOST_CHECK_EQUAL( pin( wxS( "4" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
145 &pads, &state ),
146 wxS( "4" ) );
147 BOOST_CHECK( state == PAD_RESOLUTION::IDENTITY );
148
149 // Sparse edits are ignored under forced identity (PIN_MAP_INSTANCE_OVERRIDE contract).
150 forceIdentity.m_Edits.push_back( { wxS( "4" ), wxS( "99" ) } );
151 m_symbol->SetPinMapOverride( forceIdentity );
152 BOOST_CHECK_EQUAL( pin( wxS( "4" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
153 &pads, &state ),
154 wxS( "4" ) );
155 BOOST_CHECK( state == PAD_RESOLUTION::IDENTITY );
156
157 // A sparse instance edit beats the library map.
160 edited.m_Edits.push_back( { wxS( "4" ), wxS( "99" ) } );
161 m_symbol->SetPinMapOverride( edited );
162
163 BOOST_CHECK_EQUAL( pin( wxS( "4" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
164 nullptr, &state ),
165 wxS( "99" ) );
166 BOOST_CHECK( state == PAD_RESOLUTION::MAPPED );
167}
168
169
170BOOST_AUTO_TEST_CASE( NamedMapOverride )
171{
172 PAD_RESOLUTION state;
173
174 // USE_NAMED_MAP forces a specific map by name regardless of footprint association.
175 m_lib->PinMaps().AddOrReplace( PIN_MAP( wxS( "SWAP" ) ) );
176 m_lib->PinMaps().FindByName( wxS( "SWAP" ) )->SetEntry( wxS( "1" ), wxS( "8" ) );
177
178 // Rebuild the symbol so its flattened library reference carries the new map.
179 m_symbol = std::make_unique<SCH_SYMBOL>( *m_lib, m_lib->GetLibId(), nullptr, 0, 0,
180 VECTOR2I( 0, 0 ) );
181 m_symbol->UpdatePins();
182
185 named.m_ActiveMapName = wxS( "SWAP" );
186 m_symbol->SetPinMapOverride( named );
187
188 BOOST_CHECK_EQUAL( pin( wxS( "1" ) )->GetEffectivePadNumber( m_sheet, wxEmptyString, m_dfn,
189 nullptr, &state ),
190 wxS( "8" ) );
191 BOOST_CHECK( state == PAD_RESOLUTION::MAPPED );
192}
193
194
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
Define a library symbol object.
Definition lib_symbol.h:80
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
A named pin map.
Definition pin_map.h:64
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
Definition pin_map.cpp:59
PAD_RESOLUTION
Outcome of pin-to-pad resolution (issue #2282).
Definition sch_pin.h:161
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:39
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
Per-instance override of the active pin map and a sparse delta on top.
Definition pin_map.h:199
std::vector< PIN_MAP_ENTRY > m_Edits
Definition pin_map.h:202
PIN_MAP_OVERRIDE_MODE m_Mode
Definition pin_map.h:200
std::unique_ptr< SCH_SYMBOL > m_symbol
std::unique_ptr< LIB_SYMBOL > m_lib
SCH_PIN * pin(const wxString &aNumber) const
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
KIBIS_PIN * pin
BOOST_AUTO_TEST_CASE(ThreeResolutionStates)
SCH_PIN::PAD_RESOLUTION PAD_RESOLUTION
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683