| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 | ----- 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----- 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.--    Use "*" to match any part of a suite or test name-- @return--    On success, returns an array of test objects, which should be considered opaque.--    On failure, returns `nil` and an error.---	function m.getTestsWithIdentifier(identifier)		local suiteName, testName = m.parseTestIdentifier(identifier)		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			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
 |