Module:ScribuntoUnit and Module:ScribuntoUnit/sandbox: Difference between pages

(Difference between pages)
Jump to navigation Jump to search
Page 1
Page 2
imported>Mr. Stradivarius
run tests in the order they were defined, not alphabetically
 
imported>WOSlinker
use require('strict') instead of require('Module:No globals')
 
Line 101: Line 101:
function ScribuntoUnit:markTestSkipped()
function ScribuntoUnit:markTestSkipped()
     DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3)
     DebugHelper.raise({ScribuntoUnit = true, skipped = true}, 3)
end
-------------------------------------------------------------------------------
-- Unconditionally fail a test
-- @param message optional description of the test
--
function ScribuntoUnit:fail(message)
    DebugHelper.raise({ScribuntoUnit = true, text = "Test failed", message = message}, 2)
end
end


Line 197: Line 189:
--  
--  
function ScribuntoUnit:assertEquals(expected, actual, message)
function ScribuntoUnit:assertEquals(expected, actual, message)
if type(expected) == 'number' and type(actual) == 'number' then
if type(expected) == 'number' and type(actual) == 'number' then
         self:assertWithinDelta(expected, actual, 1e-8, message)
         self:assertWithinDelta(expected, actual, 1e-8, message)
elseif expected ~= actual then
elseif expected ~= actual then
         DebugHelper.raise({
         DebugHelper.raise({
Line 208: Line 202:
         }, 2)
         }, 2)
     end
     end
end


-------------------------------------------------------------------------------
-- Checks that an input does not have the expected value.
-- @param message optional description of the test
-- @example assertNotEquals(5, add(2,2), "2+2 should not be 5")
--
function ScribuntoUnit:assertNotEquals(expected, actual, message)
if type(expected) == 'number' and type(actual) == 'number' then
        self:assertNotWithinDelta(expected, actual, 1e-8, message)
elseif expected == actual then
        DebugHelper.raise({
            ScribuntoUnit = true,
            text = string.format("Failed to assert that %s does not equal expected %s", tostring(actual), tostring(expected)),
            actual = actual,
            expected = expected,
            message = message,
        }, 2)
    end
end
end


-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Validates that both the expected and actual values are numbers
-- Checks that 'actual' is within 'delta' of 'expected'.
-- @param message optional description of the test
-- @param message optional description of the test
--  
-- @example assertEquals(1/3, 9/3, "9/3 should be 1/3", 0.000001)
local function validateNumbers(expected, actual, message)
function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message)
     if type(expected) ~= "number" then
     if type(expected) ~= "number" then
         DebugHelper.raise({
         DebugHelper.raise({
Line 241: Line 217:
             expected = expected,
             expected = expected,
             message = message,
             message = message,
         }, 3)
         }, 2)
     end
     end
     if type(actual) ~= "number" then
     if type(actual) ~= "number" then
Line 250: Line 226:
             expected = expected,
             expected = expected,
             message = message,
             message = message,
         }, 3)
         }, 2)
     end
     end
end
-------------------------------------------------------------------------------
-- Checks that 'actual' is within 'delta' of 'expected'.
-- @param message optional description of the test
-- @example assertWithinDelta(1/3, 3/9, 0.000001, "3/9 should be 1/3")
function ScribuntoUnit:assertWithinDelta(expected, actual, delta, message)
    validateNumbers(expected, actual, message)
     local diff = expected - actual
     local diff = expected - actual
     if diff < 0 then diff = - diff end  -- instead of importing math.abs
     if diff < 0 then diff = - diff end  -- instead of importing math.abs
Line 266: Line 234:
             ScribuntoUnit = true,  
             ScribuntoUnit = true,  
             text = string.format("Failed to assert that %f is within %f of expected %f", actual, delta, expected),  
             text = string.format("Failed to assert that %f is within %f of expected %f", actual, delta, expected),  
            actual = actual,
            expected = expected,
            message = message,
        }, 2)
    end
end
-------------------------------------------------------------------------------
-- Checks that 'actual' is not within 'delta' of 'expected'.
-- @param message optional description of the test
-- @example assertNotWithinDelta(1/3, 2/3, 0.000001, "1/3 should not be 2/3")
function ScribuntoUnit:assertNotWithinDelta(expected, actual, delta, message)
    validateNumbers(expected, actual, message)
    local diff = expected - actual
    if diff < 0 then diff = - diff end  -- instead of importing math.abs
    if diff <= delta then
        DebugHelper.raise({
            ScribuntoUnit = true,
            text = string.format("Failed to assert that %f is not within %f of expected %f", actual, delta, expected),
             actual = actual,
             actual = actual,
             expected = expected,
             expected = expected,
Line 424: Line 373:
         }, 2)
         }, 2)
     end
     end
end
-------------------------------------------------------------------------------
-- Checks whether a function doesn't throw an error
-- @param fn the function to test
-- @param message optional description of the test
function ScribuntoUnit:assertDoesNotThrow(fn, message)
local succeeded, actualMessage = pcall(fn)
if succeeded then
    return
end
-- For strings, strip the line number added to the error message
actualMessage = type(actualMessage) == 'string'
and string.match(actualMessage, 'Module:[^:]*:[0-9]*: (.*)')
or actualMessage
DebugHelper.raise({
ScribuntoUnit = true,
actual = actualMessage,
text = string.format('Expected no exception, but got exception with message %s',
tostring(actualMessage)
),
message = message
}, 2)
end
end


Line 455: Line 381:
function ScribuntoUnit:new(o)
function ScribuntoUnit:new(o)
     o = o or {}
     o = o or {}
    o._tests = {}
     setmetatable(o, {__index = self})
     setmetatable(o, {
    __index = self,
    __newindex = function (t, k, v)
    if type(k) == "string" and k:find('^test') and type(v) == "function" then
    -- Store test functions in the order they were defined
    table.insert(o._tests, {name = k, test = v})
    else
    rawset(t, k, v)
    end
    end
    })
     o.run = function(frame) return self:run(o, frame) end
     o.run = function(frame) return self:run(o, frame) end
     return o
     return o
Line 501: Line 416:
     else
     else
         self.failureCount = self.failureCount + 1
         self.failureCount = self.failureCount + 1
         local message = details.source or ""
         local message = details.source
         if details.message then
         if details.message then
             message = message .. details.message .. "\n"
             message = message .. details.message .. "\n"
Line 515: Line 430:
function ScribuntoUnit:runSuite(suite, frame)
function ScribuntoUnit:runSuite(suite, frame)
     self:init(frame)
     self:init(frame)
for i, testDetails in ipairs(suite._tests) do
local names = {}
self:runTest(suite, testDetails.name, testDetails.test)
    for name in pairs(suite) do
        if name:find('^test') then
table.insert(names, name)
        end
    end
table.sort(names) -- Put tests in alphabetical order.
for i, name in ipairs(names) do
local func = suite[name]
self:runTest(suite, name, func)
end
end
     return {
     return {
Line 603: Line 526:
             name = name .. ' / ' .. result.testname
             name = name .. ' / ' .. result.testname
             end
             end
                 text = text .. mw.text.nowiki(name) .. '\n| ' .. mw.text.nowiki(tostring(result.expected)) .. '\n| ' .. mw.text.nowiki(tostring(result.actual)) .. '\n'
                 text = text .. name .. '\n| ' .. mw.text.nowiki(tostring(result.expected)) .. '\n| ' .. mw.text.nowiki(tostring(result.actual)) .. '\n'
             else
             else
                 text = text .. mw.text.nowiki(result.name) .. '\n| ' .. ' colspan="2" | ' .. mw.text.nowiki(result.message) .. '\n'
                 text = text .. result.name .. '\n| ' .. ' colspan="2" | ' .. mw.text.nowiki(result.message) .. '\n'
             end
             end
         else
         else
             text = text .. '| ' .. successIcon .. '\n| ' .. mw.text.nowiki(result.name) .. '\n|\n|\n'
             text = text .. '| ' .. successIcon .. '\n| ' .. result.name .. '\n|\n|\n'
         end
         end
     end
     end