password-analyzer/tests.cpp
2023-11-03 21:12:25 +08:00

96 lines
3.5 KiB
C++

#include <vector>
#include <catch2/catch_test_macros.hpp>
#include "defs.hpp"
auto count_passwords(const DataSource &source) -> size_t {
auto cnt = 0;
for (auto const &_ : passwords(source)) cnt++;
return cnt;
}
std::string get_struct(const std::string &password);
auto string_to_cord(const std::string &password) -> std::vector<Cord>;
auto cord_to_string(const std::vector<Cord> &cords) -> std::string;
auto is_neighbour(const Cord &a, const Cord &b) -> bool;
TEST_CASE("number of CSDN is correct", "[passwords]") { REQUIRE(count_passwords(DataSource::CSDN) == 6428632); }
TEST_CASE("number of YAHOO is correct", "[passwords]") { REQUIRE(count_passwords(DataSource::YAHOO) == 442836); }
TEST_CASE("passwords(10) of CSDN is correct", "[passwords]") {
const std::string ans[] = {"12344321", "670203313747", "730413", "2535263", "KIC43dk6!",
"s12345", "apple", "lj7202", "12345", "hebeibdh"};
size_t i = 0;
for (auto const &p : passwords(DataSource::CSDN) | std::views::take(10)) {
REQUIRE(ans[i++] == p);
}
}
TEST_CASE("passwords(10) of YAHOO is correct", "[passwords]") {
const std::string ans[] = {"@fl!pm0de@", "pass", "steveol", "chotzi", "lb2512",
"scotch", "passwerd", "flipmode", "flipmode", "alden2"};
size_t i = 0;
for (auto const &p : passwords(DataSource::YAHOO) | std::views::take(10)) {
REQUIRE(ans[i++] == p);
}
}
TEST_CASE("get_struct works", "[stat_struct]") {
const std::string test_cases[][2] = {{"A", "L1"}, {"1", "D1"}, {"!", "S1"},
{"AABBCC", "L6"}, {"A1@", "L1D1S1"}, {"AbCd@", "L4S1"}};
for (auto const &[password, expected] : test_cases) {
auto ans = get_struct(password);
REQUIRE(ans == expected);
}
}
TEST_CASE("string_to_cord works", "[stat_keystroke]") {
const std::pair<std::string, std::vector<Cord>> test_cases[] = {
{"asdf", {{2, 1}, {2, 2}, {2, 3}, {2, 4}}},
{"AwDr%", {{2, 1}, {1, 2}, {2, 3}, {1, 4}, {0, 5}}},
{"p_[=}\\", {{1, 10}, {0, 11}, {1, 11}, {0, 12}, {1, 12}, {1, 13}}},
{",L>;/\"", {{3, 8}, {2, 9}, {3, 9}, {2, 10}, {3, 10}, {2, 11}}},
};
for (auto const &[password, expected] : test_cases) {
auto ans = string_to_cord(password);
REQUIRE(ans == expected);
}
}
TEST_CASE("cord_to_string works", "[stat_keystroke]") {
const std::pair<std::string, std::vector<Cord>> test_cases[] = {
{"asdf", {{2, 1}, {2, 2}, {2, 3}, {2, 4}}},
{"awdr5", {{2, 1}, {1, 2}, {2, 3}, {1, 4}, {0, 5}}},
{"p-[=]\\", {{1, 10}, {0, 11}, {1, 11}, {0, 12}, {1, 12}, {1, 13}}},
{",l.;/'", {{3, 8}, {2, 9}, {3, 9}, {2, 10}, {3, 10}, {2, 11}}},
};
for (auto const &[expected, cords] : test_cases) {
auto ans = cord_to_string(cords);
REQUIRE(ans == expected);
}
}
TEST_CASE("is_neighbour works", "[stat_keystroke]") {
const auto dict = string_to_cord("`1qwad;./"s);
const std::pair<std::pair<Cord, Cord>, bool> test_cases[] = {
{{dict[0], dict[1]}, true}, // `1
{{dict[0], dict[2]}, true}, // `q
{{dict[3], dict[4]}, true}, // wa
{{dict[3], dict[5]}, true}, // wd
{{dict[4], dict[5]}, false}, // ad
{{dict[6], dict[7]}, true}, // ;.
{{dict[6], dict[8]}, true}, // ;/
};
for (auto const &[cords, expected] : test_cases) {
auto ans = is_neighbour(cords.first, cords.second);
REQUIRE(ans == expected);
}
}