test.lua 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. --[[--------------------------------------------------------------------------
  2. LGI core testsuite runner.
  3. Copyright (c) 2010, 2011 Pavel Holejsovsky
  4. Licensed under the MIT license:
  5. http://www.opensource.org/licenses/mit-license.php
  6. --]]--------------------------------------------------------------------------
  7. -- Available groups.
  8. local groups = {}
  9. -- Testing infrastructure, tests are grouped in testgroup instances.
  10. testsuite = {}
  11. testsuite.group = {}
  12. testsuite.group.__index = testsuite.group
  13. -- Creates new named testgroup.
  14. function testsuite.group.new(name)
  15. local group = setmetatable({ name = name,
  16. results = { total = 0, failed = 0 } },
  17. testsuite.group)
  18. groups[#groups + 1] = name
  19. groups[name] = group
  20. return group
  21. end
  22. -- Adds new test.
  23. function testsuite.group:__newindex(name, func)
  24. assert(not self[name], "test already exists in the group")
  25. rawset(self, name, func)
  26. rawset(self, #self + 1, name)
  27. end
  28. -- Runs specified test(s), either by numeric id or by regexp mask.
  29. function testsuite.group:run(id)
  30. local function runfunc(num)
  31. self.results.total = self.results.total + 1
  32. if testsuite.verbose then
  33. io.write(('%-8s:%3d:%-35s'):format(self.name, num, self[num]))
  34. io.flush()
  35. end
  36. local ok, msg
  37. local func = self[self[num]]
  38. if self.debug then
  39. func()
  40. ok = true
  41. else
  42. ok, msg = xpcall(func, debug.traceback)
  43. end
  44. collectgarbage()
  45. if not ok then
  46. self.results.failed = self.results.failed + 1
  47. if not testsuite.verbose then
  48. io.write(('%-8s:%3d:%-35s'):format(self.name, num, self[num]))
  49. end
  50. io.write('FAIL\n ' .. tostring(msg) .. '\n')
  51. return
  52. end
  53. if testsuite.verbose then
  54. io.write('PASS\n')
  55. end
  56. end
  57. id = id or ''
  58. self.results.total = 0
  59. self.results.failed = 0
  60. if type(id) == 'number' then
  61. runfunc(id)
  62. else
  63. for i = 1, #self do
  64. if self[i] ~= 'debug' and self[i]:match(id) then runfunc(i) end
  65. end
  66. if (self.results.failed == 0) then
  67. io.write(('%-8s: all %d tests passed.\n'):format(
  68. self.name, self.results.total))
  69. else
  70. io.write(('%-8s: FAILED %d of %d tests\n'):format(
  71. self.name, self.results.failed, self.results.total))
  72. end
  73. end
  74. end
  75. -- Fails given test with error, number indicates how many functions on
  76. -- the stack should be skipped when reporting error location.
  77. function testsuite.fail(msg, skip)
  78. error(msg or 'failure', (skip or 1) + 1)
  79. end
  80. function testsuite.check(cond, msg, skip)
  81. if not cond then testsuite.fail(msg, (skip or 1) + 1) end
  82. end
  83. -- Helper, checks that given value has requested type and value.
  84. function testsuite.checkv(val, exp, exptype)
  85. if exptype then
  86. testsuite.check(type(val) == exptype,
  87. string.format("got type `%s', expected `%s'",
  88. type(val), exptype), 2)
  89. end
  90. testsuite.check(val == exp,
  91. string.format("got value `%s', expected `%s'",
  92. tostring(val), tostring(exp)), 2)
  93. end
  94. -- Load all known test source files.
  95. local testpath = arg[0]:sub(1, arg[0]:find('[^%/\\]+$') - 1):gsub('[/\\]$', '')
  96. for _, sourcefile in ipairs {
  97. 'gireg.lua',
  98. 'marshal.lua',
  99. 'corocbk.lua',
  100. 'record.lua',
  101. 'gobject.lua',
  102. 'glib.lua',
  103. 'variant.lua',
  104. 'dbus.lua',
  105. 'gtk.lua',
  106. 'cairo.lua',
  107. 'pango.lua',
  108. } do
  109. dofile(testpath .. '/' .. sourcefile)
  110. end
  111. -- Check for debug mode.
  112. if tests_debug or package.loaded.debugger then
  113. -- Make logs verbose (do not mute DEBUG level).
  114. testsuite.verbose = true
  115. require('lgi').log.DEBUG = 'verbose'
  116. for _, name in ipairs(groups) do
  117. groups[name].debug = true
  118. _G[name] = groups[name]
  119. end
  120. end
  121. -- Cmdline runner.
  122. local failed = false
  123. if select('#', ...) == 0 then
  124. -- Run everything.
  125. for _, group in ipairs(groups) do
  126. groups[group]:run()
  127. failed = failed or groups[group].results.failed > 0
  128. end
  129. else
  130. -- Run just those which pass the mask.
  131. for _, mask in ipairs { ... } do
  132. local group, groupmask = mask:match('^(.-):(.+)$')
  133. if not group or not groups[group] then
  134. io.write(("No test group for mask `%s' found.\n"):format(mask))
  135. return 2
  136. end
  137. groups[group]:run(groupmask)
  138. failed = failed or groups[group].results.failed > 0
  139. end
  140. end
  141. if failed then
  142. os.exit(1)
  143. end