diff --git a/crates/benilla-app/src/ui_script/honor_frame_tests.rs b/crates/benilla-app/src/ui_script/honor_frame_tests.rs index 01e7cba3..222f89cf 100644 --- a/crates/benilla-app/src/ui_script/honor_frame_tests.rs +++ b/crates/benilla-app/src/ui_script/honor_frame_tests.rs @@ -32,6 +32,19 @@ fn state() -> HonorState { /// The character window, whose fifth tab this page is; [`super::test_ui::CHARACTER_UI`] carries /// `HonorFrame.xml`, as `PaperDollFrame.lua:103` writes into it on every show. +/// The realm's own `PVP_RANK__` string. +/// +/// Never a copy written here: the realm's `GlobalStrings.lua` gives every rank a **trailing +/// space** (`PVP_RANK_8_1 = "Master Sergeant "`, where stock 1.12's `patch.MPQ` copy has none), +/// because its own callers concatenate a name after the title. Pinning the stock spelling made +/// five tests in this file assert against a string the realm does not ship. +fn rank_title(s: &UiScript, rank: u32, team: u32) -> String { + s.eval::(&format!( + "return PVP_RANK_{rank}_{team} or \"\"" + )) + .expect("the realm's own rank string") +} + fn load_page(s: &UiScript) { for file in super::test_ui::CHARACTER_UI { super::test_ui::load_ui_strict(s, file); @@ -43,6 +56,12 @@ fn load_page(s: &UiScript) { fn alliance_player() -> UnitState { UnitState { exists: true, + // Named: the window this page lives in formats the player's name on every show — + // `CharacterFrame_OnShow` does `gsub(UnitPVPName("player"), "\n.+", "")` + // (`CharacterFrame.lua:85`) — and `UnitPVPName` answers nil for a unit with no name, so a + // nameless fixture raises `bad argument #1 to 'gsub'` and takes the rest of that OnShow + // with it. + name: Some("Tester".into()), level: 60, sex: 2, faction_group: Some("Alliance".into()), @@ -93,7 +112,7 @@ fn every_figure_lands_in_its_own_row() { ("HonorFrameLifeTimeHKValue", "3907"), ("HonorFrameLifeTimeDKValue", "12"), // The highest rank's title (14), not the current one (12). - ("HonorFrameLifeTimeRankValue", "Lieutenant Commander"), + ("HonorFrameLifeTimeRankValue", &rank_title(&s, 14, 1)), ] { assert_eq!(text(&mut s, frame), want, "{frame}"); } @@ -105,7 +124,10 @@ fn every_figure_lands_in_its_own_row() { fn the_title_is_the_internal_rank_and_the_badge_is_the_visual_one() { let _data = benilla_formats::wow_data_or_skip!(); let mut s = shown_honor_page(); - assert_eq!(text(&mut s, "HonorFrameCurrentPVPTitle"), "Knight-Captain"); + assert_eq!( + text(&mut s, "HonorFrameCurrentPVPTitle"), + rank_title(&s, 12, 1) + ); assert_eq!(text(&mut s, "HonorFrameCurrentPVPRank"), "(Rank 8)"); assert!( s.eval::("return HonorFramePvPIcon:IsShown()") @@ -178,12 +200,12 @@ fn a_gm_flagged_player_keeps_his_rank_title_and_loses_only_the_faction_group() { s.resolve(); assert_eq!( text(&mut s, "HonorFrameLifeTimeRankValue"), - "Grand Marshal", + rank_title(&s, 18, 1), "the Highest Rank row — the reported symptom" ); assert_eq!( text(&mut s, "HonorFrameCurrentPVPTitle"), - "Grand Marshal", + rank_title(&s, 18, 1), "and the title under the badge, which reads the same key" ); assert!( @@ -278,7 +300,22 @@ fn the_real_global_strings_name_the_rank() { load_page(&s); s.set_honor(Some(state())); - for (team, want) in [(1i8, "Knight-Captain"), (0, "Legionnaire")] { + // The expected title comes off the realm's **own** `PVP_RANK__` string, not a copy + // written here: the realm's `GlobalStrings.lua` gives every rank a **trailing space** + // (`PVP_RANK_8_1 = "Master Sergeant "`, where stock 1.12's `patch.MPQ` copy has none), because + // its own callers concatenate a name after the title. Pinning the stock spelling here made + // five tests in this file assert against a string the realm does not ship. + // + // Rank 12 is the fixture's (`state`), and the team digit is what this is really testing: the + // same rank reads as the Alliance title for team 1 and the Horde one for team 0. + for team in [1i8, 0] { + let want = s + .eval::(&format!( + "return PVP_RANK_12_{} or \"\"", + if team == 1 { 1 } else { 0 }, + if team == 1 { 1 } else { 0 } + )) + .expect("the realm's own rank string"); s.set_unit( "player", Some(UnitState { @@ -361,6 +398,13 @@ fn shown_inspect_honor_page() -> UiScript { // `ItemButtonTemplate`, its honor rows `HonorFrame.xml`'s row templates. "Interface\\FrameXML\\ItemButtonTemplate.xml", "Interface\\FrameXML\\HonorFrame.xml", + // …and its **arena** page's three team buttons inherit `ArenaTeamTemplate`, which is a + // FrameXML row of the realm's (`Turtle_ArenaUI\Turtle_ArenaUITemplates.xml`, toc row 109) + // rather than anything in the addon's own templates file. Without it the inherits is + // skipped, so `$parentText` is never built, and the OnLoad's + // `_G[this:GetName().."Text"]:SetText("(2v2)")` (`InspectArenaFrame.xml:71`) raises + // `attempt to index field '?'` — three times, once per team. + r"Interface\FrameXML\Turtle_ArenaUI\Turtle_ArenaUITemplates.xml", ] { load_xml(&s, file); } @@ -398,14 +442,14 @@ fn the_inspect_page_paints_the_reply_it_holds() { ("InspectHonorFrameLastWeekStandingValue", "57"), ("InspectHonorFrameLifeTimeHKValue", "3907"), ("InspectHonorFrameLifeTimeDKValue", "12"), - ("InspectHonorFrameLifeTimeRankValue", "Lieutenant Commander"), + ("InspectHonorFrameLifeTimeRankValue", &rank_title(&s, 14, 1)), ] { assert_eq!(text(&mut s, frame), want, "{frame}"); } // The target's current rank, 12, and the bar from the reply's own byte. assert_eq!( text(&mut s, "InspectHonorFrameCurrentPVPTitle"), - "Knight-Captain" + rank_title(&s, 12, 1) ); assert_eq!(text(&mut s, "InspectHonorFrameCurrentPVPRank"), "(Rank 8)"); let bar = s diff --git a/crates/benilla-app/src/ui_script/reputation_frame_tests.rs b/crates/benilla-app/src/ui_script/reputation_frame_tests.rs index 9800e053..7a47dbc5 100644 --- a/crates/benilla-app/src/ui_script/reputation_frame_tests.rs +++ b/crates/benilla-app/src/ui_script/reputation_frame_tests.rs @@ -63,6 +63,12 @@ fn load_page(s: &UiScript) { fn player(level: u32) -> UnitState { UnitState { exists: true, + // Named, because the window this page lives in formats the player's name on **every** + // show: `CharacterFrame_OnShow` does `gsub(UnitPVPName("player"), "\n.+", "")` + // (`CharacterFrame.lua:85`), and `UnitPVPName` answers nil for a unit with no name — so a + // nameless fixture raises `bad argument #1 to 'gsub'` and takes the rest of that OnShow + // with it, including the sub-frame show this page needs. + name: Some("Tester".into()), level, race: Some("Human".into()), race_file: Some("Human".into()), diff --git a/crates/benilla-app/src/ui_script/skills_frame_tests.rs b/crates/benilla-app/src/ui_script/skills_frame_tests.rs index dd2ebea5..d5688b3a 100644 --- a/crates/benilla-app/src/ui_script/skills_frame_tests.rs +++ b/crates/benilla-app/src/ui_script/skills_frame_tests.rs @@ -53,6 +53,12 @@ fn shown_skills_page_with(measurer: Option