21#define BOOST_TEST_NO_MAIN
22#include <boost/test/unit_test.hpp>
31#include <wx/filename.h>
40 std::function<bool( wxString* )>
resolver = []( wxString* token ) ->
bool
42 if( *token == wxT(
"VAR" ) )
44 *token = wxT(
"value" );
47 else if( *token == wxT(
"X" ) )
52 else if( *token == wxT(
"Y" ) )
68 BOOST_CHECK(
result == wxT(
"value" ) );
75 BOOST_CHECK(
result == wxT(
"5+2" ) );
83 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
91 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
92 BOOST_CHECK(
result.Contains( wxT(
"value" ) ) );
100 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
101 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
114 "Expected escape marker in result" );
118 "Expected '+2' (from ${Y} expansion) in result" );
121 BOOST_CHECK(
result == wxT(
"@{<<<ESC_DOLLAR:X}+2}" ) );
133 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
143 "Expected '+2' (from ${Y} expansion) in: " +
result );
149 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
164 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
165 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_AT:" ) ) );
177 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
211 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
212 "kicad_qa_overlap_env_vars";
214 std::filesystem::remove_all( tmp, ec );
215 std::filesystem::create_directories( tmp /
"V10" /
"symbols", ec );
217 rootDir = wxString::FromUTF8( tmp.string() );
219 innerDir = wxString::FromUTF8( ( tmp /
"V10" ).
string() );
220 targetDir = wxString::FromUTF8( ( tmp /
"V10" /
"symbols" ).
string() );
222 wxSetEnv( wxS(
"KICAD_QA_3RD_PARTY_OUTER" ),
outerDir );
223 wxSetEnv( wxS(
"KICAD_QA_USER_LIB_INNER" ),
innerDir );
228 wxUnsetEnv( wxS(
"KICAD_QA_3RD_PARTY_OUTER" ) );
229 wxUnsetEnv( wxS(
"KICAD_QA_USER_LIB_INNER" ) );
231 std::filesystem::path tmp = std::filesystem::temp_directory_path() /
232 "kicad_qa_overlap_env_vars";
234 std::filesystem::remove_all( tmp, ec );
252 wxFileName target( targetDir, wxS(
"test.kicad_sym" ) );
255 wxString normalized =
NormalizePath( target, &envMap, wxEmptyString );
259 normalized == wxS(
"${KICAD_QA_USER_LIB_INNER}/symbols/test.kicad_sym" ),
260 wxString::Format( wxS(
"Expected '%s' but got '%s'" ),
261 wxS(
"${KICAD_QA_USER_LIB_INNER}/symbols/test.kicad_sym" ),
268 wxFileName target( targetDir, wxS(
"test.kicad_sym" ) );
271 wxString normalized =
NormalizePath( target, &envMap, wxEmptyString );
274 wxFileName expandedFn( expanded );
275 expandedFn.Normalize( wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE );
277 wxFileName originalFn( target );
278 originalFn.Normalize( wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE );
281 expandedFn.GetFullPath() == originalFn.GetFullPath(),
283 wxS(
"Round-trip mismatch: normalized='%s' expanded='%s' original='%s'" ),
284 normalized, expandedFn.GetFullPath(), originalFn.GetFullPath() ) );
307 std::function<bool( wxString* )>
resolver = []( wxString* token ) ->
bool
309 if( *token == wxT(
"#" ) )
315 if( *token == wxT(
"ROW" ) )
324 const std::vector<wxString> inputs = {
325 wxT(
"Out@{(${#}-2)*8+0}" ),
326 wxT(
"Net_@{${ROW}*2+1}" ),
327 wxT(
"@{(2-2)*8+0}" ),
328 wxT(
"${ROW}:@{${ROW}*${ROW}}" ),
329 wxT(
"plain_label_no_expr" ),
330 wxT(
"@{1+1}_@{2+2}_@{3+3}" ),
333 const unsigned int numThreads = std::max( 4u, std::thread::hardware_concurrency() );
334 const int iterations = 2000;
336 std::atomic<bool> failed{
false };
337 std::atomic<int> totalRuns{ 0 };
338 std::vector<std::thread> threads;
339 threads.reserve( numThreads );
341 for(
unsigned int t = 0; t < numThreads; ++t )
343 threads.emplace_back(
348 for(
int i = 0; i < iterations; ++i )
350 const wxString& src = inputs[( t + i ) % inputs.size()];
354 totalRuns.fetch_add( 1, std::memory_order_relaxed );
359 failed.store(
true, std::memory_order_relaxed );
364 for(
auto& th : threads )
367 BOOST_CHECK( !failed.load() );
368 BOOST_CHECK_EQUAL( totalRuns.load(),
static_cast<int>( numThreads ) * iterations );
KiCad uses environment variables internally for determining the base paths for libraries,...
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject)
Replace any environment variable & text variable references with their values.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
wxString NormalizePath(const wxFileName &aFilePath, const ENV_VAR_MAP *aEnvVars, const wxString &aProjectPath)
Normalize a file path to an environmental variable, if possible.
Helper functions to substitute paths with environmental variables.
static FILENAME_RESOLVER * resolver
std::map< wxString, ENV_VAR_ITEM > ENV_VAR_MAP
Test fixture for ExpandTextVars tests.
std::function< bool(wxString *)> resolver
Regression tests for overlapping-prefix environment variables.
OverlappingEnvVarsFixture()
ENV_VAR_MAP BuildEnvMap() const
~OverlappingEnvVarsFixture()
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(SimpleVariable)
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")