21#define BOOST_TEST_NO_MAIN
22#include <boost/test/unit_test.hpp>
31#include <wx/filename.h>
49 []( wxString* token ) ->
bool
51 if( *token == wxT(
"VAR" ) )
53 *token = wxT(
"value" );
56 else if( *token == wxT(
"X" ) )
61 else if( *token == wxT(
"Y" ) )
75 for(
const wxString& prefix : { wxString(
"ERC_WARNING" ), wxString(
"ERC_ERROR" ),
76 wxString(
"DRC_WARNING" ), wxString(
"DRC_ERROR" ) } )
78 const wxString assertion =
"${" + prefix +
" Check this item}";
90 BOOST_CHECK(
result == wxT(
"value" ) );
97 BOOST_CHECK(
result == wxT(
"5+2" ) );
105 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
113 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
114 BOOST_CHECK(
result.Contains( wxT(
"value" ) ) );
122 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
123 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
135 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
136 "Expected escape marker in result" );
139 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"+2" ) ),
140 "Expected '+2' (from ${Y} expansion) in result" );
143 BOOST_CHECK(
result == wxT(
"@{<<<ESC_DOLLAR:X}+2}" ) );
155 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
164 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"+2" ) ),
165 "Expected '+2' (from ${Y} expansion) in: " +
result );
171 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
186 BOOST_CHECK(
result.StartsWith( wxT(
"value" ) ) );
187 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_AT:" ) ) );
199 while( ( pos =
result.find( wxT(
"<<<ESC_DOLLAR:" ), pos ) ) != wxString::npos )
217 BOOST_CHECK(
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ) );
226 BOOST_CHECK(
result == wxT(
"subdir/value_file.txt" ) );
244 BOOST_CHECK_MESSAGE( !
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
245 "Variable after backslash separator should expand, not escape. Got: " +
result );
246 BOOST_CHECK(
result == wxT(
"Output\\BoM/value_file.csv" ) );
255 BOOST_CHECK(
result == wxT(
"Output\\BoM/5_V2.csv" ) );
264 BOOST_CHECK(
result == wxT(
"Output/BoM/value.csv" ) );
274 BOOST_CHECK(
path == wxT(
"Output\\BoM\\literal.csv" ) );
294 wxString
path = wxT(
"Board Stats\\${REVISION}_Stats.txt" );
298 BOOST_CHECK_MESSAGE( !
result.Contains( wxT(
"<<<ESC_DOLLAR:" ) ),
299 "Text variable after backslash path separator should not be escaped. Got: "
301 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"RevA" ) ),
302 "Expected resolved REVISION in path. Got: " +
result );
316 wxString
path = wxT(
"Output\\${COMMENT1}_${REVISION}_file.txt" );
319 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"DWG-001" ) ),
320 "Expected COMMENT1 expanded in path. Got: " +
result );
321 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"_B_" ) ),
322 "Expected REVISION expanded in path. Got: " +
result );
335 wxString
path = wxT(
"Output\\Generated_${REVISION}_file.txt" );
338 BOOST_CHECK_MESSAGE(
result.Contains( wxT(
"Generated_C_file.txt" ) ),
339 "Expected variable expansion with preceding literal text. Got: " +
result );
362 const wxFileName targetFilename( innerDir, wxS(
"test.kicad_sym" ) );
371 const wxString
expected = wxS(
"${KICAD_QA_USER_LIB_INNER}/test.kicad_sym" );
396 std::function<bool( wxString* )> resolver =
397 []( wxString* token ) ->
bool
399 if( *token == wxT(
"#" ) )
405 if( *token == wxT(
"ROW" ) )
414 const std::vector<wxString> inputs = {
415 wxT(
"Out@{(${#}-2)*8+0}" ),
416 wxT(
"Net_@{${ROW}*2+1}" ),
417 wxT(
"@{(2-2)*8+0}" ),
418 wxT(
"${ROW}:@{${ROW}*${ROW}}" ),
419 wxT(
"plain_label_no_expr" ),
420 wxT(
"@{1+1}_@{2+2}_@{3+3}" ),
423 const unsigned int numThreads = std::max( 4u, std::thread::hardware_concurrency() );
424 const int iterations = 2000;
426 std::atomic<bool> failed{
false };
427 std::atomic<int> totalRuns{ 0 };
428 std::vector<std::thread> threads;
429 threads.reserve( numThreads );
431 for(
unsigned int t = 0; t < numThreads; ++t )
433 threads.emplace_back(
438 for(
int i = 0; i < iterations; ++i )
440 const wxString& src = inputs[( t + i ) % inputs.size()];
444 totalRuns.fetch_add( 1, std::memory_order_relaxed );
449 failed.store(
true, std::memory_order_relaxed );
454 for(
auto& th : threads )
457 BOOST_CHECK( !failed.load() );
458 BOOST_CHECK_EQUAL( totalRuns.load(),
static_cast<int>( numThreads ) * iterations );
469 const wxString innerPath =
"/inner/path";
475 wxString
expected = innerPath + wxS(
"/templates" );
488 const wxString innerPath =
"/inner/path";
500 const wxString stockLibPath =
"/some/path/to/stock-libraries";
508 const wxString uri = wxS(
"${KICAD_USER_FOOTPRINT_DIR}/conn_custom.pretty" );
525 const wxString libPath =
"/some/path/to/stock-libraries";
529 BOOST_REQUIRE( wxS(
"KICAD5_FOOTPRINT_DIR" ) != currentVersionedName );
549 const wxString libPath =
"/some/path/to/stock-libraries";
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.
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)
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, 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")