KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue21821_sheet_copy_refs.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 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
35
37#include "eeschema_test_utils.h"
38
39#include <locale_io.h>
40#include <schematic.h>
41#include <sch_screen.h>
42#include <sch_sheet.h>
43#include <sch_sheet_path.h>
44#include <sch_symbol.h>
46
47
49static const wxString LED0_PATH = wxS( "/17c4bf89-456c-4209-aa21-31be7397f5ca"
50 "/adf4c8f0-c33f-488a-8e8d-4ca6638d0792"
51 "/fd71c97e-9deb-4a95-a605-8e0c9eaa9729" );
52
54static const wxString LED8_PATH = wxS( "/17c4bf89-456c-4209-aa21-31be7397f5ca"
55 "/adf4c8f0-c33f-488a-8e8d-4ca6638d0792"
56 "/af5bb00b-cab5-44ce-9731-12dfdbf0dd8b" );
57
58
60{
62 {
64
65 wxFileName fn( KI_TEST::GetEeschemaTestDataDir() );
66 fn.AppendDir( wxS( "issue21821" ) );
67 fn.SetName( wxS( "issue21821" ) );
69
70 LoadSchematic( fn );
71
72 SCH_SHEET_LIST hierarchy = m_schematic->BuildSheetListSortedByPageNumbers();
73
74 std::optional<SCH_SHEET_PATH> led0 = hierarchy.GetSheetPathByKIIDPath( KIID_PATH( LED0_PATH ) );
75 std::optional<SCH_SHEET_PATH> led8 = hierarchy.GetSheetPathByKIIDPath( KIID_PATH( LED8_PATH ) );
76
77 BOOST_REQUIRE( led0.has_value() && led8.has_value() );
78
79 m_led0Path = *led0;
80 m_led8Path = *led8;
81
82 BOOST_REQUIRE_MESSAGE( m_led0Path.LastScreen() == m_led8Path.LastScreen(),
83 "The two sub-sheets must share one screen for this test to mean "
84 "anything" );
85
86 for( SCH_ITEM* item : m_led0Path.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
87 {
88 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
89
90 if( symbol->GetField( FIELD_T::VALUE )->GetText() == wxS( "LED_Dual_AAKK" ) )
91 m_diode = symbol;
92 }
93
95 }
96
99 SCH_SYMBOL* m_diode = nullptr;
100};
101
102
107BOOST_FIXTURE_TEST_CASE( SharedScreenInstancesSurvivePaste, ISSUE21821_FIXTURE )
108{
109 // Without an empty project name on disk there is no bug left to reproduce
110 for( const SCH_SYMBOL_INSTANCE& instance : m_diode->GetInstances() )
111 BOOST_REQUIRE( instance.m_ProjectName.IsEmpty() );
112
113 BOOST_REQUIRE_EQUAL( m_diode->GetRef( &m_led0Path ), wxS( "D3" ) );
114 BOOST_REQUIRE_EQUAL( m_diode->GetRef( &m_led8Path ), wxS( "D33" ) );
115
116 PrunePastedSymbolInstances( m_diode, *m_schematic );
117
118 BOOST_CHECK_EQUAL( m_diode->GetRef( &m_led0Path ), wxS( "D3" ) );
119 BOOST_CHECK_EQUAL( m_diode->GetRef( &m_led8Path ), wxS( "D33" ) );
120
121 // Claiming the instances is what lets the orphan pruning that follows a paste see them
122 for( const SCH_SYMBOL_INSTANCE& instance : m_diode->GetInstances() )
123 BOOST_CHECK_EQUAL( instance.m_ProjectName, m_schematic->Project().GetProjectName() );
124}
125
126
130BOOST_FIXTURE_TEST_CASE( ProjectOwnedInstancesUntouched, ISSUE21821_FIXTURE )
131{
132 size_t examined = 0;
133
134 for( SCH_ITEM* item : m_led0Path.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
135 {
136 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
137
138 if( symbol == m_diode )
139 continue;
140
141 size_t countBefore = symbol->GetInstances().size();
142 wxString led0Before = symbol->GetRef( &m_led0Path );
143 wxString led8Before = symbol->GetRef( &m_led8Path );
144
145 PrunePastedSymbolInstances( symbol, *m_schematic );
146
147 BOOST_CHECK_EQUAL( symbol->GetInstances().size(), countBefore );
148 BOOST_CHECK_EQUAL( symbol->GetRef( &m_led0Path ), led0Before );
149 BOOST_CHECK_EQUAL( symbol->GetRef( &m_led8Path ), led8Before );
150 examined++;
151 }
152
153 // The resistors are the whole point of this case, an empty walk would pass for free
154 BOOST_CHECK( examined > 0 );
155}
156
157
163BOOST_FIXTURE_TEST_CASE( VirtualRootInstancesSurvivePaste, ISSUE21821_FIXTURE )
164{
165 BOOST_REQUIRE( m_schematic->Root().m_Uuid == niluuid );
166
167 std::vector<SCH_SYMBOL_INSTANCE> stored = m_diode->GetInstances();
168
169 BOOST_REQUIRE_EQUAL( stored.size(), 2 );
170
171 for( SCH_SYMBOL_INSTANCE& instance : stored )
172 {
173 KIID_PATH withVirtualRoot;
174 withVirtualRoot.push_back( niluuid );
175
176 for( const KIID& uuid : instance.m_Path )
177 withVirtualRoot.push_back( uuid );
178
179 m_diode->RemoveInstance( instance.m_Path );
180 instance.m_Path = withVirtualRoot;
181 }
182
183 for( const SCH_SYMBOL_INSTANCE& instance : stored )
184 m_diode->AddHierarchicalReference( instance );
185
186 PrunePastedSymbolInstances( m_diode, *m_schematic );
187
188 BOOST_REQUIRE_EQUAL( m_diode->GetInstances().size(), 2 );
189
190 wxString led0Ref;
191 wxString led8Ref;
192
193 for( const SCH_SYMBOL_INSTANCE& instance : m_diode->GetInstances() )
194 {
195 // The stored path is left alone; only the ownership test normalizes it
196 BOOST_CHECK( instance.m_Path.front() == niluuid );
197 BOOST_CHECK_EQUAL( instance.m_ProjectName, m_schematic->Project().GetProjectName() );
198
199 if( instance.m_Path.back() == m_led0Path.Path().back() )
200 led0Ref = instance.m_Reference;
201 else if( instance.m_Path.back() == m_led8Path.Path().back() )
202 led8Ref = instance.m_Reference;
203 }
204
205 BOOST_CHECK_EQUAL( led0Ref, wxS( "D3" ) );
206 BOOST_CHECK_EQUAL( led8Ref, wxS( "D33" ) );
207}
208
209
214BOOST_FIXTURE_TEST_CASE( ForeignAndPathlessInstancesPruned, ISSUE21821_FIXTURE )
215{
216 SCH_SYMBOL_INSTANCE foreign;
217 foreign.m_Path = KIID_PATH( wxS( "/2b1cb0b9-6a97-4b3a-9c9e-24d5f2a0a9d1"
218 "/9d0f1e5c-4a6b-4f0d-8f4a-1c2d3e4f5a6b" ) );
219 foreign.m_ProjectName = wxS( "some_other_project" );
220 foreign.m_Reference = wxS( "D99" );
221 foreign.m_Unit = 1;
222 m_diode->AddHierarchicalReference( foreign );
223
224 SCH_SYMBOL_INSTANCE pathless;
225 pathless.m_ProjectName = m_schematic->Project().GetProjectName();
226 pathless.m_Reference = wxS( "D98" );
227 pathless.m_Unit = 1;
228 m_diode->AddHierarchicalReference( pathless );
229
230 BOOST_REQUIRE_EQUAL( m_diode->GetInstances().size(), 4 );
231
232 PrunePastedSymbolInstances( m_diode, *m_schematic );
233
234 BOOST_CHECK_EQUAL( m_diode->GetInstances().size(), 2 );
235
236 for( const SCH_SYMBOL_INSTANCE& instance : m_diode->GetInstances() )
237 BOOST_CHECK( instance.m_Path == m_led0Path.Path() || instance.m_Path == m_led8Path.Path() );
238}
Definition kiid.h:46
A generic fixture for loading schematics and associated settings for qa tests.
std::unique_ptr< SCHEMATIC > m_schematic
virtual void LoadSchematic(const wxFileName &aFn)
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:138
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:165
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
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:75
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition sch_symbol.h:134
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
static const std::string KiCadSchematicFileExtension
KIID niluuid(0)
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
void PrunePastedSymbolInstances(SCH_SYMBOL *aSymbol, const SCHEMATIC &aSchematic)
Discard the instance data a paste dragged in from somewhere else, keyed by path rather than project n...
std::vector< FAB_LAYER_COLOR > dummy
A simple container for schematic symbol instance information.
@ VALUE
Field Value of part, i.e. "3.3K".
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
static const wxString LED8_PATH
Sheet path of the "dual gpio LED8" instance, which shares LED0's screen.
static const wxString LED0_PATH
Sheet path of the "dual gpio LED0" instance, taken from the reporter's files.
BOOST_FIXTURE_TEST_CASE(SharedScreenInstancesSurvivePaste, ISSUE21821_FIXTURE)
The diode's instances are stored with no project name, so keying the paste cleanup on the project nam...
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:168