KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_net_chain_resolve_terminals.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, you may find one here:
18 * https://www.gnu.org/licenses/gpl-3.0.en.html
19 */
20
21#include <boost/test/unit_test.hpp>
22
23#include <connection_graph.h>
24#include <sch_netchain.h>
26
27#include <map>
28#include <memory>
29#include <utility>
30#include <vector>
31
32
33// Friend shim into CONNECTION_GRAPH::resolvePotentialChainByTerminals so the test can
34// exercise the resolver without exposing it on the public API. Mirrors the existing
35// boost_test_inject_committed_net_chain pattern.
37 const std::pair<std::pair<wxString, wxString>,
38 std::pair<wxString, wxString>>& aTerms,
39 const std::map<std::pair<wxString, wxString>, wxString>& aRefPinToNet,
40 const std::vector<std::unique_ptr<SCH_NETCHAIN>>& aPotentials,
41 const wxString& aChainName )
42{
44 { aTerms.first.first, aTerms.first.second },
45 { aTerms.second.first, aTerms.second.second }
46 };
47
48 return CONNECTION_GRAPH::resolvePotentialChainByTerminals( termRefs, aRefPinToNet,
49 aPotentials, aChainName );
50}
51
52
60BOOST_AUTO_TEST_SUITE( NetChainRestoreResolveBothTerminals )
61
62
63using REF_PIN_KEY = std::pair<wxString, wxString>;
64using REF_PIN_TO_NET = std::map<REF_PIN_KEY, wxString>;
66
67
68static std::unique_ptr<SCH_NETCHAIN> makePotential( const wxString& aName,
69 std::initializer_list<wxString> aNets )
70{
71 auto sig = std::make_unique<SCH_NETCHAIN>();
72 sig->SetName( aName );
73
74 for( const wxString& n : aNets )
75 sig->AddNet( n );
76
77 return sig;
78}
79
80
81BOOST_AUTO_TEST_CASE( PicksChainContainingBothTerminalNets )
82{
83 REF_PIN_TO_NET refPinToNet;
84 refPinToNet[{ wxT( "U1" ), wxT( "1" ) }] = wxT( "/SHARED" );
85 refPinToNet[{ wxT( "U3" ), wxT( "5" ) }] = wxT( "/TARGET_TO" );
86
87 std::vector<std::unique_ptr<SCH_NETCHAIN>> potentials;
88
89 // First in vector shares the 'from' net but ends on a different 'to' net. Old logic
90 // would have wrongly picked this one.
91 potentials.push_back( makePotential( wxT( "potA" ), { wxT( "/SHARED" ), wxT( "/OTHER_TO" ) } ) );
92
93 // Second in vector matches both endpoints. This is the correct candidate.
94 potentials.push_back( makePotential( wxT( "potB" ), { wxT( "/SHARED" ), wxT( "/TARGET_TO" ) } ) );
95
96 TERM_PAIR terms{
97 { wxT( "U1" ), wxT( "1" ) },
98 { wxT( "U3" ), wxT( "5" ) }
99 };
100
102 terms, refPinToNet, potentials, wxT( "TEST_CHAIN" ) );
103
104 BOOST_REQUIRE( match );
105 BOOST_CHECK_EQUAL( match->GetName(), wxT( "potB" ) );
106}
107
108
109BOOST_AUTO_TEST_CASE( ReturnsNullWhenNoPotentialSpansBothEndpoints )
110{
111 REF_PIN_TO_NET refPinToNet;
112 refPinToNet[{ wxT( "U1" ), wxT( "1" ) }] = wxT( "/SHARED" );
113 refPinToNet[{ wxT( "U3" ), wxT( "5" ) }] = wxT( "/TARGET_TO" );
114
115 std::vector<std::unique_ptr<SCH_NETCHAIN>> potentials;
116 potentials.push_back( makePotential( wxT( "potA" ), { wxT( "/SHARED" ), wxT( "/OTHER" ) } ) );
117 potentials.push_back( makePotential( wxT( "potB" ), { wxT( "/UNRELATED_FROM" ),
118 wxT( "/TARGET_TO" ) } ) );
119
120 TERM_PAIR terms{
121 { wxT( "U1" ), wxT( "1" ) },
122 { wxT( "U3" ), wxT( "5" ) }
123 };
124
126 terms, refPinToNet, potentials, wxT( "TEST_CHAIN" ) );
127
128 BOOST_CHECK( match == nullptr );
129}
130
131
132BOOST_AUTO_TEST_CASE( ReturnsNullWhenEitherTerminalUnresolvable )
133{
134 REF_PIN_TO_NET refPinToNet;
135 refPinToNet[{ wxT( "U1" ), wxT( "1" ) }] = wxT( "/SHARED" );
136
137 std::vector<std::unique_ptr<SCH_NETCHAIN>> potentials;
138 potentials.push_back( makePotential( wxT( "potA" ), { wxT( "/SHARED" ), wxT( "/X" ) } ) );
139
140 TERM_PAIR terms{
141 { wxT( "U1" ), wxT( "1" ) },
142 { wxT( "MISSING" ), wxT( "9" ) }
143 };
144
146 terms, refPinToNet, potentials, wxT( "TEST_CHAIN" ) );
147
148 BOOST_CHECK( match == nullptr );
149}
150
151
152BOOST_AUTO_TEST_CASE( SwappedTerminalOrderStillResolves )
153{
154 REF_PIN_TO_NET refPinToNet;
155 refPinToNet[{ wxT( "U1" ), wxT( "1" ) }] = wxT( "/A" );
156 refPinToNet[{ wxT( "U2" ), wxT( "2" ) }] = wxT( "/B" );
157
158 std::vector<std::unique_ptr<SCH_NETCHAIN>> potentials;
159 potentials.push_back( makePotential( wxT( "pot" ), { wxT( "/A" ), wxT( "/B" ) } ) );
160
161 TERM_PAIR terms{
162 { wxT( "U2" ), wxT( "2" ) },
163 { wxT( "U1" ), wxT( "1" ) }
164 };
165
167 terms, refPinToNet, potentials, wxT( "pot" ) );
168
169 BOOST_REQUIRE( match );
170 BOOST_CHECK_EQUAL( match->GetName(), wxT( "pot" ) );
171}
172
173
174// Companion regression for [H-5]. RebuildNetChains constructs both the potential chain net
175// set and the refPin->net lookup using the same normalization: when GetNetName() is empty
176// or contains "<NO NET>", a synthetic key __SG_<code> is substituted. The lookup table here
177// must use that same synthetic key for the unnamed endpoint, otherwise common
178// one-named-one-unnamed chains fail to restore under the strict both-endpoint rule.
179BOOST_AUTO_TEST_CASE( ResolvesWhenOneEndpointIsUnnamedSyntheticName )
180{
181 REF_PIN_TO_NET refPinToNet;
182 refPinToNet[{ wxT( "U1" ), wxT( "1" ) }] = wxT( "/NAMED_SIDE" );
183 refPinToNet[{ wxT( "U2" ), wxT( "2" ) }] = wxT( "__SG_42" );
184
185 std::vector<std::unique_ptr<SCH_NETCHAIN>> potentials;
186 potentials.push_back( makePotential( wxT( "pot" ),
187 { wxT( "/NAMED_SIDE" ), wxT( "__SG_42" ) } ) );
188
189 TERM_PAIR terms{
190 { wxT( "U1" ), wxT( "1" ) },
191 { wxT( "U2" ), wxT( "2" ) }
192 };
193
195 terms, refPinToNet, potentials, wxT( "TEST_CHAIN" ) );
196
197 BOOST_REQUIRE( match );
198 BOOST_CHECK_EQUAL( match->GetName(), wxT( "pot" ) );
199}
200
201
static SCH_NETCHAIN * resolvePotentialChainByTerminals(const CHAIN_TERMINAL_REFS &aTermRefs, const std::map< std::pair< wxString, wxString >, wxString > &aRefPinToNet, const std::vector< std::unique_ptr< SCH_NETCHAIN > > &aPotentials, const wxString &aChainName)
Disambiguate the saved (refA.pinA, refB.pinB) terminal pair against the current set of potential net ...
std::pair< CHAIN_TERMINAL_REF, CHAIN_TERMINAL_REF > CHAIN_TERMINAL_REFS
A net chain is a collection of nets that are connected together through passive components.
const wxString & GetName() const
STL class.
STL namespace.
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
static std::unique_ptr< SCH_NETCHAIN > makePotential(const wxString &aName, std::initializer_list< wxString > aNets)
std::pair< REF_PIN_KEY, REF_PIN_KEY > TERM_PAIR
std::map< REF_PIN_KEY, wxString > REF_PIN_TO_NET
SCH_NETCHAIN * boost_test_resolve_potential_chain_by_terminals(const std::pair< std::pair< wxString, wxString >, std::pair< wxString, wxString > > &aTerms, const std::map< std::pair< wxString, wxString >, wxString > &aRefPinToNet, const std::vector< std::unique_ptr< SCH_NETCHAIN > > &aPotentials, const wxString &aChainName)
BOOST_AUTO_TEST_CASE(PicksChainContainingBothTerminalNets)
std::pair< wxString, wxString > REF_PIN_KEY
Regression for [H-5].
BOOST_CHECK_EQUAL(result, "25.4")