The reader is pushable now, and a letter covers rather than evicts
The last two UI integration files, both resting on `UIPanelWindows` rows the realm changed.
`ItemTextFrame` is `{ area = "left", pushable = 5 }` where 1.12's row was `pushable = 0`. That made
the reader and a quest giver's gossip left-slot rivals which replaced each other and ended each
other's session on the way out; pushable, they share the screen — one takes left, the other slides
to centre, in either order, and neither `CloseItemText` nor `CloseGossip` is queued. The test is
renamed for what it now proves. Its page bodies also pick up the realm's own three trailing
newlines on both arms of the creator fork (`ItemTextFrame.lua:41-46`), where 1.12 wrote two.
`OpenMailFrame` has no `UIPanelWindows` row at all, so `ShowUIPanel` takes its first branch — a
bare `frame:Show()` that claims no slot (`UIParent.lua:920-923`) — and a letter therefore *covers*
the centre occupant instead of evicting it. The eviction runs one way only: the letter is a
`UIChildWindows` member, so the next panel to seat anywhere hides it. And it has to **arrive** to
do that: `ShowUIPanel` returns on its first line for a frame already shown, so asking for the sheet
again while it is up reaches no slot and hides nothing.
Workspace: 191 red → 134, with zero regressions (`comm` against the pre-session list). Every one of
the 57 was in `ui_script` or these two files, and that whole surface is now green: 1113 `ui_script`
tests, `item_text_frame`, `mail_frame`, `message_keys`, `cover_input_wall`, `character_stats`. What
is left is the benilla-formats data goldens, which are documented separately and were red before.
All seven gates green.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
@@ -106,8 +106,11 @@ fn a_letter_reads_with_the_creator_tail() {
|
||||
s.fire_event("ITEM_TEXT_READY", vec![]);
|
||||
assert!(s.eval::<bool>("return ItemTextFrame:IsShown()").unwrap());
|
||||
assert!(
|
||||
page_blocks(&s).contains(&"\nasd\n\nFrom,\nOne\n\n".to_string()),
|
||||
"the reference creator tail (ITEM_TEXT_FROM really is comma'd), drawn as one raw block: {:?}",
|
||||
page_blocks(&s).contains(&"\nasd\n\nFrom,\nOne\n\n\n".to_string()),
|
||||
"the reference creator tail (ITEM_TEXT_FROM really is comma'd), drawn as one raw block. \
|
||||
Three trailing newlines, not two: the realm writes \
|
||||
`creator = \"\\n\\n\"..ITEM_TEXT_FROM..\"\\n\"..creator..\"\\n\\n\\n\"` and then \
|
||||
`SetText(\"\\n\"..ItemTextGetText()..creator)` (`ItemTextFrame.lua:41-45`): {:?}",
|
||||
page_blocks(&s)
|
||||
);
|
||||
for hidden in [
|
||||
@@ -176,8 +179,9 @@ fn a_book_page_shows_the_paging_chrome() {
|
||||
s.fire_event("ITEM_TEXT_BEGIN", vec![]);
|
||||
s.fire_event("ITEM_TEXT_READY", vec![]);
|
||||
assert!(
|
||||
page_blocks(&s).contains(&"\npage one\n".to_string()),
|
||||
"the page body drawn: {:?}",
|
||||
page_blocks(&s).contains(&"\npage one\n\n\n".to_string()),
|
||||
"the page body drawn, with the authorless arm's own three trailing newlines \
|
||||
(`SetText(\"\\n\"..ItemTextGetText()..\"\\n\\n\\n\")`, `ItemTextFrame.lua:46`): {:?}",
|
||||
page_blocks(&s)
|
||||
);
|
||||
assert_eq!(
|
||||
@@ -381,11 +385,12 @@ fn the_reported_book_crest_draws_at_the_blps_own_size() {
|
||||
}
|
||||
}
|
||||
|
||||
/// The reader's `UIPanelWindows` row (`{ area = "left", pushable = 0 }`, `UIParent.lua:20`) makes
|
||||
/// it and gossip left-slot rivals: showing one replaces the other in both orders, and each
|
||||
/// displaced window's OnHide ends its own session.
|
||||
/// The reader's `UIPanelWindows` row is `{ area = "left", pushable = 5 }` (`UIParent.lua:20`) —
|
||||
/// 1.12's was `pushable = 0`, which made it and gossip left-slot rivals that replaced each other
|
||||
/// and ended each other's session on the way out. Pushable, they share the screen instead: one
|
||||
/// takes the left slot and the other slides to centre, in either order, and neither session ends.
|
||||
#[test]
|
||||
fn a_quest_givers_gossip_displaces_the_open_reader() {
|
||||
fn a_quest_givers_gossip_seats_beside_the_open_reader() {
|
||||
let _data = benilla_formats::wow_data_or_skip!();
|
||||
use benilla_ui::script::GossipMenu;
|
||||
|
||||
@@ -412,35 +417,47 @@ fn a_quest_givers_gossip_displaces_the_open_reader() {
|
||||
}));
|
||||
s.fire_event("GOSSIP_SHOW", vec![]);
|
||||
assert!(s.take_errors().is_empty());
|
||||
// The realm made the reader **pushable** (`UIPanelWindows["ItemTextFrame"]` is
|
||||
// `{ area = "left", pushable = 5 }`, `UIParent.lua:20`), where 1.12's row was `pushable = 0`.
|
||||
// So gossip does not replace the note: it takes the left slot and the note slides to centre,
|
||||
// both open, and the read session is not ended.
|
||||
assert!(
|
||||
!s.eval::<bool>("return ItemTextFrame:IsShown()").unwrap(),
|
||||
"gossip replaced the note — the two-window stack (both drawn at 0,-104) cannot form"
|
||||
s.eval::<bool>("return GetLeftFrame():GetName() == 'GossipFrame'")
|
||||
.unwrap(),
|
||||
"gossip takes the left slot"
|
||||
);
|
||||
assert!(s
|
||||
.eval::<bool>("return GossipFrame:IsShown() and GetLeftFrame():GetName() == 'GossipFrame'")
|
||||
.unwrap());
|
||||
assert!(
|
||||
s.take_item_text_close(),
|
||||
"the displaced reader's OnHide ended the read session (CloseItemText)"
|
||||
s.eval::<bool>("return GetCenterFrame():GetName() == 'ItemTextFrame'")
|
||||
.unwrap(),
|
||||
"…and pushes the note across rather than over"
|
||||
);
|
||||
// The app's close must not disturb the gossip that displaced it.
|
||||
assert!(
|
||||
s.eval::<bool>("return ItemTextFrame:IsShown() and GossipFrame:IsShown()")
|
||||
.unwrap(),
|
||||
"both windows are up: that is what a pushable row buys"
|
||||
);
|
||||
assert!(
|
||||
!s.take_item_text_close(),
|
||||
"nothing was displaced, so no `CloseItemText` — the read session stands"
|
||||
);
|
||||
|
||||
// The app's own close takes the note and leaves the gossip that pushed it.
|
||||
s.set_item_text(None);
|
||||
s.fire_event("ITEM_TEXT_CLOSED", vec![]);
|
||||
assert!(!s.eval::<bool>("return ItemTextFrame:IsShown()").unwrap());
|
||||
assert!(s.eval::<bool>("return GossipFrame:IsShown()").unwrap());
|
||||
|
||||
// The reverse order: reading the note over an open gossip ends the gossip session.
|
||||
// The reverse order, with gossip already at the left slot: the note arrives pushable and
|
||||
// seats beside it, and the gossip session is not ended either.
|
||||
let _ = s.take_gossip_close();
|
||||
s.set_item_text(Some(letter()));
|
||||
s.fire_event("ITEM_TEXT_BEGIN", vec![]);
|
||||
s.fire_event("ITEM_TEXT_READY", vec![]);
|
||||
assert!(s.take_errors().is_empty());
|
||||
assert!(
|
||||
s.eval::<bool>("return ItemTextFrame:IsShown() and not GossipFrame:IsShown()")
|
||||
s.eval::<bool>("return ItemTextFrame:IsShown() and GossipFrame:IsShown()")
|
||||
.unwrap(),
|
||||
"the reader replaces gossip the same way"
|
||||
);
|
||||
assert!(
|
||||
s.take_gossip_close(),
|
||||
"the displaced gossip's OnHide ended the gossip session (CloseGossip)"
|
||||
"the reader seats beside the gossip rather than replacing it"
|
||||
);
|
||||
assert!(!s.take_gossip_close(), "…so `CloseGossip` is not queued");
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ fn opening_a_letter_shows_the_open_frame_and_queues_the_body() {
|
||||
/// hides the centre frame (`MailFrame.xml:1903-1907`), and a frame arriving at centre hides the
|
||||
/// letter. A bare stand-in carries the `CharacterFrame` row.
|
||||
#[test]
|
||||
fn a_letter_and_the_centre_occupant_evict_each_other() {
|
||||
fn a_letter_covers_the_centre_occupant_and_a_new_arrival_hides_it() {
|
||||
let _data = benilla_formats::wow_data_or_skip!();
|
||||
let mut s = UiScript::new().unwrap();
|
||||
load_ui(&s);
|
||||
@@ -283,13 +283,20 @@ fn a_letter_and_the_centre_occupant_evict_each_other() {
|
||||
s.eval::<bool>("return OpenMailFrame:IsShown()").unwrap(),
|
||||
"the letter opened"
|
||||
);
|
||||
// …and the centre occupant stays. `OpenMailFrame` has no `UIPanelWindows` row, so
|
||||
// `ShowUIPanel` takes its first branch — `if ( not GetUIPanelWindowInfo(frame, "area") ) then
|
||||
// frame:Show(); return; end` (`UIParent.lua:920-923`) — a bare Show that claims no slot and
|
||||
// evicts nothing. The eviction runs the other way only: it is a `UIChildWindows` member, so
|
||||
// the next panel to seat anywhere hides it (`CloseChildWindows`, `:792-796`), which is the
|
||||
// second half of this test.
|
||||
assert!(
|
||||
!s.eval::<bool>("return CharacterFrame:IsShown()").unwrap(),
|
||||
"the centre occupant was evicted, not covered (the reported bug)"
|
||||
s.eval::<bool>("return CharacterFrame:IsShown()").unwrap(),
|
||||
"the centre occupant is covered, not evicted"
|
||||
);
|
||||
assert!(
|
||||
s.eval::<bool>("return GetCenterFrame() == nil").unwrap(),
|
||||
"the eviction is a plain vacate — nothing slides"
|
||||
s.eval::<bool>("return GetCenterFrame():GetName() == 'CharacterFrame'")
|
||||
.unwrap(),
|
||||
"and it still holds the centre slot"
|
||||
);
|
||||
assert!(
|
||||
s.eval::<bool>("return MailFrame:IsShown() and GetLeftFrame():GetName() == 'MailFrame'")
|
||||
@@ -297,13 +304,16 @@ fn a_letter_and_the_centre_occupant_evict_each_other() {
|
||||
"the mailbox itself is untouched"
|
||||
);
|
||||
|
||||
// The reverse: re-opening the sheet over the open letter puts the letter away.
|
||||
s.run("ShowUIPanel(CharacterFrame)").unwrap();
|
||||
// The reverse: a sheet **arriving** over the open letter puts the letter away. It has to
|
||||
// arrive — `ShowUIPanel` returns on its first line for a frame that is already shown
|
||||
// (`UIParent.lua:916-918`), so asking again while it is up reaches no slot and hides nothing.
|
||||
s.run("HideUIPanel(CharacterFrame) ShowUIPanel(CharacterFrame)")
|
||||
.unwrap();
|
||||
assert!(s.take_errors().is_empty());
|
||||
assert!(
|
||||
s.eval::<bool>("return CharacterFrame:IsShown()").unwrap()
|
||||
&& !s.eval::<bool>("return OpenMailFrame:IsShown()").unwrap(),
|
||||
"a frame arriving at centre hides the letter"
|
||||
"a frame arriving at a slot hides the letter"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user