1-- 2-- tests/testfx.lua 3-- Automated test framework for Premake. 4-- Copyright (c) 2008-2009 Jason Perkins and the Premake project 5-- 6 7 8-- 9-- Define a namespace for the testing functions 10-- 11 12 test = { } 13 14 15-- 16-- Assertion functions 17-- 18 function test.string_contains(buffer, expected) 19 if not string.find(buffer,expected) then 20 test.fail("\n==Fail==: Expected to find :\n%s\nyet it was not found in buffer:\n%s\n", expected,buffer) 21 end 22 end 23 24 function test.string_does_not_contain(buffer, expected) 25 if string.find(buffer,expected) then 26 test.fail("\n==Fail==: Did not expected to find :\n%s\nyet it was found in buffer:\n%s\n", expected,buffer) 27 end 28 end 29 30 function test.capture(expected) 31 local actual = io.endcapture() 32 33 local ait = actual:gfind("(.-)" .. io.eol) 34 local eit = expected:gfind("(.-)\n") 35 36 local linenum = 1 37 local atxt = ait() 38 local etxt = eit() 39 while etxt do 40 if (etxt ~= atxt) then 41 test.fail("(%d) expected:\n%s\n...but was:\n%s", linenum, etxt, atxt) 42 end 43 44 linenum = linenum + 1 45 atxt = ait() 46 etxt = eit() 47 end 48 end 49 50 51 function test.closedfile(expected) 52 if expected and not test.value_closedfile then 53 test.fail("expected file to be closed") 54 elseif not expected and test.value_closedfile then 55 test.fail("expected file to remain open") 56 end 57 end 58 59 60 function test.contains(value, expected) 61 if not table.contains(value, expected) then 62 test.fail("expected value %s not found", expected) 63 end 64 end 65 66 67 function test.fail(format, ...) 68 -- convert nils into something more usefuls 69 for i = 1, arg.n do 70 if (arg[i] == nil) then 71 arg[i] = "(nil)" 72 elseif (type(arg[i]) == "table") then 73 arg[i] = "{" .. table.concat(arg[i], ", ") .. "}" 74 end 75 end 76 error(string.format(format, unpack(arg)), 3) 77 end 78 79 80 function test.filecontains(expected, fn) 81 local f = io.open(fn) 82 local actual = f:read("*a") 83 f:close() 84 if (expected ~= actual) then 85 test.fail("expected %s but was %s", expected, actual) 86 end 87 end 88 89 90 function test.isemptycapture() 91 local actual = io.endcapture() 92 if actual ~= "" then 93 test.fail("expected empty capture, but was %s", actual); 94 end 95 end 96 97 98 function test.isequal(expected, actual) 99 if (type(expected) == "table") then 100 for k,v in pairs(expected) do 101 if not (test.isequal(expected[k], actual[k])) then 102 test.fail("expected %s but was %s", expected, actual) 103 end 104 end 105 else 106 if (expected ~= actual) then 107 test.fail("expected %s but was %s", expected, actual) 108 end 109 end 110 return true 111 end 112 113 114 function test.isfalse(value) 115 if (value) then 116 test.fail("expected false but was true") 117 end 118 end 119 120 121 function test.isnil(value) 122 if (value ~= nil) then 123 test.fail("expected nil but was " .. tostring(value)) 124 end 125 end 126 127 128 function test.isnotnil(value) 129 if (value == nil) then 130 test.fail("expected not nil") 131 end 132 end 133 134 135 function test.istrue(value) 136 if (not value) then 137 test.fail("expected true but was false") 138 end 139 end 140 141 142 function test.openedfile(fname) 143 if fname ~= test.value_openedfilename then 144 local msg = "expected to open file '" .. fname .. "'" 145 if test.value_openedfilename then 146 msg = msg .. ", got '" .. test.value_openedfilename .. "'" 147 end 148 test.fail(msg) 149 end 150 end 151 152 153 function test.success(fn, ...) 154 local ok, err = pcall(fn, unpack(arg)) 155 if not ok then 156 test.fail("call failed: " .. err) 157 end 158 end 159 160 161 162-- 163-- Test stubs 164-- 165 166 local function stub_io_open(fname, mode) 167 test.value_openedfilename = fname 168 test.value_openedfilemode = mode 169 return { 170 close = function() 171 test.value_closedfile = true 172 end 173 } 174 end 175 176 local function stub_io_output(f) 177 end 178 179 local function stub_print(s) 180 end 181 182 183-- 184-- Define a collection for the test suites 185-- 186 187 T = { } 188 189 190 191-- 192-- Test execution function 193-- 194 local _OS_host = _OS 195 local function test_setup(suite, fn) 196 -- clear out some important globals 197 _ACTION = "test" 198 _ARGS = { } 199 _OPTIONS = { } 200 _OS = _OS_host 201 premake.solution.list = { } 202 io.indent = nil 203 io.eol = "\n" 204 205 -- reset captured I/O values 206 test.value_openedfilename = nil 207 test.value_openedfilemode = nil 208 test.value_closedfile = false 209 210 if suite.setup then 211 return pcall(suite.setup) 212 else 213 return true 214 end 215 end 216 217 218 local function test_run(suite, fn) 219 io.capture() 220 return pcall(fn) 221 end 222 223 224 local function test_teardown(suite, fn) 225 if suite.teardown then 226 return pcall(suite.teardown) 227 else 228 return true 229 end 230 end 231 232 233 function test.runall(suitename, testname) 234 test.print = print 235 236 print = stub_print 237 io.open = stub_io_open 238 io.output = stub_io_output 239 240 local numpassed = 0 241 local numfailed = 0 242 local start_time = os.clock() 243 244 function runtest(suitename, suitetests, testname, testfunc) 245 if suitetests.setup ~= testfunc and suitetests.teardown ~= testfunc then 246 local ok, err = test_setup(suitetests, testfunc) 247 248 if ok then 249 ok, err = test_run(suitetests, testfunc) 250 end 251 252 local tok, terr = test_teardown(suitetests, testfunc) 253 ok = ok and tok 254 err = err or terr 255 256 if (not ok) then 257 test.print(string.format("%s.%s: %s", suitename, testname, err)) 258 numfailed = numfailed + 1 259 else 260 numpassed = numpassed + 1 261 end 262 end 263 end 264 265 function runsuite(suitename, suitetests, testname) 266 if testname then 267 runtest(suitename, suitetests, testname, suitetests[testname]) 268 else 269 for testname, testfunc in pairs(suitetests) do 270 runtest(suitename, suitetests, testname, testfunc) 271 end 272 end 273 end 274 275 if suitename then 276 runsuite(suitename, T[suitename], testname) 277 else 278 for suitename, suitetests in pairs(T) do 279 runsuite(suitename, suitetests, testname) 280 end 281 end 282 283 io.write('running time : ', os.clock() - start_time,'\n') 284 print = test.print 285 return numpassed, numfailed 286 end 287 288