This repository has been archived on 2022-12-23. You can view files and clone it, but cannot push or open issues or pull requests.
fuck-premake-old2/modules/self-test/test_declare.lua

247 lines
5.6 KiB
Lua
Raw Permalink Normal View History

---
-- test_declare.lua
--
-- Declare unit test suites, and fetch tests from them.
--
-- Author Jason Perkins
-- Copyright (c) 2008-2016 Jason Perkins and the Premake project.
---
local p = premake
local m = p.modules.self_test
local _ = {}
_.suites = {}
_.suppressed = {}
---
-- Declare a new test suite.
--
-- @param suiteName
-- A unique name for the suite. This name will be displayed as part of
-- test failure messages, and also to select the suite when using the
-- `--test-only` command line parameter. Best to avoid spaces and special
-- characters which might not be command line friendly. An error will be
-- raised if the name is not unique.
-- @return
-- The new test suite object.
---
function m.declare(suiteName)
if _.suites[suiteName] then
error('Duplicate test suite "'.. suiteName .. '"', 2)
end
local _suite = {}
-- Setup a metatable for the test suites to use, this will catch duplicate tests
local suite = setmetatable({}, {
__index = _suite,
__newindex = function (table, key, value)
if m.detectDuplicateTests and _suite[key] ~= nil then
error('Duplicate test "'.. key .. '"', 2)
end
_suite[key] = value
end,
__pairs = function (table) return pairs(_suite) end,
__ipairs = function (table) return ipairs(_suite) end,
})
suite._SCRIPT_DIR = _SCRIPT_DIR
suite._TESTS_DIR = _TESTS_DIR
_.suites[suiteName] = suite
return suite
end
---
-- Prevent a particular test or suite of tests from running.
--
-- @param identifier
-- A test or suite identifier, indicating which tests should be suppressed,
-- in the form "suiteName" or "suiteName.testName".
---
function m.suppress(identifier)
if type(identifier) == "table" then
for i = 1, #identifier do
m.suppress(identifier[i])
end
else
_.suppressed[identifier] = true
end
end
function m.isSuppressed(identifier)
return _.suppressed[identifier]
end
---
-- Returns true if the provided test object represents a valid test.
---
function m.isValid(test)
if type(test.testFunction) ~= "function" then
return false
end
if test.testName == "setup" or test.testName == "teardown" then
return false
end
return true
end
---
-- Return the table of declared test suites.
---
function m.getSuites()
return _.suites
end
---
2018-06-14 14:51:36 +00:00
-- Fetch test objects via the string identifier.
--
-- @param identifier
-- An optional test or suite identifier, indicating which tests should be
-- run, in the form "suiteName" or "suiteName.testName". If not specified,
-- the global test object, representing all test suites, will be returned.
2018-06-14 14:51:36 +00:00
-- Use "*" to match any part of a suite or test name
-- @return
2018-06-14 14:51:36 +00:00
-- On success, returns an array of test objects, which should be considered opaque.
-- On failure, returns `nil` and an error.
---
2018-06-14 14:51:36 +00:00
function m.getTestsWithIdentifier(identifier)
local suiteName, testName = m.parseTestIdentifier(identifier)
2018-06-14 14:51:36 +00:00
if suiteName ~= nil and string.contains(suiteName, "*") then
local tests = {}
local pattern = string.gsub(suiteName, "*", ".*")
for _suiteName, suite in pairs(_.suites) do
local length = string.len(_suiteName)
local start, finish = string.find(_suiteName, pattern)
if start == 1 and finish == length then
if testName ~= nil then
if string.contains(testName, "*") then
local testPattern = string.gsub(testName, "*", ".*")
for _testName, test in pairs(suite) do
length = string.len(_testName)
start, finish = string.find(_testName, testPattern)
if start == 1 and finish == length then
table.insert(tests, {
suiteName = _suiteName,
suite = suite,
testName = _testName,
testFunction = test,
})
end
end
else
table.insert(tests, {
suiteName = _suiteName,
suite = suite,
testName = testName,
testFunction = suite[testName],
})
end
else
table.insert(tests, {
suiteName = _suiteName,
suite = suite,
testName = nil,
testFunction = nil,
})
end
end
end
return tests
else
local suite, test, err = _.checkTestIdentifier(_.suites, suiteName, testName)
if err then
return nil, err
end
2018-06-14 14:51:36 +00:00
return {
{
suiteName = suiteName,
suite = suite,
testName = testName,
testFunction = test
}
}
end
end
---
-- Parse a test identifier and split it into separate suite and test names.
--
-- @param identifier
-- A test identifier, which may be nil or an empty string, a test suite
-- name, or a suite and test with the format "suiteName.testName".
-- @return
-- Two values: the suite name and the test name, or nil if not included
-- in the identifier.
---
function m.parseTestIdentifier(identifier)
local suiteName, testName
if identifier then
local parts = string.explode(identifier, ".", true)
suiteName = iif(parts[1] ~= "", parts[1], nil)
testName = iif(parts[2] ~= "", parts[2], nil)
end
return suiteName, testName
end
function _.checkTestIdentifier(suites, suiteName, testName)
local suite, test
if suiteName then
suite = suites[suiteName]
if not suite then
return nil, nil, "No such test suite '" .. suiteName .. "'"
end
if testName then
test = suite[testName]
if not _.isValidTestPair(testName, test) then
return nil, nil, "No such test '" .. suiteName .. "." .. testName .. "'"
end
end
end
return suite, test
end
function _.isValidTestPair(testName, testFunc)
if type(testFunc) ~= "function" then
return false
end
if testName == "setup" or testName == "teardown" then
return false
end
return true
end