diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-29 15:43:38 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-29 15:43:38 +0200 |
| commit | 5d28d0c96cc8489645178b483835489779cb3887 (patch) | |
| tree | 90248f1c3211ca37495a774d0bc140109c299abc /packages/meshbay-node/tests/test_title_parse.py | |
| parent | 236e5e811355212945b89c4f7a99df5c837e97c7 (diff) | |
| download | meshbay-5d28d0c96cc8489645178b483835489779cb3887.tar.gz | |
feat(node): V8–V11 — show-branch ladder, year-aware _best_match, wider sequel_variants
V8: the TV/show branch of _tmdb_search used the old "first candidate over
0.6 wins" shape. It now shares one _tmdb_ladder helper with the movie
branch — score every candidate query, keep the best, fast-path a
confident primary hit. A year lifted off the show's folder name
(title_parse.year_in, e.g. "Some.Show.2022.S01") rescues a sub-0.6 hit
that lands on the exact year. title_parse.clean_query de-dots a
folder-derived title without naive_title's extension-stripping trap.
V9: _best_match gains an optional `year`. When the top result is not a
confident textual hit (ratio < 0.6) and a year was requested, a
different result of that exact release year is preferred — TMDB already
year-filtered the search, so this is a hard corroboration, not the fuzzy
re-rank §3.3 warns against. A confident top hit is never overridden.
search_movie/search_tv forward the year.
V10: sequel_variants widened — trailing Roman→digit as well as
digit→Roman, spelled-out indices (one..twelve / un..douze / ordinals),
and a "Part N" / "Chapitre N" wrapper. Still empty for a trailing word
that is not an index or a 4-digit year.
V11: when the primary hit is already decent (>= 0.6) and there is nothing
more specific to try (no alternative_title, no sequel variant — only a
punctuation restatement left), the ladder returns without the extra
requests. The clean-title common case is back to one call.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018BMLQjqFGCize2KtNBT79v
Diffstat (limited to 'packages/meshbay-node/tests/test_title_parse.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_title_parse.py | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_title_parse.py b/packages/meshbay-node/tests/test_title_parse.py index 03fb588..ac4d434 100644 --- a/packages/meshbay-node/tests/test_title_parse.py +++ b/packages/meshbay-node/tests/test_title_parse.py @@ -6,12 +6,14 @@ is a manual acceptance step (§11), not something this repo's corpus holds. from meshbay_node.indexer.title_parse import ( ParsedName, + clean_query, leading_episode_number, naive_title, parse_episode_filename, parse_movie_filename, season_from_folder_name, sequel_variants, + year_in, ) @@ -69,6 +71,48 @@ def test_sequel_variants_empty_when_no_trailing_digit(): assert sequel_variants("Some Movie") == [] +# ── §10.1/V10: wider sequel-index handling ────────────────────────────────── + +def test_sequel_variants_roman_numeral_offers_the_digit_form(): + v = sequel_variants("Old Frontier III") + assert "Old Frontier" in v + assert "Old Frontier 3" in v + + +def test_sequel_variants_strips_a_part_keyword_wrapper(): + v = sequel_variants("Some Saga Part 2") + assert "Some Saga" in v + assert "Some Saga II" in v + + +def test_sequel_variants_reads_a_spelled_out_index(): + v = sequel_variants("Story Chapter Three") + assert "Story" in v + assert "Story 3" in v and "Story III" in v + + +def test_sequel_variants_ignores_a_trailing_word_that_is_not_an_index(): + assert sequel_variants("The Dark Knight") == [] + assert sequel_variants("In Bruges") == [] + + +def test_sequel_variants_ignores_a_four_digit_year_suffix(): + assert sequel_variants("Blade Runner 2049") == [] + + +def test_year_in_lifts_a_year_from_a_show_folder_name(): + assert year_in("Some.Show.2022.S01") == 2022 + assert year_in("Some Show") is None + assert year_in("Episode 100 of 2010") == 2010 + + +def test_clean_query_despaces_a_folder_name_without_eating_the_last_word(): + # naive_title would rsplit on the last dot and drop ".Name" + assert clean_query("Some.Show.Name") == "Some Show Name" + assert clean_query("Some.Show.Name.S01") == "Some Show Name S01" + assert naive_title("Some.Show.Name") != "Some Show Name" # the trap it avoids + + # ── bug 2026-08-29: guessit peels "Volume N" off the title ───────────────── def test_movie_volume_number_is_folded_back_into_the_title(): |