KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_schematic_root_input.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
21#include <qa_utils/file_utils.h>
22#include <eeschema_helpers.h>
23#include <locale_io.h>
24#include <project.h>
26#include <schematic.h>
27#include <sch_screen.h>
28#include <sch_sheet.h>
30#include <wx/ffile.h>
31#include <reporter.h>
32
33
34namespace
35{
36size_t replaceFileText( const wxString& aPath, const wxString& aOld, const wxString& aNew )
37{
38 wxString contents;
39
40 {
41 wxFFile input( aPath, "rb" );
42 BOOST_REQUIRE( input.IsOpened() && input.ReadAll( &contents ) );
43 }
44
45 const size_t count = contents.Replace( aOld, aNew );
46 wxFFile output( aPath, "wb" );
47 BOOST_REQUIRE( output.IsOpened() && output.Write( contents ) );
48 return count;
49}
50}
51
52
53BOOST_AUTO_TEST_CASE( HeadlessLoaderRequiresRootProvenanceOnlyWhenRequested )
54{
55 LOCALE_IO locale;
57 KI_TEST::SCOPED_TEMP_DIR directory( "sch-root-input" );
58 const wxString source = KI_TEST::GetEeschemaTestDataDir() + "issue23840/";
59
60 for( const wxString& filename : { wxString( "BusAndVectors.kicad_pro" ),
61 wxString( "BusAndVectors.kicad_sch" ), wxString( "LEDs.kicad_sch" ) } )
62 {
63 BOOST_REQUIRE( wxCopyFile( source + filename, directory.PathStr() + "/" + filename ) );
64 }
65
66 SETTINGS_MANAGER settings;
67 BOOST_REQUIRE( settings.LoadProject( directory.PathStr() + "/BusAndVectors.kicad_pro" ) );
68 const wxString rootFile = directory.PathStr() + "/BusAndVectors.kicad_sch";
69 const wxString childFile = directory.PathStr() + "/LEDs.kicad_sch";
70 std::unique_ptr<SCHEMATIC> root( EESCHEMA_HELPERS::LoadSchematic(
71 rootFile, false, false, &settings.Prj(), false, &reporter ) );
72 BOOST_REQUIRE( root );
73 BOOST_CHECK_EQUAL( root->Hierarchy().size(), 3 );
74 root.reset();
75
76 {
77 reporter.Clear();
78 std::unique_ptr<SCHEMATIC> child( EESCHEMA_HELPERS::LoadSchematic(
79 childFile, false, false, &settings.Prj(), false, &reporter ) );
80 BOOST_CHECK( !child );
81 BOOST_CHECK( reporter.GetMessages().Contains( "hierarchical subsheet" ) );
82 }
83
84 std::unique_ptr<SCHEMATIC> child( EESCHEMA_HELPERS::LoadSchematic(
85 childFile, false, false, &settings.Prj(), false ) );
86 BOOST_REQUIRE( child );
87 BOOST_CHECK_EQUAL( child->Hierarchy().size(), 1 );
88 const KIID childId = child->GetTopLevelSheet( 0 )->m_Uuid;
89 child.reset();
90
91 // Declaring a former child as a top-level sheet makes its new role explicit.
92 settings.Prj().GetProjectFile().GetTopLevelSheets() = {
93 TOP_LEVEL_SHEET_INFO( childId, wxS( "LEDs" ), wxS( "LEDs.kicad_sch" ) )
94 };
96 childFile, false, false, &settings.Prj(), false, &reporter ) );
97 BOOST_REQUIRE( child );
98 BOOST_CHECK_EQUAL( child->Hierarchy().size(), 1 );
99 child.reset();
100 settings.Prj().GetProjectFile().GetTopLevelSheets().clear();
101
102 // A shared file can retain parent placements while also being used as a root.
103 BOOST_REQUIRE_GT( replaceFileText( childFile,
104 wxS( "/4394464a-8613-4d36-8dd8-51c322850652/0ed71495-8674-4a6e-a1f9-3d74c1903959" ),
105 wxS( "/42beb834-d08e-4ccf-b2ec-2a6c2b0cfb9c" ) ), 0 );
106
108 childFile, false, false, &settings.Prj(), false, &reporter ) );
109 BOOST_REQUIRE( child );
110 BOOST_CHECK_EQUAL( child->Hierarchy().size(), 1 );
111}
112
113
114BOOST_AUTO_TEST_CASE( HeadlessLoaderReportsMalformedModernRootInstance )
115{
116 LOCALE_IO locale;
118 KI_TEST::SCOPED_TEMP_DIR directory( "sch-malformed-root" );
119 const wxString source = KI_TEST::GetEeschemaTestDataDir() + "issue23840/";
120
121 for( const wxString& filename : { wxString( "BusAndVectors.kicad_pro" ),
122 wxString( "BusAndVectors.kicad_sch" ), wxString( "LEDs.kicad_sch" ) } )
123 {
124 BOOST_REQUIRE( wxCopyFile( source + filename, directory.PathStr() + "/" + filename ) );
125 }
126
127 const wxString rootFile = directory.PathStr() + "/BusAndVectors.kicad_sch";
128 BOOST_REQUIRE_EQUAL( replaceFileText( rootFile,
129 wxS( "(path \"/\"" ), wxS( "(path \"/4394464a-8613-4d36-8dd8-51c322850652\"" ) ), 1 );
130
131 SETTINGS_MANAGER settings;
132 BOOST_REQUIRE( settings.LoadProject( directory.PathStr() + "/BusAndVectors.kicad_pro" ) );
133
134 {
135 reporter.Clear();
136 std::unique_ptr<SCHEMATIC> schematic( EESCHEMA_HELPERS::LoadSchematic(
137 rootFile, false, false, &settings.Prj(), false, &reporter ) );
138 BOOST_CHECK( !schematic );
139 BOOST_CHECK( reporter.GetMessages().Contains( "malformed root sheet instance path" ) );
140 }
141
142 std::unique_ptr<SCHEMATIC> schematic( EESCHEMA_HELPERS::LoadSchematic(
143 rootFile, false, false, &settings.Prj(), false ) );
144 BOOST_REQUIRE( schematic );
145 BOOST_CHECK_EQUAL( schematic->Hierarchy().size(), 3 );
146}
147
148
149BOOST_AUTO_TEST_CASE( HeadlessRootValidationPreservesFlatAndOlderNativeInputs )
150{
151 LOCALE_IO locale;
153 KI_TEST::SCOPED_TEMP_DIR directory( "sch-root-compatibility" );
154 const wxString source = KI_TEST::GetEeschemaTestDataDir();
155
156 for( const wxString& filename : { wxString( "SVG-Test.kicad_pro" ), wxString( "SVG-Test.kicad_sch" ),
157 wxString( "toplevel2.kicad_sch" ), wxString( "toplevel3.kicad_sch" ) } )
158 {
159 BOOST_REQUIRE( wxCopyFile( source + "issue25198/" + filename,
160 directory.PathStr() + "/" + filename ) );
161 }
162
163 SETTINGS_MANAGER settings;
164 BOOST_REQUIRE( settings.LoadProject( directory.PathStr() + "/SVG-Test.kicad_pro" ) );
165 std::unique_ptr<SCHEMATIC> flat( EESCHEMA_HELPERS::LoadSchematic(
166 directory.PathStr() + "/SVG-Test.kicad_sch", false, false, &settings.Prj(), false, &reporter ) );
167 BOOST_REQUIRE( flat );
168 BOOST_CHECK_EQUAL( flat->GetTopLevelSheets().size(), 3 );
169 BOOST_CHECK_EQUAL( flat->Hierarchy().size(), 3 );
170 flat.reset();
171
172 BOOST_REQUIRE_EQUAL( replaceFileText( directory.PathStr() + "/toplevel2.kicad_sch",
173 wxS( "(path \"/\"" ), wxS( "(path \"/4394464a-8613-4d36-8dd8-51c322850652\"" ) ), 1 );
174
175 {
176 reporter.Clear();
178 directory.PathStr() + "/SVG-Test.kicad_sch", false, false, &settings.Prj(), false, &reporter ) );
179 BOOST_CHECK( !flat );
180 BOOST_CHECK( reporter.GetMessages().Contains( "malformed root sheet instance path" ) );
181 }
182
183 const wxString oldFile = directory.PathStr() + "/NoConnectPinsConnectedByLine.kicad_sch";
184 BOOST_REQUIRE( wxCopyFile( source + "NoConnectPinsConnectedByLine.kicad_sch", oldFile ) );
185 std::unique_ptr<SCHEMATIC> old( EESCHEMA_HELPERS::LoadSchematic(
186 oldFile, false, false, &settings.Prj(), false, &reporter ) );
187 BOOST_REQUIRE( old );
188 BOOST_CHECK_LT( old->RootScreen()->GetFileFormatVersionAtLoad(), 20221110 );
189 BOOST_CHECK_EQUAL( old->Hierarchy().size(), 1 );
190}
static SCHEMATIC * LoadSchematic(const wxString &aFileName, bool aSetActive, bool aForceDefaultProject, PROJECT *aProject=nullptr, bool aCalculateConnectivity=true, REPORTER *aRootReporter=nullptr)
Definition kiid.h:46
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
std::vector< TOP_LEVEL_SHEET_INFO > & GetTopLevelSheets()
virtual PROJECT_FILE & GetProjectFile() const
Definition project.h:201
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
A wrapper for reporting to a wxString object.
Definition reporter.h:242
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
Information about a top-level schematic sheet.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
IbisParser parser & reporter
BOOST_AUTO_TEST_CASE(HeadlessLoaderRequiresRootProvenanceOnlyWhenRequested)
BOOST_CHECK_EQUAL(result, "25.4")