#pragma once namespace TestUtil { inline std::string ReadFile(const std::filesystem::path& p) { std::ifstream f(p); std::stringstream ss; ss << f.rdbuf(); return ss.str(); } inline std::filesystem::path CopyFixtureToTemp(std::string_view testName, const std::filesystem::path& source) { namespace fs = std::filesystem; fs::path tmp = fs::temp_directory_path() / std::format("crafter-test-{}", testName); fs::remove_all(tmp); fs::copy(source, tmp, fs::copy_options::recursive); return tmp; } struct CmdResult { int exitCode; std::string output; }; inline CmdResult RunInDir(const std::filesystem::path& cwd, std::string_view command) { namespace fs = std::filesystem; // Log inside cwd so parallel test drivers don't trample each other. fs::path log = cwd / ".crafter-cmd-output.log"; std::string cmd = std::format("cd '{}' && {} > '{}' 2>&1", cwd.string(), command, log.string()); int rc = std::system(cmd.c_str()); std::string out = ReadFile(log); std::error_code ec; fs::remove(log, ec); return {rc, std::move(out)}; } }