KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue22576_subsheet_standalone.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
34
36
37#include <connection_graph.h>
38#include <schematic.h>
39#include <sch_sheet.h>
40#include <sch_screen.h>
41#include <sch_symbol.h>
42#include <sch_sheet_path.h>
44#include <locale_io.h>
45
46
48{
51
53 std::unique_ptr<SCHEMATIC> m_schematic;
54};
55
56
64BOOST_FIXTURE_TEST_CASE( Issue22576MissingInstancesFallback, ISSUE22576_FIXTURE )
65{
67
68 // Create a minimal schematic with a symbol that has existing instance data
69 m_schematic = std::make_unique<SCHEMATIC>( nullptr );
70 m_schematic->Reset();
71
72 SCH_SHEET* rootSheet = new SCH_SHEET( m_schematic.get() );
73 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
74 rootSheet->SetScreen( screen );
75
76 // Create a symbol
77 SCH_SYMBOL* symbol = new SCH_SYMBOL();
78 symbol->SetLibId( LIB_ID( wxT( "Device" ), wxT( "R" ) ) );
79 symbol->SetPosition( VECTOR2I( 0, 0 ) );
80 symbol->GetField( FIELD_T::REFERENCE )->SetText( wxT( "R202" ) );
81 symbol->SetPrefix( wxT( "R" ) );
82 screen->Append( symbol );
83
84 // Add an instance for a "different" project path (simulating the parent hierarchy)
85 // This is what would exist if the file was saved as part of a hierarchical project
86 KIID_PATH existingPath;
87 existingPath.push_back( KIID() ); // Some other root sheet UUID
88 existingPath.push_back( KIID() ); // This sheet's UUID in that hierarchy
89
90 SCH_SYMBOL_INSTANCE existingInstance;
91 existingInstance.m_Path = existingPath;
92 existingInstance.m_Reference = wxT( "R202" );
93 existingInstance.m_Unit = 1;
94 existingInstance.m_ProjectName = wxT( "ParentProject" );
95 symbol->AddHierarchicalReference( existingInstance );
96
97 // Set up the schematic
98 m_schematic->AddTopLevelSheet( rootSheet );
99
100 // Now simulate opening as a standalone project
101 // This creates a NEW path that doesn't match the existing instance
102 SCH_SHEET_PATH newPath;
103 newPath.push_back( rootSheet );
104 newPath.Rehash();
105
106 // Before the fix, CheckForMissingSymbolInstances would set unannotated reference "R?"
107 // After the fix, it should use the existing instance data "R202"
108 wxString newProjectName = wxT( "StandaloneProject" );
109 newPath.CheckForMissingSymbolInstances( newProjectName );
110
111 // Verify the symbol now has an instance for the new path with the correct reference
112 wxString ref = symbol->GetRef( &newPath );
113
114 BOOST_TEST_MESSAGE( "Reference after CheckForMissingSymbolInstances: " << ref );
115
116 // The reference should be "R202" (from existing instance), NOT "R?" (unannotated)
117 BOOST_CHECK_MESSAGE( ref == wxT( "R202" ),
118 "Symbol reference should use existing instance data, not unannotated" );
119 BOOST_CHECK_MESSAGE( !ref.EndsWith( wxT( "?" ) ),
120 "Symbol reference should NOT be unannotated" );
121}
122
123
130BOOST_FIXTURE_TEST_CASE( Issue22576NoInstancesFallback, ISSUE22576_FIXTURE )
131{
133
134 m_schematic = std::make_unique<SCHEMATIC>( nullptr );
135 m_schematic->Reset();
136
137 SCH_SHEET* rootSheet = new SCH_SHEET( m_schematic.get() );
138 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
139 rootSheet->SetScreen( screen );
140
141 // Create a symbol with NO instances, only field text
142 SCH_SYMBOL* symbol = new SCH_SYMBOL();
143 symbol->SetLibId( LIB_ID( wxT( "Device" ), wxT( "C" ) ) );
144 symbol->SetPosition( VECTOR2I( 0, 0 ) );
145 symbol->GetField( FIELD_T::REFERENCE )->SetText( wxT( "C101" ) );
146 symbol->SetPrefix( wxT( "C" ) );
147 screen->Append( symbol );
148
149 // Verify no instances exist
150 BOOST_REQUIRE( symbol->GetInstances().empty() );
151
152 m_schematic->AddTopLevelSheet( rootSheet );
153
154 SCH_SHEET_PATH newPath;
155 newPath.push_back( rootSheet );
156 newPath.Rehash();
157
158 wxString newProjectName = wxT( "NewProject" );
159 newPath.CheckForMissingSymbolInstances( newProjectName );
160
161 wxString ref = symbol->GetRef( &newPath );
162
163 BOOST_TEST_MESSAGE( "Reference after CheckForMissingSymbolInstances (no prior instances): " << ref );
164
165 // Should use the field text "C101"
166 BOOST_CHECK_MESSAGE( ref == wxT( "C101" ),
167 "Symbol reference should use field text when no instances exist" );
168}
169
170
177BOOST_FIXTURE_TEST_CASE( Issue22576MultipleSymbolsFallback, ISSUE22576_FIXTURE )
178{
180
181 m_schematic = std::make_unique<SCHEMATIC>( nullptr );
182 m_schematic->Reset();
183
184 SCH_SHEET* rootSheet = new SCH_SHEET( m_schematic.get() );
185 SCH_SCREEN* screen = new SCH_SCREEN( m_schematic.get() );
186 rootSheet->SetScreen( screen );
187
188 // Create the "current" path first
189 m_schematic->AddTopLevelSheet( rootSheet );
190
191 SCH_SHEET_PATH currentPath;
192 currentPath.push_back( rootSheet );
193 currentPath.Rehash();
194
195 // Path for "other project" instances
196 KIID_PATH otherPath;
197 otherPath.push_back( KIID() );
198 otherPath.push_back( KIID() );
199
200 // Symbol 1: Has instance for other path only (should use that instance's ref)
201 SCH_SYMBOL* symbol1 = new SCH_SYMBOL();
202 symbol1->SetLibId( LIB_ID( wxT( "Device" ), wxT( "R" ) ) );
203 symbol1->SetPosition( VECTOR2I( 0, 0 ) );
204 symbol1->GetField( FIELD_T::REFERENCE )->SetText( wxT( "R?" ) ); // Field is unannotated
205 symbol1->SetPrefix( wxT( "R" ) );
206
208 inst1.m_Path = otherPath;
209 inst1.m_Reference = wxT( "R202" );
210 inst1.m_Unit = 1;
211 inst1.m_ProjectName = wxT( "OtherProject" );
212 symbol1->AddHierarchicalReference( inst1 );
213 screen->Append( symbol1 );
214
215 // Symbol 2: Has instance for current path (should keep it)
216 SCH_SYMBOL* symbol2 = new SCH_SYMBOL();
217 symbol2->SetLibId( LIB_ID( wxT( "Device" ), wxT( "C" ) ) );
218 symbol2->SetPosition( VECTOR2I( 1000, 0 ) );
219 symbol2->GetField( FIELD_T::REFERENCE )->SetText( wxT( "C101" ) );
220 symbol2->SetPrefix( wxT( "C" ) );
221 symbol2->SetRef( &currentPath, wxT( "C101" ) );
222 screen->Append( symbol2 );
223
224 // Symbol 3: No instances at all (should use field text)
225 SCH_SYMBOL* symbol3 = new SCH_SYMBOL();
226 symbol3->SetLibId( LIB_ID( wxT( "Device" ), wxT( "L" ) ) );
227 symbol3->SetPosition( VECTOR2I( 2000, 0 ) );
228 symbol3->GetField( FIELD_T::REFERENCE )->SetText( wxT( "L1" ) );
229 symbol3->SetPrefix( wxT( "L" ) );
230 screen->Append( symbol3 );
231
232 wxString projectName = wxT( "CurrentProject" );
233 currentPath.CheckForMissingSymbolInstances( projectName );
234
235 // Verify each symbol
236 wxString ref1 = symbol1->GetRef( &currentPath );
237 wxString ref2 = symbol2->GetRef( &currentPath );
238 wxString ref3 = symbol3->GetRef( &currentPath );
239
240 BOOST_TEST_MESSAGE( "Symbol1 (other instance only): " << ref1 );
241 BOOST_TEST_MESSAGE( "Symbol2 (current instance): " << ref2 );
242 BOOST_TEST_MESSAGE( "Symbol3 (no instances): " << ref3 );
243
244 BOOST_CHECK_MESSAGE( ref1 == wxT( "R202" ),
245 "Symbol with other-path instance should use that reference" );
246 BOOST_CHECK_MESSAGE( ref2 == wxT( "C101" ),
247 "Symbol with current-path instance should keep its reference" );
248 BOOST_CHECK_MESSAGE( ref3 == wxT( "L1" ),
249 "Symbol with no instances should use field text" );
250}
Definition kiid.h:44
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
void SetText(const wxString &aText) override
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
void CheckForMissingSymbolInstances(const wxString &aProjectName)
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Schematic symbol object.
Definition sch_symbol.h:69
void SetLibId(const LIB_ID &aName)
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition sch_symbol.h:128
void SetPosition(const VECTOR2I &aPosition) override
Definition sch_symbol.h:886
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
void SetPrefix(const wxString &aPrefix)
Definition sch_symbol.h:232
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.
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
A simple container for schematic symbol instance information.
@ REFERENCE
Field Reference of part, i.e. "IC21".
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_FIXTURE_TEST_CASE(Issue22576MissingInstancesFallback, ISSUE22576_FIXTURE)
Test that CheckForMissingSymbolInstances uses existing instance data as fallback.
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683