//! The fade and flash kits — the stock `UIParent.lua`'s since 1988, walked from `UIParent`'s own //! `` (`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::("return UIFrameIsFading(BenillaFadeProbe) == 1") .unwrap(), "on the fade list" ); assert_eq!( s.eval::("return BenillaFadeProbe:GetAlpha()").unwrap(), 0.0, "the fade armed at its IN startAlpha" ); s.tick(0.5); s.resolve(); let mid = s.eval::("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::("return BenillaFadeProbe:GetAlpha()").unwrap(), 1.0, "the fade completes at its endAlpha" ); assert!( !s.eval::("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::("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::("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::("return table.getn(FLASHFRAMES)").unwrap(), 0, "the flash finished and the frame left the list" ); assert!( !s.eval::("return BenillaFlashProbe:IsShown()") .unwrap(), "showWhenDone was nil, so it ends hidden" ); }