KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue24044_expression_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
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, see <https://www.gnu.org/licenses/>.
18 */
19
22
23#include <schematic.h>
24#include <sch_sheet.h>
25#include <sch_sheet_path.h>
26#include <sch_sheet_pin.h>
27#include <sch_screen.h>
28#include <sch_label.h>
30#include <locale_io.h>
31
32
34{
36 std::unique_ptr<SCHEMATIC> m_schematic;
37};
38
39
64BOOST_FIXTURE_TEST_CASE( Issue24044ExpressionNetNames, ISSUE_24044_FIXTURE )
65{
67
68 KI_TEST::LoadSchematic( m_settingsManager, "issue24044/issue24044", m_schematic );
69
70 SCH_SHEET_LIST hierarchy = m_schematic->Hierarchy();
71
72 // Collect the two sub-sheet instance paths (both reference channels.kicad_sch but on
73 // different pages).
74 std::vector<SCH_SHEET_PATH> childPaths;
75
76 for( const SCH_SHEET_PATH& path : hierarchy )
77 {
78 if( path.size() == 2 )
79 childPaths.push_back( path );
80 }
81
82 BOOST_REQUIRE_EQUAL( childPaths.size(), 2U );
83
84 for( const SCH_SHEET_PATH& childPath : childPaths )
85 {
86 SCH_SHEET* childSheet = childPath.Last();
87 BOOST_REQUIRE( childSheet );
88
89 // Build the lookup on the child sheet's hierarchical labels
90 std::set<wxString> labelTexts;
91
92 for( SCH_ITEM* item : childSheet->GetScreen()->Items() )
93 {
94 if( item->Type() == SCH_HIER_LABEL_T )
95 {
96 SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
97 labelTexts.insert( label->GetShownText( &childPath, false ) );
98 }
99 }
100
101 wxString labelList;
102
103 for( const wxString& t : labelTexts )
104 {
105 if( !labelList.IsEmpty() )
106 labelList += wxT( "," );
107
108 labelList += t;
109 }
110
111 // Every sheet pin's resolved name must appear in the child's hierarchical labels
112 for( SCH_SHEET_PIN* pin : childSheet->GetPins() )
113 {
114 wxString pinText = pin->GetShownText( &childPath, false );
115
116 BOOST_CHECK_MESSAGE( !pinText.Contains( wxT( "@{" ) )
117 && !pinText.Contains( wxT( "${" ) ),
118 wxString::Format( "Sheet pin '%s' on path '%s' did not fully "
119 "resolve expression variables",
120 pinText,
121 childPath.PathHumanReadable() ) );
122
123 BOOST_CHECK_MESSAGE( labelTexts.count( pinText ) == 1,
124 wxString::Format( "Sheet pin '%s' on path '%s' has no matching "
125 "hierarchical label inside the child sheet. "
126 "Labels: [%s]",
127 pinText,
128 childPath.PathHumanReadable(),
129 labelList ) );
130 }
131 }
132
133 // Each sheet instance should produce a different resolved name (the expression depends
134 // on the page number, so the two instances must disambiguate).
135 std::set<wxString> allPinTexts;
136
137 for( const SCH_SHEET_PATH& childPath : childPaths )
138 {
139 for( SCH_SHEET_PIN* pin : childPath.Last()->GetPins() )
140 allPinTexts.insert( pin->GetShownText( &childPath, false ) );
141 }
142
143 BOOST_CHECK_EQUAL( allPinTexts.size(), 4U );
144
145 // Verify the computed names match the expected formula for each page number
146 for( const SCH_SHEET_PATH& childPath : childPaths )
147 {
148 long page = 0;
149 BOOST_REQUIRE( childPath.GetPageNumber().ToLong( &page ) );
150
151 std::set<wxString> expected = {
152 wxString::Format( "Ch%ld", ( page - 2 ) * 2 + 0 ),
153 wxString::Format( "Ch%ld", ( page - 2 ) * 2 + 1 )
154 };
155
156 std::set<wxString> actual;
157
158 for( SCH_SHEET_PIN* pin : childPath.Last()->GetPins() )
159 actual.insert( pin->GetShownText( &childPath, false ) );
160
161 wxString actualList;
162
163 for( const wxString& t : actual )
164 {
165 if( !actualList.IsEmpty() )
166 actualList += wxT( "," );
167
168 actualList += t;
169 }
170
172 wxString::Format( "Page %ld expected {Ch%ld, Ch%ld} but got {%s}",
173 page,
174 ( page - 2 ) * 2 + 0,
175 ( page - 2 ) * 2 + 1,
176 actualList ) );
177 }
178}
179
180
194BOOST_FIXTURE_TEST_CASE( Issue24044PathFormEquivalence, ISSUE_24044_FIXTURE )
195{
197
198 KI_TEST::LoadSchematic( m_settingsManager, "issue24044/issue24044", m_schematic );
199
200 std::vector<SCH_SHEET_PATH> childPaths;
201
202 for( const SCH_SHEET_PATH& path : m_schematic->Hierarchy() )
203 {
204 if( path.size() == 2 )
205 childPaths.push_back( path );
206 }
207
208 BOOST_REQUIRE_EQUAL( childPaths.size(), 2U );
209
210 for( const SCH_SHEET_PATH& childPath : childPaths )
211 {
212 SCH_SHEET* childSheet = childPath.Last();
213 BOOST_REQUIRE( childSheet );
214
215 // Build the parent-screen path (drop the trailing child sheet). This is the path
216 // shape that callers such as sch_selection_tool pass in.
217 SCH_SHEET_PATH parentPath = childPath;
218 parentPath.pop_back();
219
220 BOOST_REQUIRE_EQUAL( parentPath.size() + 1U, childPath.size() );
221
222 for( SCH_SHEET_PIN* pin : childSheet->GetPins() )
223 {
224 wxString fromChildPath = pin->GetShownText( &childPath, false );
225 wxString fromParentPath = pin->GetShownText( &parentPath, false );
226
227 BOOST_CHECK_MESSAGE( fromChildPath == fromParentPath,
228 wxString::Format( "Sheet pin resolution diverged between "
229 "path forms: child='%s' parent='%s'",
230 fromChildPath,
231 fromParentPath ) );
232 }
233 }
234}
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
wxString GetShownText(const SCH_SHEET_PATH *aPath, bool aAllowExtraText, int aDepth=0) const override
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:115
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
size_t size() const
Forwarded method from std::vector.
void pop_back()
Forwarded method from std::vector.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:139
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:227
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::vector< FAB_LAYER_COLOR > dummy
std::unique_ptr< SCHEMATIC > m_schematic
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_FIXTURE_TEST_CASE(Issue24044ExpressionNetNames, ISSUE_24044_FIXTURE)
Test for issue #24044: Inconsistent internal evaluation of net names when using expressions.
std::string path
KIBIS_PIN * pin
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
int actual
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_HIER_LABEL_T
Definition typeinfo.h:166