Files
Card-Collection-Manager-3/tests/japanese_pokemon_en_catalog_tests.cpp
T
2026-07-23 10:29:01 +02:00

168 lines
6.5 KiB
C++

#include <doctest/doctest.h>
#include "ccm/games/pokemonjp/JapanesePokemonEnCatalog.hpp"
using namespace ccm;
TEST_SUITE("JapanesePokemonEnCatalog") {
TEST_CASE("parses sets and prints") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"({
"sets": {
"PMCG1": {
"name_en": "Expansion Pack",
"name_ja": "拡張パック",
"releaseDate": "1996/10/20"
}
},
"prints": [
{
"set_id": "PMCG1",
"local_id": "001",
"name_en": "Charmander",
"name_ja": "ヒトカゲ",
"name_en_source": "bulbapedia"
}
]
})");
REQUIRE(catalog.isOk());
CHECK_FALSE(catalog.value().empty());
auto set = catalog.value().findSet("PMCG1");
REQUIRE(set.has_value());
CHECK(set->nameEn == "Expansion Pack");
CHECK(set->releaseDate == "1996/10/20");
auto print = catalog.value().findPrint("PMCG1", "001");
REQUIRE(print.has_value());
CHECK(print->nameEn == "Charmander");
CHECK(print->nameEnSource == "bulbapedia");
}
TEST_CASE("parses optional tcgplayer_id and image_url") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"({
"sets": {},
"prints": [
{
"set_id": "PMCG1",
"local_id": "021",
"name_en": "Charizard",
"name_ja": "リザードン",
"tcgplayer_id": 575604
},
{
"set_id": "SV1a",
"local_id": "001",
"name_en": "Tropius",
"image_url": "https://example.com/tropius.png"
}
]
})");
REQUIRE(catalog.isOk());
auto charizard = catalog.value().findPrint("PMCG1", "021");
REQUIRE(charizard.has_value());
CHECK(charizard->tcgplayerId == "575604");
CHECK(JapanesePokemonEnCatalog::previewImageUrlFromPrint(*charizard) ==
"https://product-images.tcgplayer.com/fit-in/437x437/575604.jpg");
auto tropius = catalog.value().findPrint("SV1a", "001");
REQUIRE(tropius.has_value());
CHECK(JapanesePokemonEnCatalog::previewImageUrlFromPrint(*tropius) ==
"https://example.com/tropius.png");
}
TEST_CASE("findPrintsByName is case-insensitive on English") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"({
"sets": {},
"prints": [
{"set_id":"PMCG1","local_id":"001","name_en":"Charmander","name_ja":"ヒトカゲ"}
]
})");
REQUIRE(catalog.isOk());
const auto hits = catalog.value().findPrintsByName("PMCG1", "charmander");
REQUIRE(hits.size() == 1);
CHECK(hits[0].localId == "001");
}
TEST_CASE("findPrintsByName matches qualified English titles by bare prefix") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"json({
"sets": {},
"prints": [
{"set_id":"UnnumberedPromo","local_id":"007","name_en":"Mewtwo (CoroCoro promo)"},
{"set_id":"UnnumberedPromo","local_id":"008","name_en":"Mewtwo (Fan Book promo)"},
{"set_id":"UnnumberedPromo","local_id":"045","name_en":"Mewtwo Strikes Back (Jumbo)"},
{"set_id":"UnnumberedPromo","local_id":"001","name_en":"Pikachu (CoroCoro promo)"}
]
})json");
REQUIRE(catalog.isOk());
const auto hits = catalog.value().findPrintsByName("UnnumberedPromo", "Mewtwo");
REQUIRE(hits.size() == 3);
CHECK(hits[0].localId == "007");
CHECK(hits[1].localId == "008");
CHECK(hits[2].localId == "045");
// Exact full title still works.
const auto exact = catalog.value().findPrintsByName(
"UnnumberedPromo", "Mewtwo Strikes Back (Jumbo)");
REQUIRE(exact.size() == 1);
CHECK(exact[0].localId == "045");
}
TEST_CASE("findPrintsByName whole-token matches owner and GR titles") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"json({
"sets": {},
"prints": [
{"set_id":"UnnumberedPromo","local_id":"227","name_en":"Team GR's Mewtwo (Pokémon Card GB2 promo)"},
{"set_id":"UnnumberedPromo","local_id":"045","name_en":"Mewtwo Strikes Back (CoroCoro promo) (Jumbo)"},
{"set_id":"UnnumberedPromo","local_id":"016","name_en":"Mew (CoroCoro promo)"}
]
})json");
REQUIRE(catalog.isOk());
const auto mewtwo = catalog.value().findPrintsByName("UnnumberedPromo", "Mewtwo");
REQUIRE(mewtwo.size() == 2);
CHECK(mewtwo[0].localId == "227");
CHECK(mewtwo[1].localId == "045");
// "Mew" must not match "Mewtwo …" rows.
const auto mew = catalog.value().findPrintsByName("UnnumberedPromo", "Mew");
REQUIRE(mew.size() == 1);
CHECK(mew[0].localId == "016");
}
TEST_CASE("hasPrintsForSet reports curated classic products") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"({
"sets": {},
"prints": [
{"set_id":"TamamushiCG","local_id":"021","name_en":"Celadon City Gym"}
]
})");
REQUIRE(catalog.isOk());
CHECK(catalog.value().hasPrintsForSet("TamamushiCG"));
CHECK_FALSE(catalog.value().hasPrintsForSet("PMCG1"));
}
TEST_CASE("printsForSet returns all prints for a set id") {
const auto catalog = JapanesePokemonEnCatalog::parse(R"({
"sets": {},
"prints": [
{"set_id":"A","local_id":"1","name_en":"One"},
{"set_id":"A","local_id":"2","name_en":"Two"},
{"set_id":"B","local_id":"1","name_en":"Other"}
]
})");
REQUIRE(catalog.isOk());
const auto prints = catalog.value().printsForSet("A");
REQUIRE(prints.size() == 2);
CHECK(catalog.value().printsForSet("missing").empty());
}
TEST_CASE("missing set/print returns nullopt") {
JapanesePokemonEnCatalog empty;
CHECK_FALSE(empty.findSet("X").has_value());
CHECK_FALSE(empty.findPrint("X", "1").has_value());
CHECK(empty.empty());
}
TEST_CASE("malformed JSON is an error") {
CHECK(JapanesePokemonEnCatalog::parse("{not json").isErr());
}
}