-- Kør: luajit tests/test_storageView.lua (fra repo-roden) -- Røgtest af vareoversigten i fanerne Lagre (v1.52) med falske GUI-elementer: opbygning, fold ud, -- opdatering hvert sekund og skift til bygningsvisning må ikke kaste, og tallene skal lande i cellerne. local failures = 0 local function check(name, actual, expected) if actual == expected then print("OK " .. name) else failures = failures + 1; print(string.format("FAIL %s: forventede %s, fik %s", name, tostring(expected), tostring(actual))) end end -- ---- falske GUI-elementer ---- local Element = {} Element.__index = Element local function newElement(names, size) local element = setmetatable({children = {}, text = nil, visible = true, size = size or {0.5, 0.02}}, Element) for _, name in ipairs(names or {}) do element.children[name] = setmetatable({children = {}, name = name, visible = true, size = {0.2, 0.01}}, Element) end return element end function Element:clone() local copy = newElement({}, {self.size[1], self.size[2]}); for n, c in pairs(self.children) do copy.children[n] = setmetatable({children = {}, name = n, visible = true, size = {c.size[1], c.size[2]}}, Element) end; return copy end function Element:getDescendantByName(name) return self.children[name] end function Element:setText(text) self.text = text end function Element:setTexts(texts) self.texts = texts end function Element:setState(state) self.state = state end function Element:setVisible(visible) self.visible = visible end function Element:setSize(x, y) self.size = {x, y} end function Element:setImageColor(_, r, g, b, a) self.color = {r, g, b, a} end function Element:setTextColor(r, g, b, a) self.textColor = {r, g, b, a} end function Element:delete() end function Element:mouseEvent() return false end -- ---- spil-globaler ---- Class = function() return {} end TabbedMenuFrameElement = {} InputAction = {} FocusManager = {loadElementFromCustomValues = function() end, removeElement = function() end} Logging = {warning = function(...) print("WARN", string.format(...)) end, info = function() end} local titles = {[31] = "Straw", [5] = "Sugar", [9] = "Milk"} g_fillTypeManager = {getFillTypeTitleByIndex = function(_, i) return titles[i] end, getFillTypeNameByIndex = function(_, i) return titles[i] end} g_currentMission = {getFarmId = function() return 1 end} g_i18n = nil dofile("FS25_ADSmartPickup/adStorageStats.lua") ADRunsController = {store = {runs = {}}} ADRuns = {getRun = function() return nil end} ADFlowView = {wrapText = function(text) return {text} end} ADSources = { getFarmInventory = function() return ADSources.inventory end, getFarmRates = function() return {[31] = {consumption = 1000, production = 0}, [5] = {consumption = 0, production = 500}} end, getMarketQuote = function(ft) if ft == 5 then return {price = 1.0, top = 1.05} end return nil end, } ADSources.inventory = { {kind = "silo", name = "Farma #1", placeable = "p1", entries = {{fillType = 31, level = 300, capacity = 1000}, {fillType = 5, level = 20000, capacity = 21000}}}, {kind = "silo", name = "Farma #2", placeable = "p2", entries = {{fillType = 31, level = 700, capacity = 1000}}}, {kind = "factory", name = "Sugar mill", placeable = "p3", entries = {{fillType = 5, level = 10, capacity = 100, isOutput = true}}}, } local i18nTexts = {} local i18n = {getText = function(_, key) i18nTexts[key] = true; if key:find("days") then return "%.1f d" end if key:find("share") then return "%d %%" end if key:find("alert_full") then return "%s %d %% %s" end if key:find("alert_empty") then return "%s %s %s %s" end if key:find("alert_sell") then return "%s %d %s" end if key:find("pallets") then return "%d p" end if key:find("perDay") or key:find("fullIn") then return "%s" end return key end} SmartPickupFrame = {} local function load(path) local chunk = assert(loadfile(path)); chunk() end SmartPickupFrame.new = nil load("FS25_ADSmartPickup/gui/SmartPickupFrame.lua") load("FS25_ADSmartPickup/gui/SmartPickupStorageTab.lua") load("FS25_ADSmartPickup/gui/SmartPickupStorageView.lua") load("FS25_ADSmartPickup/gui/SmartPickupFlowTab.lua") -- en frame uden spillets klasse-maskineri: kun det fanen bruger local frame = setmetatable({}, {__index = SmartPickupFrame}) frame.i18n = i18n frame.clonedRows, frame.rowData = {}, {} frame.currentTab = 7 -- Siloer local rows = {} frame.boxLayout = {elements = rows, invalidateLayout = function() end} frame.productPrefab = newElement({"option", "title"}) frame.productPrefab.children.option.children.ignore = newElement() frame.textPrefab = newElement({"title"}) frame.kpiPrefab = newElement({"v1", "l1", "v2", "l2", "v3", "l3", "v4", "l4"}) frame.alertPrefab = newElement({"dot", "c1"}) frame.itemPrefab = newElement({"c1", "c2", "c3", "c4", "bar", "barBg"}) frame.subPrefab = newElement({"c1", "c2", "c3", "c4", "bar", "barBg"}) frame.statPrefab = newElement({"c1", "c2", "c3", "c4", "c5", "c6", "c7"}) frame.gridPrefab = newElement({"c1", "c2", "c3"}) for _, prefab in ipairs({frame.productPrefab, frame.textPrefab, frame.kpiPrefab, frame.alertPrefab, frame.itemPrefab, frame.subPrefab, frame.statPrefab, frame.gridPrefab}) do local base = prefab.clone prefab.clone = function(self) local copy = base(self); if self.children.option then copy.children.option.children.ignore = newElement() end; table.insert(rows, copy); return copy end end frame.getAdEnv = function() return {} end frame.setStatusText = function() end frame.refreshButtons = function() end frame.restoreFocusIfLost = function() end frame.colorRows = function() end for _, name in ipairs({"startButtonInfo", "renameButtonInfo", "deleteButtonInfo", "stopAllButtonInfo", "renameBuildingButtonInfo"}) do frame[name] = {} end local function texts() local list = {} for _, row in ipairs(rows) do for _, name in ipairs({"title", "c1", "c2", "c3", "c4", "v1", "v3"}) do local child = row.children[name] if child ~= nil and child.text ~= nil then table.insert(list, child.text) end end end return table.concat(list, "|") end -- SVW1: opbygning af Siloer i varevisning local ok, err = pcall(frame.rebuild, frame) check("SVW1 opbygning kaster ikke", ok, true) if not ok then print(err) end local all = texts() check("SVW1 straw-række", all:find("+ Straw", 1, true) ~= nil, true) check("SVW1 sugar-række", all:find("+ Sugar", 1, true) ~= nil, true) check("SVW1 straw 1.0k/2.0k 50 %", all:find("1.0k/2.0k · 50 %", 1, true) ~= nil, true) check("SVW1 ingen bygninger før klik", all:find("Farma #2", 1, true), nil) check("SVW1 fabrikkens sukker ikke i siloer", all:find("Sugar mill", 1, true), nil) check("SVW1 kræver handling: straw løber tør", all:find("spu_alert", 1, true) == nil and all:find("Straw 1.0 d", 1, true) ~= nil, true) -- SVW2: klik på straw folder ud; bygninger med mest først local strawRow = frame.itemView.itemRows[1] ok, err = pcall(frame.toggleItem, frame, 31) check("SVW2 fold ud kaster ikke", ok, true) if not ok then print(err) end all = texts() local first, second = all:find("Farma #2", 1, true), all:find("Farma #1", 1, true) check("SVW2 Farma #2 vist", first ~= nil, true) check("SVW2 flest først", first ~= nil and second ~= nil and first < second, true) check("SVW2 markør skiftet", all:find("– Straw", 1, true) ~= nil, true) check("SVW2 andel", all:find("70 %", 1, true) ~= nil, true) -- SVW3: opdatering hvert sekund med nye tal, samme struktur ADSources.inventory[2].entries[1].level = 900 ok, err = pcall(frame.refreshLive, frame) check("SVW3 opdatering kaster ikke", ok, true) if not ok then print(err) end check("SVW3 ny total i cellen", texts():find("1.2k/2.0k · 60 %", 1, true) ~= nil, true) local bar = frame.itemView.itemRows[1].bar check("SVW3 bjælke 60 %", math.floor(bar.size[1] / 0.2 * 100 + 0.5), 60) check("SVW3 bjælke gul (løber tør < 3 d)", bar.color ~= nil and bar.color[1] > 0.9 and bar.color[2] > 0.7, true) -- SVW4: skift til bygningsvisning og tilbage ok, err = pcall(frame.onClickStorageView, frame, SmartPickupFrame.STORAGE_VIEW_BUILDINGS) check("SVW4 bygningsvisning kaster ikke", ok, true) if not ok then print(err) end check("SVW4 ingen varevisning", frame.itemView, nil) ok = pcall(frame.onClickStorageView, frame, SmartPickupFrame.STORAGE_VIEW_ITEMS) check("SVW4 tilbage til varer", ok and frame.itemView ~= nil, true) -- SVW5: fabrikker-fanen: output næsten fuldt -> rød frame.currentTab = 6 ok, err = pcall(frame.rebuild, frame) check("SVW5 fabrikker kaster ikke", ok, true) if not ok then print(err) end -- SVW7: udfoldet vare hvor to siloer bytter plads i mængde -> ingen genopbygning, rækkerne følger bygningen frame.currentTab = 7 frame.expandedItems = nil frame:rebuild() frame:toggleItem(31) local subsBefore = frame.itemView.itemRows[1].subs ADSources.inventory[1].entries[1].level = 950 -- Farma #1 (300 -> 950) forbi Farma #2 (900) for _ = 1, 12 do frame:refreshLive() end check("SVW7 samme rækker (ingen genopbygning)", frame.itemView.itemRows[1].subs, subsBefore) check("SVW7 første underrække er stadig Farma #2", subsBefore[1].cells[1].text, "Farma #2") check("SVW7 anden underrække viser Farma #1's nye tal", subsBefore[2].cells[2].text:find("950", 1, true) ~= nil, true) -- SVW6: alle brugte l10n-nøgler findes i begge sprogfiler for _, file in ipairs({"FS25_ADSmartPickup/l10n/l10n_da.xml", "FS25_ADSmartPickup/l10n/l10n_en.xml"}) do local content = io.open(file):read("*a") for key in pairs(i18nTexts) do if key:find("^spu_") and not content:find('name="' .. key .. '"', 1, true) then failures = failures + 1 print("FAIL SVW6 mangler " .. key .. " i " .. file) end end end print(failures == 0 and "\nALLE TESTS OK" or ("\n" .. failures .. " FEJL")) os.exit(failures == 0 and 0 or 1)