//! The per-story display quota, measured against real headlines. //! //! Dedup collapses rewordings of one report; this bounds the other kind of //! repetition — many different reports about the same record. Every headline //! here is verbatim from a live Google News feed on 2026-08-05, where seven of //! the twelve visible slots were King Gizzard's "Alien Metal" announcement //! arriving from seven outlets that shared almost no vocabulary. use metadata::{news_story_key, news_story_quota, ArtistNewsItem}; const GIZZ: &str = "King Gizzard & The Lizard Wizard"; fn key(title: &str, artist: &str) -> Option { news_story_key(title, artist) } fn item(title: &str, date: i64) -> ArtistNewsItem { ArtistNewsItem { title: title.to_string(), url: title.to_string(), source: String::new(), date, host: String::new(), others: 0, } } // ------------------------------------------------------------ extraction #[test] fn every_alien_metal_headline_names_the_same_work() { // Five quote it, two only capitalise it after "Album". All seven are one // story and between them they held seven of twelve panel slots. for title in [ "King Gizzard & the Lizard Wizard rave on with some \u{2018}Alien Metal\u{2019}", "King Gizzard & the Lizard Wizard announce 28th album \u{2018}Alien Metal\u{2019}", "King Gizzard & the Lizard Wizard Share Title Track From Forthcoming LP \u{2018}Alien Metal\u{2019}", "King Gizzard and the Lizard Wizard announce EDM album, \u{2018}Alien Metal\u{2019}", "King Gizzard & The Lizard Wizard Announce 28th Album 'Alien Metal,' Brooklyn Rave", "King Gizzard & The Lizard Wizard Release Title Track from Techno Album Alien Metal: Stream", "King Gizzard & The Lizard Wizard Detail New Album Alien Metal", ] { assert_eq!(key(title, GIZZ).as_deref(), Some("alien metal"), "{title}"); } } #[test] fn a_cue_adjacent_quote_outranks_an_earlier_one() { // The album is the story; "Two Hands" is the track it leads with. assert_eq!( key("Pond Announce New Album 'Terrestrials': Hear \"Two Hands\"", "Pond").as_deref(), Some("terrestrials"), ); assert_eq!( key("Pond Share New Single \"Terrestrials\": Listen", "Pond").as_deref(), Some("terrestrials"), ); } #[test] fn a_curly_quote_may_close_on_its_straight_twin() { // Verbatim from the feed — one headline, two different quote characters. assert_eq!( key("Weezer Enlists Kenny Beats to Produce \u{2018}The Gold Album'", "Weezer").as_deref(), Some("gold album"), ); } #[test] fn the_artist_name_and_a_leading_article_come_off_the_key() { // Five headlines about one tour. Without this they split into "the // gathering" and "weezer the gathering" and pass the quota twice. for title in [ "Weezer Announce \u{2018}The Gathering\u{2019} Arena Tour", "Weezer Announce \u{201c}Weezer: The Gathering\u{201d}", "'Weezer: The Gathering' tour heading to Nationwide Arena in October", "Weezer Play Pop-Up Rooftop Gig to Mark \u{2018}The Gathering\u{2019} Tour", ] { assert_eq!(key(title, "Weezer").as_deref(), Some("gathering"), "{title}"); } } #[test] fn a_work_cue_inside_a_quote_does_not_introduce_one() { // Three headlines about the single "C.E.O.", live on 2026-08-05. The third // quotes an older song, and the cue inside THAT quote was keying the // headline as a work called "homage" — a third slot for one story. for title in [ "Weezer\u{2019}s \u{201c}C.E.O.\u{201d} Video Has Curry Barker, Celeb Cameos, & A \u{201c}Sweater Song\u{201d} Homage", "Weezer Unveil New Single \"C.E.O.\", Expand \"Weezer: The Gathering\" with New Tour Dates", "Weezer Go Back in Time for \u{2018}C.E.O.\u{2019} Music Video", ] { assert_eq!(key(title, "Weezer").as_deref(), Some("c e o"), "{title}"); } } #[test] fn a_possessive_apostrophe_does_not_open_a_span() { // If it did, the span would run from "'s Rivers…" to the next real quote // and every span after it would be misaligned. assert_eq!( key("Weezer's Rivers Cuomo drops new single 'Shine Again'", "Weezer").as_deref(), Some("shine again"), ); } // ------------------------------------------------------- what is NOT a work #[test] fn a_generic_run_after_a_cue_is_not_a_work() { // Each of these keyed as a "work" before the generic list existed — // `review`, `list` and `next week` — grouping unrelated headlines. for (title, artist) in [ ("Panda Bear / Sonic Boom: A ? of WHEN Album Review", "Panda Bear"), ("Weezer Concert Setlist: Discover the Average Song List", "Weezer"), ( "Weezer Announce North American Tour, Tease New Album, and Are Releasing a New Song Next Week", "Weezer", ), ("Track Review: Paramore \u{2013} Running Out of Time", "Panda Bear"), ] { assert_eq!(key(title, artist), None, "{title}"); } } #[test] fn an_unclosed_run_is_not_a_work() { // "Album Speculation [Watch]" — a run that neither ends the headline nor // stops at punctuation is ordinary prose. assert_eq!( key("Billy Strings & King Gizzard Share Video From The Studio, Fueling Album Speculation [Watch]", GIZZ), None, ); // A capitalised function word ends the run: this is a credit, not a work. assert_eq!( key("Panda Bear Announces Tour and New Album, Shares Video for New Song With Cindy Lee: Watch", "Panda Bear"), None, ); } #[test] fn a_long_quote_is_speech_not_a_title() { assert_eq!( key("\u{201c}It\u{2019}s 5 days since they released new music \u{2013} was starting to think we\u{2019}d never hear from them again\u{201d}: King Gizzard And The Lizard Wizard\u{2019}s 24 albums in 11 years?", GIZZ), None, ); } #[test] fn headlines_that_name_no_work_are_never_keyed() { // These are the majority, and they are the reason the quota can never // empty a feed. assert_eq!(key("King Gizzard & The Lizard Wizard Share New Single", GIZZ), None); assert_eq!(key("King Gizzard & The Lizard Wizard Australia 2026 Tour", GIZZ), None); assert_eq!(key("toe Announces October Shows in Osaka and Tokyo", "toe"), None); } // ----------------------------------------------------------------- quota #[test] fn the_quota_keeps_the_first_two_of_a_story_and_all_the_rest() { // The list arrives newest-first, so "first two" is "the two most recent". let titles = [ "King Gizzard & the Lizard Wizard rave on with some \u{2018}Alien Metal\u{2019}", "King Gizzard & The Lizard Wizard Share New Single", "King Gizzard & The Lizard Wizard Release Title Track from Techno Album Alien Metal: Stream", "King Gizzard & the Lizard Wizard announce 28th album \u{2018}Alien Metal\u{2019}", "King Gizzard & The Lizard Wizard Detail New Album Alien Metal", "King Gizzard & The Lizard Wizard Australia 2026 Tour", ]; let items: Vec<_> = titles .iter() .enumerate() .map(|(i, t)| item(t, 1_785_000_000 - i as i64 * 86_400)) .collect(); let out = news_story_quota(items, GIZZ); let kept: Vec<&str> = out.iter().map(|i| i.title.as_str()).collect(); assert_eq!(kept, vec![titles[0], titles[1], titles[2], titles[5]]); } #[test] fn the_quota_never_empties_a_feed() { // Pond's whole in-feed life was five reports of one record. Two survive, // which is the point: an empty row would be worse than a repeated one. let items: Vec<_> = [ "Pond Return With Psych\u{2019}d Out Track \u{2018}Terrestrials\u{2019}", "Pond Share New Single \"Terrestrials\": Listen", "Pond Announce North American Tour Behind New Album 'Terrestrials'", "Pond Announce New Album 'Terrestrials': Hear \"Two Hands\"", "Pond \u{2018}Terrestrials\u{2019} Review: Less Sometimes Is Really More", ] .iter() .map(|t| item(t, 1_785_000_000)) .collect(); assert_eq!(news_story_quota(items, "Pond").len(), 2); }