Progressive title truncation, publisher tiebreak, thematic-year fix
Long transcribed box titles that defeat search now retry with shorter heads (pre-separator, pre-"Game ..." descriptor, first-two-words from the pre-subtitle part) matched exact-only against the head — fuzzy thresholds stay untouched. Tie-breaks gain a publisher pick: when the box showed a publisher and exactly one exact-named candidate is from that publisher, it wins (SPI's Sorcerer 1975 now beats the more-owned White Wizard Sorcerer 2019). The extract prompt excludes thematic/ subject years from year_hint; re-extracting Flat Top's photo drops the bogus 1942, and a regression test pins that a wrong year can never drive version selection. Re-extraction also drifted two transcriptions (DUNGEON!, and Herbaceous misread as "Hebarceos") — fixtures added; the misread demos review's re-search rescue in the end-to-end run. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -187,3 +187,110 @@ def test_score_version_no_overlap():
|
||||
languages=("English",),
|
||||
)
|
||||
assert _score_version(entry, version) == 0
|
||||
|
||||
|
||||
# -- progressive title truncation (long transcribed box titles) ---------
|
||||
|
||||
from bggpipe.normalize import normalize_title # noqa: E402
|
||||
from bggpipe.resolve import _truncation_heads # noqa: E402
|
||||
|
||||
CIV_TITLE = (
|
||||
"CIVILIZATION Game of the Heroic Age - The Dawn of History 8000 BC to 250 BC"
|
||||
)
|
||||
AH_HINT = "The Avalon Hill Game Company, Baltimore, Maryland"
|
||||
|
||||
|
||||
def _entry(title, **kw):
|
||||
return TitleEntry(title_raw=title, title_normalized=normalize_title(title), **kw)
|
||||
|
||||
|
||||
def test_truncation_heads_order_and_dedupe():
|
||||
heads = _truncation_heads(CIV_TITLE)
|
||||
assert heads[0] == "CIVILIZATION Game of the Heroic Age" # before separator
|
||||
assert heads[1] == "CIVILIZATION" # before the "Game ..." descriptor
|
||||
assert len(heads) <= 3
|
||||
|
||||
|
||||
def test_truncation_heads_game_word_without_separator():
|
||||
assert _truncation_heads("SORCERER The Game of Magical Conflict")[0] == "SORCERER"
|
||||
|
||||
|
||||
def test_truncation_heads_two_word_fallback():
|
||||
heads = _truncation_heads(
|
||||
"STARFORCE ALPHA CENTAURI Interstellar Conflict in the 25th Century"
|
||||
)
|
||||
assert heads[-1] == "STARFORCE ALPHA"
|
||||
|
||||
|
||||
def test_short_titles_get_no_heads():
|
||||
assert _truncation_heads("Catan") == []
|
||||
assert _truncation_heads("Herbaceous") == []
|
||||
|
||||
|
||||
def test_civilization_resolves_via_truncation(client):
|
||||
entry = _entry(
|
||||
CIV_TITLE,
|
||||
publisher_hint=AH_HINT,
|
||||
edition_hint="Bookcase Game",
|
||||
language_hint="English",
|
||||
)
|
||||
row = resolve_entry(client, entry)
|
||||
assert (row.match_status, row.bgg_id) == ("auto", 71)
|
||||
# publisher cue picks the Avalon Hill version, not Hartland/Gibsons
|
||||
assert row.version_status == "version_auto"
|
||||
assert row.version_id == 71001
|
||||
|
||||
|
||||
def test_advanced_civilization_resolves_as_expansion(client):
|
||||
entry = _entry(
|
||||
"ADVANCED CIVILIZATION Game Expansion of the Heroic Age - "
|
||||
"Featuring New Civilization, Commodity, and Calamity Cards",
|
||||
publisher_hint=AH_HINT,
|
||||
edition_hint="Bookcase Game",
|
||||
language_hint="English",
|
||||
)
|
||||
row = resolve_entry(client, entry)
|
||||
assert (row.match_status, row.bgg_id, row.type) == (
|
||||
"auto",
|
||||
177,
|
||||
"boardgameexpansion",
|
||||
)
|
||||
assert row.version_status == "version_auto"
|
||||
|
||||
|
||||
def test_sorcerer_publisher_tiebreak_beats_owned_dominance(client):
|
||||
"""Head search finds TWO games named 'Sorcerer' (SPI 1975 vs White
|
||||
Wizard 2019, which has far more owners) — the SPI publisher cue must
|
||||
pick the SPI game, and the edition cue the Designer's Edition."""
|
||||
entry = _entry(
|
||||
"SORCERER The Game of Magical Conflict",
|
||||
publisher_hint="Simulations Publications Incorporated (SPI)",
|
||||
edition_hint="Designer's Edition",
|
||||
language_hint="English",
|
||||
)
|
||||
row = resolve_entry(client, entry)
|
||||
assert (row.match_status, row.bgg_id) == ("auto", 3585)
|
||||
assert row.version_status == "version_auto"
|
||||
assert row.version_name == "SPI Designer's Edition"
|
||||
|
||||
|
||||
def test_starforce_two_word_head_matches_full_title(client):
|
||||
entry = _entry(
|
||||
"STARFORCE ALPHA CENTAURI Interstellar Conflict in the 25th Century",
|
||||
publisher_hint="Simulations Publications Incorporated (SPI)",
|
||||
edition_hint="Designer's Edition",
|
||||
language_hint="English",
|
||||
)
|
||||
row = resolve_entry(client, entry)
|
||||
assert (row.match_status, row.bgg_id) == ("auto", 2524)
|
||||
assert row.version_status == "version_auto"
|
||||
|
||||
|
||||
def test_wrong_year_hint_never_drives_a_version(client):
|
||||
"""Flat Top's box says 1942 (the theme, not the print year): version
|
||||
scoring must not pick any version off the back of it."""
|
||||
entry = _entry("FLAT TOP", year_hint=1942, language_hint="English")
|
||||
row = resolve_entry(client, entry)
|
||||
assert (row.match_status, row.bgg_id) == ("auto", 2529)
|
||||
assert row.version_status == "version_unknown"
|
||||
assert row.version_id is None
|
||||
|
||||
Reference in New Issue
Block a user