foxygit / Torlinkc Log in
commits tags

/tests/test_support.hpp · 1.69 KB

raw
#pragma once

#include <cstdlib>
#include <filesystem>
#include <random>
#include <string>

#include <doctest/doctest.h>

#include "torlinkc/engine/types.hpp"

// doctest stringifies both sides of a failed CHECK(a == b); without this it
// can't turn a DownloadStatus/SeedStatus into a doctest::String, so give it
// the same names the app itself displays.
namespace doctest {
template <>
struct StringMaker<torlinkc::DownloadStatus> {
  static String convert(const torlinkc::DownloadStatus& value) {
    return torlinkc::downloadStatusToString(value).c_str();
  }
};
template <>
struct StringMaker<torlinkc::SeedStatus> {
  static String convert(const torlinkc::SeedStatus& value) { return torlinkc::seedStatusToString(value).c_str(); }
};
}  // namespace doctest

namespace torlinkc::test {

// Points TORLINK_STATE_DIR at a fresh temp dir for the lifetime of the
// object, so tests that exercise persistence never touch real user data
// (mirrors the TS test suite's use of the same env var). Any DownloadQueue
// or persist.* call implicitly writes to disk, so every test that touches
// either must keep one of these alive.
class StateDirSandbox {
 public:
  StateDirSandbox() {
    std::random_device rd;
    dir_ = std::filesystem::temp_directory_path() / ("torlinkc-test-" + std::to_string(rd()));
    std::filesystem::create_directories(dir_);
    setenv("TORLINK_STATE_DIR", dir_.c_str(), 1);
  }
  ~StateDirSandbox() {
    unsetenv("TORLINK_STATE_DIR");
    std::error_code ec;
    std::filesystem::remove_all(dir_, ec);
  }

  StateDirSandbox(const StateDirSandbox&) = delete;
  StateDirSandbox& operator=(const StateDirSandbox&) = delete;

 private:
  std::filesystem::path dir_;
};

}  // namespace torlinkc::test