21#include <boost/test/unit_test.hpp>
32#include <wx/filename.h>
48void writeFileContents(
const wxString& aPath,
const std::string& aContent )
50 wxFFile fp( aPath, wxT(
"wb" ) );
53 if( !aContent.empty() )
54 BOOST_REQUIRE( fp.Write( aContent.data(), aContent.size() ) == aContent.size() );
62unsigned countSiblingTemps(
const wxString& aTargetPath )
64 wxFileName fn( aTargetPath );
65 wxString dir = fn.GetPath();
66 wxString pattern = fn.GetFullName() + wxT(
".kicad-save-*" );
67 wxArrayString matches;
68 wxDir::GetAllFiles( dir, &matches, pattern, wxDIR_FILES );
69 return matches.GetCount();
80 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
84 f.
Print( 0,
"(kicad_test (content \"hello\"))\n" );
92 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
102 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
103 const std::string original =
"(original \"do not lose me\")\n";
104 writeFileContents( target, original );
109 f.
Print( 0,
"(partial " );
113 throw std::runtime_error(
"simulated serializer failure" );
115 std::runtime_error );
119 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
128 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
129 const std::string original =
"(original \"keep me\")\n";
130 writeFileContents( target, original );
134 f.
Print( 0,
"(uncommitted content)\n" );
138 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
147 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
148 const std::string original =
"original streaming content\n";
149 writeFileContents( target, original );
154 f.
Print( 0,
"partial write before the crash " );
155 throw std::runtime_error(
"simulated exporter failure" );
157 std::runtime_error );
161 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
169 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
170 const std::string original =
"original export content\n";
171 writeFileContents( target, original );
175 f.
Print( 0,
"uncommitted streaming content\n" );
179 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
186 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
187 const std::string payload =
"{\"setting\":42}\n";
195 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
204 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
205 const std::string original =
"unchanged\n";
206 writeFileContents( target, original );
211 wxString bogus = target + wxT(
"/subdir/cannot-create" );
226 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
228 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
235 f.
Print( 0,
"(doomed save)\n" );
243 BOOST_REQUIRE_MESSAGE( threw,
"Finish() must throw IO_ERROR when atomic commit fails" );
245 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
252 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
254 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
261 f.
Print( 0,
"doomed streaming save\n" );
269 BOOST_REQUIRE_MESSAGE( threw,
"Finish() must throw IO_ERROR when atomic commit fails" );
271 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
280 const wxString sep = wxFileName::GetPathSeparator();
284 const wxString target = tempDir.
PathStr() + sep + wxT(
"stream-ok" );
286 f.
Print( 0,
"saved once\n" );
294 const wxString target = tempDir.
PathStr() + sep + wxT(
"stream-fail" );
295 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
298 f.
Print( 0,
"doomed streaming save\n" );
306 const wxString target = tempDir.
PathStr() + sep + wxT(
"prettified-ok" );
308 f.
Print( 0,
"(saved once)\n" );
316 const wxString target = tempDir.
PathStr() + sep + wxT(
"prettified-fail" );
317 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
320 f.
Print( 0,
"(doomed pretty save)\n" );
333 model.SetEmptyLayout();
336 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
337 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
341 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
351 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
353 BOOST_REQUIRE( wxFileName::Mkdir( target, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL ) );
359 f.
Print( 0,
"(implicit doomed)\n" );
363 BOOST_REQUIRE_EQUAL( logCounter.
GetCount(), 0u );
365 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
373 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
378 f.
Print( 0,
"(new_file content)\n" );
385 BOOST_REQUIRE_EQUAL( countSiblingTemps( target ), 0u );
389#if !defined( _WIN32 )
397 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
398 const std::string original =
"original\n";
399 writeFileContents( target, original );
401 BOOST_REQUIRE_EQUAL( chmod( target.fn_str(), 0400 ), 0 );
403 const std::string payload =
"replacement\n";
410 BOOST_REQUIRE_EQUAL( stat( target.fn_str(), &st ), 0 );
411 BOOST_REQUIRE_EQUAL( st.st_mode & 0777, 0400 );
419 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
420 const std::string payload =
"fresh\n";
421 const mode_t previousMask = umask( 022 );
426 umask( previousMask );
428 BOOST_REQUIRE_MESSAGE( written, err );
431 BOOST_REQUIRE_EQUAL( stat( target.fn_str(), &st ), 0 );
442 const wxString referent = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"referent" );
443 const wxString linkPath = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"link" );
444 const std::string original =
"referent original\n";
445 writeFileContents( referent, original );
447 BOOST_REQUIRE_EQUAL( symlink( referent.fn_str(), linkPath.fn_str() ), 0 );
449 const std::string payload =
"replacement via symlink\n";
456 BOOST_REQUIRE_EQUAL( lstat( linkPath.fn_str(), &st ), 0 );
471 const wxString target = tempDir.
PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
472 const std::string original =
"original\n";
473 writeFileContents( target, original );
474 BOOST_REQUIRE_EQUAL( chmod( target.fn_str(), 0400 ), 0 );
479 wxString bogus = target + wxT(
"/cannot-create" );
484 BOOST_REQUIRE_EQUAL( stat( target.fn_str(), &st ), 0 );
485 BOOST_REQUIRE_EQUAL( st.st_mode & 0777, 0400 );
496 const wxString target = tempDir.PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
497 const std::string original =
"original\n";
498 writeFileContents( target, original );
501 FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN ) );
503 const std::string payload =
"replacement\n";
509 DWORD attrs = GetFileAttributesW( target.wc_str() );
517 SetFileAttributesW( target.wc_str(), FILE_ATTRIBUTE_NORMAL );
524 const wxString target = tempDir.PathStr() + wxFileName::GetPathSeparator() + wxT(
"target" );
525 const wxString probe = tempDir.PathStr() + wxFileName::GetPathSeparator() + wxT(
"probe" );
526 writeFileContents( target,
"original\n" );
527 writeFileContents( probe,
"" );
531 PSECURITY_DESCRIPTOR sd =
nullptr;
532 BOOST_REQUIRE( ConvertStringSecurityDescriptorToSecurityDescriptorW(
533 L"D:P(A;;0x11019f;;;OW)(A;;0x11019f;;;WD)", SDDL_REVISION_1, &sd,
nullptr ) );
535 const BOOL applied = SetFileSecurityW( target.wc_str(), DACL_SECURITY_INFORMATION, sd );
540 const std::string payload =
"replacement\n";
Handle the graphic items list to draw/plot the frame and title block.
static DS_DATA_MODEL & GetTheInstance()
Return the instance of DS_DATA_MODEL used in the application.
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A scoped application of a wxLog target that counts error-level messages.
unsigned GetCount() const
wxString PathStr() const
Get the path to the temporary directory as a wxString.
std::string LoadStringData(const wxString &aPath)
Load the contents of a file into a string.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(PrettifiedFormatter_HappyPath)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")
#define CHECK_WX_ASSERT(STATEMENT)
A test macro to check a wxASSERT is thrown.