Skip to content

Commit

Permalink
Merge pull request #82 from bluebird75/combine-include-and-exclude
Browse files Browse the repository at this point in the history
Combine include and exclude
  • Loading branch information
bluebird75 committed Feb 13, 2017
2 parents d2f1ffa + a3f34f3 commit 391c67b
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 28 deletions.
61 changes: 45 additions & 16 deletions luaunit.lua
Expand Up @@ -265,18 +265,49 @@ end
M.private.strMatch = strMatch

local function patternFilter(patterns, expr, nil_result)
-- Check if any of `patterns` is contained in `expr`. If so, return `true`.
-- Return `false` if none of the patterns are contained in expr. If patterns
-- is `nil` (= unset), return default value passed in `nil_result`.
if patterns ~= nil then
-- Run `expr` through the inclusion and exclusion rules defined in patterns
-- and return true if expr shall be included, false for excluded.
-- Inclusion pattern are defined as normal patterns, exclusions
-- patterns start with `!` and are followed by a normal pattern
-- If patterns is `nil` (= unset) or empty, return default value passed in `nil_result`.

if patterns ~= nil and #patterns > 0 then
local DONT_KNOW, ACCEPT, REJECT = nil, true, false
local result = DONT_KNOW

for _, pattern in ipairs(patterns) do
if string.find(expr, pattern) then
return true
local exclude = false
if (pattern:sub(1,1) == '!') then
exclude = true
pattern = pattern:sub(2)
end
-- print('pattern: ',pattern)
-- print('exclude: ',exclude)

-- when result is not set or already accepted, match pattern
-- only for rejecting
if exclude and (result == DONT_KNOW or result == ACCEPT) then
if string.find(expr, pattern) then
result = REJECT
end
end

-- when result is not set or already rejected, match pattern
-- only for accepting
if (not exclude) and (result == DONT_KNOW or result == REJECT) then
if string.find(expr, pattern) then
result = ACCEPT
end
end
end

return false -- no match from patterns
if result == DONT_KNOW then
-- when no match is found, for inclusive patterns, it means refuse expr
-- for negative pattern, it means accept expr
return (patterns[1]:sub(1,1) == '!')
end

return result
end

return nil_result
Expand Down Expand Up @@ -2104,10 +2135,11 @@ end
end
return
elseif state == SET_EXCLUDE then
if result['exclude'] then
table.insert( result['exclude'], cmdArg )
local notArg = '!'..cmdArg
if result['pattern'] then
table.insert( result['pattern'], notArg )
else
result['exclude'] = { cmdArg }
result['pattern'] = { notArg }
end
return
end
Expand Down Expand Up @@ -2276,7 +2308,6 @@ end
startDate = os.date(os.getenv('LUAUNIT_DATEFMT')),
startIsodate = os.date('%Y-%m-%dT%H:%M:%S'),
patternIncludeFilter = self.patternIncludeFilter,
patternExcludeFilter = self.patternExcludeFilter,
tests = {},
failures = {},
errors = {},
Expand Down Expand Up @@ -2580,12 +2611,11 @@ end
return result
end

function M.LuaUnit.applyPatternFilter( patternIncFilter, patternExcFilter, listOfNameAndInst )
function M.LuaUnit.applyPatternFilter( patternIncFilter, listOfNameAndInst )
local included, excluded = {}, {}
for i, v in ipairs( listOfNameAndInst ) do
-- local name, instance = v[1], v[2]
if patternFilter( patternIncFilter, v[1], true ) and
not patternFilter( patternExcFilter, v[1], false ) then
if patternFilter( patternIncFilter, v[1], true ) then
table.insert( included, v )
else
table.insert( excluded, v )
Expand All @@ -2607,7 +2637,7 @@ end
randomizeTable( expandedList )
end
local filteredList, filteredOutList = self.applyPatternFilter(
self.patternIncludeFilter, self.patternExcludeFilter, expandedList )
self.patternIncludeFilter, expandedList )

self:startSuite( #filteredList, #filteredOutList )

Expand Down Expand Up @@ -2727,7 +2757,6 @@ end

self.exeCount = options.exeCount
self.patternIncludeFilter = options.pattern
self.patternExcludeFilter = options.exclude
self.randomize = options.randomize

if options.output then
Expand Down
64 changes: 52 additions & 12 deletions test/test_luaunit.lua
Expand Up @@ -566,9 +566,10 @@ TestLuaUnitUtilities = { __class__ = 'TestLuaUnitUtilities' }
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-p', 'toto' } ), { pattern={'toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-p', 'titi', '-p', 'toto' } ), { pattern={'titi', 'toto'} } )
lu.assertErrorMsgContains( 'Missing argument after -p', lu.LuaUnit.parseCmdLine, { '-p', } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '--exclude', 'toto' } ), { exclude={'toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-x', 'toto' } ), { exclude={'toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-x', 'titi', '-x', 'toto' } ), { exclude={'titi', 'toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '--exclude', 'toto' } ), { pattern={'!toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-x', 'toto' } ), { pattern={'!toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-x', 'titi', '-x', 'toto' } ), { pattern={'!titi', '!toto'} } )
lu.assertEquals( lu.LuaUnit.parseCmdLine( { '-x', 'titi', '-p', 'foo', '-x', 'toto' } ), { pattern={'!titi', 'foo', '!toto'} } )
lu.assertErrorMsgContains( 'Missing argument after -x', lu.LuaUnit.parseCmdLine, { '-x', } )

-- count
Expand All @@ -586,12 +587,46 @@ TestLuaUnitUtilities = { __class__ = 'TestLuaUnitUtilities' }

function TestLuaUnitUtilities:test_patternFilter()
lu.assertEquals( lu.private.patternFilter( nil, 'toto', true), true )
lu.assertEquals( lu.private.patternFilter( {}, 'toto', true), false )
lu.assertEquals( lu.private.patternFilter( nil, 'titi', false), false )
lu.assertEquals( lu.private.patternFilter( {}, 'toto', false), false )
lu.assertEquals( lu.private.patternFilter( {}, 'toto', true), true )

-- positive pattern
lu.assertEquals( lu.private.patternFilter( {'toto'}, 'toto'), true )
lu.assertEquals( lu.private.patternFilter( {'toto'}, 'yyytotoxxx'), true )
lu.assertEquals( lu.private.patternFilter( {'titi', 'toto'}, 'yyytotoxxx'), true )
lu.assertEquals( lu.private.patternFilter( {'titi', 'toto'}, 'tutu'), false )
lu.assertEquals( lu.private.patternFilter( {'titi', 'to..'}, 'yyytoxxx'), true )

-- negative pattern
lu.assertEquals( lu.private.patternFilter( {'!toto'}, 'toto'), false )
lu.assertEquals( lu.private.patternFilter( {'!t.t.'}, 'titi'), false )
lu.assertEquals( lu.private.patternFilter( {'!toto'}, 'titi'), true )
lu.assertEquals( lu.private.patternFilter( {'!toto'}, 'yyytotoxxx'), false )
lu.assertEquals( lu.private.patternFilter( {'!titi', '!toto'}, 'yyytotoxxx'), false )
lu.assertEquals( lu.private.patternFilter( {'!titi', '!toto'}, 'tutu'), true )
lu.assertEquals( lu.private.patternFilter( {'!titi', '!to..'}, 'yyytoxxx'), false )

-- combine patterns
lu.assertEquals( lu.private.patternFilter( { 'foo' }, 'foo'), true )
lu.assertEquals( lu.private.patternFilter( { 'foo', '!foo' }, 'foo'), false )
lu.assertEquals( lu.private.patternFilter( { 'foo', '!foo', 'foo' }, 'foo'), true )
lu.assertEquals( lu.private.patternFilter( { 'foo', '!foo', 'foo', '!foo' }, 'foo'), false )

lu.assertEquals( lu.private.patternFilter( { '!foo' }, 'foo'), false )
lu.assertEquals( lu.private.patternFilter( { '!foo', 'foo' }, 'foo'), true )
lu.assertEquals( lu.private.patternFilter( { '!foo', 'foo', '!foo' }, 'foo'), false )
lu.assertEquals( lu.private.patternFilter( { '!foo', 'foo', '!foo', 'foo' }, 'foo'), true )

lu.assertEquals( lu.private.patternFilter( { 'f..', '!foo', '__foo__' }, 'toto'), false )
lu.assertEquals( lu.private.patternFilter( { 'f..', '!foo', '__foo__' }, 'fii'), true )
lu.assertEquals( lu.private.patternFilter( { 'f..', '!foo', '__foo__' }, 'foo'), false )
lu.assertEquals( lu.private.patternFilter( { 'f..', '!foo', '__foo__' }, '__foo__'), true )

lu.assertEquals( lu.private.patternFilter( { '!f..', 'foo', '!__foo__' }, 'toto'), true )
lu.assertEquals( lu.private.patternFilter( { '!f..', 'foo', '!__foo__' }, 'fii'), false )
lu.assertEquals( lu.private.patternFilter( { '!f..', 'foo', '!__foo__' }, 'foo'), true )
lu.assertEquals( lu.private.patternFilter( { '!f..', 'foo', '!__foo__' }, '__foo__'), false )
end

function TestLuaUnitUtilities:test_applyPatternFilter()
Expand All @@ -604,39 +639,44 @@ TestLuaUnitUtilities = { __class__ = 'TestLuaUnitUtilities' }
}

-- default action: include everything
local included, excluded = lu.LuaUnit.applyPatternFilter( nil, nil, testset )
local included, excluded = lu.LuaUnit.applyPatternFilter( nil, testset )
lu.assertEquals( #included, 8 )
lu.assertEquals( excluded, {} )

-- single exclude pattern (= select anything not matching "bar")
included, excluded = lu.LuaUnit.applyPatternFilter( nil, {'bar'}, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'!bar'}, testset )
lu.assertEquals( included, {testset[1], testset[3], testset[5]} )
lu.assertEquals( #excluded, 5 )

-- single include pattern
included, excluded = lu.LuaUnit.applyPatternFilter( {'t.t.'}, nil, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'t.t.'}, testset )
lu.assertEquals( #included, 6 )
lu.assertEquals( excluded, {testset[7], testset[8]} )

-- single include and exclude patterns
included, excluded = lu.LuaUnit.applyPatternFilter( {'foo'}, {'test'}, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'foo', '!test'}, testset )
lu.assertEquals( included, {testset[1], testset[3], testset[5], testset[7]} )
lu.assertEquals( #excluded, 4 )

-- multiple (specific) includes
included, excluded = lu.LuaUnit.applyPatternFilter( {'toto', 'titi'}, nil, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'toto', 'titi'}, testset )
lu.assertEquals( included, {testset[1], testset[2], testset[3], testset[4]} )
lu.assertEquals( #excluded, 4 )

-- multiple excludes
included, excluded = lu.LuaUnit.applyPatternFilter( nil, {'tata', '%.bar'}, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'!tata', '!%.bar'}, testset )
lu.assertEquals( included, {testset[1], testset[3], testset[8]} )
lu.assertEquals( #excluded, 5 )

-- combined test
included, excluded = lu.LuaUnit.applyPatternFilter( {'t[oai]', 'bar$', 'test'}, {'%.b', 'titi'}, testset )
included, excluded = lu.LuaUnit.applyPatternFilter( {'t[oai]', 'bar$', 'test', '!%.b', '!titi'}, testset )
lu.assertEquals( included, {testset[1], testset[5], testset[8]} )
lu.assertEquals( #excluded, 5 )

--[[ Combining positive and negative filters ]]--
included, excluded = lu.LuaUnit.applyPatternFilter( {'foo', 'bar', '!t.t.', '%.bar'}, testset )
lu.assertEquals( included, {testset[2], testset[4], testset[6], testset[7], testset[8]} )
lu.assertEquals( #excluded, 3 )
end

function TestLuaUnitUtilities:test_strMatch()
Expand Down Expand Up @@ -2638,7 +2678,7 @@ TestLuaUnitExecution = { __class__ = 'TestLuaUnitExecution' }
lu.assertEquals( executedTests[7], "MyTestToto2:test1" )
lu.assertEquals( #executedTests, 7)

runner:runSuite('-x', 'Toto2', '-p', 'Toto.' )
runner:runSuite('-p', 'Toto.', '-x', 'Toto2' )
lu.assertEquals( runner.result.testCount, 5) -- MyTestToto2 excluded
end

Expand Down

0 comments on commit 391c67b

Please sign in to comment.