Files
benilla-octo/crates/benilla-app/src/ui_script/fade_tests.rs
T
SamandClaude Opus 5.5 449324b7be a clone without the install runs the suite green
465 tests loaded the stock interface off the install without declaring
it, and 25 addon tests assumed the install beside the corpus; each now
opens with `wow_data_or_skip!`. The gates run the workspace tests a
second time with `WOW_DATA=`, so a test that reads the install
undeclared fails at land instead of on a contributor's clone. The skip
log writes each line in one call so parallel tests do not interleave.

Verified: the workspace tests with `WOW_DATA=` in a checkout that has
the addon corpus pass 6972, fail 0, and log 1555 skips; on a fresh
clone of main before this change they failed 465.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-23 19:10:41 +07:00

125 lines
4.9 KiB
Rust

//! The fade and flash kits — the stock `UIParent.lua`'s since 1988, walked from `UIParent`'s own
//! `<OnUpdate>` (`UIFrameFadeUpdate` / `UIFrameFlashUpdate`), which is what the reference does
//! too: no tick driver of ours, and a cinematic's `UIParent:Hide()` stops both walks the way it
//! stops the reference's. What these guard is the arithmetic and the list discipline — a fade
//! ramps linearly to its endAlpha and leaves `FADEFRAMES`; a flash alternates for its duration,
//! refuses a re-arm while flashing, and ends hidden when `showWhenDone` is nil.
use benilla_ui::script::UiScript;
use super::test_ui::load_ui as load_xml;
#[test]
fn a_started_fade_ramps_off_uiparents_tick_and_completes() {
benilla_formats::wow_data_or_skip!();
let mut s = UiScript::new().unwrap();
s.set_screen_size(1024.0, 768.0);
load_xml(&s, r"Interface\FrameXML\MoneyFrame.lua");
load_xml(&s, r"Interface\FrameXML\MoneyFrame.xml");
load_xml(&s, r"Interface\FrameXML\UIParent.xml");
load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.lua");
load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.xml");
load_xml(&s, r"Interface\FrameXML\GlobalStrings.lua");
load_xml(&s, r"Interface\FrameXML\BasicControls.xml");
load_xml(&s, r"Interface\FrameXML\LocaleProperties.lua");
load_xml(&s, r"Interface\FrameXML\StaticPopup.xml");
s.resolve();
s.run(r#"CreateFrame("Frame", "BenillaFadeProbe")"#)
.unwrap();
s.run("UIFrameFadeIn(BenillaFadeProbe, 1.0)").unwrap();
assert!(
s.eval::<bool>("return UIFrameIsFading(BenillaFadeProbe) == 1")
.unwrap(),
"on the fade list"
);
assert_eq!(
s.eval::<f64>("return BenillaFadeProbe:GetAlpha()").unwrap(),
0.0,
"the fade armed at its IN startAlpha"
);
s.tick(0.5);
s.resolve();
let mid = s.eval::<f64>("return BenillaFadeProbe:GetAlpha()").unwrap();
assert!(
(mid - 0.5).abs() < 1e-3,
"half the timeToFade in, half the ramp: {mid}"
);
s.tick(0.6); // past timeToFade: the fade completes and leaves the list
s.resolve();
assert_eq!(
s.eval::<f64>("return BenillaFadeProbe:GetAlpha()").unwrap(),
1.0,
"the fade completes at its endAlpha"
);
assert!(
!s.eval::<bool>("return UIFrameIsFading(BenillaFadeProbe) == 1")
.unwrap(),
"…and leaves the list"
);
assert!(s.errors().is_empty(), "script errors: {:?}", s.errors());
}
/// **The FLASH kit alternates and stops** — the fade kit's twin, transcribed from `UIParent.lua`
/// because two stock windows call it and nothing answered (1879).
///
/// Driven rather than merely loaded: a kit that is present but never exercised is exactly how
/// twelve faux lists shipped unable to scroll (1868), so this runs a real flash to completion.
#[test]
fn a_flash_alternates_then_stops() {
benilla_formats::wow_data_or_skip!();
let mut s = UiScript::new().unwrap();
s.set_screen_size(1024.0, 768.0);
load_xml(&s, r"Interface\FrameXML\MoneyFrame.lua");
load_xml(&s, r"Interface\FrameXML\MoneyFrame.xml");
load_xml(&s, r"Interface\FrameXML\UIParent.xml");
load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.lua");
load_xml(&s, r"Interface\FrameXML\UIPanelTemplates.xml");
load_xml(&s, r"Interface\FrameXML\GlobalStrings.lua");
load_xml(&s, r"Interface\FrameXML\BasicControls.xml");
load_xml(&s, r"Interface\FrameXML\LocaleProperties.lua");
load_xml(&s, r"Interface\FrameXML\StaticPopup.xml");
s.resolve();
// Parked until something asks — the whole point of the driver over UIParent's own OnUpdate.
s.run(
r#"Probe = CreateFrame("Frame", "BenillaFlashProbe", UIParent)
Probe:SetWidth(10) Probe:SetHeight(10) Probe:SetPoint("TOPLEFT", 0, 0)
UIFrameFlash(Probe, 0.05, 0.05, 0.3, nil, 0, 0)"#,
)
.unwrap();
assert!(
s.eval::<bool>("return UIFrameIsFlashing(BenillaFlashProbe) == 1")
.unwrap(),
"the frame is on the flash list"
);
// Re-arming an already-flashing frame is a no-op, not a second entry (ref UIParent.lua:1234).
s.run("UIFrameFlash(BenillaFlashProbe, 1, 1, 1, nil, 0, 0)")
.unwrap();
assert_eq!(
s.eval::<i64>("return table.getn(FLASHFRAMES)").unwrap(),
1,
"already flashing: the reference returns rather than re-arming"
);
// Run past flashDuration: the frame leaves both lists, is restored to full alpha, and — with
// `showWhenDone` nil — ends hidden.
for _ in 0..40 {
s.tick(0.016);
s.resolve();
}
assert!(s.errors().is_empty(), "flashing raised: {:?}", s.errors());
assert_eq!(
s.eval::<i64>("return table.getn(FLASHFRAMES)").unwrap(),
0,
"the flash finished and the frame left the list"
);
assert!(
!s.eval::<bool>("return BenillaFlashProbe:IsShown()")
.unwrap(),
"showWhenDone was nil, so it ends hidden"
);
}