diff --git a/unittest/TestCwCheat.cpp b/unittest/TestCwCheat.cpp index 83eb4a205a..54c6490a7e 100644 --- a/unittest/TestCwCheat.cpp +++ b/unittest/TestCwCheat.cpp @@ -135,17 +135,23 @@ static bool RunCheatTest(CWCheatEngine &engine, const CheatCode &cheat, const st } static bool RunCheatTests() { - const Path filename("unittest_cheats.ini"); + const Path filename = UnitTestTempPath("unittest_cheats.ini"); if (!File::WriteStringToFile(true, g_cheatFile, filename)) { printf("Can't write %s\n", filename.c_str()); return false; } - CheatFileParser parser(filename, "TEST00000"); - const bool parsed = parser.Parse(); - for (const std::string &error : parser.GetErrors()) { - printf("%s\n", error.c_str()); + bool parsed; + std::vector cheats; + { + // The parser holds the file open, which keeps it from being deleted on Windows. + CheatFileParser parser(filename, "TEST00000"); + parsed = parser.Parse(); + for (const std::string &error : parser.GetErrors()) { + printf("%s\n", error.c_str()); + } + cheats = parser.GetCheats(); } - const std::vector cheats = parser.GetCheats(); + File::Delete(filename); EXPECT_TRUE(parsed); EXPECT_EQ_INT((int)cheats.size(), 14); @@ -180,23 +186,30 @@ static bool RunCheatTests() { success = success && RunCheatTest(engine, cheats[13], { { 0x08802000, 0x11111111 } }); } - File::Delete(filename); return success; } static bool TestCheatParseErrors() { - const Path filename("unittest_cheats_bad.ini"); + const Path filename = UnitTestTempPath("unittest_cheats_bad.ini"); const char *content = "_S TEST00000\n_C1 Mixed\n_L 0x20002000 0x00000001\n_M 0x08802004 0x00000002\n_C1 Extended\n_N 0xD4000001 0x00000001\n"; if (!File::WriteStringToFile(true, content, filename)) { return false; } - CheatFileParser parser(filename, "TEST00000"); - EXPECT_FALSE(parser.Parse()); - EXPECT_EQ_INT((int)parser.GetErrors().size(), 2); - EXPECT_EQ_INT((int)parser.GetCheats().size(), 1); - EXPECT_EQ_INT((int)parser.GetCheats()[0].lines.size(), 1); - EXPECT_TRUE(parser.GetCheats()[0].format == CheatCodeFormat::CwCheat); + bool parsed; + size_t errorCount; + std::vector cheats; + { + CheatFileParser parser(filename, "TEST00000"); + parsed = parser.Parse(); + errorCount = parser.GetErrors().size(); + cheats = parser.GetCheats(); + } File::Delete(filename); + EXPECT_FALSE(parsed); + EXPECT_EQ_INT((int)errorCount, 2); + EXPECT_EQ_INT((int)cheats.size(), 1); + EXPECT_EQ_INT((int)cheats[0].lines.size(), 1); + EXPECT_TRUE(cheats[0].format == CheatCodeFormat::CwCheat); return true; } diff --git a/unittest/TestTextureReplacer.cpp b/unittest/TestTextureReplacer.cpp index b2f468323c..21e4c6d1d4 100644 --- a/unittest/TestTextureReplacer.cpp +++ b/unittest/TestTextureReplacer.cpp @@ -712,7 +712,7 @@ static bool TestSaveIndexedOption(const Path &packDir) { } bool TestTextureReplacer() { - Path packDir = Path("unittest_texture_pack"); + Path packDir = UnitTestTempPath("unittest_texture_pack"); if (!CreateTestPack(packDir)) { return false; } diff --git a/unittest/TestZipSlip.cpp b/unittest/TestZipSlip.cpp index 623206d091..17994606e0 100644 --- a/unittest/TestZipSlip.cpp +++ b/unittest/TestZipSlip.cpp @@ -46,7 +46,7 @@ static bool CreateZipWithEntry(const Path &zipPath, const std::string &entryName // Crafts a zip with a parent-directory entry and verifies ExtractZipContents // refuses to write outside the destination directory (Zip Slip). static bool TestZipSlipExtraction() { - Path tempRoot = Path("unittest_zip_slip_test"); + Path tempRoot = UnitTestTempPath("unittest_zip_slip_test"); File::DeleteDirRecursively(tempRoot); EXPECT_TRUE(File::CreateDir(tempRoot)); diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index 90ec581f63..6ffe79fc23 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -131,6 +131,24 @@ // Set to true for more verbose unit tests. bool g_testLog = false; +Path UnitTestTempPath(const char *name) { +#if PPSSPP_PLATFORM(WINDOWS) + const wchar_t *temp = _wgetenv(L"TEMP"); + if (temp && *temp) { + return Path(ConvertWStringToUTF8(temp)) / name; + } +#else + const char *temp = getenv("TMPDIR"); + if (temp && *temp) { + return Path(temp) / name; + } +#if !PPSSPP_PLATFORM(ANDROID) + return Path("/tmp") / name; +#endif +#endif + return Path(name); +} + std::string System_GetProperty(SystemProperty prop) { return ""; } std::vector System_GetPropertyStringVec(SystemProperty prop) { return std::vector(); } int64_t System_GetPropertyInt(SystemProperty prop) { diff --git a/unittest/UnitTest.h b/unittest/UnitTest.h index 963e43609d..39d0a4f13c 100644 --- a/unittest/UnitTest.h +++ b/unittest/UnitTest.h @@ -6,6 +6,7 @@ #include #include +#include "Common/File/Path.h" #include "Common/TimeUtil.h" // For benchmarks: calls fn over and over, callsPerBatch at a time between reads of the clock, for at @@ -50,6 +51,9 @@ inline bool rel_equal(float a, float b, float precision) { extern bool g_testLog; +// Where a test should put a file or directory it creates, so it doesn't land in the working directory. +Path UnitTestTempPath(const char *name); + // Calls check on a few million inputs chosen to make trouble for a VFPU dot product (see // UnitTest.cpp), and stops at the first false. bool ForEachVFPUDotTestCase(const std::function &check);