|
| 1 | +--============================================================== |
| 2 | +--= Tests for LuaPreprocess. |
| 3 | +--============================================================== |
| 4 | + |
| 5 | +local results = {} |
| 6 | + |
| 7 | +local function doTest(description, f, ...) |
| 8 | + print("Running test: "..description) |
| 9 | + |
| 10 | + local ok, err = pcall(f, ...) |
| 11 | + if not ok then print("Error: "..tostring(err)) end |
| 12 | + |
| 13 | + table.insert(results, {description=description, ok=ok}) |
| 14 | +end |
| 15 | + |
| 16 | +local function addLabel(label) |
| 17 | + table.insert(results, {label=label}) |
| 18 | +end |
| 19 | + |
| 20 | +local function trim(s) |
| 21 | + return (s:gsub("^%s+", ""):gsub("%s+$", "")) |
| 22 | +end |
| 23 | + |
| 24 | +local function assertCodeOutput(codeOut, codeExpected, message) |
| 25 | + assert(trim(codeOut) == codeExpected, (message or "Unexpected output: "..codeOut)) |
| 26 | +end |
| 27 | + |
| 28 | +--============================================================== |
| 29 | + |
| 30 | + |
| 31 | + |
| 32 | +addLabel("Preprocessor code.") |
| 33 | + |
| 34 | +doTest("Inline block with simple expression.", function() |
| 35 | + local pp = assert(loadfile"preprocess.lua")() |
| 36 | + local luaIn = [[ |
| 37 | + local x = !(1+2*3) |
| 38 | + ]] |
| 39 | + |
| 40 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 41 | + assertCodeOutput(luaOut, [[local x = 7]]) |
| 42 | +end) |
| 43 | + |
| 44 | +doTest("Static branch.", function() |
| 45 | + local pp = assert(loadfile"preprocess.lua")() |
| 46 | + local luaIn = [[ |
| 47 | + !if FLAG then |
| 48 | + print("Yes") |
| 49 | + !else |
| 50 | + print("No") |
| 51 | + !end |
| 52 | + ]] |
| 53 | + |
| 54 | + pp.metaEnvironment.FLAG = true |
| 55 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 56 | + assertCodeOutput(luaOut, [[print("Yes")]], "Unexpected output with FLAG=true.") |
| 57 | + |
| 58 | + pp.metaEnvironment.FLAG = false |
| 59 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 60 | + assertCodeOutput(luaOut, [[print("No")]], "Unexpected output with FLAG=false.") |
| 61 | +end) |
| 62 | + |
| 63 | +doTest("Output value from metaprogram.", function() |
| 64 | + local pp = assert(loadfile"preprocess.lua")() |
| 65 | + local luaIn = [[ |
| 66 | + !local t = { |
| 67 | + z = 99, |
| 68 | + a = 2, |
| 69 | + } |
| 70 | + local theTable = !(t) |
| 71 | + ]] |
| 72 | + |
| 73 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 74 | + -- Table keys should be sorted. We want consistent output! |
| 75 | + assertCodeOutput(luaOut, [[local theTable = {a=2,z=99}]]) |
| 76 | +end) |
| 77 | + |
| 78 | +doTest("Generate code.", function() |
| 79 | + local pp = assert(loadfile"preprocess.lua")() |
| 80 | + local luaIn = [[ |
| 81 | + !( |
| 82 | + outputLua("local s = ") |
| 83 | + outputValue("\n") |
| 84 | + ) |
| 85 | + ]] |
| 86 | + |
| 87 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 88 | + assertCodeOutput(luaOut, ("local s = %q"):format("\n")) |
| 89 | + |
| 90 | + local luaOut = assert(pp.processString{ code=luaIn, debug=true }) |
| 91 | + assertCodeOutput(luaOut, [[local s = "\n"]]) -- Debug mode changes how newlines appear in string values. |
| 92 | +end) |
| 93 | + |
| 94 | +doTest("Parsing extended preprocessor line.", function() |
| 95 | + local pp = assert(loadfile"preprocess.lua")() |
| 96 | + local luaIn = [[ |
| 97 | + !local str = "foo\ |
| 98 | + "; local arr = { |
| 99 | + 10, |
| 100 | + }; local z = ( |
| 101 | + 100+(3^3) |
| 102 | + )+arr[ |
| 103 | + 1 |
| 104 | + ]; --[=[ Comment in metaprogram. |
| 105 | + ]=] |
| 106 | +
|
| 107 | + local z = !(z) |
| 108 | + ]] |
| 109 | + |
| 110 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 111 | + assertCodeOutput(luaOut, [[local z = 137]]) |
| 112 | +end) |
| 113 | + |
| 114 | +doTest("Dual code.", function() |
| 115 | + local pp = assert(loadfile"preprocess.lua")() |
| 116 | + local luaIn = [[ |
| 117 | + !local one = 1 |
| 118 | + !local two = 2 |
| 119 | + !!local sum = one+two -- The expression is evaluated in the metaprogram. |
| 120 | + ]] |
| 121 | + |
| 122 | + local luaOut = assert(pp.processString{ code=luaIn }) |
| 123 | + assertCodeOutput(luaOut, [[local sum = 3]]) |
| 124 | +end) |
| 125 | + |
| 126 | +doTest("Expression or not?", function() |
| 127 | + local pp = assert(loadfile"preprocess.lua")() |
| 128 | + |
| 129 | + local luaOut = assert(pp.processString{ code=[[ |
| 130 | + foo(!( math.floor(1.5) )) |
| 131 | + ]]}) |
| 132 | + assertCodeOutput(luaOut, [[foo(1)]]) |
| 133 | + |
| 134 | + local luaOut = assert(pp.processString{ code=[[ |
| 135 | + !( math.floor(1.5); ) |
| 136 | + ]]}) |
| 137 | + assertCodeOutput(luaOut, [[]]) |
| 138 | + |
| 139 | + local luaOut = assert(pp.processString{ code=[[ |
| 140 | + !( x = math.floor(1.5) ) |
| 141 | + ]]}) |
| 142 | + assertCodeOutput(luaOut, [[]]) |
| 143 | +end) |
| 144 | + |
| 145 | +doTest("Output values of different types.", function() |
| 146 | + local pp = assert(loadfile"preprocess.lua")() |
| 147 | + |
| 148 | + -- Valid: Numbers, strings, tables, booleans, nil. |
| 149 | + |
| 150 | + local luaOut = assert(pp.processString{ code=[[ num = !(123) ]]}) |
| 151 | + assertCodeOutput(luaOut, [[num = 123]]) |
| 152 | + |
| 153 | + local luaOut = assert(pp.processString{ code=[[ str = !("foo") ]]}) |
| 154 | + assertCodeOutput(luaOut, [[str = "foo"]]) |
| 155 | + |
| 156 | + local luaOut = assert(pp.processString{ code=[[ t = !({}) ]]}) |
| 157 | + assertCodeOutput(luaOut, [[t = {}]]) |
| 158 | + |
| 159 | + local luaOut = assert(pp.processString{ code=[[ bool, nothing = !(true), !(nil) ]]}) |
| 160 | + assertCodeOutput(luaOut, [[bool, nothing = true, nil]]) |
| 161 | + |
| 162 | + -- Invalid: Functions, userdata, coroutines. |
| 163 | + |
| 164 | + local luaOut = pp.processString{ code=[[ func = !(function()end) ]]} |
| 165 | + assert(not luaOut) |
| 166 | + |
| 167 | + local luaOut = pp.processString{ code=[[ file = !(io.stdout) ]]} |
| 168 | + assert(not luaOut) |
| 169 | + |
| 170 | + local luaOut = pp.processString{ code=[[ co = !(coroutine.create(function()end)) ]]} |
| 171 | + assert(not luaOut) |
| 172 | +end) |
| 173 | + |
| 174 | + |
| 175 | + |
| 176 | +addLabel("Library API.") |
| 177 | + |
| 178 | +doTest("Get useful tokens.", function() |
| 179 | + local pp = assert(loadfile"preprocess.lua")() |
| 180 | + local tokens = pp.tokenize[[local x = 5 -- Foo!]] |
| 181 | + |
| 182 | + pp.removeUselessTokens(tokens) |
| 183 | + |
| 184 | + assert(#tokens == 4, "Unexpected amount of tokens.") |
| 185 | + assert(tokens[1].type == "keyword", "Unexpected token type 1.") |
| 186 | + assert(tokens[1].value == "local", "Unexpected token value 1.") |
| 187 | + assert(tokens[2].type == "identifier", "Unexpected token type 2.") |
| 188 | + assert(tokens[2].value == "x", "Unexpected token value 2.") |
| 189 | + assert(tokens[3].type == "punctuation", "Unexpected token type 3.") |
| 190 | + assert(tokens[3].value == "=", "Unexpected token value 3.") |
| 191 | + assert(tokens[4].type == "number", "Unexpected token type 4.") |
| 192 | + assert(tokens[4].value == 5, "Unexpected token value 4.") |
| 193 | +end) |
| 194 | + |
| 195 | +doTest("Serialize.", function() |
| 196 | + local pp = assert(loadfile"preprocess.lua")() |
| 197 | + |
| 198 | + local t = { |
| 199 | + z = 99, |
| 200 | + a = 2, |
| 201 | + } |
| 202 | + |
| 203 | + local luaOut = assert(pp.toLua(t)) |
| 204 | + assertCodeOutput(luaOut, [[{a=2,z=99}]]) -- Note: Table keys should be sorted. |
| 205 | +end) |
| 206 | + |
| 207 | + |
| 208 | + |
| 209 | +--============================================================== |
| 210 | + |
| 211 | +local countResults = 0 |
| 212 | +local countFails = 0 |
| 213 | + |
| 214 | +for _, result in ipairs(results) do |
| 215 | + if not result.label then |
| 216 | + countResults = countResults+1 |
| 217 | + if not result.ok then countFails = countFails+1 end |
| 218 | + end |
| 219 | +end |
| 220 | + |
| 221 | +print() |
| 222 | +print("Results:") |
| 223 | + |
| 224 | +for _, result in ipairs(results) do |
| 225 | + if result.label then |
| 226 | + print("------ "..result.label) |
| 227 | + elseif result.ok then |
| 228 | + print("ok "..result.description) |
| 229 | + else |
| 230 | + print("FAILED "..result.description) |
| 231 | + end |
| 232 | +end |
| 233 | + |
| 234 | +print() |
| 235 | +if countFails == 0 then |
| 236 | + print("All "..countResults.." tests passed!") |
| 237 | +else |
| 238 | + print(countFails.."/"..countResults.." tests FAILED!!!") |
| 239 | +end |
0 commit comments