25#include <boost/test/unit_test.hpp>
38#include <wx/filename.h>
39#include <wx/stdpaths.h>
48 wxString tempDir = wxStandardPaths::Get().GetTempDir();
49 wxString projectPath = tempDir + wxFileName::GetPathSeparator() + wxT(
"test_project.kicad_pro");
53 m_schematic = std::make_unique<SCHEMATIC>(
nullptr );
63 if( wxFileExists( file ) )
72 wxString tempDir = wxStandardPaths::Get().GetTempDir();
73 wxString fileName = wxFileName::CreateTempFileName( tempDir + wxFileName::GetPathSeparator() + aPrefix );
95 m_schematic->CreateDefaultScreens();
98 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
101 SCH_SCREEN* screen = topSheets[0]->GetScreen();
106 topSheets[0]->SetName(
"Main Sheet" );
110 BOOST_CHECK( !currentSheet.
empty() );
111 if( !currentSheet.
empty() )
113 BOOST_CHECK( currentSheet.
Last() != &m_schematic->Root() );
118 wxString fileName = GetTempFileName(
"test_schematic" );
119 fileName +=
".kicad_sch";
120 m_tempFiles.push_back( fileName );
123 BOOST_CHECK_NO_THROW( io.
SaveSchematicFile( fileName, topSheets[0], m_schematic.get() ) );
126 BOOST_CHECK( wxFileExists( fileName ) );
129 m_schematic->Reset();
130 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
132 BOOST_CHECK_NO_THROW( loadedSheet = io.
LoadSchematicFile( fileName, m_schematic.get() ) );
133 BOOST_CHECK( loadedSheet !=
nullptr );
138 m_schematic->AddTopLevelSheet( loadedSheet );
139 m_schematic->RemoveTopLevelSheet( defaultSheet );
143 BOOST_CHECK( m_schematic->IsValid() );
147 BOOST_CHECK( !currentSheet2.
empty() );
148 if( !currentSheet2.
empty() )
150 BOOST_CHECK( currentSheet2.
Last() != &m_schematic->Root() );
155 wxString fileName2 = GetTempFileName(
"test_schematic_resave" );
156 fileName2 +=
".kicad_sch";
157 m_tempFiles.push_back( fileName2 );
159 std::vector<SCH_SHEET*> topSheets2 = m_schematic->GetTopLevelSheets();
164 BOOST_CHECK_NO_THROW( io.
SaveSchematicFile( fileName2, topSheets2[0], m_schematic.get() ) );
167 BOOST_CHECK( wxFileExists( fileName2 ) );
178 m_schematic->CreateDefaultScreens();
180 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
183 SCH_SCREEN* screen = topSheets[0]->GetScreen();
188 subSheet->
SetName(
"SubSheet" );
193 screen->
Append( subSheet );
196 wxString mainFileName = GetTempFileName(
"test_main" );
197 mainFileName +=
".kicad_sch";
198 m_tempFiles.push_back( mainFileName );
201 wxString subFileName = GetTempFileName(
"test_sub" );
202 subFileName +=
".kicad_sch";
203 m_tempFiles.push_back( subFileName );
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() ) );
210 m_schematic->Reset();
211 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
213 BOOST_CHECK_NO_THROW( loadedSheet = io.
LoadSchematicFile( mainFileName, m_schematic.get() ) );
214 BOOST_CHECK( loadedSheet !=
nullptr );
218 m_schematic->AddTopLevelSheet( loadedSheet );
219 m_schematic->RemoveTopLevelSheet( defaultSheet );
223 m_schematic->RefreshHierarchy();
230 wxString mainFileName2 = GetTempFileName(
"test_main_resave" );
231 mainFileName2 +=
".kicad_sch";
232 m_tempFiles.push_back( mainFileName2 );
234 std::vector<SCH_SHEET*> topSheets2 = m_schematic->GetTopLevelSheets();
238 BOOST_CHECK_NO_THROW( io.
SaveSchematicFile( mainFileName2, topSheets2[0], m_schematic.get() ) );
241 BOOST_CHECK( wxFileExists( mainFileName2 ) );
255 fn.AppendDir(
"legacy_hierarchy" );
256 fn.SetName(
"legacy_hierarchy" );
258 wxString mainFile = fn.GetFullPath();
267 BOOST_CHECK_NO_THROW( loadedSheet = io.
LoadSchematicFile( mainFile, m_schematic.get() ) );
273 m_schematic->Reset();
274 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
275 m_schematic->AddTopLevelSheet( loadedSheet );
276 m_schematic->RemoveTopLevelSheet( defaultSheet );
280 m_schematic->RefreshHierarchy();
286 BOOST_REQUIRE_EQUAL( hierarchy.size(), 3 );
289 for(
size_t i = 0; i < hierarchy.size(); i++ )
292 BOOST_TEST_MESSAGE(
"\nSheet path [" + std::to_string(i) +
"]: " +
path.PathHumanReadable(
false ).ToStdString() );
298 BOOST_CHECK(
path.LastScreen() !=
nullptr );
300 if(
path.LastScreen() )
317 std::map<wxString, int> referenceCount;
318 int totalInstances = 0;
323 if( !
path.LastScreen() )
341 if( symbolInstance.
m_Path.empty() )
345 " has EMPTY instance path!" );
351 " -> " + symbolInstance.
m_Reference.ToStdString() +
352 " (path: " + symbolInstance.
m_Path.
AsString().ToStdString() +
")" );
358 " has NO instance for path " +
path.Path().AsString().ToStdString() );
366 BOOST_TEST_MESSAGE(
" Unique references: " + std::to_string( referenceCount.size() ) );
372 BOOST_CHECK( totalInstances > 0 );
376 for(
const auto& pair : referenceCount )
378 BOOST_TEST_MESSAGE(
" " + pair.first.ToStdString() +
": " + std::to_string( pair.second ) );
383 wxString saveFile = GetTempFileName(
"legacy_hierarchy_resave" );
385 m_tempFiles.push_back( saveFile );
387 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
391 BOOST_CHECK_NO_THROW( io.
SaveSchematicFile( saveFile, topSheets[0], m_schematic.get() ) );
392 BOOST_CHECK( wxFileExists( saveFile ) );
406 m_schematic->CreateDefaultScreens();
408 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
417 subSheet->
SetName(
"SubSheet" );
421 topScreen->
Append( subSheet );
423 m_schematic->RefreshHierarchy();
427 wxString wksPath = GetTempFileName(
"embed_wks" );
428 wksPath +=
".kicad_wks";
429 m_tempFiles.push_back( wksPath );
432 wxFFile wksFile( wksPath,
"wb" );
434 const wxString wksBody = wxT(
"(kicad_wks)" );
438 BOOST_REQUIRE( m_schematic->GetEmbeddedFiles()->AddFile( wxFileName( wksPath ),
false )
440 BOOST_REQUIRE( !m_schematic->GetEmbeddedFiles()->IsEmpty() );
442 wxString topFileName = GetTempFileName(
"embed_main" );
443 topFileName +=
".kicad_sch";
444 m_tempFiles.push_back( topFileName );
447 BOOST_CHECK_NO_THROW( io.
SaveSchematicFile( topFileName, topSheet, m_schematic.get() ) );
450 wxFFile readback( topFileName,
"rb" );
452 BOOST_REQUIRE( readback.IsOpened() && readback.ReadAll( &contents ) );
454 const wxString embeddedName = wxFileName( wksPath ).GetFullName();
457 "Top-level sheet file is missing (embedded_files) block" );
459 "Top-level sheet file is missing the embedded worksheet entry" );
461 "Top-level sheet file is missing (type worksheet) marker" );
471 m_schematic->CreateDefaultScreens();
473 std::vector<SCH_SHEET*> topSheets = m_schematic->GetTopLevelSheets();
476 SCH_SCREEN* screen = topSheets[0]->GetScreen();
479 m_project->GetTextVars()[wxT(
"SUBSHEET_FILE" )] = wxT(
"resolved_subsheet" );
483 subSheet->
SetName(
"SubSheet" );
485 subSheet->
SetFileName(
"${SUBSHEET_FILE}.kicad_sch" );
486 screen->
Append( subSheet );
489 wxString mainFileName = GetTempFileName(
"tv_main" );
490 mainFileName +=
".kicad_sch";
491 m_tempFiles.push_back( mainFileName );
493 wxFileName subOnDisk( mainFileName );
494 subOnDisk.SetFullName(
"resolved_subsheet.kicad_sch" );
495 wxString subFileName = subOnDisk.GetFullPath();
496 m_tempFiles.push_back( subFileName );
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() ) );
503 m_schematic->Reset();
504 SCH_SHEET* defaultSheet = m_schematic->GetTopLevelSheet( 0 );
506 BOOST_REQUIRE_NO_THROW( loadedSheet = io.
LoadSchematicFile( mainFileName, m_schematic.get() ) );
509 m_schematic->AddTopLevelSheet( loadedSheet );
510 m_schematic->RemoveTopLevelSheet( defaultSheet );
512 m_schematic->RefreshHierarchy();
517 loadedSub =
static_cast<SCH_SHEET*
>( item );
527 "Sub-sheet screen filename still contains an unresolved text variable: "
531 BOOST_CHECK_EQUAL( loadedScreenFn.GetFullName(), wxString(
"resolved_subsheet.kicad_sch" ) );
EE_TYPE OfType(KICAD_T aType) const
wxString AsString() const
wxString AsString() const
Container for project specific data.
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,...
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
EE_RTREE & Items()
Get the full RTree, usually for iterating.
const wxString & GetFileName() const
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.
void SetFileName(const wxString &aFilename)
wxString GetFileName() const
Return the filename corresponding to this sheet.
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
static const std::string KiCadSchematicFileExtension
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()
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")