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.isequal(expected, actual) 91 if (type(expected) == "table") then 92 for k,v in pairs(expected) do 93 if not (test.isequal(expected[k], actual[k])) then 94 test.fail("expected %s but was %s", expected, actual) 95 end 96 end 97 else 98 if (expected ~= actual) then 99 test.fail("expected %s but was %s", expected, actual) 100 end 101 end 102 return true 103 end 104 105 106 function test.isfalse(value) 107 if (value) then 108 test.fail("expected false but was true") 109 end 110 end 111 112 113 function test.isnil(value) 114 if (value ~= nil) then 115 test.fail("expected nil but was " .. tostring(value)) 116 end 117 end 118 119 120 function test.isnotnil(value) 121 if (value == nil) then 122 test.fail("expected not nil") 123 end 124 end 125 126 127 function test.istrue(value) 128 if (not value) then 129 test.fail("expected true but was false") 130 end 131 end 132 133 134 function test.openedfile(fname) 135 if fname ~= test.value_openedfilename then 136 local msg = "expected to open file '" .. fname .. "'" 137 if test.value_openedfilename then 138 msg = msg .. ", got '" .. test.value_openedfilename .. "'" 139 end 140 test.fail(msg) 141 end 142 end 143 144 145 function test.success(fn, ...) 146 local ok, err = pcall(fn, unpack(arg)) 147 if not ok then 148 test.fail("call failed: " .. err) 149 end 150 end 151 152 153 154-- 155-- Test stubs 156-- 157 158 local function stub_io_open(fname, mode) 159 test.value_openedfilename = fname 160 test.value_openedfilemode = mode 161 return { 162 close = function() 163 test.value_closedfile = true 164 end 165 } 166 end 167 168 local function stub_io_output(f) 169 end 170 171 local function stub_print(s) 172 end 173 174 175-- 176-- Define a collection for the test suites 177-- 178 179 T = { } 180 181 182 183-- 184-- Test execution function 185-- 186 187 local function test_setup(suite, fn) 188 -- clear out some important globals 189 _ACTION = "test" 190 _ARGS = { } 191 _OPTIONS = { } 192 premake.solution.list = { } 193 194 -- reset captured I/O values 195 test.value_openedfilename = nil 196 test.value_openedfilemode = nil 197 test.value_closedfile = false 198 199 if suite.setup then 200 return pcall(suite.setup) 201 else 202 return true 203 end 204 end 205 206 207 local function test_run(suite, fn) 208 return pcall(fn) 209 end 210 211 212 local function test_teardown(suite, fn) 213 if suite.teardown then 214 return pcall(suite.teardown) 215 else 216 return true 217 end 218 end 219 220 221 function test.runall() 222 test.print = print 223 224 print = stub_print 225 io.open = stub_io_open 226 io.output = stub_io_output 227 228 local numpassed = 0 229 local numfailed = 0 230 231 for suitename, suitetests in pairs(T) do 232 for testname, testfunc in pairs(suitetests) do 233 234 local ok, err = test_setup(suitetests, testfunc) 235 236 if ok then 237 ok, err = test_run(suitetests, testfunc) 238 end 239 240 local tok, terr = test_teardown(suitetests, testfunc) 241 ok = ok and tok 242 err = err or tok 243 244 if (not ok) then 245 test.print(string.format("%s.%s: %s", suitename, testname, err)) 246 numfailed = numfailed + 1 247 else 248 numpassed = numpassed + 1 249 end 250 251 end 252 end 253 254 print = test.print 255 return numpassed, numfailed 256 end 257 258