-- Load the helper script dofile("luahelper.lua") -- Test helper function local function assert(condition, message) if not condition then error("ASSERTION FAILED: " .. (message or "unknown error")) end end local function test(name, fn) local ok, err = pcall(fn) if ok then print("PASS: " .. name) else print("FAIL: " .. name .. " - " .. tostring(err)) end end -- Test findElements test("findElements finds all matching elements recursively", function() local testXML = { _tag = "root", _children = { { _tag = "item", _attr = { name = "sword" } }, { _tag = "item", _attr = { name = "shield" } }, { _tag = "container", _children = { { _tag = "item", _attr = { name = "potion" } }, }, }, }, } local items = findElements(testXML, "item") assert(#items == 3, "Should find 3 items total (recursive)") assert(items[1]._attr.name == "sword", "First item should be sword") assert(items[3]._attr.name == "potion", "Third item should be potion (from nested)") end) -- Test getNumAttr and setNumAttr test("getNumAttr gets numeric attribute", function() local elem = { _tag = "item", _attr = { damage = "10" } } local damage = getNumAttr(elem, "damage") assert(damage == 10, "Should get damage as number") end) test("getNumAttr returns nil for missing attribute", function() local elem = { _tag = "item", _attr = {} } local damage = getNumAttr(elem, "damage") assert(damage == nil, "Should return nil for missing attribute") end) test("setNumAttr sets numeric attribute", function() local elem = { _tag = "item", _attr = {} } setNumAttr(elem, "damage", 20) assert(elem._attr.damage == "20", "Should set damage as string") end) -- Test modifyNumAttr test("modifyNumAttr modifies numeric attribute", function() local elem = { _tag = "item", _attr = { weight = "5.5" } } local modified = modifyNumAttr(elem, "weight", function(val) return val * 2 end) assert(modified == true, "Should return true when modified") assert(elem._attr.weight == "11.0", "Should double weight") end) test("modifyNumAttr returns false for missing attribute", function() local elem = { _tag = "item", _attr = {} } local modified = modifyNumAttr(elem, "weight", function(val) return val * 2 end) assert(modified == false, "Should return false when attribute missing") end) -- Test filterElements test("filterElements filters by predicate", function() local testXML = { _tag = "root", _children = { { _tag = "item", _attr = { healing = "20" } }, { _tag = "item", _attr = { damage = "10" } }, { _tag = "item", _attr = { healing = "50" } }, }, } local healingItems = filterElements(testXML, function(elem) return hasAttr(elem, "healing") end) assert(#healingItems == 2, "Should find 2 healing items") end) -- Test visitElements test("visitElements visits all elements", function() local testXML = { _tag = "root", _children = { { _tag = "item" }, { _tag = "container", _children = { { _tag = "item" }, } }, }, } local count = 0 visitElements(testXML, function(elem) count = count + 1 end) assert(count == 4, "Should visit 4 elements (root + 2 items + container)") end) -- Test getText and setText test("getText gets text content", function() local elem = { _tag = "item", _text = "Iron Sword" } local text = getText(elem) assert(text == "Iron Sword", "Should get text content") end) test("setText sets text content", function() local elem = { _tag = "item" } setText(elem, "New Text") assert(elem._text == "New Text", "Should set text content") end) -- Test hasAttr and getAttr test("hasAttr checks attribute existence", function() local elem = { _tag = "item", _attr = { damage = "10" } } assert(hasAttr(elem, "damage") == true, "Should have damage") assert(hasAttr(elem, "magic") == false, "Should not have magic") end) test("getAttr gets attribute value", function() local elem = { _tag = "item", _attr = { name = "sword" } } assert(getAttr(elem, "name") == "sword", "Should get name attribute") assert(getAttr(elem, "missing") == nil, "Should return nil for missing") end) test("setAttr sets attribute value", function() local elem = { _tag = "item" } setAttr(elem, "name", "sword") assert(elem._attr.name == "sword", "Should set attribute") end) -- Test findFirstElement test("findFirstElement finds first direct child", function() local parent = { _tag = "root", _children = { { _tag = "item", _attr = { id = "1" } }, { _tag = "item", _attr = { id = "2" } }, }, } local first = findFirstElement(parent, "item") assert(first._attr.id == "1", "Should find first item") end) test("findFirstElement returns nil when not found", function() local parent = { _tag = "root", _children = {} } local result = findFirstElement(parent, "item") assert(result == nil, "Should return nil when not found") end) -- Test getChildren test("getChildren gets all direct children with tag", function() local parent = { _tag = "root", _children = { { _tag = "item", _attr = { id = "1" } }, { _tag = "config" }, { _tag = "item", _attr = { id = "2" } }, }, } local items = getChildren(parent, "item") assert(#items == 2, "Should get 2 items") assert(items[1]._attr.id == "1", "First should have id=1") assert(items[2]._attr.id == "2", "Second should have id=2") end) -- Test countChildren test("countChildren counts direct children with tag", function() local parent = { _tag = "root", _children = { { _tag = "item" }, { _tag = "config" }, { _tag = "item" }, }, } assert(countChildren(parent, "item") == 2, "Should count 2 items") assert(countChildren(parent, "config") == 1, "Should count 1 config") end) -- Test addChild test("addChild adds child element", function() local parent = { _tag = "root", _children = {} } addChild(parent, { _tag = "item" }) assert(#parent._children == 1, "Should have 1 child") assert(parent._children[1]._tag == "item", "Child should be item") end) test("addChild creates children array if needed", function() local parent = { _tag = "root" } addChild(parent, { _tag = "item" }) assert(parent._children ~= nil, "Should create _children") assert(#parent._children == 1, "Should have 1 child") end) -- Test removeChildren test("removeChildren removes all matching children", function() local parent = { _tag = "root", _children = { { _tag = "item" }, { _tag = "config" }, { _tag = "item" }, }, } local removed = removeChildren(parent, "item") assert(removed == 2, "Should remove 2 items") assert(#parent._children == 1, "Should have 1 child left") assert(parent._children[1]._tag == "config", "Remaining should be config") end) test("removeChildren returns 0 when none found", function() local parent = { _tag = "root", _children = { { _tag = "item" } }, } local removed = removeChildren(parent, "config") assert(removed == 0, "Should remove 0") assert(#parent._children == 1, "Should still have 1 child") end) print("\nAll tests completed!")