KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_save_load_schematic.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 2
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
24
25#include <boost/test/unit_test.hpp>
26#include <eeschema_test_utils.h>
27
29#include <sch_screen.h>
30#include <sch_sheet.h>
31#include <sch_symbol.h>
32#include <schematic.h>
33#include <kiid.h>
34#include <sch_file_versions.h>
36
37#include <wx/ffile.h>
38#include <wx/filename.h>
39#include <wx/stdpaths.h>
40
41
43{
46 {
47 // Create a temporary project file so we have a valid project name
48 wxString tempDir = wxStandardPaths::Get().GetTempDir();
49 wxString projectPath = tempDir + wxFileName::GetPathSeparator() + wxT("test_project.kicad_pro");
50 m_tempFiles.push_back( projectPath );
51
52 m_settingsManager.LoadProject( projectPath.ToStdString() );
53 m_schematic = std::make_unique<SCHEMATIC>( nullptr );
55 m_schematic->SetProject( m_project );
56 }
57
59 {
60 // Clean up temp files
61 for( const wxString& file : m_tempFiles )
62 {
63 if( wxFileExists( file ) )
64 wxRemoveFile( file );
65 }
66
67 m_schematic.reset();
68 }
69
70 wxString GetTempFileName( const wxString& aPrefix )
71 {
72 wxString tempDir = wxStandardPaths::Get().GetTempDir();
73 wxString fileName = wxFileName::CreateTempFileName( tempDir + wxFileName::GetPathSeparator() + aPrefix );
74 m_tempFiles.push_back( fileName );
75 return fileName;
76 }
77
79 std::unique_ptr<SCHEMATIC> m_schematic;
81 std::vector<wxString> m_tempFiles;
82};
83
84
85BOOST_FIXTURE_TEST_SUITE( SaveLoadSchematic, SAVE_LOAD_FIXTURE )
86
87
88
92BOOST_AUTO_TEST_CASE( TestSaveLoadSimpleSchematic )
93{
94 // Create a simple schematic
95 m_schematic->CreateDefaultScreens();
96
97 // Get the first (and only) top-level sheet
98 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
99 BOOST_REQUIRE( !topSheets.empty() );
100
101 SCH_SCREEN* screen = topSheets[0]->GetScreen();
102 BOOST_REQUIRE( screen != nullptr );
103
104 // Set some basic properties
105 screen->SetFileName( "test.kicad_sch" );
106 topSheets[0]->SetName( "Main Sheet" );
107
108 // Verify that currentSheet is set to a top-level sheet, not virtual root
109 SCH_SHEET_PATH& currentSheet = m_schematic->CurrentSheet();
110 BOOST_CHECK( !currentSheet.empty() );
111 if( !currentSheet.empty() )
112 {
113 BOOST_CHECK( currentSheet.Last() != &m_schematic->Root() );
114 BOOST_CHECK( currentSheet.Last()->m_Uuid != niluuid );
115 }
116
117 // Save the schematic
118 wxString fileName = GetTempFileName( "test_schematic" );
119 fileName += ".kicad_sch";
120 m_tempFiles.push_back( fileName );
121
123 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( fileName, topSheets[0], m_schematic.get() ) );
124
125 // Verify file was created
126 BOOST_CHECK( wxFileExists( fileName ) );
127
128 // Now try to load it back
129 m_schematic->Reset();
130 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
131 SCH_SHEET* loadedSheet = nullptr;
132 BOOST_CHECK_NO_THROW( loadedSheet = io.LoadSchematicFile( fileName, m_schematic.get() ) );
133 BOOST_CHECK( loadedSheet != nullptr );
134
135 if( loadedSheet )
136 {
137 // Set it as root (which should create virtual root and make it a top-level sheet)
138 m_schematic->AddTopLevelSheet( loadedSheet );
139 m_schematic->RemoveTopLevelSheet( defaultSheet );
140 delete defaultSheet;
141
142 // Verify we can access the schematic
143 BOOST_CHECK( m_schematic->IsValid() );
144
145 // Verify current sheet is NOT the virtual root
146 SCH_SHEET_PATH& currentSheet2 = m_schematic->CurrentSheet();
147 BOOST_CHECK( !currentSheet2.empty() );
148 if( !currentSheet2.empty() )
149 {
150 BOOST_CHECK( currentSheet2.Last() != &m_schematic->Root() );
151 BOOST_CHECK( currentSheet2.Last()->m_Uuid != niluuid );
152 }
153
154 // Try to save again (this is where the bug occurs)
155 wxString fileName2 = GetTempFileName( "test_schematic_resave" );
156 fileName2 += ".kicad_sch";
157 m_tempFiles.push_back( fileName2 );
158
159 std::vector<SCH_SHEET*> topSheets2 = m_schematic->GetTopLevelSheets();
160 BOOST_REQUIRE( !topSheets2.empty() );
161
162 // This should not assert - this is the key test for the bug fix
163 // Symbol instances should be preserved, not dropped
164 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( fileName2, topSheets2[0], m_schematic.get() ) );
165
166 // Verify the second file was created
167 BOOST_CHECK( wxFileExists( fileName2 ) );
168 }
169}
170
171
175BOOST_AUTO_TEST_CASE( TestSaveLoadHierarchicalSchematic )
176{
177 // Create a schematic with hierarchy
178 m_schematic->CreateDefaultScreens();
179
180 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
181 BOOST_REQUIRE( !topSheets.empty() );
182
183 SCH_SCREEN* screen = topSheets[0]->GetScreen();
184 BOOST_REQUIRE( screen != nullptr );
185
186 // Create a sub-sheet
187 SCH_SHEET* subSheet = new SCH_SHEET( m_schematic.get() );
188 subSheet->SetName( "SubSheet" );
189 SCH_SCREEN* subScreen = new SCH_SCREEN( m_schematic.get() );
190 subSheet->SetScreen( subScreen );
191 subSheet->SetFileName( "subsheet.kicad_sch" );
192 subScreen->SetFileName( "subsheet.kicad_sch" );
193 screen->Append( subSheet );
194
195 // Save the main sheet
196 wxString mainFileName = GetTempFileName( "test_main" );
197 mainFileName += ".kicad_sch";
198 m_tempFiles.push_back( mainFileName );
199
200 // Save the sub-sheet
201 wxString subFileName = GetTempFileName( "test_sub" );
202 subFileName += ".kicad_sch";
203 m_tempFiles.push_back( subFileName );
204
206 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( mainFileName, topSheets[0], m_schematic.get() ) );
207 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( subFileName, subSheet, m_schematic.get() ) );
208
209 // Load it back
210 m_schematic->Reset();
211 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
212 SCH_SHEET* loadedSheet = nullptr;
213 BOOST_CHECK_NO_THROW( loadedSheet = io.LoadSchematicFile( mainFileName, m_schematic.get() ) );
214 BOOST_CHECK( loadedSheet != nullptr );
215
216 if( loadedSheet )
217 {
218 m_schematic->AddTopLevelSheet( loadedSheet );
219 m_schematic->RemoveTopLevelSheet( defaultSheet );
220 delete defaultSheet;
221
222 // Build hierarchy
223 m_schematic->RefreshHierarchy();
224
225 // Verify hierarchy has 2 sheets (main + sub)
226 SCH_SHEET_LIST hierarchy = m_schematic->Hierarchy();
227 BOOST_CHECK_EQUAL( hierarchy.size(), 2 );
228
229 // Try to save again
230 wxString mainFileName2 = GetTempFileName( "test_main_resave" );
231 mainFileName2 += ".kicad_sch";
232 m_tempFiles.push_back( mainFileName2 );
233
234 std::vector<SCH_SHEET*> topSheets2 = m_schematic->GetTopLevelSheets();
235 BOOST_REQUIRE( !topSheets2.empty() );
236
237 // This should not assert - this is the key test for the bug fix
238 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( mainFileName2, topSheets2[0], m_schematic.get() ) );
239
240 // Verify the file was created
241 BOOST_CHECK( wxFileExists( mainFileName2 ) );
242 }
243}
244
245
251BOOST_AUTO_TEST_CASE( TestLoadLegacyHierarchicalSchematic )
252{
253 // Load the legacy hierarchical schematic
254 wxFileName fn( KI_TEST::GetEeschemaTestDataDir() );
255 fn.AppendDir( "legacy_hierarchy" );
256 fn.SetName( "legacy_hierarchy" );
258 wxString mainFile = fn.GetFullPath();
259
260 BOOST_TEST_MESSAGE( "Loading schematic: " + mainFile.ToStdString() );
261 BOOST_REQUIRE( wxFileExists( mainFile ) );
262
264 SCH_SHEET* loadedSheet = nullptr;
265
266 // Load the schematic
267 BOOST_CHECK_NO_THROW( loadedSheet = io.LoadSchematicFile( mainFile, m_schematic.get() ) );
268 BOOST_REQUIRE( loadedSheet != nullptr );
269
270 BOOST_TEST_MESSAGE( "Loaded sheet UUID: " + loadedSheet->m_Uuid.AsString().ToStdString() );
271 BOOST_TEST_MESSAGE( "Loaded sheet name: " + loadedSheet->GetName().ToStdString() );
272
273 m_schematic->Reset();
274 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
275 m_schematic->AddTopLevelSheet( loadedSheet );
276 m_schematic->RemoveTopLevelSheet( defaultSheet );
277 delete defaultSheet;
278
279 // Build the hierarchy
280 m_schematic->RefreshHierarchy();
281 SCH_SHEET_LIST hierarchy = m_schematic->Hierarchy();
282
283 BOOST_TEST_MESSAGE( "Hierarchy size: " + std::to_string( hierarchy.size() ) );
284
285 // This schematic has 1 root + 2 sub-sheets = 3 total sheets
286 BOOST_REQUIRE_EQUAL( hierarchy.size(), 3 );
287
288 // Check each sheet path
289 for( size_t i = 0; i < hierarchy.size(); i++ )
290 {
291 const SCH_SHEET_PATH& path = hierarchy[i];
292 BOOST_TEST_MESSAGE( "\nSheet path [" + std::to_string(i) + "]: " + path.PathHumanReadable( false ).ToStdString() );
293 BOOST_TEST_MESSAGE( " Path KIID: " + path.Path().AsString().ToStdString() );
294 BOOST_TEST_MESSAGE( std::string(" Last screen: ") + (path.LastScreen() ? "YES" : "NO") );
295 BOOST_TEST_MESSAGE( " Path size: " + std::to_string( path.size() ) );
296
297 // Verify path has a screen
298 BOOST_CHECK( path.LastScreen() != nullptr );
299
300 if( path.LastScreen() )
301 {
302 // Count symbols on this sheet
303 int symbolCount = 0;
304 for( SCH_ITEM* item : path.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
305 {
306 symbolCount++;
307 }
308 BOOST_TEST_MESSAGE( " Symbol count: " + std::to_string( symbolCount ) );
309 }
310 }
311
312 // Check for missing instances (this should create them if needed)
313 BOOST_TEST_MESSAGE( "\nChecking for missing symbol instances..." );
314 hierarchy.CheckForMissingSymbolInstances( m_project->GetProjectName() );
315
316 // Now verify that symbols have proper instance data
317 std::map<wxString, int> referenceCount;
318 int totalInstances = 0;
319 int emptyPaths = 0;
320
321 for( const SCH_SHEET_PATH& path : hierarchy )
322 {
323 if( !path.LastScreen() )
324 continue;
325
326 BOOST_TEST_MESSAGE( "\nVerifying instances for path: " + path.PathHumanReadable( false ).ToStdString() );
327
328 for( SCH_ITEM* item : path.LastScreen()->Items().OfType( SCH_SYMBOL_T ) )
329 {
330 SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
331 SCH_SYMBOL_INSTANCE symbolInstance;
332
333 // Check if symbol has instance for this path
334 bool hasInstance = symbol->GetInstance( symbolInstance, path.Path() );
335
336 if( hasInstance )
337 {
338 totalInstances++;
339
340 // Check that path is not empty
341 if( symbolInstance.m_Path.empty() )
342 {
343 emptyPaths++;
344 BOOST_TEST_MESSAGE( " ERROR: Symbol " + symbol->m_Uuid.AsString().ToStdString() +
345 " has EMPTY instance path!" );
346 }
347 else
348 {
349 referenceCount[symbolInstance.m_Reference]++;
350 BOOST_TEST_MESSAGE( " Symbol " + symbol->m_Uuid.AsString().ToStdString() +
351 " -> " + symbolInstance.m_Reference.ToStdString() +
352 " (path: " + symbolInstance.m_Path.AsString().ToStdString() + ")" );
353 }
354 }
355 else
356 {
357 BOOST_TEST_MESSAGE( " WARNING: Symbol " + symbol->m_Uuid.AsString().ToStdString() +
358 " has NO instance for path " + path.Path().AsString().ToStdString() );
359 }
360 }
361 }
362
363 BOOST_TEST_MESSAGE( "\nSummary:" );
364 BOOST_TEST_MESSAGE( " Total instances: " + std::to_string( totalInstances ) );
365 BOOST_TEST_MESSAGE( " Empty paths: " + std::to_string( emptyPaths ) );
366 BOOST_TEST_MESSAGE( " Unique references: " + std::to_string( referenceCount.size() ) );
367
368 // CRITICAL: No symbol instance should have an empty path
369 BOOST_CHECK_EQUAL( emptyPaths, 0 );
370
371 // The schematic should have instances for all symbols
372 BOOST_CHECK( totalInstances > 0 );
373
374 // Print reference counts for debugging
375 BOOST_TEST_MESSAGE( "\nReference designator counts:" );
376 for( const auto& pair : referenceCount )
377 {
378 BOOST_TEST_MESSAGE( " " + pair.first.ToStdString() + ": " + std::to_string( pair.second ) );
379 }
380
381 // Try to save the schematic - this should NOT crash or assert
382 BOOST_TEST_MESSAGE( "\nAttempting to save schematic..." );
383 wxString saveFile = GetTempFileName( "legacy_hierarchy_resave" );
384 saveFile += "." + FILEEXT::KiCadSchematicFileExtension;
385 m_tempFiles.push_back( saveFile );
386
387 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
388 BOOST_REQUIRE( !topSheets.empty() );
389
390 // This is the critical test - saving should not assert on empty paths
391 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( saveFile, topSheets[0], m_schematic.get() ) );
392 BOOST_CHECK( wxFileExists( saveFile ) );
393
394 BOOST_TEST_MESSAGE( "Save successful!" );
395}
396
397
404BOOST_AUTO_TEST_CASE( TestEmbeddedFilesPersistedInHierarchy )
405{
406 m_schematic->CreateDefaultScreens();
407
408 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
409 BOOST_REQUIRE( !topSheets.empty() );
410
411 SCH_SHEET* topSheet = topSheets[0];
412 SCH_SCREEN* topScreen = topSheet->GetScreen();
413 BOOST_REQUIRE( topScreen );
414
415 SCH_SHEET* subSheet = new SCH_SHEET( m_schematic.get() );
416 SCH_SCREEN* subScreen = new SCH_SCREEN( m_schematic.get() );
417 subSheet->SetName( "SubSheet" );
418 subSheet->SetScreen( subScreen );
419 subSheet->SetFileName( "subsheet.kicad_sch" );
420 subScreen->SetFileName( "subsheet.kicad_sch" );
421 topScreen->Append( subSheet );
422
423 m_schematic->RefreshHierarchy();
424
425 // Drive the same code path Page Settings uses: write a real .kicad_wks and embed it via
426 // the file-based AddFile overload, which handles type detection, compression, and encoding.
427 wxString wksPath = GetTempFileName( "embed_wks" );
428 wksPath += ".kicad_wks";
429 m_tempFiles.push_back( wksPath );
430
431 {
432 wxFFile wksFile( wksPath, "wb" );
433 BOOST_REQUIRE( wksFile.IsOpened() );
434 const wxString wksBody = wxT( "(kicad_wks)" );
435 BOOST_REQUIRE( wksFile.Write( wksBody ) );
436 }
437
438 BOOST_REQUIRE( m_schematic->GetEmbeddedFiles()->AddFile( wxFileName( wksPath ), false )
439 != nullptr );
440 BOOST_REQUIRE( !m_schematic->GetEmbeddedFiles()->IsEmpty() );
441
442 wxString topFileName = GetTempFileName( "embed_main" );
443 topFileName += ".kicad_sch";
444 m_tempFiles.push_back( topFileName );
445
447 BOOST_CHECK_NO_THROW( io.SaveSchematicFile( topFileName, topSheet, m_schematic.get() ) );
448 BOOST_REQUIRE( wxFileExists( topFileName ) );
449
450 wxFFile readback( topFileName, "rb" );
451 wxString contents;
452 BOOST_REQUIRE( readback.IsOpened() && readback.ReadAll( &contents ) );
453
454 const wxString embeddedName = wxFileName( wksPath ).GetFullName();
455
456 BOOST_CHECK_MESSAGE( contents.Contains( "embedded_files" ),
457 "Top-level sheet file is missing (embedded_files) block" );
458 BOOST_CHECK_MESSAGE( contents.Contains( embeddedName ),
459 "Top-level sheet file is missing the embedded worksheet entry" );
460 BOOST_CHECK_MESSAGE( contents.Contains( "(type worksheet)" ),
461 "Top-level sheet file is missing (type worksheet) marker" );
462}
463
464
469BOOST_AUTO_TEST_CASE( TestLoadSheetFileWithTextVariable )
470{
471 m_schematic->CreateDefaultScreens();
472
473 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
474 BOOST_REQUIRE( !topSheets.empty() );
475
476 SCH_SCREEN* screen = topSheets[0]->GetScreen();
477 BOOST_REQUIRE( screen != nullptr );
478
479 m_project->GetTextVars()[wxT( "SUBSHEET_FILE" )] = wxT( "resolved_subsheet" );
480
481 SCH_SHEET* subSheet = new SCH_SHEET( m_schematic.get() );
482 SCH_SCREEN* subScreen = new SCH_SCREEN( m_schematic.get() );
483 subSheet->SetName( "SubSheet" );
484 subSheet->SetScreen( subScreen );
485 subSheet->SetFileName( "${SUBSHEET_FILE}.kicad_sch" );
486 screen->Append( subSheet );
487
488 // Save the sub-sheet at the resolved path next to the main file, where the loader looks.
489 wxString mainFileName = GetTempFileName( "tv_main" );
490 mainFileName += ".kicad_sch";
491 m_tempFiles.push_back( mainFileName );
492
493 wxFileName subOnDisk( mainFileName );
494 subOnDisk.SetFullName( "resolved_subsheet.kicad_sch" );
495 wxString subFileName = subOnDisk.GetFullPath();
496 m_tempFiles.push_back( subFileName );
497 subScreen->SetFileName( subFileName );
498
500 BOOST_REQUIRE_NO_THROW( io.SaveSchematicFile( mainFileName, topSheets[0], m_schematic.get() ) );
501 BOOST_REQUIRE_NO_THROW( io.SaveSchematicFile( subFileName, subSheet, m_schematic.get() ) );
502
503 m_schematic->Reset();
504 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
505 SCH_SHEET* loadedSheet = nullptr;
506 BOOST_REQUIRE_NO_THROW( loadedSheet = io.LoadSchematicFile( mainFileName, m_schematic.get() ) );
507 BOOST_REQUIRE( loadedSheet != nullptr );
508
509 m_schematic->AddTopLevelSheet( loadedSheet );
510 m_schematic->RemoveTopLevelSheet( defaultSheet );
511 delete defaultSheet;
512 m_schematic->RefreshHierarchy();
513
514 SCH_SHEET* loadedSub = nullptr;
515
516 for( SCH_ITEM* item : loadedSheet->GetScreen()->Items().OfType( SCH_SHEET_T ) )
517 loadedSub = static_cast<SCH_SHEET*>( item );
518
519 BOOST_REQUIRE( loadedSub != nullptr );
520
521 // Stored field keeps the raw variable for portability.
522 BOOST_CHECK_EQUAL( loadedSub->GetFileName(), wxString( "${SUBSHEET_FILE}.kicad_sch" ) );
523
524 // Screen must load from the resolved file, not the literal ${...} path.
525 BOOST_REQUIRE( loadedSub->GetScreen() != nullptr );
526 BOOST_CHECK_MESSAGE( !loadedSub->GetScreen()->GetFileName().Contains( "${" ),
527 "Sub-sheet screen filename still contains an unresolved text variable: "
528 + loadedSub->GetScreen()->GetFileName() );
529
530 wxFileName loadedScreenFn( loadedSub->GetScreen()->GetFileName() );
531 BOOST_CHECK_EQUAL( loadedScreenFn.GetFullName(), wxString( "resolved_subsheet.kicad_sch" ) );
532}
533
534
const KIID m_Uuid
Definition eda_item.h:531
EE_TYPE OfType(KICAD_T aType) const
Definition sch_rtree.h:221
wxString AsString() const
Definition kiid.cpp:393
wxString AsString() const
Definition kiid.cpp:242
Container for project specific data.
Definition project.h:62
A SCH_IO derivation for loading schematic files using the new s-expression file format.
void SaveSchematicFile(const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aSchematic to a storage file in a format that this SCH_IO implementation knows about,...
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:115
const wxString & GetFileName() const
Definition sch_screen.h:150
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void CheckForMissingSymbolInstances(const wxString &aProjectName)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
bool empty() const
Forwarded method from std::vector.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:44
void SetFileName(const wxString &aFilename)
Definition sch_sheet.h:376
wxString GetFileName() const
Return the filename corresponding to this sheet.
Definition sch_sheet.h:370
wxString GetName() const
Definition sch_sheet.h:136
void SetName(const wxString &aName)
Definition sch_sheet.h:137
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:139
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Schematic symbol object.
Definition sch_symbol.h:69
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
static const std::string KiCadSchematicFileExtension
KIID niluuid(0)
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
std::vector< wxString > m_tempFiles
wxString GetTempFileName(const wxString &aPrefix)
SETTINGS_MANAGER m_settingsManager
std::unique_ptr< SCHEMATIC > m_schematic
A simple container for schematic symbol instance information.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string path
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))
BOOST_AUTO_TEST_CASE(TestSaveLoadSimpleSchematic)
Test that we can save and reload a schematic with the virtual root pattern and that symbol instances ...
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_SHEET_T
Definition typeinfo.h:172