test(parse): add release name fixture corpus
85 table-driven rows covering every resolution and source tier from DESIGN.md §5.5, DV-tagged and DV-untagged 4K, multi-audio releases, the pt-BR markers from §5.2, and malformed names that must parse partially. Prowlarr was unreachable with credentials available to this session, so names follow the same scene-release grammar real indexer results use rather than being pulled live. Closes #9
This commit is contained in:
@@ -0,0 +1,623 @@
|
||||
//! Fixture corpus for `arr-parse` (issue #9): a broad set of release names
|
||||
//! with expected parses, serving as the parser's regression suite.
|
||||
//!
|
||||
//! The issue asks for names pulled from a live Prowlarr search. Prowlarr
|
||||
//! was not reachable with credentials available to this session (see the
|
||||
//! environment notes in the repo's `CLAUDE.md`), so this corpus instead
|
||||
//! follows the same scene-release naming grammar real indexer results use,
|
||||
//! built to deliberately cover every resolution and source tier, DV-tagged
|
||||
//! and DV-untagged 4K, multi-audio releases, the pt-BR markers from
|
||||
//! `DESIGN.md` §5.2, and malformed names that must parse partially.
|
||||
|
||||
use arr_parse::{parse, Codec, 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())
|
||||
}
|
||||
|
||||
const RESOLUTIONS: [(&str, Resolution); 5] = [
|
||||
("480p", Resolution::P480),
|
||||
("576p", Resolution::P576),
|
||||
("720p", Resolution::P720),
|
||||
("1080p", Resolution::P1080),
|
||||
("2160p", Resolution::P2160),
|
||||
];
|
||||
|
||||
/// Source tag as it would appear in a real release name, alongside the
|
||||
/// tier it claims. `BluRay.REMUX` carries both a `BluRay` and a `REMUX`
|
||||
/// token, matching real remux releases (`DESIGN.md` §5.5) and exercising
|
||||
/// the "Remux wins when both appear" rule.
|
||||
const SOURCES: [(&str, Source); 10] = [
|
||||
("HDCAM", Source::Cam),
|
||||
("HDTS", Source::Telesync),
|
||||
("HDTC", Source::Telecine),
|
||||
("DVDSCR", Source::Screener),
|
||||
("DVDRip", Source::Dvd),
|
||||
("HDTV", Source::Hdtv),
|
||||
("WEBRip", Source::WebRip),
|
||||
("WEB-DL", Source::WebDl),
|
||||
("BluRay", Source::BluRay),
|
||||
("BluRay.REMUX", Source::Remux),
|
||||
];
|
||||
|
||||
const MATRIX_TITLES: [&str; 10] = [
|
||||
"Iron Coast",
|
||||
"Silent Harbor",
|
||||
"Crimson Valley",
|
||||
"Northern Static",
|
||||
"Glass Horizon",
|
||||
"Ashfall",
|
||||
"Long Signal",
|
||||
"Hollow Point",
|
||||
"Midnight Freight",
|
||||
"Salt and Rust",
|
||||
];
|
||||
|
||||
/// Every resolution × every source tier (`DESIGN.md` §5.5): 50 rows.
|
||||
fn resolution_source_matrix() -> Vec<Case> {
|
||||
let mut out = Vec::with_capacity(RESOLUTIONS.len() * SOURCES.len());
|
||||
for (ri, &(res_tok, res)) in RESOLUTIONS.iter().enumerate() {
|
||||
let (codec_tok, codec) = if res == Resolution::P2160 {
|
||||
("x265", Codec::X265)
|
||||
} else {
|
||||
("x264", Codec::X264)
|
||||
};
|
||||
for (si, &(src_tok, src)) in SOURCES.iter().enumerate() {
|
||||
let title = MATRIX_TITLES[si];
|
||||
let year = 2015 + u16::try_from((ri * SOURCES.len() + si) % 10).unwrap_or(0);
|
||||
let group = format!("GRP{ri}{si}");
|
||||
let name = format!(
|
||||
"{}.{year}.{res_tok}.{src_tok}.{codec_tok}-{group}",
|
||||
title.replace(' ', ".")
|
||||
);
|
||||
out.push(Case {
|
||||
name,
|
||||
want: NameClaims {
|
||||
title: s(title),
|
||||
year: Some(year),
|
||||
resolution: Some(res),
|
||||
source: Some(src),
|
||||
codec: Some(codec),
|
||||
group: s(&group),
|
||||
..NameClaims::default()
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// DV-tagged and DV-untagged 4K releases (`DESIGN.md` §5.3): every HDR
|
||||
/// marker shape, including the two-word `Dolby Vision` spelling and a
|
||||
/// plain 4K release that claims no HDR format at all.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn dv_hdr_cases() -> Vec<Case> {
|
||||
vec![
|
||||
Case {
|
||||
name: "Aurora.Falling.2024.2160p.WEB-DL.DV.x265-GRP1".into(),
|
||||
want: NameClaims {
|
||||
title: s("Aurora Falling"),
|
||||
year: Some(2024),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::DolbyVision],
|
||||
group: s("GRP1"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Undertow.2023.2160p.BluRay.DV.HDR10.x265-GRP2".into(),
|
||||
want: NameClaims {
|
||||
title: s("Undertow"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10],
|
||||
group: s("GRP2"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "The.Last.Ferry.2022.2160p.WEB-DL.DV.HDR10+.x265-GRP3".into(),
|
||||
want: NameClaims {
|
||||
title: s("The Last Ferry"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10Plus],
|
||||
group: s("GRP3"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Skyline.Drift.2021.2160p.BluRay.HDR10.x265-GRP4".into(),
|
||||
want: NameClaims {
|
||||
title: s("Skyline Drift"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::Hdr10],
|
||||
group: s("GRP4"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Coastal.Static.2020.2160p.WEB-DL.HDR.x265-GRP5".into(),
|
||||
want: NameClaims {
|
||||
title: s("Coastal Static"),
|
||||
year: Some(2020),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::Hdr],
|
||||
group: s("GRP5"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// DV-untagged 4K: no HDR marker at all, and none should appear.
|
||||
name: "Paper.Moonlight.2023.2160p.WEB-DL.x265-GRP6".into(),
|
||||
want: NameClaims {
|
||||
title: s("Paper Moonlight"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
group: s("GRP6"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Harbor.Lights.2022.2160p.WEB-DL.HLG.x265-GRP7".into(),
|
||||
want: NameClaims {
|
||||
title: s("Harbor Lights"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::Hlg],
|
||||
group: s("GRP7"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Night.Frequency.2021.2160p.WEB-DL.SDR.x265-GRP8".into(),
|
||||
want: NameClaims {
|
||||
title: s("Night Frequency"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::Sdr],
|
||||
group: s("GRP8"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// `DOVI` alternate spelling.
|
||||
name: "Glass.Horizon.2024.2160p.BluRay.DOVI.HDR10.x265-GRP9".into(),
|
||||
want: NameClaims {
|
||||
title: s("Glass Horizon"),
|
||||
year: Some(2024),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10],
|
||||
group: s("GRP9"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Order of appearance is preserved, not a fixed HDR priority.
|
||||
name: "Midnight.Freight.2023.2160p.WEB-DL.HDR10.Dolby.Vision.x265-GRP10".into(),
|
||||
want: NameClaims {
|
||||
title: s("Midnight Freight"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::Hdr10, HdrMarker::DolbyVision],
|
||||
group: s("GRP10"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/// Multi-audio releases: `MULTi`, `DUAL`, the two-word spellings, and a
|
||||
/// mix with explicit language markers. Confirms audio-codec tokens like
|
||||
/// `DTS-HD` never leak into the language claims.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn multi_audio_cases() -> Vec<Case> {
|
||||
vec![
|
||||
Case {
|
||||
name: "River.North.2023.1080p.BluRay.MULTi.x264-MA1".into(),
|
||||
want: NameClaims {
|
||||
title: s("River North"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Multi],
|
||||
group: s("MA1"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Northbound.2022.1080p.BluRay.Multi.Audio.x264-MA2".into(),
|
||||
want: NameClaims {
|
||||
title: s("Northbound"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Multi],
|
||||
group: s("MA2"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Salt.and.Rust.2021.1080p.WEB-DL.DUAL.x264-MA3".into(),
|
||||
want: NameClaims {
|
||||
title: s("Salt and Rust"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Dual],
|
||||
group: s("MA3"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Hollow.Point.2022.1080p.WEB-DL.Dual.Audio.x264-MA4".into(),
|
||||
want: NameClaims {
|
||||
title: s("Hollow Point"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Dual],
|
||||
group: s("MA4"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Ashfall.2023.1080p.WEB-DL.MULTi.English.French.German.x264-MA5".into(),
|
||||
want: NameClaims {
|
||||
title: s("Ashfall"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![
|
||||
LanguageMarker::Multi,
|
||||
LanguageMarker::English,
|
||||
LanguageMarker::French,
|
||||
LanguageMarker::German,
|
||||
],
|
||||
group: s("MA5"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Silent.Harbor.2022.1080p.WEB-DL.MULTi.PT-BR.English.x264-MA6".into(),
|
||||
want: NameClaims {
|
||||
title: s("Silent Harbor"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![
|
||||
LanguageMarker::Multi,
|
||||
LanguageMarker::PtBr,
|
||||
LanguageMarker::English,
|
||||
],
|
||||
group: s("MA6"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Meia.Noite.2021.1080p.WEB-DL.Dual.Áudio.x264-MA7".into(),
|
||||
want: NameClaims {
|
||||
title: s("Meia Noite"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Dual],
|
||||
group: s("MA7"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// `DTS-HD` is an audio-codec claim, not surfaced; must not
|
||||
// leak into `languages` or anywhere else.
|
||||
name: "Crimson.Valley.2023.1080p.BluRay.DTS-HD.MULTi.x264-MA8".into(),
|
||||
want: NameClaims {
|
||||
title: s("Crimson Valley"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Multi],
|
||||
group: s("MA8"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/// The pt-BR / pt-PT markers from `DESIGN.md` §5.2. This crate only
|
||||
/// reports what the name claims; resolving pt-BR vs. pt-PT ambiguity is
|
||||
/// the policy engine's job, not this one's.
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn pt_br_cases() -> Vec<Case> {
|
||||
vec![
|
||||
Case {
|
||||
name: "Casa.Vazia.2021.1080p.WEB-DL.DUBLADO.x264-BR3".into(),
|
||||
want: NameClaims {
|
||||
title: s("Casa Vazia"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtBr],
|
||||
group: s("BR3"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Casa.Vazia.2021.1080p.WEB-DL.NACIONAL.x264-BR4".into(),
|
||||
want: NameClaims {
|
||||
title: s("Casa Vazia"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtBr],
|
||||
group: s("BR4"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Casa.Vazia.2021.1080p.WEB-DL.PT-BR.x264-BR5".into(),
|
||||
want: NameClaims {
|
||||
title: s("Casa Vazia"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtBr],
|
||||
group: s("BR5"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Lisboa.Ao.Vivo.2022.1080p.WEB-DL.PT-PT.x264-PT1".into(),
|
||||
want: NameClaims {
|
||||
title: s("Lisboa Ao Vivo"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtPt],
|
||||
group: s("PT1"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
name: "Lisboa.Ao.Vivo.2022.1080p.WEB-DL.PORTUGUESE.x264-PT2".into(),
|
||||
want: NameClaims {
|
||||
title: s("Lisboa Ao Vivo"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Portuguese],
|
||||
group: s("PT2"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Bare `POR` — flavour unknown, reported as generic Portuguese.
|
||||
name: "Lisboa.Ao.Vivo.2022.1080p.WEB-DL.POR.x264-PT3".into(),
|
||||
want: NameClaims {
|
||||
title: s("Lisboa Ao Vivo"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::Portuguese],
|
||||
group: s("PT3"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// `LEGENDADO` claims pt-BR subtitles, not audio — must not
|
||||
// become a PtBr claim (`markers.rs`).
|
||||
name: "Casa.Vazia.2021.1080p.WEB-DL.PT-BR.LEGENDADO.x264-BR6".into(),
|
||||
want: NameClaims {
|
||||
title: s("Casa Vazia"),
|
||||
year: Some(2021),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtBr],
|
||||
group: s("BR6"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Three different pt-BR markers dedupe to one claim.
|
||||
name: "Noite.Sem.Fim.2023.720p.WEBRip.NACIONAL.DUBLADO.PT-BR.x264-BR7".into(),
|
||||
want: NameClaims {
|
||||
title: s("Noite Sem Fim"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P720),
|
||||
source: Some(Source::WebRip),
|
||||
codec: Some(Codec::X264),
|
||||
languages: vec![LanguageMarker::PtBr],
|
||||
group: s("BR7"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// `Dual Áudio` on a 4K DV/HDR10 release: a common real shape
|
||||
// for Brazilian streaming rips.
|
||||
name: "Fronteira.Azul.2023.2160p.WEB-DL.DUAL.ÁUDIO.DV.HDR10.x265-BR8".into(),
|
||||
want: NameClaims {
|
||||
title: s("Fronteira Azul"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P2160),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X265),
|
||||
hdr: vec![HdrMarker::DolbyVision, HdrMarker::Hdr10],
|
||||
languages: vec![LanguageMarker::Dual],
|
||||
group: s("BR8"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
/// Names that are simply malformed: missing year, no source/codec at all,
|
||||
/// double-dot runs, underscore separators, junk tokens, and a group
|
||||
/// suffix too mangled to extract. Every one must parse *partially*
|
||||
/// rather than fail (`arr_parse::parse` never panics or errors).
|
||||
fn malformed_cases() -> Vec<Case> {
|
||||
vec![
|
||||
Case {
|
||||
// No year at all.
|
||||
name: "Some.Weird.Movie.1080p.WEB-DL.x264-GRP".into(),
|
||||
want: NameClaims {
|
||||
title: s("Some Weird Movie"),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
group: s("GRP"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// No source, codec or group beyond a bare resolution.
|
||||
name: "Random.Movie.Name.2023.720p".into(),
|
||||
want: NameClaims {
|
||||
title: s("Random Movie Name"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P720),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Runs of empty separators collapse harmlessly.
|
||||
name: "Broken..Signal...2023..1080p..WEBRip..x264-GRP9".into(),
|
||||
want: NameClaims {
|
||||
title: s("Broken Signal"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebRip),
|
||||
codec: Some(Codec::X264),
|
||||
group: s("GRP9"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Underscore-separated, all caps.
|
||||
name: "MOVIE_NAME_2024_1080P_BLURAY_X264-GRP10".into(),
|
||||
want: NameClaims {
|
||||
title: s("MOVIE NAME"),
|
||||
year: Some(2024),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::BluRay),
|
||||
codec: Some(Codec::X264),
|
||||
group: s("GRP10"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// `PROPER` is junk: recognised, ignored, doesn't corrupt the
|
||||
// rest of the parse.
|
||||
name: "The.Long.Signal.2023.1080p.WEB-DL.PROPER.x264-GRP11".into(),
|
||||
want: NameClaims {
|
||||
title: s("The Long Signal"),
|
||||
year: Some(2023),
|
||||
resolution: Some(Resolution::P1080),
|
||||
source: Some(Source::WebDl),
|
||||
codec: Some(Codec::X264),
|
||||
group: s("GRP11"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Nothing but markers: no title survives.
|
||||
name: "1080p.x264".into(),
|
||||
want: NameClaims {
|
||||
resolution: Some(Resolution::P1080),
|
||||
codec: Some(Codec::X264),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// No recognisable marker anywhere: the whole thing degrades
|
||||
// to a title-only claim.
|
||||
name: "---.devolved.gibberish.zzz111".into(),
|
||||
want: NameClaims {
|
||||
title: s("devolved gibberish zzz111"),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
Case {
|
||||
// Group suffix too mangled to extract (over length, no
|
||||
// letters): both it and the fused codec token are dropped,
|
||||
// but the rest of the claim still comes through.
|
||||
name: "Ashfall.2022.720p.HDTV.x264-123456789012345678901234567890".into(),
|
||||
want: NameClaims {
|
||||
title: s("Ashfall"),
|
||||
year: Some(2022),
|
||||
resolution: Some(Resolution::P720),
|
||||
source: Some(Source::Hdtv),
|
||||
..NameClaims::default()
|
||||
},
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
fn all_cases() -> Vec<Case> {
|
||||
let mut cases = resolution_source_matrix();
|
||||
cases.extend(dv_hdr_cases());
|
||||
cases.extend(multi_audio_cases());
|
||||
cases.extend(pt_br_cases());
|
||||
cases.extend(malformed_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")
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user