27#include <system_error>
30#include <boost/test/unit_test.hpp>
35#include <wx/filename.h>
38#if defined (__MINGW32__)
50 std::filesystem::path path;
52 explicit ScratchRoot(
const char* aTag )
54 namespace fs = std::filesystem;
56 path = fs::temp_directory_path( ec );
57 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
59 path /= std::string(
"kicad_qa_issue24467_" ) + aTag +
"_"
60 + std::to_string(
static_cast<unsigned long>( wxGetProcessId() ) );
62 fs::remove_all( path, ec );
63 fs::create_directories( path, ec );
64 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
70 std::filesystem::remove_all( path, ec );
75bool contains(
const wxArrayString& aFiles,
const std::filesystem::path& aPath )
77 const wxString want = wxString::FromUTF8( aPath.string() );
79 for(
const wxString& f : aFiles )
92bool createSymlinkOrSkip(
const std::filesystem::path& aTarget,
93 const std::filesystem::path& aLink )
96 std::filesystem::create_directory_symlink( aTarget, aLink, ec );
99 BOOST_TEST_MESSAGE(
"Skipping: symlink creation unsupported (" << ec.message() <<
")" );
114 namespace fs = std::filesystem;
116 const ScratchRoot scratch(
"loop" );
117 const fs::path stepFile = scratch.path /
"R_0603.step";
119 std::ofstream( stepFile ) <<
"ISO-10303-21;\n";
121 if( !createSymlinkOrSkip(
".", scratch.path /
"loop" ) )
127 BOOST_CHECK( contains( files, stepFile ) );
135 namespace fs = std::filesystem;
137 const ScratchRoot scratch(
"follow" );
138 const fs::path realDir = scratch.path /
"real";
139 const fs::path linkedDir = scratch.path /
"scan";
140 const fs::path stepFile = realDir /
"R_0603.step";
143 fs::create_directories( realDir, ec );
144 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
146 std::ofstream( stepFile ) <<
"ISO-10303-21;\n";
148 if( !createSymlinkOrSkip( realDir, linkedDir ) )
155 BOOST_CHECK( contains( files, linkedDir /
"R_0603.step" ) );
164 namespace fs = std::filesystem;
166 const ScratchRoot scratch(
"ancestor" );
167 const fs::path root = scratch.path /
"scan";
168 const fs::path outside = scratch.path /
"outside";
169 const fs::path outsideFile = outside /
"Outside.step";
172 fs::create_directories( root, ec );
173 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
174 fs::create_directories( outside, ec );
175 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
177 std::ofstream( outsideFile ) <<
"ISO-10303-21;\n";
179 if( !createSymlinkOrSkip( scratch.path, root /
"up" ) )
185 BOOST_CHECK( !contains( files, root /
"up" /
"outside" /
"Outside.step" ) );
186 BOOST_CHECK( !contains( files, outsideFile ) );
194 namespace fs = std::filesystem;
196 const ScratchRoot scratch(
"spec" );
198 std::ofstream( scratch.path /
"R_0603.step" ) <<
"ISO-10303-21;\n";
199 std::ofstream( scratch.path /
"R_0603.wrl" ) <<
"#VRML\n";
205 BOOST_CHECK( contains( files, scratch.path /
"R_0603.step" ) );
213 namespace fs = std::filesystem;
215 const ScratchRoot scratch(
"subdirs" );
216 const fs::path subDir = scratch.path /
"Resistor_SMD.3dshapes";
219 fs::create_directories( subDir, ec );
220 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
222 if( !createSymlinkOrSkip(
".", scratch.path /
"loop" ) )
228 BOOST_CHECK( contains( dirs, subDir ) );
238 namespace fs = std::filesystem;
240 const ScratchRoot scratch(
"hidden" );
241 const fs::path normalFile = scratch.path /
"R_0603.step";
242 const fs::path hiddenFile = scratch.path /
".hidden.step";
244 std::ofstream( normalFile ) <<
"ISO-10303-21;\n";
245 std::ofstream( hiddenFile ) <<
"ISO-10303-21;\n";
248 SetFileAttributesW( hiddenFile.c_str(), FILE_ATTRIBUTE_HIDDEN );
251 wxArrayString withHidden;
254 BOOST_CHECK( contains( withHidden, normalFile ) );
255 BOOST_CHECK( contains( withHidden, hiddenFile ) );
257 wxArrayString noHidden;
259 wxDIR_FILES | wxDIR_DIRS );
261 BOOST_CHECK( contains( noHidden, normalFile ) );
262 BOOST_CHECK( !contains( noHidden, hiddenFile ) );
272 namespace fs = std::filesystem;
274 const ScratchRoot scratch(
"external" );
275 const fs::path root = scratch.path /
"scan";
276 const fs::path external = scratch.path /
"external_lib";
277 const fs::path externalFile = external /
"C_0402.step";
280 fs::create_directories( root, ec );
281 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
282 fs::create_directories( external, ec );
283 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
285 std::ofstream( externalFile ) <<
"ISO-10303-21;\n";
287 if( !createSymlinkOrSkip( external, root /
"alias" ) )
293 BOOST_CHECK( contains( files, root /
"alias" /
"C_0402.step" ) );
void CollectSubdirsLoopSafe(const wxString &aRoot, wxArrayString &aDirs, int aFlags)
Recursively collect every subdirectory under aRoot using the same loop detection as CollectFilesLoopS...
void CollectFilesLoopSafe(const wxString &aRoot, wxArrayString &aFiles, const wxString &aFileSpec, int aFlags)
Recursively collect every file under aRoot, deduplicating subdirectories by their resolved path.
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(RecursiveSymlinkTerminates)
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")