922 lines
35 KiB
Rust
922 lines
35 KiB
Rust
//! Fixture corpus for `arr-parse` (issue #9): real release names captured
|
|
//! from a manual Torznab search against several Prowlarr indexers (1337x,
|
|
//! YTS, The Pirate Bay, Portugas), with expected parses pinned from the
|
|
//! parser's own (already-tested) output.
|
|
//!
|
|
//! Deliberately covers every resolution and source tier from `DESIGN.md`
|
|
//! §5.5, DV-tagged and DV-untagged 4K releases, multi-audio releases, the
|
|
//! pt-BR/pt-PT markers from §5.2, and real-world malformed names that
|
|
//! must parse partially rather than fail.
|
|
|
|
use arr_parse::{
|
|
parse, Codec, Edition, EpisodeClaim, HdrMarker, LanguageMarker, NameClaims, Resolution, Source,
|
|
};
|
|
use serde as _;
|
|
|
|
struct Case {
|
|
name: String,
|
|
want: NameClaims,
|
|
}
|
|
|
|
#[allow(clippy::unnecessary_wraps)]
|
|
fn s(v: &str) -> Option<String> {
|
|
Some(v.to_string())
|
|
}
|
|
|
|
#[allow(clippy::unnecessary_wraps)]
|
|
fn episodes(season: u32, episodes: &[u32]) -> Option<EpisodeClaim> {
|
|
Some(EpisodeClaim::Episodes {
|
|
season,
|
|
episodes: episodes.to_vec(),
|
|
})
|
|
}
|
|
|
|
/// Every resolution and every source tier appears at least once here,
|
|
/// pulled from a broad search rather than picked to fit.
|
|
#[allow(clippy::too_many_lines)]
|
|
fn matrix_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "Twisters.2024.1080p.BluRay.x264-HiP_EniaHD".into(),
|
|
want: NameClaims {
|
|
title: s("Twisters"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Thine Ears Shall Bleed (2024) 720p WEBRip x264 -YTS".into(),
|
|
want: NameClaims {
|
|
title: s("Thine Ears Shall Bleed"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::WebRip),
|
|
codec: Some(Codec::X264),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Ludwig 2024 S02E01 1080p iP WEB-DL AAC2 0 H 264-RAWR".into(),
|
|
want: NameClaims {
|
|
title: s("Ludwig"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
group: s("RAWR"),
|
|
episode: episodes(2, &[1]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "The Rookie S08E14 720p HDTV x264-SYNCOPY".into(),
|
|
want: NameClaims {
|
|
title: s("The Rookie"),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::Hdtv),
|
|
codec: Some(Codec::X264),
|
|
group: s("SYNCOPY"),
|
|
episode: episodes(8, &[14]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "The King of Queens S03E22 720p BluRay x264-CtrlHD".into(),
|
|
want: NameClaims {
|
|
title: s("The King of Queens"),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X264),
|
|
group: s("CtrlHD"),
|
|
episode: episodes(3, &[22]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Scream.2022.1080p.Bluray.REMUX.AVC.DTS-HD.MA.7.1-4K4U".into(),
|
|
want: NameClaims {
|
|
title: s("Scream"),
|
|
year: Some(2022),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::Remux),
|
|
codec: Some(Codec::X264),
|
|
group: s("4K4U"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "28 Years Later 2025 1080p CAM x264-RGB".into(),
|
|
want: NameClaims {
|
|
title: s("28 Years Later"),
|
|
year: Some(2025),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::Cam),
|
|
codec: Some(Codec::X264),
|
|
group: s("RGB"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "A.Minecraft.Movie.2025.1080p.TeleSync.X264.COLLECTiVE".into(),
|
|
want: NameClaims {
|
|
title: s("A Minecraft Movie"),
|
|
year: Some(2025),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::Telesync),
|
|
codec: Some(Codec::X264),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Alita Battle Angel 2019 720p HDTC x264 AC3-ETRG".into(),
|
|
want: NameClaims {
|
|
title: s("Alita Battle Angel"),
|
|
year: Some(2019),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::Telecine),
|
|
codec: Some(Codec::X264),
|
|
group: s("ETRG"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "1917.2019.1080p.SCREENER.DD.2.0.HEVC-DDR[EtHD]".into(),
|
|
want: NameClaims {
|
|
title: s("1917"),
|
|
year: Some(2019),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::Screener),
|
|
codec: Some(Codec::X265),
|
|
group: s("DDR"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "A.Hidden.Life.2019.DVDSCR.x264-TOPKEK".into(),
|
|
want: NameClaims {
|
|
title: s("A Hidden Life"),
|
|
year: Some(2019),
|
|
source: Some(Source::Screener),
|
|
codec: Some(Codec::X264),
|
|
group: s("TOPKEK"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Taina.A.Origem.2014.DVDRip.XviD.Nacional.SenhoreSTorrenT".into(),
|
|
want: NameClaims {
|
|
title: s("Taina A Origem"),
|
|
year: Some(2014),
|
|
source: Some(Source::Dvd),
|
|
codec: Some(Codec::Xvid),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// Portugas appends "Portuguese PT-PT" after the real release
|
|
// name; both tokens are genuine language markers to this crate.
|
|
name: "Sinais.de.Fogo.1995.PAL.DVD.REMUX.MPEG-2.DD.5.1-SANTANA Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("Sinais de Fogo"),
|
|
year: Some(1995),
|
|
source: Some(Source::Remux),
|
|
languages: vec![LanguageMarker::Portuguese, LanguageMarker::PtPt],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Papamobile (2025) 1080p BRRip 5.1 x264 -YTS".into(),
|
|
want: NameClaims {
|
|
title: s("Papamobile"),
|
|
year: Some(2025),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X264),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "La caméra de Claire (2017) 720p BRRip x264 -YTS".into(),
|
|
want: NameClaims {
|
|
title: s("La caméra de Claire"),
|
|
year: Some(2017),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X264),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Vampire.Hunter.D.1985.1080p.BDRip.Dual.Audio.10bits.x265-Rapta".into(),
|
|
want: NameClaims {
|
|
title: s("Vampire Hunter D"),
|
|
year: Some(1985),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
languages: vec![LanguageMarker::Dual],
|
|
group: s("Rapta"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Dune.2021.2160p.HMAX.WEB-DL.DDP5.1.Atmos.HDR.HEVC-EVO[TGx]".into(),
|
|
want: NameClaims {
|
|
title: s("Dune"),
|
|
year: Some(2021),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
hdr: vec![HdrMarker::Hdr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "National.Treasure:.Edge.of.History.S01.2160p.WEB-DL.DD+.5.1.Atmos.H.265-NTb"
|
|
.into(),
|
|
want: NameClaims {
|
|
title: s("National Treasure: Edge of History"),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
group: s("NTb"),
|
|
episode: Some(EpisodeClaim::Season { season: 1 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// DV-untagged 4K: no HDR marker at all despite being a real UHD
|
|
// release.
|
|
name: "All.Of.Us.Strangers.2023.2160p.4K.WEB.x265.10bit.AAC5.1 [YTS.MX] [88]".into(),
|
|
want: NameClaims {
|
|
title: s("All Of Us Strangers"),
|
|
year: Some(2023),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
group: s("YTS.MX"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Alien.1979.THEATRICAL.PROPER.2160p.BluRay.REMUX.HEVC.DTS-HD.MA.5.1-FGT".into(),
|
|
want: NameClaims {
|
|
title: s("Alien"),
|
|
year: Some(1979),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::Remux),
|
|
codec: Some(Codec::X265),
|
|
editions: vec![Edition::Theatrical],
|
|
group: s("FGT"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "WWE Friday Night Smackdown 2026 08 21 SatFeed 480p HDTV H264 Star [TJET]".into(),
|
|
want: NameClaims {
|
|
title: s("WWE Friday Night Smackdown"),
|
|
year: Some(2026),
|
|
resolution: Some(Resolution::P480),
|
|
source: Some(Source::Hdtv),
|
|
codec: Some(Codec::X264),
|
|
group: s("TJET"),
|
|
episode: Some(EpisodeClaim::Daily { year: 2026, month: 8, day: 21 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// No source token at all beyond a bare resolution.
|
|
name: "Court Cam S08E37 480p x264-mSD".into(),
|
|
want: NameClaims {
|
|
title: s("Court Cam"),
|
|
resolution: Some(Resolution::P480),
|
|
codec: Some(Codec::X264),
|
|
group: s("mSD"),
|
|
episode: episodes(8, &[37]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// `AUHDTV` is a real tag this crate doesn't recognise — source
|
|
// stays unclaimed rather than guessed.
|
|
name: "A League Of Their Own UK Road Trip Southeast Asia S01E01 INTERNAL 2160p AUHDTV x265-FaiLED".into(),
|
|
want: NameClaims {
|
|
title: s("A League Of Their Own UK Road Trip Southeast Asia"),
|
|
resolution: Some(Resolution::P2160),
|
|
codec: Some(Codec::X265),
|
|
group: s("FaiLED"),
|
|
episode: episodes(1, &[1]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "The Tale of The Princess Kaguya 2013 BRRip DUAL AUDIO".into(),
|
|
want: NameClaims {
|
|
title: s("The Tale of The Princess Kaguya"),
|
|
year: Some(2013),
|
|
source: Some(Source::BluRay),
|
|
languages: vec![LanguageMarker::Dual],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Watchmen: Chapter II.2024.2160p.HDR10.BRRip.OPUS5.1.AV1.BluBit".into(),
|
|
want: NameClaims {
|
|
title: s("Watchmen: Chapter II"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::Av1),
|
|
hdr: vec![HdrMarker::Hdr10],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
/// The pt-BR / pt-PT markers from `DESIGN.md` §5.2, pulled mostly from the
|
|
/// Portugas indexer. This crate only reports what the name claims;
|
|
/// resolving pt-BR vs. pt-PT ambiguity is the policy engine's job.
|
|
#[allow(clippy::too_many_lines)]
|
|
fn pt_br_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "007 Contra Spectre 2015 1080p BluRay DUAL [Dublado] LAPUMiA".into(),
|
|
want: NameClaims {
|
|
title: s("007 Contra Spectre"),
|
|
year: Some(2015),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
languages: vec![LanguageMarker::Dual, LanguageMarker::PtBr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Afonso.Padilha.Geracoes.2023.1080p.WEB-DL.NACIONAL.5.1-COMANDOPLAY".into(),
|
|
want: NameClaims {
|
|
title: s("Afonso Padilha Geracoes"),
|
|
year: Some(2023),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
group: s("COMANDOPLAY"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// `HDRip` isn't in this crate's source vocabulary — real
|
|
// releases do claim tags outside it, and source stays `None`.
|
|
name: "A.Culpa.E.Das.Estrelas.2014.DUBLADO.HDRip.XViD-AFTP".into(),
|
|
want: NameClaims {
|
|
title: s("A Culpa E Das Estrelas"),
|
|
year: Some(2014),
|
|
codec: Some(Codec::Xvid),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
group: s("AFTP"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Marília Mendonça DVD Ao Vivo (2015)".into(),
|
|
want: NameClaims {
|
|
title: s("Marília Mendonça"),
|
|
year: Some(2015),
|
|
source: Some(Source::Dvd),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Princesinha.Sofia.Era.Uma.Vez.DVDRip.XviD.MP3.Dublado.PT-BR.avi".into(),
|
|
want: NameClaims {
|
|
title: s("Princesinha Sofia Era Uma Vez"),
|
|
source: Some(Source::Dvd),
|
|
codec: Some(Codec::Xvid),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "A.África.de.José.de.Guimarães.2013.576p.FLMN.WEB-DL.AAC.2.0.H.264-1v0live.mkv Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("A África de José de Guimarães"),
|
|
year: Some(2013),
|
|
resolution: Some(Resolution::P576),
|
|
source: Some(Source::WebDl),
|
|
languages: vec![LanguageMarker::Portuguese, LanguageMarker::PtPt],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Aleixo.PSI.2017.S01.1080i.SICR.HDTV.AAC.2.0.H264-MTRX Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("Aleixo PSI"),
|
|
year: Some(2017),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::Hdtv),
|
|
languages: vec![LanguageMarker::Portuguese, LanguageMarker::PtPt],
|
|
episode: Some(EpisodeClaim::Season { season: 1 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Camilo.o.Pendura.S01.576p.WEB-DL.AAC.2.0.H.264-1v0live Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("Camilo o Pendura"),
|
|
resolution: Some(Resolution::P576),
|
|
source: Some(Source::WebDl),
|
|
languages: vec![LanguageMarker::Portuguese, LanguageMarker::PtPt],
|
|
episode: Some(EpisodeClaim::Season { season: 1 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Espiao.Nacionalizado.Nosso.1975.576p.TVRip.x264.AAC.2.0-CRVLX Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("Espiao Nacionalizado Nosso"),
|
|
year: Some(1975),
|
|
resolution: Some(Resolution::P576),
|
|
codec: Some(Codec::X264),
|
|
languages: vec![LanguageMarker::Portuguese, LanguageMarker::PtPt],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "GOAT.2026.1080p.BluRay.AV1.10bit.HDR.MULTi.Opus-Maghuro.mkv Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("GOAT"),
|
|
year: Some(2026),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::Av1),
|
|
hdr: vec![HdrMarker::Hdr],
|
|
languages: vec![
|
|
LanguageMarker::Multi,
|
|
LanguageMarker::Portuguese,
|
|
LanguageMarker::PtPt,
|
|
],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Lion.Of.Oz.2000.HYBRID.576p.DVDRip.x264.MULTI.DD.2.0-CRVLX Portuguese PT-PT".into(),
|
|
want: NameClaims {
|
|
title: s("Lion Of Oz"),
|
|
year: Some(2000),
|
|
resolution: Some(Resolution::P576),
|
|
source: Some(Source::Dvd),
|
|
codec: Some(Codec::X264),
|
|
languages: vec![
|
|
LanguageMarker::Multi,
|
|
LanguageMarker::Portuguese,
|
|
LanguageMarker::PtPt,
|
|
],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
/// Multi-audio releases: `MULTi`/`MULTI` and `DUAL`/`DUAL AUDIO` in the
|
|
/// wild, including combinations with explicit language names.
|
|
fn multi_audio_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "Haikyu S04E18 MULTi 480p x264-mSD".into(),
|
|
want: NameClaims {
|
|
title: s("Haikyu"),
|
|
resolution: Some(Resolution::P480),
|
|
codec: Some(Codec::X264),
|
|
languages: vec![LanguageMarker::Multi],
|
|
group: s("mSD"),
|
|
episode: episodes(4, &[18]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "113 2025 S01E01 MULTI 1080p WEB X264-HiggsBoson".into(),
|
|
want: NameClaims {
|
|
title: s("113"),
|
|
year: Some(2025),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
languages: vec![LanguageMarker::Multi],
|
|
group: s("HiggsBoson"),
|
|
episode: episodes(1, &[1]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Absolon 2003 720p WEB-DL x264 Eng Subs Dual Audio Hindi DDP 2.0 English DDP 2.0 Exclusive By Dr-STAR".into(),
|
|
want: NameClaims {
|
|
title: s("Absolon"),
|
|
year: Some(2003),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
languages: vec![LanguageMarker::English, LanguageMarker::Dual],
|
|
group: s("STAR"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Death Note Relight 2 L's Successors (2008) (1080p BluRay x265 10 bit Dual Audio) [WeSLeY]".into(),
|
|
want: NameClaims {
|
|
title: s("Death Note Relight 2 L's Successors"),
|
|
year: Some(2008),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
languages: vec![LanguageMarker::Dual],
|
|
group: s("WeSLeY"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "A.Shop.for.Killers.S02.2160p.DSNP.WEB-DL.DUAL.DD+.5.1.DV.HDR10+.H.265-Kitsune".into(),
|
|
want: NameClaims {
|
|
title: s("A Shop for Killers"),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10Plus],
|
|
languages: vec![LanguageMarker::Dual],
|
|
group: s("Kitsune"),
|
|
episode: Some(EpisodeClaim::Season { season: 2 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Avengers.Age.of.Ultron.2015.Multi.UHD.2160p.Blu-Ray.x265.HDR.ATM".into(),
|
|
want: NameClaims {
|
|
title: s("Avengers Age of Ultron"),
|
|
year: Some(2015),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::Hdr],
|
|
languages: vec![LanguageMarker::Multi],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
/// DV-tagged 4K releases from real UHD uploads (`DESIGN.md` §5.3): every
|
|
/// HDR marker shape appearing alongside `DV`, plus AV1/HEVC codec
|
|
/// variety and an `IMAX` edition.
|
|
#[allow(clippy::too_many_lines)]
|
|
fn dv_hdr_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "28.Years.Later.The.Bone.Temple.2026.2160p.WEB-DL.DV.HDR10+.DDP5.1.Atmos.MP4-BTM".into(),
|
|
want: NameClaims {
|
|
title: s("28 Years Later The Bone Temple"),
|
|
year: Some(2026),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10Plus],
|
|
group: s("BTM"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// `BRRemux` isn't in this crate's vocabulary; source stays
|
|
// unclaimed rather than guessed at.
|
|
name: "Ace Ventura - When Nature Calls (1995) 2160p BRRemux h265 DV HDR10 5.1 -3G_Rips".into(),
|
|
want: NameClaims {
|
|
title: s("Ace Ventura - When Nature Calls"),
|
|
year: Some(1995),
|
|
resolution: Some(Resolution::P2160),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "After Hours 1985 UHD BluRay 2160p HDR10 DV HEVC FLAC 1.0 x265-E".into(),
|
|
want: NameClaims {
|
|
title: s("After Hours"),
|
|
year: Some(1985),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::Hdr10, HdrMarker::DolbyVision],
|
|
group: s("E"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Akira.1988.UHD.BluRay.2160p.TrueHD.Atmos.7.1.DV.HEVC.HYBRID.REMUX-FraMeSToR".into(),
|
|
want: NameClaims {
|
|
title: s("Akira"),
|
|
year: Some(1988),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::Remux),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::DolbyVision],
|
|
group: s("FraMeSToR"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Aquaman (2018) IMAX 2160p 4K UHD HDR10 DV Blu ray REMUX Dual Audio [Hindi + English] ESub ~ RemuxDoc".into(),
|
|
want: NameClaims {
|
|
title: s("Aquaman"),
|
|
year: Some(2018),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::Remux),
|
|
hdr: vec![HdrMarker::Hdr10, HdrMarker::DolbyVision],
|
|
languages: vec![LanguageMarker::Dual, LanguageMarker::English],
|
|
editions: vec![Edition::Imax],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Abraham's Boys 2025 UHD BluRay 2160p HDR10+ HEVC DTS HD MA 5.1 x265-E".into(),
|
|
want: NameClaims {
|
|
title: s("Abraham's Boys"),
|
|
year: Some(2025),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::Hdr10Plus],
|
|
group: s("E"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Sweeney.Todd.The.Demon.Barber.of.Fleet.Street.2007.2160p.UHD.BluRay.Opus.5.1.HDR.AV1-Maghuro.mkv".into(),
|
|
want: NameClaims {
|
|
title: s("Sweeney Todd The Demon Barber of Fleet Street"),
|
|
year: Some(2007),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::Av1),
|
|
hdr: vec![HdrMarker::Hdr],
|
|
group: s("Maghuro"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Come.Play.2020.2160p.WEB-DL.HDR.DTS.5.1.H.265-4K4U".into(),
|
|
want: NameClaims {
|
|
title: s("Come Play"),
|
|
year: Some(2020),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::Hdr],
|
|
group: s("4K4U"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
/// Real names that are simply malformed — stray quoting, an HTML entity
|
|
/// leaking through, non-media metadata, an escaped apostrophe, multiple
|
|
/// spaces. Every one must still parse *partially* rather than fail
|
|
/// (`arr_parse::parse` never panics or errors).
|
|
fn malformed_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "2.Coelhos.2012.BRRip.720p.x264-VTM_SL '(Nacional)'".into(),
|
|
want: NameClaims {
|
|
title: s("2 Coelhos"),
|
|
year: Some(2012),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::BluRay),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "A Busca (2013) BDRip bluray 720p '' Nacional -derew".into(),
|
|
want: NameClaims {
|
|
title: s("A Busca"),
|
|
year: Some(2013),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::BluRay),
|
|
languages: vec![LanguageMarker::PtBr],
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// An unescaped `&` HTML entity, straight from the indexer.
|
|
name:
|
|
"Bill & Ted's Bogus Journey 1991 UHD BluRay 2160p HDR10 DV HEVC LPCM 2.0 x265-E"
|
|
.into(),
|
|
want: NameClaims {
|
|
title: s("Bill & Ted's Bogus Journey"),
|
|
year: Some(1991),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::Hdr10, HdrMarker::DolbyVision],
|
|
group: s("E"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
// Not a movie or TV release at all — a game upload. Degrades
|
|
// to a title-only claim rather than failing.
|
|
name: "DEMON'S TILT b11419829 MULTi10 GNU/Linux Wine jc141 (Appid=422510)"
|
|
.into(),
|
|
want: NameClaims {
|
|
title: s("DEMON'S TILT b11419829 MULTi10 GNU/Linux Wine jc141 Appid=422510"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Agenty Bezopasnoj Nacional\\'nosti [RUS][Novyj Disk](2007)".into(),
|
|
want: NameClaims {
|
|
title: s("Agenty Bezopasnoj Nacional\\'nosti RUS Novyj Disk"),
|
|
year: Some(2007),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Punk'd (2003) Season 1 S01 (480i NTSC DVD Remux AC3 2.0)".into(),
|
|
want: NameClaims {
|
|
title: s("Punk'd"),
|
|
year: Some(2003),
|
|
resolution: Some(Resolution::P480),
|
|
source: Some(Source::Remux),
|
|
episode: Some(EpisodeClaim::Season { season: 1 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
/// Season and episode tags, the distinction grab selection turns on
|
|
/// (issue #37): single episodes, season packs, multi-episode files and
|
|
/// daily-dated shows.
|
|
#[allow(clippy::too_many_lines)]
|
|
fn tv_cases() -> Vec<Case> {
|
|
vec![
|
|
Case {
|
|
name: "The Rookie S08E14 720p HDTV x264-SYNCOPY".into(),
|
|
want: NameClaims {
|
|
title: s("The Rookie"),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::Hdtv),
|
|
codec: Some(Codec::X264),
|
|
group: s("SYNCOPY"),
|
|
episode: episodes(8, &[14]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Slow.Horses.1x02.1080p.WEB-DL.DDP5.1.H.264-NTb".into(),
|
|
want: NameClaims {
|
|
title: s("Slow Horses"),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
group: s("NTb"),
|
|
episode: episodes(1, &[2]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Severance.S02.2160p.ATVP.WEB-DL.DDP5.1.Atmos.DV.HDR.H.265-FLUX".into(),
|
|
want: NameClaims {
|
|
title: s("Severance"),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr],
|
|
group: s("FLUX"),
|
|
episode: Some(EpisodeClaim::Season { season: 2 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "The Bear Season 3 1080p WEB-DL x265-GROUP".into(),
|
|
want: NameClaims {
|
|
title: s("The Bear"),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
group: s("GROUP"),
|
|
episode: Some(EpisodeClaim::Season { season: 3 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Peep.Show.S01-S09.COMPLETE.1080p.BluRay.x264-SHORTBREHD".into(),
|
|
want: NameClaims {
|
|
title: s("Peep Show"),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::BluRay),
|
|
codec: Some(Codec::X264),
|
|
group: s("SHORTBREHD"),
|
|
episode: Some(EpisodeClaim::Seasons { first: 1, last: 9 }),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Adventure.Time.S05E01E02.1080p.WEB-DL.AAC2.0.H.264-iT00NZ".into(),
|
|
want: NameClaims {
|
|
title: s("Adventure Time"),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
group: s("iT00NZ"),
|
|
episode: episodes(5, &[1, 2]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Bluey.S03E01-E04.1080p.WEB-DL.DD+5.1.H.264-playWEB".into(),
|
|
want: NameClaims {
|
|
title: s("Bluey"),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
group: s("playWEB"),
|
|
episode: episodes(3, &[1, 2, 3, 4]),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "The.Daily.Show.2024.05.13.Jon.Stewart.1080p.WEB.h264-EDITH".into(),
|
|
want: NameClaims {
|
|
title: s("The Daily Show"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P1080),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X264),
|
|
group: s("EDITH"),
|
|
episode: Some(EpisodeClaim::Daily {
|
|
year: 2024,
|
|
month: 5,
|
|
day: 13,
|
|
}),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Last.Week.Tonight.With.John.Oliver.2024-09-15.720p.HDTV.x264-aAF".into(),
|
|
want: NameClaims {
|
|
title: s("Last Week Tonight With John Oliver"),
|
|
resolution: Some(Resolution::P720),
|
|
source: Some(Source::Hdtv),
|
|
codec: Some(Codec::X264),
|
|
group: s("aAF"),
|
|
episode: Some(EpisodeClaim::Daily {
|
|
year: 2024,
|
|
month: 9,
|
|
day: 15,
|
|
}),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
Case {
|
|
name: "Dune.Part.Two.2024.2160p.WEB-DL.DDP5.1.Atmos.H.265-FLUX".into(),
|
|
want: NameClaims {
|
|
title: s("Dune Part Two"),
|
|
year: Some(2024),
|
|
resolution: Some(Resolution::P2160),
|
|
source: Some(Source::WebDl),
|
|
codec: Some(Codec::X265),
|
|
group: s("FLUX"),
|
|
..NameClaims::default()
|
|
},
|
|
},
|
|
]
|
|
}
|
|
|
|
fn all_cases() -> Vec<Case> {
|
|
let mut cases = matrix_cases();
|
|
cases.extend(pt_br_cases());
|
|
cases.extend(multi_audio_cases());
|
|
cases.extend(dv_hdr_cases());
|
|
cases.extend(malformed_cases());
|
|
cases.extend(tv_cases());
|
|
cases
|
|
}
|
|
|
|
#[test]
|
|
fn corpus_rows_parse_as_expected() {
|
|
let cases = all_cases();
|
|
let mut failures = Vec::new();
|
|
for Case { name, want } in &cases {
|
|
let got = parse(name);
|
|
if &got != want {
|
|
failures.push(format!("{name:?}\n got: {got:?}\n want: {want:?}"));
|
|
}
|
|
}
|
|
assert!(
|
|
failures.is_empty(),
|
|
"{}/{} mismatches:\n{}",
|
|
failures.len(),
|
|
cases.len(),
|
|
failures.join("\n")
|
|
);
|
|
}
|