37#include <wx/filename.h>
39#include <wx/stdpaths.h>
56 if( wxFileExists( file ) )
63 wxString tempDir = wxStandardPaths::Get().GetTempDir();
64 wxString fileName = tempDir + wxFileName::GetPathSeparator()
65 + wxString::Format(
"test_lib_%d.kicad_sym", rand() );
76 std::ofstream file( aPath.ToStdString() );
78 file <<
"(kicad_symbol_lib (version 20231120) (generator \"kicad_symbol_editor\")\n";
79 file <<
" (generator_version \"8.0\")\n";
81 for(
int i = 1; i <= aSymbolCount; i++ )
83 file <<
" (symbol \"Symbol_" << i <<
"\"\n";
84 file <<
" (exclude_from_sim no) (in_bom yes) (on_board yes)\n";
85 file <<
" (duplicate_pin_numbers_are_jumpers no)\n";
86 file <<
" (property \"Reference\" \"U\" (at 0 0 0)\n";
87 file <<
" (effects (font (size 1.27 1.27)))\n";
89 file <<
" (property \"Value\" \"Symbol_" << i <<
"\" (at 0 2.54 0)\n";
90 file <<
" (effects (font (size 1.27 1.27)))\n";
92 file <<
" (property \"Footprint\" \"\" (at 0 0 0)\n";
93 file <<
" (effects (font (size 1.27 1.27)) hide)\n";
95 file <<
" (property \"Datasheet\" \"\" (at 0 0 0)\n";
96 file <<
" (effects (font (size 1.27 1.27)) hide)\n";
98 file <<
" (property \"Description\" \"Test symbol " << i <<
"\" (at 0 0 0)\n";
99 file <<
" (effects (font (size 1.27 1.27)) hide)\n";
101 file <<
" (symbol \"Symbol_" << i <<
"_1_1\"\n";
102 file <<
" (rectangle (start -2.54 2.54) (end 2.54 -2.54)\n";
103 file <<
" (stroke (width 0.254) (type default))\n";
104 file <<
" (fill (type background))\n";
122 std::ifstream inFile( aPath.ToStdString() );
123 std::string content( ( std::istreambuf_iterator<char>( inFile ) ),
124 std::istreambuf_iterator<char>() );
128 std::string searchFor =
"Symbol_" + std::to_string( aSymbolNumber ) +
"_1_1";
129 size_t pos = content.find( searchFor );
131 if( pos != std::string::npos )
135 pos = content.find(
" (symbol \"Symbol_" + std::to_string( aSymbolNumber + 1 ), pos );
137 if( pos != std::string::npos )
140 content.insert( pos + 10,
"CORRUPT_DATA_HERE{{{invalid}}}syntax###" );
145 std::ofstream outFile( aPath.ToStdString() );
163 wxString libPath = GetTempLibraryPath();
164 const int symbolCount = 5;
167 CreateValidLibrary( libPath, symbolCount );
172 BOOST_CHECK_NO_THROW( cache.
Load() );
178 for(
int i = 1; i <= symbolCount; i++ )
180 wxString symbolName = wxString::Format(
"Symbol_%d", i );
181 BOOST_CHECK_MESSAGE( symbols.find( symbolName ) != symbols.end(),
182 "Symbol " << symbolName <<
" should be present" );
193 wxString libPath = GetTempLibraryPath();
194 const int symbolCount = 5;
195 const int corruptSymbol = 3;
198 CreateValidLibrary( libPath, symbolCount );
201 CorruptLibraryAfterSymbol( libPath, corruptSymbol - 1 );
214 for(
int i = 1; i < corruptSymbol; i++ )
216 wxString symbolName = wxString::Format(
"Symbol_%d", i );
217 BOOST_CHECK_MESSAGE( symbols.find( symbolName ) != symbols.end(),
218 "Symbol " << symbolName <<
" should be present (before corrupt symbol)" );
223 wxString symbolName = wxString::Format(
"Symbol_%d", corruptSymbol );
224 BOOST_CHECK_MESSAGE( symbols.find( symbolName ) == symbols.end(),
225 "Symbol " << symbolName <<
" should NOT be present (corrupt symbol)" );
229 for(
int i = corruptSymbol + 1; i <= symbolCount; i++ )
231 wxString symbolName = wxString::Format(
"Symbol_%d", i );
232 BOOST_CHECK_MESSAGE( symbols.find( symbolName ) != symbols.end(),
233 "Symbol " << symbolName <<
" should be present (after corrupt symbol, recovered)" );
248 wxString libPath = GetTempLibraryPath();
249 wxString backupPath = libPath +
".backup";
250 m_tempFiles.push_back( backupPath );
252 const int symbolCount = 5;
253 const int corruptSymbol = 3;
256 CreateValidLibrary( libPath, symbolCount );
259 wxCopyFile( libPath, backupPath );
262 CorruptLibraryAfterSymbol( libPath, corruptSymbol - 1 );
270 BOOST_FAIL(
"Load should have thrown an exception due to parse error" );
283 "HasParseError() should return true after a parse error" );
304 wxString libPath = GetTempLibraryPath();
305 const int symbolCount = 5;
306 const int corruptAfter = 2;
309 CreateValidLibrary( libPath, symbolCount );
310 CorruptLibraryAfterSymbol( libPath, corruptAfter );
328 "HasParseError() should return true after parse error during load" );
331 wxString validLibPath = GetTempLibraryPath();
332 CreateValidLibrary( validLibPath, symbolCount );
339 BOOST_CHECK_NO_THROW( validCache.
Load() );
343 "HasParseError() should return false after successful load" );
347 BOOST_CHECK_NO_THROW( validCache.
Save() );
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A cache assistant for the KiCad s-expression symbol libraries.
void Save(const std::optional< bool > &aOpt=std::nullopt) override
Save the entire library to file m_libFileName;.
bool HasParseError() const
const LIB_SYMBOL_MAP & GetSymbolMap() const
void SetModified(bool aModified=true)
void CreateValidLibrary(const wxString &aPath, int aSymbolCount)
Create a valid symbol library file with the specified number of symbols.
SYMBOL_LIBRARY_PARSE_ERROR_FIXTURE()
~SYMBOL_LIBRARY_PARSE_ERROR_FIXTURE()
void CorruptLibraryAfterSymbol(const wxString &aPath, int aSymbolNumber)
Corrupt the library file by introducing a parse error after the specified symbol.
std::vector< wxString > m_tempFiles
wxString GetTempLibraryPath()
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(ValidLibraryLoadsCompletely)
Test that a valid library can be created, loaded, and all symbols are present.
BOOST_CHECK_EQUAL(result, "25.4")