blob: 3b0eeb8705118987ee9b02c3fbbde6c9f894748b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
-- Unit checks for custom/extensions/syntax-highlight.lua, run under a
-- standalone Lua by t0502-syntax-highlight.sh with the script path as the
-- first argument. The filter remembers whether the lexers loaded for the
-- life of the interpreter, so the two sides of that split are two runs of
-- this file. In highlight mode the shell points CGIT_SCINTILLUA_PATH at the
-- fake-lexers directory beside this file and every path through a working
-- lexer is checked, and in nolexers mode it points at an empty directory so
-- the escaped fallback is what everything renders through.

local test_directory = arg[0]:match("^(.*)/") or "."
local h = dofile(test_directory .. "/harness.lua")

local script = arg[1]
local mode = arg[2] or "highlight"

h.load(script)

local function render(filename, text)
	return h.run({ filename }, { text })
end

if mode == "nolexers" then
	local out, ret = render("hello.fake", "if 42")
	h.equals("without lexers source is served escaped", out, "if 42")
	h.equals("close answers zero", ret, 0)

	out = render("hello.fake", "a <b> & c")
	h.equals("the fallback escapes markup", out, "a &lt;b&gt; &amp; c")

	-- Large output leaves in slices, and a byte lost at a boundary would
	-- put the line numbers beside it out of step, so the whole escaped
	-- blob has to come back intact across several slices.
	out = render("big.fake", string.rep("x<y>", 30000))
	h.equals("slicing loses nothing at the boundaries", out,
		string.rep("x&lt;y&gt;", 30000))

	h.finish()
end

local out, ret = render("hello.fake", "if 42 'hi' & zz")
h.contains("keywords are wrapped in their class", out,
	"<span class='hl-keyword'>if</span>")
h.contains("numbers are wrapped in their class", out,
	"<span class='hl-number'>42</span>")
h.contains("a dotted tag maps by its first component", out,
	"<span class='hl-string'>'hi'</span>")
h.contains("bytes between tokens are escaped", out, " &amp; ")
h.contains("later tokens still highlight", out,
	"<span class='hl-keyword'>zz</span>")
h.equals("close answers zero", ret, 0)

out = h.run({ "split.fake" }, { "i", "f" })
h.equals("writes are joined before lexing", out,
	"<span class='hl-keyword'>if</span>")

-- The short lexer tags four bytes and stops, and every byte after it still
-- has to reach the page.
out = render("cut.short", "abcd<ef>")
h.equals("a lexer stopping early leaves an escaped tail", out,
	"<span class='hl-keyword'>abcd</span>&lt;ef&gt;")

out = render("boom.badlex", "some <code>")
h.equals("a lexer that raises falls back to escaped text", out,
	"some &lt;code&gt;")

-- The viadetect lexer name only resolves through detect(), so highlighted
-- output proves the detection path ran ahead of the extension path.
out = render("script.viadetect", "if")
h.equals("filename detection picks the lexer", out,
	"<span class='hl-keyword'>if</span>")

out = render("tool.py", "import <x>")
h.equals("an extension with no lexer serves escaped text", out,
	"import &lt;x&gt;")

out = render("noextension", "words <here>")
h.equals("a file with no extension serves escaped text", out,
	"words &lt;here&gt;")

out = render("big.fake", string.rep("a", 512 * 1024 + 1))
h.excludes("an oversized blob skips the lexing pass", out, "<span")
h.equals("and still arrives whole", #out, 512 * 1024 + 1)

out, ret = render("empty.fake", "")
h.equals("an empty blob renders empty", out, "")
h.equals("an empty blob still answers zero", ret, 0)

-- cgit's C sink stops at the first NUL byte, which the script documents for
-- binaries that slip past the text detection.
out = render("blob.bin", "ab\0cd")
h.contains("bytes before a nul survive", out, "ab")
h.excludes("bytes after a nul are dropped", out, "cd")

h.finish()