27#include <system_error>
30#include <boost/test/unit_test.hpp>
35#include <wx/filename.h>
47 std::filesystem::path path;
49 explicit ScratchRoot(
const char* aTag )
51 namespace fs = std::filesystem;
53 path = fs::temp_directory_path( ec );
54 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
56 path /= std::string(
"kicad_qa_issue24467_" ) + aTag +
"_"
57 + std::to_string(
static_cast<unsigned long>( wxGetProcessId() ) );
59 fs::remove_all( path, ec );
60 fs::create_directories( path, ec );
61 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
67 std::filesystem::remove_all( path, ec );
72bool contains(
const wxArrayString& aFiles,
const std::filesystem::path& aPath )
74 const wxString want = wxString::FromUTF8( aPath.string() );
76 for(
const wxString& f : aFiles )
89bool createSymlinkOrSkip(
const std::filesystem::path& aTarget,
90 const std::filesystem::path& aLink )
93 std::filesystem::create_directory_symlink( aTarget, aLink, ec );
96 BOOST_TEST_MESSAGE(
"Skipping: symlink creation unsupported (" << ec.message() <<
")" );
111 namespace fs = std::filesystem;
113 const ScratchRoot scratch(
"loop" );
114 const fs::path stepFile = scratch.path /
"R_0603.step";
116 std::ofstream( stepFile ) <<
"ISO-10303-21;\n";
118 if( !createSymlinkOrSkip(
".", scratch.path /
"loop" ) )
124 BOOST_CHECK( contains( files, stepFile ) );
132 namespace fs = std::filesystem;
134 const ScratchRoot scratch(
"follow" );
135 const fs::path realDir = scratch.path /
"real";
136 const fs::path linkedDir = scratch.path /
"scan";
137 const fs::path stepFile = realDir /
"R_0603.step";
140 fs::create_directories( realDir, ec );
141 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
143 std::ofstream( stepFile ) <<
"ISO-10303-21;\n";
145 if( !createSymlinkOrSkip( realDir, linkedDir ) )
152 BOOST_CHECK( contains( files, linkedDir /
"R_0603.step" ) );
161 namespace fs = std::filesystem;
163 const ScratchRoot scratch(
"ancestor" );
164 const fs::path root = scratch.path /
"scan";
165 const fs::path outside = scratch.path /
"outside";
166 const fs::path outsideFile = outside /
"Outside.step";
169 fs::create_directories( root, ec );
170 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
171 fs::create_directories( outside, ec );
172 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
174 std::ofstream( outsideFile ) <<
"ISO-10303-21;\n";
176 if( !createSymlinkOrSkip( scratch.path, root /
"up" ) )
182 BOOST_CHECK( !contains( files, root /
"up" /
"outside" /
"Outside.step" ) );
183 BOOST_CHECK( !contains( files, outsideFile ) );
191 namespace fs = std::filesystem;
193 const ScratchRoot scratch(
"spec" );
195 std::ofstream( scratch.path /
"R_0603.step" ) <<
"ISO-10303-21;\n";
196 std::ofstream( scratch.path /
"R_0603.wrl" ) <<
"#VRML\n";
202 BOOST_CHECK( contains( files, scratch.path /
"R_0603.step" ) );
210 namespace fs = std::filesystem;
212 const ScratchRoot scratch(
"subdirs" );
213 const fs::path subDir = scratch.path /
"Resistor_SMD.3dshapes";
216 fs::create_directories( subDir, ec );
217 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
219 if( !createSymlinkOrSkip(
".", scratch.path /
"loop" ) )
225 BOOST_CHECK( contains( dirs, subDir ) );
235 namespace fs = std::filesystem;
237 const ScratchRoot scratch(
"hidden" );
238 const fs::path normalFile = scratch.path /
"R_0603.step";
239 const fs::path hiddenFile = scratch.path /
".hidden.step";
241 std::ofstream( normalFile ) <<
"ISO-10303-21;\n";
242 std::ofstream( hiddenFile ) <<
"ISO-10303-21;\n";
245 SetFileAttributesW( hiddenFile.c_str(), FILE_ATTRIBUTE_HIDDEN );
248 wxArrayString withHidden;
251 BOOST_CHECK( contains( withHidden, normalFile ) );
252 BOOST_CHECK( contains( withHidden, hiddenFile ) );
254 wxArrayString noHidden;
256 wxDIR_FILES | wxDIR_DIRS );
258 BOOST_CHECK( contains( noHidden, normalFile ) );
259 BOOST_CHECK( !contains( noHidden, hiddenFile ) );
269 namespace fs = std::filesystem;
271 const ScratchRoot scratch(
"external" );
272 const fs::path root = scratch.path /
"scan";
273 const fs::path external = scratch.path /
"external_lib";
274 const fs::path externalFile = external /
"C_0402.step";
277 fs::create_directories( root, ec );
278 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
279 fs::create_directories( external, ec );
280 BOOST_REQUIRE_MESSAGE( !ec, ec.message() );
282 std::ofstream( externalFile ) <<
"ISO-10303-21;\n";
284 if( !createSymlinkOrSkip( external, root /
"alias" ) )
290 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")