29#include <pegtl/contrib/analyze.hpp>
46 BOOST_REQUIRE( tao::pegtl::analyze< LIBRARY_TABLE_GRAMMAR::LIB_TABLE_FILE >( 1 ) == 0 );
53 tl::expected<LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR>
result = parser.
ParseBuffer(
"" );
60 std::vector<std::string> cases = {
66 p.append(
"libraries/" );
70 for(
const std::string&
path : cases )
87 wxString expected_error;
89 bool check_formatted =
true;
92 std::vector<TESTCASE> cases = {
93 { .filename =
"sym-lib-table", .expected_rows = 224 },
94 { .filename =
"fp-lib-table", .expected_rows = 146 },
95 { .filename =
"nested-symbols", .expected_rows = 6 },
96 { .filename =
"nested-disabled", .expected_rows = 4 },
97 { .filename =
"nested-hidden", .expected_rows = 4 },
98 { .filename =
"cycle", .expected_rows = 2 },
99 { .filename =
"sym-hand-edited", .expected_rows = 2, .check_formatted =
false },
100 { .filename =
"corrupted", .expected_error =
"Syntax error at line 6, column 9" },
101 { .filename =
"truncated", .expected_error =
"Syntax error at line 11, column 1" }
105 fn.AppendDir(
"libraries" );
107 for(
const auto& [filename, expected_error, expected_rows, check_formatted] : cases )
111 fn.SetName( filename );
116 BOOST_REQUIRE_MESSAGE(
table.Rows().size() == expected_rows,
117 wxString::Format(
"Expected %zu rows but got %zu",
118 expected_rows,
table.Rows().size() ) );
120 BOOST_REQUIRE_MESSAGE(
table.ErrorDescription() == expected_error,
121 wxString::Format(
"Expected error '%s' but got '%s'",
122 expected_error,
table.ErrorDescription() ) );
125 if( !
table.IsOk() || !check_formatted )
129 inFp.open( fn.GetFullPath().fn_str() );
132 std::stringstream inBuf;
133 inBuf << inFp.rdbuf();
134 std::string inData = inBuf.str();
137 table.Format( &formatter );
139 KICAD_FORMAT::FORMAT_MODE::LIBRARY_TABLE );
141 if( formatter.
GetString().compare( inData ) != 0 )
193 fn.AppendDir(
"libraries" );
196 fn.SetName(
"nested-disabled" );
199 BOOST_REQUIRE_MESSAGE( disabledTable.
Rows().size() == 4,
200 wxString::Format(
"Expected 4 rows but got %zu",
201 disabledTable.
Rows().size() ) );
204 bool foundDisabledRow =
false;
210 BOOST_REQUIRE_MESSAGE( row.Disabled(),
211 "Nested table row should have disabled flag set" );
212 foundDisabledRow =
true;
216 BOOST_REQUIRE_MESSAGE( foundDisabledRow,
217 "Disabled nested table row not found in parsed table" );
220 fn.SetName(
"nested-hidden" );
223 BOOST_REQUIRE_MESSAGE( hiddenTable.
Rows().size() == 4,
224 wxString::Format(
"Expected 4 rows but got %zu",
225 hiddenTable.
Rows().size() ) );
227 bool foundHiddenRow =
false;
233 BOOST_REQUIRE_MESSAGE( row.Hidden(),
234 "Nested table row should have hidden flag set" );
235 foundHiddenRow =
true;
239 BOOST_REQUIRE_MESSAGE( foundHiddenRow,
240 "Hidden nested table row not found in parsed table" );
259 std::vector<const LIBRARY_TABLE_ROW*> seededPointers;
260 std::vector<wxString> seededUris;
262 for(
int i = 0; i < 4; ++i )
265 row.
SetNickname( wxString::Format( wxS(
"seed_%d" ), i ) );
266 row.
SetURI( wxString::Format( wxS(
"${KIPRJMOD}/libs/seed_%d.kicad_sym" ), i ) );
269 seededPointers.push_back( &row );
270 seededUris.push_back( row.
URI() );
276 for(
int i = 0; i < 64; ++i )
279 row.
SetNickname( wxString::Format( wxS(
"extra_%d" ), i ) );
280 row.
SetURI( wxString::Format( wxS(
"${KIPRJMOD}/libs/extra_%d.kicad_sym" ), i ) );
283 for(
size_t j = 0; j < seededPointers.size(); ++j )
285 BOOST_REQUIRE_MESSAGE(
286 seededPointers[j]->URI() == seededUris[j],
288 wxS(
"Seed row %zu pointer was invalidated after inserting %d rows: "
289 "expected URI '%s', got '%s'" ),
290 j, i + 1, seededUris[j], seededPointers[j]->URI() ) );
314 bool expectedPcmManaged;
315 wxString description;
318 std::vector<CASE> cases = {
319 { wxS(
"${KICAD10_3RD_PARTY}/symbols/foo/foo.kicad_sym" ),
true,
320 wxS(
"Versioned 3RD_PARTY template should be recognised as PCM-managed" ) },
321 { wxS(
"${KICAD9_3RD_PARTY}/symbols/legacy/legacy.kicad_sym" ),
true,
322 wxS(
"Legacy versioned 3RD_PARTY template should still match the wildcard" ) },
323 { wxS(
"${KICAD10_3RD_PARTY}/footprints/bar/bar.pretty" ),
true,
324 wxS(
"Footprint library using 3RD_PARTY template should match" ) },
325 { wxS(
"${KICAD_USER_LIB}/symbols/test.kicad_sym" ),
false,
326 wxS(
"Row using a different env var must not be flagged as PCM-managed" ) },
327 { wxS(
"${KIPRJMOD}/libs/local.kicad_sym" ),
false,
328 wxS(
"Project-relative row must not be flagged as PCM-managed" ) },
329 { wxS(
"/abs/path/to/lib.kicad_sym" ),
false,
330 wxS(
"Absolute path row must not be flagged as PCM-managed" ) },
331 { wxS(
"${}" ),
false,
332 wxS(
"Malformed empty var name must not match" ) },
333 { wxS(
"${KICAD10_3RD_PARTY_EXTRA}/foo" ),
false,
334 wxS(
"Similar-but-different var name must not match" ) },
337 for(
const CASE& c : cases )
345 actual == c.expectedPcmManaged,
346 wxString::Format( wxS(
"%s: URI='%s' expected=%d actual=%d" ),
347 c.description, c.uri, c.expectedPcmManaged ? 1 : 0,
357 fn.AppendDir(
"libraries" );
358 fn.SetName(
"sym-lib-table" );
360 wxFileName tmpFn = wxFileName::CreateTempFileName(
"kicad_test_ro_" );
361 wxCopyFile( fn.GetFullPath(), tmpFn.GetFullPath() );
371 tmpFn.SetPermissions( wxS_IRUSR | wxS_IRGRP | wxS_IROTH );
377 if( wxFileName( tmpFn.GetFullPath() ).IsFileWritable() )
380 "read-only permissions (running as root?)" );
394 tmpFn.SetPermissions( wxS_IRUSR | wxS_IWUSR );
395 wxRemoveFile( tmpFn.GetFullPath() );
405 wxString tablePath = wxT(
"/some/read-only/path/sym-lib-table" );
406 wxString nickname1 = wxT(
"LibA" );
407 wxString nickname2 = wxT(
"LibB" );
457 const bool hadEntry = vars.count( templateVar ) > 0;
475 vars[templateVar] = savedEntry;
477 vars.erase( templateVar );
KiCad uses environment variables internally for determining the base paths for libraries,...
void SetDefinedExternally(bool aIsDefinedExternally=true)
std::map< wxString, std::map< wxString, LIB_OVERRIDE > > m_LibOverrides
Overrides for libraries in read-only nested tables.
static wxString StockTableTokenizedURI(LIBRARY_TABLE_TYPE aType)
void ClearLibOverride(const wxString &aTablePath, const wxString &aNickname)
Removes any override for a library that no longer needs one.
std::optional< LIBRARY_TABLE * > Table(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope)
Retrieves a given table; creating a new empty project table if a valid project is loaded and the give...
void SetLibOverride(const wxString &aTablePath, const wxString &aNickname, bool aDisabled, bool aHidden)
Set a user override for a library in a read-only nested table.
static bool IsPcmManagedRow(const LIBRARY_TABLE_ROW &aRow)
Return true if a library table row was added by the Plugin and Content Manager.
std::vector< LIBRARY_TABLE_ROW * > Rows(LIBRARY_TABLE_TYPE aType, LIBRARY_TABLE_SCOPE aScope=LIBRARY_TABLE_SCOPE::BOTH, bool aIncludeInvalid=false) const
Returns a flattened list of libraries of the given type.
void LoadGlobalTables(std::initializer_list< LIBRARY_TABLE_TYPE > aTablesToLoad={})
(Re)loads the global library tables in the given list, or all tables if no list is given
static wxString StockTableReferenceURI(LIBRARY_TABLE_TYPE aType)
static wxString StockTablePath(LIBRARY_TABLE_TYPE aType)
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > ParseBuffer(const std::string &aBuffer)
tl::expected< LIBRARY_TABLE_IR, LIBRARY_PARSE_ERROR > Parse(const std::filesystem::path &aPath)
void SetNickname(const wxString &aNickname)
void SetType(const wxString &aType)
static const wxString TABLE_TYPE_NAME
void SetURI(const wxString &aUri)
const wxString & URI() const
LIBRARY_RESULT< void > Save()
bool IsReadOnly() const
Returns true if the underlying file exists but is not writable.
const std::deque< LIBRARY_TABLE_ROW > & Rows() const
virtual COMMON_SETTINGS * GetCommonSettings() const
virtual SETTINGS_MANAGER & GetSettingsManager() const
T * GetAppSettings(const char *aFilename)
Return a handle to the a given settings by type.
Functions related to environment variables, including help functions.
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
tl::expected< ResultType, LIBRARY_ERROR > LIBRARY_RESULT
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
std::string GetTestDataRootDir()
PGM_BASE & Pgm()
The global program "get" accessor.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(Grammar)
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))
std::vector< std::vector< std::string > > table
BOOST_TEST_CONTEXT("Test Clearance")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")