KiCad PCB EDA Suite
test_sch_reference_list.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 (C) 2022 Roberto Fernandez Bautista <[email protected]>
5 * Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22#include "eeschema_test_utils.h"
23
24#include <sch_reference_list.h>
25#include <sch_sheet_path.h> // SCH_MULTI_UNIT_REFERENCE_MAP
26
27
29{
30 wxString m_KIID;
31 wxString m_OriginalRef;
32 wxString m_ExpectedRef;
34};
35
36
38{
39protected:
40 void loadTestCase( wxString aSchematicRelativePath, std::vector<REANNOTATED_REFERENCE> aRefs );
41
42 SCH_SYMBOL* getSymbolByKIID( wxString aKIID, SCH_SHEET_PATH* aSymbolPath );
43
45
46 void checkAnnotation( std::vector<REANNOTATED_REFERENCE> aRefs );
47
50};
51
52
53void TEST_SCH_REFERENCE_LIST_FIXTURE::loadTestCase( wxString aSchematicRelativePath,
54 std::vector<REANNOTATED_REFERENCE> aRefs )
55{
57 m_lockedRefs.clear();
58
59 LoadSchematic( aSchematicRelativePath );
60
61 // Create list of references to reannotate
62 for( REANNOTATED_REFERENCE ref : aRefs )
63 {
64 SCH_SHEET_PATH symbolPath;
65 SCH_SYMBOL* symbol = getSymbolByKIID( ref.m_KIID, &symbolPath );
66
67 //Make sure test case is built properly
68 BOOST_REQUIRE_NE( symbol, nullptr );
69 BOOST_REQUIRE_EQUAL( symbol->GetRef( &symbolPath, true ), ref.m_OriginalRef );
70
71 if( ref.m_IncludeInReannotationList )
72 {
73 symbolPath.AppendSymbol( m_refsToReannotate, symbol );
74 symbolPath.AppendMultiUnitSymbol( m_lockedRefs, symbol );
75 }
76 }
77}
78
79
81 SCH_SHEET_PATH* aSymbolPath )
82{
84
85 KIID symKIID( aKIID );
86 SCH_ITEM* foundItem = sheets.GetItem( symKIID, aSymbolPath );
87 SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( foundItem );
88
89 return symbol;
90};
91
92
94{
95 // Build List of additional references to pass into Annotate()
96 SCH_REFERENCE_LIST allRefs, additionalRefs;
97
98 m_schematic.GetSheets().GetSymbols( allRefs );
99
100 for( size_t i = 0; i < allRefs.GetCount(); ++i )
101 {
102 if( !m_refsToReannotate.Contains( allRefs[i] ) )
103 additionalRefs.AddItem( allRefs[i] );
104 }
105
106 return additionalRefs;
107}
108
109
110void TEST_SCH_REFERENCE_LIST_FIXTURE::checkAnnotation( std::vector<REANNOTATED_REFERENCE> aRefs )
111{
112 for( REANNOTATED_REFERENCE ref : aRefs )
113 {
114 SCH_SHEET_PATH symbolPath;
115 SCH_SYMBOL* symbol = getSymbolByKIID( ref.m_KIID, &symbolPath );
116
117 BOOST_CHECK_EQUAL( symbol->GetRef( &symbolPath, true ), ref.m_ExpectedRef );
118 }
119}
120
121
122BOOST_FIXTURE_TEST_SUITE( SchReferenceList, TEST_SCH_REFERENCE_LIST_FIXTURE )
123
124
126{
127 std::string m_caseName;
130 std::vector<REANNOTATED_REFERENCE> m_ExpectedReannotations;
131};
132
133// Case 1: same value, same libref
134// Case 2: same value, different libref
135// Case 3: different value, same libref
136// Case 4: Not annotated unit to reannotate
137// Case 5: Duplicate references
138static const std::vector<REANNOTATION_CASE> reannotationCases = {
139 { "CASE 1. Rename only selected. All units selected",
140 "test_multiunit_reannotate",
141 1,
142 {
143 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
144 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
145 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
146 } },
147 { "CASE 1. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
148 "test_multiunit_reannotate",
149 1,
150 {
151 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
152 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U2B", true },
153 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
154 } },
155 { "CASE 1. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
156 "test_multiunit_reannotate",
157 1,
158 {
159 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
160 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
161 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
162 } },
163 { "CASE 2. Rename only selected. All units selected",
164 "test_multiunit_reannotate_2",
165 1,
166 {
167 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
168 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
169 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
170 } },
171 { "CASE 2. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
172 "test_multiunit_reannotate_2",
173 1,
174 {
175 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
176 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
177 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
178 } },
179 { "CASE 2. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
180 "test_multiunit_reannotate_2",
181 1,
182 {
183 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
184 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
185 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
186 } },
187 { "CASE 3. Rename only selected. All units selected",
188 "test_multiunit_reannotate_3",
189 1,
190 {
191 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U3A", true },
192 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
193 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
194 } },
195 { "CASE 3. Rename only selected. Only unit B selected (A and C should NOT be reannotated)",
196 "test_multiunit_reannotate_3",
197 1,
198 {
199 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
200 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
201 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U99C", false },
202 } },
203 { "CASE 3. Rename only selected. Only units B and C selected (A should NOT be reannotated)",
204 "test_multiunit_reannotate_3",
205 1,
206 {
207 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U99A", "U99A", false },
208 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U99B", "U3B", true },
209 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U99C", "U3C", true },
210 } },
211 { "CASE 4 - Not previously annotated (does not get added to multi-unit locked group)",
212 "test_multiunit_reannotate_4",
213 1,
214 {
215 { "549455c3-ab6e-454e-94b0-5ca9e521ae0b", "U?B", "U2B", true },
216 } },
217 { "CASE 5 - Duplicate annotation. 1 selected",
218 "test_multiunit_reannotate_5",
219 10,
220 {
221 { "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
222 { "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U2B", false },
223 { "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
224 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U2A", false },
225 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U11B", true },
226 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U2C", false },
227 } },
228 { "CASE 5 - Duplicate annotation. 2 selected",
229 "test_multiunit_reannotate_5",
230 10,
231 {
232 { "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
233 { "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U11B", true },
234 { "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
235 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U2A", false },
236 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U12B", true },
237 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U2C", false },
238 } },
239};
240
241// @todo simplify or refactor this test case.
242// Currently it simulates part of SCH_EDIT_FRAME::AnnotateSymbols
244{
245 for( const REANNOTATION_CASE& c : reannotationCases )
246 {
247 BOOST_TEST_INFO_SCOPE( c.m_caseName );
248
249 loadTestCase( c.m_SchematicRelativePath, c.m_ExpectedReannotations );
250
251 m_refsToReannotate.RemoveAnnotation( true );
252 m_refsToReannotate.SplitReferences();
253 m_refsToReannotate.Annotate( false, 0, c.m_StartNumber, m_lockedRefs, getAdditionalRefs() );
254 m_refsToReannotate.UpdateAnnotation();
255
256 checkAnnotation( c.m_ExpectedReannotations );
257 }
258}
259
260
262{
263 std::string m_caseName;
265 std::vector<REANNOTATED_REFERENCE> m_ExpectedReannotations;
266};
267
268
269static const std::vector<DUPLICATE_REANNOTATION_CASE> reannotateDuplicatesCases = {
270 { "Reannotate Duplicates. Simple case",
271 "test_multiunit_reannotate_5",
272 {
273 { "d43a1d25-d37a-467a-8b09-10cf2e2ace09", "U2A", "U2A", false },
274 { "cd562bae-2426-44e6-8196-59eee5439809", "U2B", "U2B", false },
275 { "3f20a749-efe3-4804-8fef-435caaa8dacb", "U2C", "U2C", false },
276 { "cf058f25-2bad-4c49-a0c4-f059825c427f", "U2A", "U3A", true },
277 { "e6c8127f-e282-4128-8744-05f7893bc3ec", "U2B", "U3B", true },
278 { "db066797-b21c-4c1c-9591-8c7c549f8087", "U2C", "U3C", true },
279 } },
280};
281
282
283BOOST_AUTO_TEST_CASE( ReannotateDuplicates )
284{
286 {
287 BOOST_TEST_INFO_SCOPE( c.m_caseName );
288
289 loadTestCase( c.m_SchematicRelativePath, c.m_ExpectedReannotations );
290
291 m_refsToReannotate.ReannotateDuplicates( getAdditionalRefs() );
292 m_refsToReannotate.UpdateAnnotation();
293
294 checkAnnotation( c.m_ExpectedReannotations );
295 }
296}
297
298
299BOOST_AUTO_TEST_SUITE_END()
Definition: kiid.h:48
A generic fixture for loading schematics and associated settings for qa tests.
virtual void LoadSchematic(const wxString &aRelativePath)
SCHEMATIC m_schematic
ā€¨Schematic to load
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:86
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
bool Contains(const SCH_REFERENCE &aItem) const
Return true if aItem exists in this list.
size_t GetCount() const
void AddItem(const SCH_REFERENCE &aItem)
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
SCH_ITEM * GetItem(const KIID &aID, SCH_SHEET_PATH *aPathOut=nullptr) const
Fetch a SCH_ITEM by ID.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void AppendMultiUnitSymbol(SCH_MULTI_UNIT_REFERENCE_MAP &aRefList, SCH_SYMBOL *aSymbol, bool aIncludePowerSymbols=true) const
Append a SCH_REFERENCE_LIST object to aRefList based on aSymbol, storing same-reference set of multi-...
void AppendSymbol(SCH_REFERENCE_LIST &aReferences, SCH_SYMBOL *aSymbol, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Append a SCH_REFERENCE object to aReferences based on aSymbol.
Schematic symbol object.
Definition: sch_symbol.h:80
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const
Return the reference for the given sheet path.
Definition: sch_symbol.cpp:624
void checkAnnotation(std::vector< REANNOTATED_REFERENCE > aRefs)
SCH_MULTI_UNIT_REFERENCE_MAP m_lockedRefs
void loadTestCase(wxString aSchematicRelativePath, std::vector< REANNOTATED_REFERENCE > aRefs)
SCH_SYMBOL * getSymbolByKIID(wxString aKIID, SCH_SHEET_PATH *aSymbolPath)
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
std::map< wxString, SCH_REFERENCE_LIST > SCH_MULTI_UNIT_REFERENCE_MAP
Container to map reference designators for multi-unit parts.
std::vector< REANNOTATED_REFERENCE > m_ExpectedReannotations
wxString m_KIID
KIID of the symbol to reannotate.
wxString m_ExpectedRef
Expected Reference Designator (after reannotating)
wxString m_OriginalRef
Original Reference Designator (prior to reannotating)
bool m_IncludeInReannotationList
True if reference is "selected" for reannotation.
std::vector< REANNOTATED_REFERENCE > m_ExpectedReannotations
static const std::vector< REANNOTATION_CASE > reannotationCases
BOOST_AUTO_TEST_CASE(Reannotate)
static const std::vector< DUPLICATE_REANNOTATION_CASE > reannotateDuplicatesCases