-- Unit checks for custom/extensions/link-trailers.lua, run under a standalone -- Lua by t0506-link-trailers.sh with the script path as the argument. The -- shipped configuration links Fixes and Reverts object names to ./?id= and a -- bare URL to itself, and leaves Closes and Bug marks as text. The rest runs -- with the commented-out tracker rules switched on, linking those marks to -- bugs.example.com, and checks that shape, the key matching and the values -- that must pass through untouched. local test_directory = arg[0]:match("^(.*)/") or "." local h = dofile(test_directory .. "/harness.lua") local script = arg[1] h.load(script) local function render(key, text) return h.run({ key, "commit" }, { text }) end h.equals("an unedited copy leaves a Closes mark as text", render("Closes", "#45"), "#45") h.load_with(script, { { "-- { key = \"Closes\"", "{ key = \"Closes\"" }, { "-- { key = \"Bug\"", "{ key = \"Bug\"" }, }) local out, ret = render("Fixes", "1234567 (\"plain commit\")") h.contains("a Fixes object name links to its commit", out, "1234567 (\"plain commit\")") h.equals("close answers zero", ret, 0) out = render("fixes", "1234567") h.contains("the key matches case insensitively", out, "1234567") out = render("Fixes", "123456") h.equals("six hex characters stay text", out, "123456") out = render("Reverts", "cafebabe") h.contains("a Reverts object name links too", out, "cafebabe") out = render("Closes", "#45") h.equals("a Closes mark links to the tracker", out, "#45") out = render("Bug", "45") h.equals("a bare Bug number links to the tracker", out, "45") out = render("Closes", "not a number") h.equals("a Closes value that is no number stays text", out, "not a number") out = render("Link", "https://example.com/?a=1&b=2") h.equals("a bare URL links to itself with its escaping kept", out, "https://example.com/?a=1&b=2") out = render("Whatever", "https://example.com/x") h.contains("a URL links under any key", out, "") out = render("Link", "https://example.com/it's") h.equals("a URL holding a quote stays text", out, "https://example.com/it's") out = render("Link", "see https://example.com/x") h.equals("a URL inside other text stays text", out, "see https://example.com/x") out = render("Reported-by", "someone") h.equals("a key with no rule passes through", out, "someone") -- cgit hands the value over already escaped. out = render("Reported-by", "a & b <c>") h.equals("an escaped value passes through as it came", out, "a & b <c>") out = h.run({ "Fixes", "commit" }, { "12345", "67 tail" }) h.contains("a value split across writes is seen whole", out, "1234567 tail") out, ret = render("Fixes", "") h.equals("an empty value stays empty", out, "") h.equals("an empty value still answers zero", ret, 0) -- A rule broad enough to capture a quote or a percent sign still has to -- leave a url that stays inside its attribute and means what it says. h.load_with(script, { { "local rules = {", "local rules = { { key = \"Ref\", pattern = \"^(%S+)$\", url = \"https://t/%s\" }," } }) out = render("Ref", "a'b%c") h.equals("a captured value is percent-encoded into the url", out, "a'b%c") -- A malformed pattern is the operator's error, so that rule is skipped and -- the next one for the key still runs. h.load_with(script, { { "local rules = {", "local rules = { { key = \"Fixes\", pattern = \"(%x+\", url = \"https://x/%s\" }," } }) out = render("Fixes", "1234567") h.equals("a malformed rule is skipped for the next one", out, "1234567") -- Only http and https links are drawn, so another scheme stays text. out = render("Link", "javascript://x") h.equals("a url of any other scheme stays text", out, "javascript://x") h.load_with(script, { { "local rules = {", "local rules = { { pattern = \"^T(%d+)$\", url = \"https://t/%s\" }," } }) out = render("Whatever", "T12") h.equals("a rule without a key applies to every trailer", out, "T12") h.load_with(script, { { "local link_urls = true", "local link_urls = false" } }) out = render("Link", "https://example.com/x") h.equals("bare urls can be left as text", out, "https://example.com/x") h.load_with(script, { { "-- { key = \"CVE\"", "{ key = \"CVE\"" }, { "-- url = \"https://www.cve.org", " url = \"https://www.cve.org" }, }) out = render("CVE", "CVE-2024-12345") h.equals("the shipped CVE example links to its record", out, "CVE-2024-12345") -- A long value of url starts is checked against the url pattern once, from -- its start, so it costs no more than its length. h.stays_linear("a long value is checked in linear time", function(text) return (render("Link", text)) end, function(count) return string.rep("http://", count) .. " " end, 10000) h.finish()