//! `CreateFrame`'s fourth argument against the **real** `assets/ui` templates — the corpus idiom, //! end to end. //! //! The unit tests for the runtime template path live in //! `benilla-ui/src/script/tests/create_frame_template.rs` and drive synthetic templates. This one //! exists because the thing an addon actually types is //! //! ```lua //! local tab = CreateFrame("Button", "MyTab", UIParent, "TabButtonTemplate") //! getglobal("MyTab".."Text"):SetText("Hi") //! ``` //! //! against a template *we* wrote, loaded the way the client loads it — six hundred lines of real //! FrameXML above it, a font registry, an anchor graph — not a four-line fixture. Every assertion //! below is a global an addon would reach for. use benilla_ui::script::UiScript; const UI_DIR: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/assets/ui"); /// The prefix of `benilla.toc`'s load order these templates need: the font registry, the panel kit, /// UIParent (the parent every addon passes), and the faux-scroll kit. const FILES: [&str; 5] = [ "Fonts.xml", "MoneyFrame.xml", "UiPanels.xml", "UIParent.xml", "ScrollTemplates.xml", ]; fn load_ui(script: &UiScript) { let dir = std::path::Path::new(UI_DIR); let provider = |req: &str| -> Option> { let norm = req.replace('\\', "/"); let base = norm.rsplit('/').next().unwrap_or(&norm); std::fs::read(dir.join(&norm)) .or_else(|_| std::fs::read(dir.join(base))) .ok() }; for file in FILES { let text = std::fs::read_to_string(dir.join(file)) .unwrap_or_else(|e| panic!("reading {file}: {e}")); let doc = benilla_ui::framexml::parse(&text).unwrap_or_else(|e| panic!("parsing {file}: {e}")); let report = benilla_ui::loader::load(script, &doc, &provider); assert!( report.errors.is_empty(), "{file} loaded with errors: {:#?}", report.errors ); } } /// The line an addon writes, and the globals it reads on the next one. /// /// `TabButtonTemplate` (UiPanels.xml) is a `