Twelve more, all of them numbers the realm moved out from under
Both clusters left after the chat-window shadow were stale numbers written into tests rather than anything of ours, and both are stale because the realm's FrameXML moved — which is the thing to suspect first in this crate. Seven in `battlefield_minimap_tests`: the manifest was expected to warn exactly once, about `gxRefresh`. This client does not register that CVar because no target offers the exclusive mode-set a refresh rate needs, and the only reader was stock `OptionsFrame.lua`'s `OptionsFrameRefreshDropDown_OnLoad` — which the realm replaced with a rewrite that has no refresh-rate dropdown at all: three mentions of the CVar in `patch.MPQ`'s stock copy, none in `patch-4.mpq`'s. The list is now empty rather than gone, so a realm that restores the stock window brings the row back and that is where it shows. Five in `questlog_tests`, from three separate numbers in the one file: `"Quests: 8/20"` — the realm sets `MAX_QUESTLOG_QUESTS = 25`, and this file had already learned that once: another test reads the cap off the global with a comment saying why. This call site had been missed, so it is read the same way. A wheel notch was asserted to scroll the list, with eight fixture quests described as "two more than the list shows". The realm shows `QUESTS_DISPLAYED = 24` where 1.12 shows six, so eight fit with room to spare and the notch had nothing to move — the `assert_ne!` was passing only while the row count read as six, which is to say it stopped testing anything a while ago. The log is re-seated past the window for that leg, sized off the live global, and put back to the eight the rest of the test reads. And `frame_rect(quads, 300.0, 261.0)` / `(384.0, 512.0)` hunted the quad list for a bare frame of a given size, which is a number the realm can change and did. `named_rect` asks the frame where it is instead. Nothing any of those tests asserts was ever about the size: they clip reward plates and text against the pane and compare the window's own edges. 269 → 160, still nothing newly failing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
@@ -8,9 +8,16 @@ use benilla_ui::script::{
|
||||
WorldStateUiView, ARROW_MODEL,
|
||||
};
|
||||
|
||||
/// The manifest's one warning. Deviation: `gxRefresh`, read at `OptionsFrame.lua:300`, is not
|
||||
/// registered, because nothing here can set a refresh rate.
|
||||
const MANIFEST_WARNINGS: [&str; 1] = ["unknown CVar 'gxRefresh' (not host-registered) — ignored"];
|
||||
/// The whole manifest, loaded, warns about **nothing**.
|
||||
///
|
||||
/// It held one row until now: `gxRefresh`, which this client does not register because no target
|
||||
/// offers the exclusive mode-set a refresh rate needs. The reader was stock `OptionsFrame.lua`'s
|
||||
/// `OptionsFrameRefreshDropDown_OnLoad` (l.300) — and the realm has replaced that file with
|
||||
/// Turtle's rewrite, which has no refresh-rate dropdown and reads the CVar nowhere: 3 mentions in
|
||||
/// `patch.MPQ`'s stock copy, **0** in `patch-4.mpq`'s. So the deviation is still a deviation and
|
||||
/// nothing reaches it, which is why this list is empty rather than deleted — a realm that puts the
|
||||
/// stock window back brings the row back with it, and this is where that shows.
|
||||
const MANIFEST_WARNINGS: [&str; 0] = [];
|
||||
|
||||
fn quiet(s: &UiScript) {
|
||||
assert!(s.errors().is_empty(), "script errors: {:#?}", s.errors());
|
||||
|
||||
@@ -3,23 +3,32 @@
|
||||
//! the list and detail scroll frames inherit (`QuestLogFrame.xml:589`, `:606`).
|
||||
|
||||
use benilla_ui::script::{
|
||||
ExtractedQuad, PartyMemberInfo, PartyState, QuadContent, QuestItemView, QuestLogDetail,
|
||||
QuestLogEntryView, QuestLogObjectiveView, QuestLogState, SoundRequest, UiScript,
|
||||
PartyMemberInfo, PartyState, QuadContent, QuestItemView, QuestLogDetail, QuestLogEntryView,
|
||||
QuestLogObjectiveView, QuestLogState, SoundRequest, UiScript,
|
||||
};
|
||||
|
||||
use super::test_ui::load_ui as load_xml;
|
||||
|
||||
/// The rect of the frame sized `w` by `h`, from the `QuadContent::Frame` quad every frame emits.
|
||||
fn frame_rect(quads: &[ExtractedQuad], w: f32, h: f32) -> benilla_ui::layout::Rect {
|
||||
quads
|
||||
/// A named frame's own resolved rect, asked of the frame instead of hunted for among the quads by
|
||||
/// size.
|
||||
///
|
||||
/// This replaces a `frame_rect(quads, w, h)` that hunted the quad list for a bare frame of a
|
||||
/// given size, because a size written in a test is a number the realm can change: the detail
|
||||
/// scroll frame was 300x261 and the window 384x512 when these tests were written, and the realm's
|
||||
/// `QuestLogFrame` is a different shape now — it shows `QUESTS_DISPLAYED = 24` rows where 1.12
|
||||
/// shows six. Five tests died looking for quads that no longer exist. Nothing any of them asserts
|
||||
/// is about the size: they clip reward plates and text against the pane and compare the window's
|
||||
/// own edges, so the frame is asked where it is.
|
||||
fn named_rect(s: &UiScript, name: &str) -> benilla_ui::layout::Rect {
|
||||
let edges: Vec<f32> = ["GetBottom", "GetLeft", "GetTop", "GetRight"]
|
||||
.iter()
|
||||
.find_map(|q| match &q.content {
|
||||
QuadContent::Frame => q
|
||||
.rect
|
||||
.filter(|r| (r.width() - w).abs() < 0.5 && (r.height() - h).abs() < 0.5),
|
||||
_ => None,
|
||||
.map(|getter| {
|
||||
s.eval::<f32>(&format!("return {name}:{getter}()"))
|
||||
.unwrap_or_else(|e| panic!("{name}:{getter}(): {e}"))
|
||||
})
|
||||
.unwrap_or_else(|| panic!("no bare-frame quad sized {w}x{h}"))
|
||||
.collect();
|
||||
benilla_ui::layout::Rect::new(edges[0], edges[1], edges[2], edges[3])
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
@@ -44,10 +53,21 @@ thread_local! {
|
||||
};
|
||||
}
|
||||
|
||||
/// Eight quests, two more than the list shows (`QUESTS_DISPLAYED`, `QuestLogFrame.lua:1`); only
|
||||
/// quest 1 has an objective, and each has its own `quest_id`, the watch set's key.
|
||||
/// Eight quests; only quest 1 has an objective, and each has its own `quest_id`, the watch set's
|
||||
/// key.
|
||||
///
|
||||
/// Eight **no longer overflows the list**: the realm shows `QUESTS_DISPLAYED = 24` rows at once
|
||||
/// where 1.12 shows 6, so a fixture this size fits with room to spare and nothing about it can
|
||||
/// scroll. Anything testing the scroll seats [`entries`] off the live global instead — see
|
||||
/// `the_wheel_scrolls_a_list_longer_than_the_realm_displays`.
|
||||
fn eight_entries() -> QuestLogState {
|
||||
let entries = (1..=8)
|
||||
entries(8)
|
||||
}
|
||||
|
||||
/// `n` quests in the shape [`eight_entries`] describes, so a test that needs to overflow the list
|
||||
/// can size itself off `QUESTS_DISPLAYED` rather than off 1.12's row count.
|
||||
fn entries(n: u32) -> QuestLogState {
|
||||
let entries = (1..=n)
|
||||
.map(|i| QuestLogEntryView {
|
||||
quest_id: i,
|
||||
title: format!("Quest {i}"),
|
||||
@@ -70,7 +90,7 @@ fn eight_entries() -> QuestLogState {
|
||||
})
|
||||
.collect();
|
||||
QuestLogState {
|
||||
num_quests: 8,
|
||||
num_quests: n,
|
||||
entries,
|
||||
hidden_quest_ids: Vec::new(),
|
||||
}
|
||||
@@ -153,10 +173,16 @@ fn shipped_questlog_frame_drives_end_to_end() {
|
||||
.eval::<String>("return QuestLogTitle1NormalText:GetText()")
|
||||
.unwrap()
|
||||
.contains("Quest 1"));
|
||||
// The cap off the global, for the reason `the_quest_count_reads_the_realms_own_cap` gives
|
||||
// below: OctoWoW's `QuestLogFrame.lua` sets `MAX_QUESTLOG_QUESTS = 25`, and pinning 1.12's 20
|
||||
// here was the same mistake made twice in one file.
|
||||
let cap = s
|
||||
.eval::<i64>("return MAX_QUESTLOG_QUESTS")
|
||||
.expect("the realm's quest-log cap");
|
||||
assert_eq!(
|
||||
s.eval::<String>("return QuestLogQuestCount:GetText()")
|
||||
.unwrap(),
|
||||
"Quests: |cffffffff8/20|r"
|
||||
format!("Quests: |cffffffff8/{cap}|r")
|
||||
);
|
||||
assert_eq!(s.eval::<i64>("return GetQuestLogSelection()").unwrap(), 1);
|
||||
|
||||
@@ -201,7 +227,21 @@ fn shipped_questlog_frame_drives_end_to_end() {
|
||||
// Choices and rewards share one pool: item 1 is the reward, item 2 unused.
|
||||
assert!(!s.eval::<bool>("return QuestLogItem2:IsShown()").unwrap());
|
||||
|
||||
// Wheel down over row 3, a list row (the detail pane shows quest 1).
|
||||
// Wheel down over a list row — on a log long enough to scroll.
|
||||
//
|
||||
// Eight quests used to be "two more than the list shows", which was 1.12's six. The realm's
|
||||
// `QuestLogFrame.lua` shows **`QUESTS_DISPLAYED = 24`**, so eight fit with room to spare and
|
||||
// the notch had nothing to move: this `assert_ne!` was passing on a stale row count and went
|
||||
// red the moment the count was read off the realm. So the log is re-seated past the window
|
||||
// for this leg, sized off the live global rather than off any number written here, and put
|
||||
// back to the eight the rest of the test reads.
|
||||
let displayed = s
|
||||
.eval::<i64>("return QUESTS_DISPLAYED")
|
||||
.expect("the realm's visible row count");
|
||||
#[allow(clippy::cast_sign_loss)]
|
||||
let seated = u32::try_from(displayed).expect("a positive row count") + 4;
|
||||
s.set_quest_log(entries(seated));
|
||||
s.run("QuestLog_Update()").unwrap();
|
||||
s.resolve();
|
||||
let quads = s.extract();
|
||||
let (wx, wy) = quads
|
||||
@@ -223,8 +263,16 @@ fn shipped_questlog_frame_drives_end_to_end() {
|
||||
s.eval::<String>("return QuestLogTitle1NormalText:GetText()")
|
||||
.unwrap(),
|
||||
before,
|
||||
"wheel-down scrolled the list"
|
||||
"wheel-down scrolled {seated} quests in a {displayed}-row window"
|
||||
);
|
||||
// Back to the eight, scrolled to the top and quest 1 selected, which is the state the rest of
|
||||
// this test was written against.
|
||||
s.set_quest_log(eight_entries());
|
||||
s.run(
|
||||
"QuestLogListScrollFrameScrollBar:SetValue(0) QuestLog_Update() QuestLog_SetSelection(1)",
|
||||
)
|
||||
.unwrap();
|
||||
s.resolve();
|
||||
assert_eq!(s.eval::<i64>("return GetQuestLogSelection()").unwrap(), 1);
|
||||
|
||||
// Abandon, then No: the ABANDON_QUEST popup closes and queues nothing.
|
||||
@@ -338,7 +386,7 @@ fn shift_click_toggles_the_watch_checkbox_and_the_tracker_hud() {
|
||||
// Row 1, quest 1, the one with an objective: 300x16 at the window's TOPLEFT +19,-75
|
||||
// (`QuestLogFrame.xml:4-7`, `:535-539`).
|
||||
s.resolve();
|
||||
let win = frame_rect(&s.extract(), 384.0, 512.0);
|
||||
let win = named_rect(&s, "QuestLogFrame");
|
||||
let (rx, ry) = (win.left + 19.0 + 150.0, win.top - 75.0 - 8.0);
|
||||
s.set_modifiers(true, false, false);
|
||||
s.mouse_button(rx, ry, "LeftButton", true);
|
||||
@@ -451,7 +499,7 @@ fn watch_guards_no_op_without_erroring() {
|
||||
// Rows are 300x16 from the window's TOPLEFT +19,-75, each overlapping the last by 1, a 15 px
|
||||
// pitch (`QuestLogFrame.xml:535-548`).
|
||||
s.resolve();
|
||||
let win = frame_rect(&s.extract(), 384.0, 512.0);
|
||||
let win = named_rect(&s, "QuestLogFrame");
|
||||
let row_center = |n: u32| win.top - 75.0 - 15.0 * (n - 1) as f32 - 8.0;
|
||||
let x = win.left + 19.0 + 150.0;
|
||||
|
||||
@@ -1010,7 +1058,7 @@ fn overflowing_detail_content_clips_to_the_scrollframe_rect() {
|
||||
|
||||
s.resolve();
|
||||
let quads = s.extract();
|
||||
let scroll_rect = frame_rect(&quads, 300.0, 261.0);
|
||||
let scroll_rect = named_rect(&s, "QuestLogDetailScrollFrame");
|
||||
|
||||
let reward_plate_clips: Vec<Option<benilla_ui::layout::Rect>> = quads
|
||||
.iter()
|
||||
@@ -1082,8 +1130,7 @@ fn wheel_over_the_detail_pane_changes_vertical_scroll() {
|
||||
s.resolve(); // the measures reach the scroll range and the bar
|
||||
|
||||
s.resolve();
|
||||
let quads = s.extract();
|
||||
let scroll_rect = frame_rect(&quads, 300.0, 261.0);
|
||||
let scroll_rect = named_rect(&s, "QuestLogDetailScrollFrame");
|
||||
// Near the pane's top-left, clear of the reward row.
|
||||
let (x, y) = (scroll_rect.left + 10.0, scroll_rect.top - 10.0);
|
||||
|
||||
@@ -1441,7 +1488,7 @@ fn shift_click_on_a_title_posts_the_quest_name_with_chat_open_and_watches_with_i
|
||||
|
||||
// Row 1's centre: 300x16 at the window's TOPLEFT +19,-75.
|
||||
s.resolve();
|
||||
let win = frame_rect(&s.extract(), 384.0, 512.0);
|
||||
let win = named_rect(&s, "QuestLogFrame");
|
||||
let (rx, ry) = (win.left + 19.0 + 150.0, win.top - 75.0 - 8.0);
|
||||
let shift_click = |s: &mut UiScript| {
|
||||
s.set_modifiers(true, false, false);
|
||||
|
||||
Reference in New Issue
Block a user