commits
tags
#include <doctest/doctest.h>
#include "torlinkc/ui/sort.hpp"
using namespace torlinkc;
using namespace torlinkc::ui;
namespace {
TorrentResult r(std::string infoHash, std::int64_t sizeBytes = 0, int seeders = 0, std::string source = "yts",
std::optional<std::int64_t> added = std::nullopt) {
TorrentResult t;
t.infoHash = infoHash;
t.name = infoHash;
t.sizeBytes = sizeBytes;
t.seeders = seeders;
t.source = std::move(source);
t.magnet = "magnet:?xt=urn:btih:" + infoHash;
t.added = added;
return t;
}
std::vector<std::string> ids(const std::vector<TorrentResult>& list) {
std::vector<std::string> out;
for (const auto& t : list) out.push_back(t.infoHash);
return out;
}
} // namespace
TEST_CASE("nextSort cycles through 9 states and back to none") {
Sort s = std::nullopt;
std::vector<Sort> seq;
for (int i = 0; i < 9; ++i) {
s = nextSort(s);
seq.push_back(s);
}
REQUIRE(seq.size() == 9);
CHECK(seq[0] == SortState{SortField::Size, SortDir::Asc});
CHECK(seq[1] == SortState{SortField::Size, SortDir::Desc});
CHECK(seq[2] == SortState{SortField::Seeders, SortDir::Asc});
CHECK(seq[3] == SortState{SortField::Seeders, SortDir::Desc});
CHECK(seq[4] == SortState{SortField::Source, SortDir::Asc});
CHECK(seq[5] == SortState{SortField::Source, SortDir::Desc});
CHECK(seq[6] == SortState{SortField::Added, SortDir::Asc});
CHECK(seq[7] == SortState{SortField::Added, SortDir::Desc});
CHECK_FALSE(seq[8].has_value());
}
TEST_CASE("sortCycle has exactly 9 states starting with none") {
CHECK(sortCycle().size() == 9);
CHECK_FALSE(sortCycle()[0].has_value());
}
TEST_CASE("sortArrow points up for asc and down for desc") {
CHECK(sortArrow(SortDir::Asc) == "▴");
CHECK(sortArrow(SortDir::Desc) == "▾");
}
TEST_CASE("sortResults none preserves the original arrival order") {
std::vector<TorrentResult> list = {r("a", 1, 1), r("b", 9, 9), r("c", 5, 5)};
CHECK(ids(sortResults(list, std::nullopt)) == std::vector<std::string>{"a", "b", "c"});
}
TEST_CASE("sortResults size asc: smallest first") {
std::vector<TorrentResult> list = {r("a", 500), r("b", 100), r("c", 900)};
CHECK(ids(sortResults(list, SortState{SortField::Size, SortDir::Asc})) == std::vector<std::string>{"b", "a", "c"});
}
TEST_CASE("sortResults size desc: largest first") {
std::vector<TorrentResult> list = {r("a", 500), r("b", 100), r("c", 900)};
CHECK(ids(sortResults(list, SortState{SortField::Size, SortDir::Desc})) == std::vector<std::string>{"c", "a", "b"});
}
TEST_CASE("sortResults seeders asc: fewest first") {
std::vector<TorrentResult> list = {r("a", 0, 50), r("b", 0, 5), r("c", 0, 90)};
CHECK(ids(sortResults(list, SortState{SortField::Seeders, SortDir::Asc})) ==
std::vector<std::string>{"b", "a", "c"});
}
TEST_CASE("sortResults seeders desc: most first") {
std::vector<TorrentResult> list = {r("a", 0, 50), r("b", 0, 5), r("c", 0, 90)};
CHECK(ids(sortResults(list, SortState{SortField::Seeders, SortDir::Desc})) ==
std::vector<std::string>{"c", "a", "b"});
}
TEST_CASE("sortResults source asc: A->Z by source id") {
std::vector<TorrentResult> list = {r("a", 0, 0, "yts"), r("b", 0, 0, "eztv"), r("c", 0, 0, "nyaa")};
CHECK(ids(sortResults(list, SortState{SortField::Source, SortDir::Asc})) ==
std::vector<std::string>{"b", "c", "a"});
}
TEST_CASE("sortResults source desc: Z->A by source id") {
std::vector<TorrentResult> list = {r("a", 0, 0, "eztv"), r("b", 0, 0, "yts"), r("c", 0, 0, "nyaa")};
CHECK(ids(sortResults(list, SortState{SortField::Source, SortDir::Desc})) ==
std::vector<std::string>{"b", "c", "a"});
}
TEST_CASE("sortResults added asc: oldest first") {
std::vector<TorrentResult> list = {r("a", 0, 0, "yts", 300), r("b", 0, 0, "yts", 100), r("c", 0, 0, "yts", 200)};
CHECK(ids(sortResults(list, SortState{SortField::Added, SortDir::Asc})) ==
std::vector<std::string>{"b", "c", "a"});
}
TEST_CASE("sortResults added desc: newest first") {
std::vector<TorrentResult> list = {r("a", 0, 0, "yts", 300), r("b", 0, 0, "yts", 100), r("c", 0, 0, "yts", 200)};
CHECK(ids(sortResults(list, SortState{SortField::Added, SortDir::Desc})) ==
std::vector<std::string>{"a", "c", "b"});
}
TEST_CASE("sortResults added treats missing timestamps as zero") {
std::vector<TorrentResult> list = {r("a", 0, 0, "yts", 500), r("b", 0, 0, "yts", std::nullopt),
r("c", 0, 0, "yts", 100)};
CHECK(ids(sortResults(list, SortState{SortField::Added, SortDir::Asc})) ==
std::vector<std::string>{"b", "c", "a"});
}
TEST_CASE("sortResults does not mutate the input") {
std::vector<TorrentResult> list = {r("a", 1), r("b", 2)};
const auto before = ids(list);
sortResults(list, SortState{SortField::Size, SortDir::Asc});
CHECK(ids(list) == before);
}