KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_symbol_library_adapter.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 modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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
24
25#include <wx/textfile.h>
26
27#include <filesystem>
28
29
30namespace
31{
32
38class TEST_SYMBOL_LIBRARY_ADAPTER : public SYMBOL_LIBRARY_ADAPTER
39{
40public:
42
43 void SeedLoadError( const wxString& aNickname )
44 {
45 m_libraries[aNickname].status.load_status = LOAD_STATUS::LOAD_ERROR;
46 }
47
50 void SeedLoadError( const wxString& aNickname, const wxString& aMessage )
51 {
52 m_libraries[aNickname].status.load_status = LOAD_STATUS::LOAD_ERROR;
53 m_libraries[aNickname].status.error = LIBRARY_ERROR( aMessage );
54 }
55
57 void SeedLoaded( const wxString& aNickname )
58 {
59 m_libraries[aNickname].status.load_status = LOAD_STATUS::LOADED;
60 }
61};
62
63
65class SCOPED_SYM_LIB_TABLE
66{
67public:
68 SCOPED_SYM_LIB_TABLE( const std::vector<wxString>& aNicknamesInTableOrder )
69 {
70 std::error_code ec;
71 m_dir = std::filesystem::temp_directory_path( ec )
72 / std::filesystem::path( wxString::Format( wxS( "kicad_qa_symlibtbl_%p" ), (void*) this )
73 .ToStdString() );
74 std::filesystem::create_directories( m_dir, ec );
75
76 wxTextFile file( wxString( ( m_dir / "sym-lib-table" ).string() ) );
77 file.Create();
78 file.AddLine( wxS( "(sym_lib_table" ) );
79 file.AddLine( wxS( " (version 7)" ) );
80
81 for( const wxString& nickname : aNicknamesInTableOrder )
82 {
83 file.AddLine( wxString::Format(
84 wxS( " (lib (name \"%s\")(type \"KiCad\")(uri \"${KIPRJMOD}/%s.kicad_sym\")(options \"\")(descr \"\"))" ),
85 nickname, nickname ) );
86 }
87
88 file.AddLine( wxS( ")" ) );
89 file.Write();
90 file.Close();
91 }
92
93 ~SCOPED_SYM_LIB_TABLE()
94 {
95 std::error_code ec;
96 std::filesystem::remove_all( m_dir, ec );
97 }
98
99 wxString Path() const { return wxString( m_dir.string() ); }
100
101private:
102 std::filesystem::path m_dir;
103};
104
105} // namespace
106
107
108BOOST_AUTO_TEST_SUITE( SymbolLibraryAdapter )
109
110
111
119BOOST_AUTO_TEST_CASE( IsSymbolLibWritableHandlesFailedLoad )
120{
121 LIBRARY_MANAGER manager;
122 TEST_SYMBOL_LIBRARY_ADAPTER adapter( manager );
123
124 adapter.SeedLoadError( wxS( "BadLib" ) );
125
126 BOOST_CHECK_EQUAL( adapter.IsSymbolLibWritable( wxS( "BadLib" ) ), false );
127
128 // A library that was never even attempted must also be safe.
129 BOOST_CHECK_EQUAL( adapter.IsSymbolLibWritable( wxS( "NeverSeen" ) ), false );
130}
131
132
141BOOST_AUTO_TEST_CASE( GetLibraryNamesSortedRegardlessOfTableOrder )
142{
143 const std::vector<wxString> tableOrder = { wxS( "Zebra" ), wxS( "amplifier" ), wxS( "Device" ),
144 wxS( "Board_2" ), wxS( "Board_10" ) };
145
146 SCOPED_SYM_LIB_TABLE tableFile( tableOrder );
147
148 LIBRARY_MANAGER manager;
149 manager.LoadProjectTables( tableFile.Path(), { LIBRARY_TABLE_TYPE::SYMBOL } );
150
151 TEST_SYMBOL_LIBRARY_ADAPTER adapter( manager );
152
153 for( const wxString& nickname : tableOrder )
154 adapter.SeedLoaded( nickname );
155
156 const std::vector<wxString> names = adapter.GetLibraryNames();
157
158 const std::vector<wxString> expected = { wxS( "amplifier" ), wxS( "Board_2" ), wxS( "Board_10" ),
159 wxS( "Device" ), wxS( "Zebra" ) };
160
161 BOOST_CHECK_EQUAL_COLLECTIONS( names.begin(), names.end(), expected.begin(), expected.end() );
162}
163
164
176BOOST_AUTO_TEST_CASE( PartiallyLoadedTableReportsNoSpuriousErrors )
177{
178 const std::vector<wxString> tableOrder = { wxS( "Device" ), wxS( "Connector" ), wxS( "Amplifier" ),
179 wxS( "Regulator" ), wxS( "BadLib" ) };
180
181 SCOPED_SYM_LIB_TABLE tableFile( tableOrder );
182
183 LIBRARY_MANAGER manager;
184 manager.LoadProjectTables( tableFile.Path(), { LIBRARY_TABLE_TYPE::SYMBOL } );
185
186 TEST_SYMBOL_LIBRARY_ADAPTER adapter( manager );
187
188 // Simulate a preload caught mid-flight: two libraries resolved, one genuinely failed,
189 // and the remaining table rows have no entry yet because loading has not reached them.
190 adapter.SeedLoaded( wxS( "Device" ) );
191 adapter.SeedLoaded( wxS( "Connector" ) );
192 adapter.SeedLoadError( wxS( "BadLib" ), wxS( "File is corrupt" ) );
193
194 const wxString errors = adapter.GetLibraryLoadErrors();
195
196 // The unloaded-but-present rows must not masquerade as missing-from-table errors.
197 BOOST_CHECK( !errors.Contains( wxS( "not found in library table" ) ) );
198 BOOST_CHECK( !errors.Contains( wxS( "Amplifier" ) ) );
199 BOOST_CHECK( !errors.Contains( wxS( "Regulator" ) ) );
200
201 // The genuine failure must still be reported.
202 BOOST_CHECK( errors.Contains( wxS( "BadLib" ) ) );
203 BOOST_CHECK( errors.Contains( wxS( "File is corrupt" ) ) );
204}
205
206
void LoadProjectTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the project library tables in the given list, or all tables if no list is given
An interface to the global shared library manager that is schematic-specific and linked to one projec...
SYMBOL_LIBRARY_ADAPTER(LIBRARY_MANAGER &aManager)
static std::string ToStdString(const wxString &aStr)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_AUTO_TEST_CASE(IsSymbolLibWritableHandlesFailedLoad)
Regression test for a null-plugin dereference crash.
BOOST_CHECK_EQUAL(result, "25.4")