#include "vdm/rules/collision.hpp" #include #include #include #include #include "vtest.hpp" using vdm::rules::CollisionPolicy; using vdm::rules::resolve_collision; namespace { std::function exists_in(const std::set &names) { return [&names](std::string_view s) { return names.count(std::string(s)) > 0; }; } } // namespace VT_TEST(collision_no_collision_returns_desired) { std::set existing = {"other.txt"}; VT_CHECK_EQ(resolve_collision("file.txt", exists_in(existing)), std::string("file.txt")); } VT_TEST(collision_renames_on_conflict) { std::set existing = {"file.txt"}; VT_CHECK_EQ(resolve_collision("file.txt", exists_in(existing)), std::string("file (1).txt")); } VT_TEST(collision_finds_first_free_slot) { std::set existing = {"file.txt", "file (1).txt", "file (2).txt"}; VT_CHECK_EQ(resolve_collision("file.txt", exists_in(existing)), std::string("file (3).txt")); } VT_TEST(collision_no_extension) { std::set existing = {"README"}; VT_CHECK_EQ(resolve_collision("README", exists_in(existing)), std::string("README (1)")); } VT_TEST(collision_dotfile_treated_as_no_extension) { std::set existing = {".gitignore"}; VT_CHECK_EQ(resolve_collision(".gitignore", exists_in(existing)), std::string(".gitignore (1)")); } VT_TEST(collision_overwrite_policy_ignores_existence) { std::set existing = {"file.txt"}; VT_CHECK_EQ(resolve_collision("file.txt", exists_in(existing), CollisionPolicy::overwrite), std::string("file.txt")); } VT_TEST(collision_gives_up_after_max_attempts_without_fabricating) { auto always_exists = [](std::string_view) { return true; }; auto out = resolve_collision("file.txt", always_exists, CollisionPolicy::rename, 3); VT_CHECK_EQ(out, std::string("file (3).txt")); // last attempted, still colliding }