/** * Coaster name matching tests. * * Each case documents a real mismatch found between Queue-Times ride names * and RCDB coaster names, along with the park where it was observed. * * Run with: npm test */ import { test } from "node:test"; import assert from "node:assert/strict"; import { isCoasterMatch, normalizeForMatch } from "../lib/coaster-match.ts"; // ── Helper ────────────────────────────────────────────────────────────────── function makeSet(...rcdbNames: string[]): Set { return new Set(rcdbNames.map(normalizeForMatch)); } // ── Should MATCH (Queue-Times name → RCDB name) ────────────────────────────── test("exact match after lowercasing", () => { assert.ok(isCoasterMatch("Goliath", makeSet("Goliath"))); }); test("trademark symbol stripped — BATMAN™ The Ride (Over Georgia, Magic Mountain)", () => { assert.ok(isCoasterMatch("BATMAN™ The Ride", makeSet("Batman The Ride"))); }); test("leading THE stripped — THE RIDDLER Mindbender (Over Georgia)", () => { assert.ok(isCoasterMatch("THE RIDDLER Mindbender", makeSet("Riddler Mindbender"))); }); test("trademark + leading THE — THE RIDDLER™'s Revenge (Magic Mountain)", () => { assert.ok(isCoasterMatch("THE RIDDLER™'s Revenge", makeSet("Riddler's Revenge"))); }); test("curly apostrophe possessive stripped — CATWOMAN™ Whip (New England)", () => { assert.ok(isCoasterMatch("CATWOMAN™ Whip", makeSet("Catwoman's Whip"))); }); test("straight apostrophe possessive stripped", () => { assert.ok(isCoasterMatch("Riddler's Revenge", makeSet("Riddler's Revenge"))); }); test("trademark + colon punctuation — SUPERMAN™: Ultimate Flight (Over Georgia)", () => { assert.ok(isCoasterMatch("SUPERMAN™: Ultimate Flight", makeSet("Superman - Ultimate Flight"))); }); test("QT drops subtitle — Apocalypse (Magic Mountain)", () => { assert.ok(isCoasterMatch("Apocalypse", makeSet("Apocalypse the Ride"))); }); test("QT adds subtitle — The New Revolution - Classic (Magic Mountain)", () => { assert.ok(isCoasterMatch("The New Revolution - Classic", makeSet("New Revolution"))); }); test("QT exclamation stripped — SCREAM (Magic Mountain)", () => { assert.ok(isCoasterMatch("SCREAM", makeSet("Scream!"))); }); test("space-split word — BAT GIRL™: Coaster Chase (Fiesta Texas)", () => { assert.ok(isCoasterMatch("BAT GIRL™: Coaster Chase", makeSet("Batgirl Coaster Chase"))); }); test("trademark + 4D subtitle — THE JOKER™ 4D Free Fly Coaster (New England)", () => { assert.ok(isCoasterMatch("THE JOKER™ 4D Free Fly Coaster", makeSet("Joker"))); }); test("Great American Scream Machine — top-level QT rides array (Over Georgia)", () => { assert.ok(isCoasterMatch("The Great American Scream Machine", makeSet("Great American Scream Machine"))); }); test("THE JOKER™ Funhouse Coaster — top-level QT rides array (Over Georgia)", () => { assert.ok(isCoasterMatch("THE JOKER™ Funhouse Coaster", makeSet("Joker Funhouse Coaster"))); }); // ── Should NOT MATCH (false positives) ────────────────────────────────────── test("false positive: Joker y Harley Quinn ≠ Joker (Six Flags Mexico)", () => { assert.ok(!isCoasterMatch("Joker y Harley Quinn", makeSet("Joker"))); }); test("false positive: unrelated ride does not match", () => { assert.ok(!isCoasterMatch("SkyScreamer", makeSet("Goliath"))); }); test("false positive: short prefix with conjunction — de connector", () => { assert.ok(!isCoasterMatch("Batman de Gotham", makeSet("Batman"))); });