-- Offline behavioral evidence for the existing party Show AFK setting. -- Run with Lua 5.1; pass a checkout and optionally a baseline raid-frame file. -- Executes the production options helpers, settings proxies and status painter. -- WoW APIs and FontStrings are replaced; live-client validation is separate. local repo = assert(arg[1], "checkout path required") local sourcePath = arg[2] or (repo .. "/EllesmereUIRaidFrames/EllesmereUIRaidFrames.lua") local function read(path) local file = assert(io.open(path, "rb")) local value = file:read("*a") file:close() return value end local source = read(sourcePath) local options = read(repo .. "/EllesmereUIOptions/EUI_RaidFrames_Options.lua") assert(loadfile(sourcePath)) local function extract(text, firstMarker, lastMarker) local first = assert(text:find(firstMarker, 1, true), firstMarker) local last = assert(text:find(lastMarker, first + #firstMarker, true), lastMarker) return text:sub(first, last - 1) end local function equal(actual, expected, reason) if actual ~= expected then error(reason .. ": expected " .. tostring(expected) .. ", got " .. tostring(actual), 2) end end local function fixture(profile) local env = setmetatable({}, { __index = _G }) env.db = { profile = profile } env.EllesmereUI = { L = function(text) return text end } env.ns = { EllesmereUI = env.EllesmereUI } env.wipe = function(value) for key in pairs(value) do value[key] = nil end return value end env.UnitIsAFK = function() return true end env.issecretvalue = function() return false end env.ReloadAndUpdate = function() end local function execute(text) local chunk = assert(loadstring(text, "@production-extract")) setfenv(chunk, env) return chunk() end execute(extract(source, "ns._PARTY_KEY_SECTION = {}", "-- Party inherits raid strata")) execute(extract(source, "ns._partyProxy = setmetatable({}, {", "-- Compute the party indicator/aura scale")) execute(extract(source, "ns._PaintStatusText = function", "ns._UpdateButtonHealth = function")) local helpers = execute(extract(options, "local _partyCtx = false", "-- Context-aware direct write") .. [[ return { context = function(party) _partyCtx = party end, set = SSet, get = SGet, value = SVal, } ]]) local function render(settings) local fs = { visible = false } function fs:SetText(text) self.text = text end function fs:SetTextColor() end function fs:Show() self.visible = true end function fs:Hide() self.visible = false end env.ns._PaintStatusText({ statusText = fs }, settings, "player", true, false) return fs.visible, fs.text end return env, helpers, render end local passed, failed = 0, 0 local function test(name, fn) local ok, message = pcall(fn) if ok then passed = passed + 1 io.write("PASS ", name, "\n") else failed = failed + 1 io.write("FAIL ", name, "\n ", tostring(message), "\n") end end test("custom party enable preserves raid disabled and updates both live views", function() local env, ui, render = fixture({ statusShowAFK = false, partySyncSections = { indicators = false } }) ui.context(true) ui.set("statusShowAFK", true) equal(env.db.profile.statusShowAFK, false, "raid choice must be preserved") equal(env.db.profile.party_statusShowAFK, true, "party choice must be saved separately") equal(ui.value("statusShowAFK", false), true, "party toggle reflects its setting") equal(render(env.ns._scaledPartyProxy), true, "AFK party member receives a label") ui.context(false) equal(ui.value("statusShowAFK", false), false, "raid toggle remains disabled") equal(render(env.ns._scaledProfile), false, "raid label remains hidden") end) test("custom party disable preserves raid enabled", function() local env, ui, render = fixture({ statusShowAFK = true, partySyncSections = { indicators = false } }) ui.context(true) ui.set("statusShowAFK", false) equal(env.db.profile.statusShowAFK, true, "raid enabled choice must be preserved") equal(env.db.profile.party_statusShowAFK, false, "false override must not fall through") equal(render(env.ns._scaledPartyProxy), false, "party label is hidden") equal(render(env.ns._scaledProfile), true, "raid label is still visible") end) test("stored custom party choice survives proxy reconstruction", function() local env, ui, render = fixture({ statusShowAFK = false, party_statusShowAFK = true, partySyncSections = { indicators = false } }) env.ns._RefreshProxyModes() equal(render(env.ns._scaledPartyProxy), true, "stored party choice controls live AFK text") equal(render(env.ns._scaledProfile), false, "reconstruction does not enable raid AFK") end) test("synced party continues inheriting raid with a dormant custom value", function() local env, ui, render = fixture({ statusShowAFK = false, party_statusShowAFK = true, partySyncSections = { indicators = true } }) ui.context(false) ui.set("statusShowAFK", true) equal(render(env.ns._scaledPartyProxy), true, "synced party follows raid enable") ui.set("statusShowAFK", false) equal(render(env.ns._scaledPartyProxy), false, "synced party follows raid disable") equal(env.db.profile.party_statusShowAFK, true, "dormant value is not rewritten") end) test("custom party with no override inherits the raid value", function() local env, ui, render = fixture({ statusShowAFK = true, partySyncSections = { indicators = false } }) ui.context(true) equal(ui.value("statusShowAFK", false), true, "new custom section initially inherits raid") equal(render(env.ns._scaledPartyProxy), true, "runtime also inherits raid") equal(env.db.profile.party_statusShowAFK, nil, "reading does not create an override") end) test("default synced profile keeps AFK text disabled", function() local env, ui, render = fixture({ statusShowAFK = false }) equal(render(env.ns._scaledPartyProxy), false, "default party has no AFK label") equal(render(env.ns._scaledProfile), false, "default raid has no AFK label") end) io.write(string.format("RESULT %d passed, %d failed\n", passed, failed)) if failed > 0 then os.exit(1) end