Thu, 23 Mar 2023 15:12:30 +0000
Serialize XML in a consistent order by default
This overrides all XML serialization to emit attributes in an ordered form, so
the XML will match across multiple runs. This can be useful for comparing
different runs, or even two stanzas printed in the same run (e.g. if there is
a mismatch).
local function lines(l, indent) return table.concat(l, "\n"..string.rep(" ", indent or 0)); end local quiet_handlers = { "test-failed", "test-error" }; local function new(config) local pretty = require "scansion.pretty".new({ sorted = config.ordered; }); local handlers = { ["script"] = function (data) return "TEST: "..(data.title or data.filename or "untitled"); end; ["test-passed"] = function () return "PASS"; end; ["test-failed"] = function (data) local error_text; if data.reason and data.reason.type == "unexpected-stanza" then error_text = "Received unexpected stanza:\n\n"..pretty(data.reason.data.stanza, 4); if data.reason.data.expected then error_text = error_text.."\n\nExpected:\n\n"..pretty(data.reason.data.expected, 4); end else error_text = tostring(data.reason); end return lines({ "FAILED: "..data.name; ""; (error_text:gsub("\n", "\n ")); ""; }, 4); end; ["test-error"] = function (data) return lines({ "ERROR: "..data.name; ""; (tostring(data.reason):gsub("\n", "\n ")); ""; }, 4); end; ["action"] = function (data) local action = data.action; local obj_type = data.object_type; local l = {}; if data.annotation then table.insert(l, action.annotation); end table.insert(l, data.object.." "..action); if data.extra and obj_type == "client" and (action == "sends" or action == "receives") then table.insert(l, "\n"..pretty(lines(data.extra), 4).."\n"); end return lines(l); end; ["end"] = function (data) local r = {}; local all_results = {}; for _, v in pairs(data.summary.all) do table.insert(all_results, v); end table.sort(all_results, function (a, b) return a.name < b.name end); print(""); print("Summary"); print("-------"); for _, test_result in ipairs(all_results) do print("", test_result.status, test_result.name); end print(""); for _, test_result in ipairs{ "ok", "fail", "error", "skipped", "total" } do local count = data.summary[test_result] and #data.summary[test_result] or 0; table.insert(r, tostring(count).." "..test_result); end return table.concat(r, " / "); end; }; local h = {}; if config.quiet then for _, handler_name in ipairs(quiet_handlers) do h[handler_name] = handlers[handler_name]; end if config.summary then h["end"] = handlers["end"]; end else h = handlers; end return h; end return { new = new; }