21#define BOOST_TEST_NO_MAIN
22#include <boost/test/unit_test.hpp>
31#include <wx/filename.h>
50 []( wxString* token ) ->
bool
52 if( *token == wxT(
"VAR" ) )
54 *token = wxT(
"value" );
57 else if( *token == wxT(
"X" ) )
62 else if( *token == wxT(
"Y" ) )
76 for(
const wxString& prefix : { wxString(
"ERC_WARNING" ), wxString(
"ERC_ERROR" ),
77 wxString(
"DRC_WARNING" ), wxString(
"DRC_ERROR" ) } )
79 const wxString assertion =
"${" + prefix +
" Check this item}";
91 BOOST_CHECK(
result == wxT(
"value" ) );
98 BOOST_CHECK(
result == wxT(
"5+2" ) );
106 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
114 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
115 BOOST_CHECK(
result.Contains( wxT(
"value" ) ) );
123 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
124 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
136 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
137 "Expected escape marker in result" );
140 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"+2" ) ),
141 "Expected '+2' (from ${Y} expansion) in result" );
144 BOOST_CHECK(
result == wxT(
"@{<<<ESC_DOLLAR:X}+2}" ) );
156 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
165 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"+2" ) ),
166 "Expected '+2' (from ${Y} expansion) in: " +
result );
172 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
187 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
188 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_AT:" ) ) );
200 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
218 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
227 BOOST_CHECK(
result == wxT(
"subdir/value_file.txt" ) );
245 BOOST_CHECK_MESSAGE( !
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
246 "Variable after backslash separator should expand, not escape. Got: " +
result );
247 BOOST_CHECK(
result == wxT(
"Output\\BoM/value_file.csv" ) );
256 BOOST_CHECK(
result == wxT(
"Output\\BoM/5_V2.csv" ) );
265 BOOST_CHECK(
result == wxT(
"Output/BoM/value.csv" ) );
275 BOOST_CHECK(
path == wxT(
"Output\\BoM\\literal.csv" ) );
295 wxString
path = wxT(
"Board Stats\\${REVISION}_Stats.txt" );
299 BOOST_CHECK_MESSAGE( !
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
300 "Text variable after backslash path separator should not be escaped. Got: "
302 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"RevA" ) ),
303 "Expected resolved REVISION in path. Got: " +
result );
317 wxString
path = wxT(
"Output\\${COMMENT1}_${REVISION}_file.txt" );
320 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"DWG-001" ) ),
321 "Expected COMMENT1 expanded in path. Got: " +
result );
322 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"_B_" ) ),
323 "Expected REVISION expanded in path. Got: " +
result );
336 wxString
path = wxT(
"Output\\Generated_${REVISION}_file.txt" );
339 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"Generated_C_file.txt" ) ),
340 "Expected variable expansion with preceding literal text. Got: " +
result );
363 const wxFileName targetFilename( innerDir, wxS(
"test.kicad_sym" ) );
372 const wxString
expected = wxS(
"${KICAD_QA_USER_LIB_INNER}/test.kicad_sym" );
397 std::function<bool( wxString* )> resolver =
398 []( wxString* token ) ->
bool
400 if( *token == wxT(
"#" ) )
406 if( *token == wxT(
"ROW" ) )
415 const std::vector<wxString> inputs = {
416 wxT(
"Out@{(${#}-2)*8+0}" ),
417 wxT(
"Net_@{${ROW}*2+1}" ),
418 wxT(
"@{(2-2)*8+0}" ),
419 wxT(
"${ROW}:@{${ROW}*${ROW}}" ),
420 wxT(
"plain_label_no_expr" ),
421 wxT(
"@{1+1}_@{2+2}_@{3+3}" ),
424 const unsigned int numThreads = std::max( 4u, std::thread::hardware_concurrency() );
425 const int iterations = 2000;
427 std::atomic<bool> failed{
false };
428 std::atomic<int> totalRuns{ 0 };
429 std::vector<std::thread> threads;
430 threads.reserve( numThreads );
432 for(
unsigned int t = 0; t < numThreads; ++t )
434 threads.emplace_back(
439 for(
int i = 0; i < iterations; ++i )
441 const wxString& src = inputs[( t + i ) % inputs.size()];
445 totalRuns.fetch_add( 1, std::memory_order_relaxed );
450 failed.store(
true, std::memory_order_relaxed );
455 for(
auto& th : threads )
458 BOOST_CHECK( !failed.load() );
459 BOOST_CHECK_EQUAL( totalRuns.load(),
static_cast<int>( numThreads ) * iterations );
470 const wxString innerPath =
"/inner/path";
476 wxString
expected = innerPath + wxS(
"/templates" );
489 const wxString innerPath =
"/inner/path";
501 const wxString stockLibPath =
"/some/path/to/stock-libraries";
509 const wxString uri = wxS(
"${KICAD_USER_FOOTPRINT_DIR}/conn_custom.pretty" );
526 const wxString libPath =
"/some/path/to/stock-libraries";
530 BOOST_REQUIRE( wxS(
"KICAD5_FOOTPRINT_DIR" ) != currentVersionedName );
550 const wxString libPath =
"/some/path/to/stock-libraries";
584 wxString home = wxGetHomeDir();
586 BOOST_CHECK(
ExpandPathVariables( wxS(
"~/out/file.zip" ),
nullptr ) == home + wxS(
"/out/file.zip" ) );
static std::optional< VECTOR2D > normalized(const VECTOR2D &aVec)
wxString ResolveOutputPath(const wxString &aPath, bool aPathIsDirectory, PROJECT *aProject) const
void SetTitleBlock(const TITLE_BLOCK &aTitleBlock)
RAII helper that sets a KiCad program-level environment variable for the lifetime of the object.
RAII helper that sets a process-level environment variable for the lifetime of the object.
wxString PathStr() const
Get the path to the temporary directory as a wxString.
wxString CreateChildDirStr(const wxString &aName) const
Create and return the path to a direct child directory as a wxString.
Container for project specific data.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
void SetRevision(const wxString &aRevision)
void SetComment(int aIdx, const wxString &aComment)
wxString ExpandPathVariables(const wxString &aPath, const PROJECT *aProject, const std::function< bool(wxString *)> *aTextResolver)
Expand text variables, environment variables and a leading '~' in a user-entered file path.
const wxString ResolveUriByEnvVars(const wxString &aUri, const PROJECT *aProject)
Replace any environment and/or text variables in URIs.
const wxString ExpandEnvVarSubstitutions(const wxString &aString, const PROJECT *aProject, bool aAllowEscapes)
Replace any environment variable & text variable references with their values.
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, RESOLUTION_CONTEXT aContext)
wxString NormalizeFilePathForTextVars(const wxString &aPath)
Normalize a file path so its text variables survive ExpandTextVars.
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
static bool empty(const wxTextEntryBase *aCtrl)
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.
Functions related to environment variables, including help functions.
KICOMMON_API bool IsVersionedEnvVar(const wxString &aName, const wxString &aBaseName)
Test whether a name is a versioned KiCad environment variable for the given base, i....
KICOMMON_API wxString GetVersionedEnvVarName(const wxString &aBaseName)
Construct a versioned environment variable based on this KiCad major version.
PGM_BASE & Pgm()
The global program "get" accessor.
Test fixture for ExpandTextVars tests.
std::function< bool(wxString *)> resolver
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_CASE(AssertionsRemainAvailableOnlyDuringRuleChecks)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")