From b8d93b380a9f32d3e88f29742196d93c33dd29dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20H=C3=BCbner?= Date: Fri, 12 May 2023 18:37:20 +0200 Subject: [PATCH 1/3] chore(tests): Remove irrelevant package paths from test script --- try | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/try b/try index d13f0449..119dd8f1 100755 --- a/try +++ b/try @@ -1,4 +1,4 @@ #!/bin/sh luarocks remove busted --force luarocks make -LUA_PATH="./?.lua;./?/init.lua;./src/?/?.lua;./src/?/init.lua;$LUA_PATH" busted $@ +LUA_PATH="./?.lua;./?/init.lua;$LUA_PATH" busted "$@" From 2f6e28f53100d7613eda83a57d1b6fe0b0d6d86e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20H=C3=BCbner?= Date: Fri, 12 May 2023 18:37:20 +0200 Subject: [PATCH 2/3] feat(*): add --exclude-name-file and --log-success options These two options are meant to be used together to allow re-running only the failing tests of a test suite. The --log-success option appends the name of each test to the given file, the --exclude-name-file option specifies a file that lists tests which should not be run. --- busted/modules/cli.lua | 2 ++ busted/modules/filter_loader.lua | 25 +++++++++++++++++++++---- busted/runner.lua | 23 +++++++++++++++++++++++ completions/bash/busted.bash | 6 ++++++ completions/zsh/_busted | 2 ++ spec/cl_spec.lua | 22 ++++++++++++++++++++++ 6 files changed, 76 insertions(+), 4 deletions(-) diff --git a/busted/modules/cli.lua b/busted/modules/cli.lua index b60b9087..753205c8 100644 --- a/busted/modules/cli.lua +++ b/busted/modules/cli.lua @@ -130,6 +130,8 @@ return function(options) cli:option('--exclude-tags=TAGS', 'do not run tests with these #tags, takes precedence over --tags', {}, processList) cli:option('--filter=PATTERN', 'only run test names matching the Lua pattern', {}, processMultiOption) cli:option('--filter-out=PATTERN', 'do not run test names matching the Lua pattern, takes precedence over --filter', {}, processMultiOption) + cli:option('--exclude-names-file=FILE', 'do not run the tests with names listed in the given file, takes precedence over --filter', nil, processOption) + cli:option('--log-success=FILE', 'append the name of each successful test to the given file', nil, processOption) cli:option('-m, --lpath=PATH', 'optional path to be prefixed to the Lua module search path', lpathprefix, processPath) cli:option('--cpath=PATH', 'optional path to be prefixed to the Lua C module search path', cpathprefix, processPath) cli:option('-r, --run=RUN', 'config to run from .busted file', nil, processOption) diff --git a/busted/modules/filter_loader.lua b/busted/modules/filter_loader.lua index 7154ff2a..9210f721 100644 --- a/busted/modules/filter_loader.lua +++ b/busted/modules/filter_loader.lua @@ -46,6 +46,22 @@ return function() return nil, true end + local excludeNames = {} + if options.excludeNamesFile then + for name in io.lines(options.excludeNamesFile) do + table.insert(excludeNames, name) + end + end + + local excludeNamesFile = function(name) + for _, filter in ipairs(excludeNames) do + if getFullName(name) == filter then + return nil, false + end + end + return nil, true + end + local filterNames = function(name) for _, filter in pairs(options.filter) do if getFullName(name):find(filter) ~= nil then @@ -122,10 +138,11 @@ return function() applyFilter({ 'file', 'describe', 'it', 'pending' }, 'nokeepgoing', skipOnError) -- The following filters are applied in reverse order - applyFilter({ 'it', 'pending' } , 'filter' , filterNames ) - applyFilter({ 'describe', 'it', 'pending' }, 'filterOut' , filterOutNames ) - applyFilter({ 'it', 'pending' } , 'tags' , filterTags ) - applyFilter({ 'describe', 'it', 'pending' }, 'excludeTags', filterExcludeTags) + applyFilter({ 'it', 'pending' } , 'filter' , filterNames ) + applyFilter({ 'describe', 'it', 'pending' }, 'filterOut' , filterOutNames ) + applyFilter({ 'describe', 'it', 'pending' }, 'excludeNamesFile', excludeNamesFile) + applyFilter({ 'it', 'pending' } , 'tags' , filterTags ) + applyFilter({ 'describe', 'it', 'pending' }, 'excludeTags' , filterExcludeTags ) end return filter diff --git a/busted/runner.lua b/busted/runner.lua index eb81bca1..91ac1bcf 100644 --- a/busted/runner.lua +++ b/busted/runner.lua @@ -154,12 +154,35 @@ return function(options) end end + local getFullName = function(name) + local parent = busted.context.get() + local names = { name } + + while parent and (parent.name or parent.descriptor) and + parent.descriptor ~= 'file' do + table.insert(names, 1, parent.name or parent.descriptor) + parent = busted.context.parent(parent) + end + + return table.concat(names, ' ') + end + + if cliArgs['log-success'] then + local logFile = assert(io.open(cliArgs['log-success'], 'a')) + busted.subscribe({ 'test', 'end' }, function (test, parent, status) + if status == "success" then + logFile:write(getFullName() .. "\n") + end + end) + end + -- Load tag and test filters filterLoader(busted, { tags = cliArgs.tags, excludeTags = cliArgs['exclude-tags'], filter = cliArgs.filter, filterOut = cliArgs['filter-out'], + excludeNamesFile = cliArgs['exclude-names-file'], list = cliArgs.list, nokeepgoing = not cliArgs['keep-going'], suppressPending = cliArgs['suppress-pending'], diff --git a/completions/bash/busted.bash b/completions/bash/busted.bash index fb2af435..46f63bc2 100644 --- a/completions/bash/busted.bash +++ b/completions/bash/busted.bash @@ -140,6 +140,10 @@ _busted() { # no completion available return 0 ;; + --exclude-names-file|--log-success) + _filedir + return 0 + ;; -m|--lpath|--cpath) _filedir -d return 0 @@ -175,10 +179,12 @@ _busted() { --lua= --ignore-lua --filter= --filter-out= + --exclude-names-file= --repeat= --seed= --lang= --loaders= + --log-success --helper= -c --coverage --no-coverage -s --enable-sound --no-enable-sound diff --git a/completions/zsh/_busted b/completions/zsh/_busted index 8f100d16..66d03a0b 100644 --- a/completions/zsh/_busted +++ b/completions/zsh/_busted @@ -56,6 +56,8 @@ _busted_args=( "--exclude-tags=[Do not run tests with these #tags, takes precedence over --tags]: :" "--filter=[Only run test names matching the Lua pattern]: :" "--filter-out=[Do not run test names matching the Lua pattern, takes precedence over --filter]: :" +"--exclude-names-file=[Do not run the tests with names listed in the given file, takes precedence over --filter]:files:_files" +"--log-success=[Append the name of each successful test to the given file]:file:_files" "-e[Execute Lua statement]: :" "(-v --verbose --no-verbose)"{-v,--verbose}"[Verbose output of errors]" "(-v --verbose --no-verbose)--no-verbose[Disable verbose output of errors]" diff --git a/spec/cl_spec.lua b/spec/cl_spec.lua index d482bac0..5d2817da 100644 --- a/spec/cl_spec.lua +++ b/spec/cl_spec.lua @@ -135,6 +135,28 @@ describe('Tests the busted command-line options', function() assert.is_true(success) end) + local function count_successes(out) + local count = 0 + for successes in out:gmatch('(%d+) success') do + count = count + successes + end + return count + end + + it('tests running with --log-success and --exclude-names-file specified', function () + local logfile = os.tmpname() + local success, errcnt, out, err = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) + assert.is_false(success) + assert.equals(8, errcnt) + assert.equals(2, count_successes(out)) + -- re-run tests with previously successful tests skipped + success, errcnt, out, err = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) + assert.is_false(success) + assert.equals(8, errcnt) + assert.equals(0, count_successes(out)) + os.remove(logfile) + end) + it('tests running with --filter specified in describe', function () local success, errcnt = executeBusted('--pattern=_filter.lua$ --filter="patt1"') assert.is_false(success) From b17880d8ecfb1296de3ddd52aefdbdd4fbd77c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hans=20H=C3=BCbner?= Date: Mon, 15 May 2023 16:17:22 +0200 Subject: [PATCH 3/3] feat(*): add --name option to single out individual test(s) --- busted/modules/cli.lua | 1 + busted/modules/filter_loader.lua | 12 +++++++++++- busted/runner.lua | 1 + completions/bash/busted.bash | 3 ++- completions/zsh/_busted | 1 + spec/cl_spec.lua | 4 ++-- 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/busted/modules/cli.lua b/busted/modules/cli.lua index 753205c8..0cca3e2b 100644 --- a/busted/modules/cli.lua +++ b/busted/modules/cli.lua @@ -129,6 +129,7 @@ return function(options) cli:option('-t, --tags=TAGS', 'only run tests with these #tags', {}, processList) cli:option('--exclude-tags=TAGS', 'do not run tests with these #tags, takes precedence over --tags', {}, processList) cli:option('--filter=PATTERN', 'only run test names matching the Lua pattern', {}, processMultiOption) + cli:option('--name=NAME', 'run test with the given full name', {}, processMultiOption) cli:option('--filter-out=PATTERN', 'do not run test names matching the Lua pattern, takes precedence over --filter', {}, processMultiOption) cli:option('--exclude-names-file=FILE', 'do not run the tests with names listed in the given file, takes precedence over --filter', nil, processOption) cli:option('--log-success=FILE', 'append the name of each successful test to the given file', nil, processOption) diff --git a/busted/modules/filter_loader.lua b/busted/modules/filter_loader.lua index 9210f721..e5c15182 100644 --- a/busted/modules/filter_loader.lua +++ b/busted/modules/filter_loader.lua @@ -62,6 +62,15 @@ return function() return nil, true end + local name = function(name) + for _, candidate in pairs(options.name) do + if string.find(candidate, getFullName(name), 1, true) then + return nil, true + end + end + return nil, (#options.name == 0) + end + local filterNames = function(name) for _, filter in pairs(options.filter) do if getFullName(name):find(filter) ~= nil then @@ -139,8 +148,9 @@ return function() -- The following filters are applied in reverse order applyFilter({ 'it', 'pending' } , 'filter' , filterNames ) + applyFilter({ 'describe', 'it', 'pending' }, 'name' , name ) applyFilter({ 'describe', 'it', 'pending' }, 'filterOut' , filterOutNames ) - applyFilter({ 'describe', 'it', 'pending' }, 'excludeNamesFile', excludeNamesFile) + applyFilter({ 'describe', 'it', 'pending' }, 'excludeNamesFile', excludeNamesFile ) applyFilter({ 'it', 'pending' } , 'tags' , filterTags ) applyFilter({ 'describe', 'it', 'pending' }, 'excludeTags' , filterExcludeTags ) end diff --git a/busted/runner.lua b/busted/runner.lua index 91ac1bcf..ce4a4830 100644 --- a/busted/runner.lua +++ b/busted/runner.lua @@ -181,6 +181,7 @@ return function(options) tags = cliArgs.tags, excludeTags = cliArgs['exclude-tags'], filter = cliArgs.filter, + name = cliArgs.name, filterOut = cliArgs['filter-out'], excludeNamesFile = cliArgs['exclude-names-file'], list = cliArgs.list, diff --git a/completions/bash/busted.bash b/completions/bash/busted.bash index 46f63bc2..30a761d6 100644 --- a/completions/bash/busted.bash +++ b/completions/bash/busted.bash @@ -136,7 +136,7 @@ _busted() { # no completion available return 0 ;; - --filter|--filter-out) + --filter|--filter-out|--name) # no completion available return 0 ;; @@ -179,6 +179,7 @@ _busted() { --lua= --ignore-lua --filter= --filter-out= + --name= --exclude-names-file= --repeat= --seed= diff --git a/completions/zsh/_busted b/completions/zsh/_busted index 66d03a0b..d74d7794 100644 --- a/completions/zsh/_busted +++ b/completions/zsh/_busted @@ -57,6 +57,7 @@ _busted_args=( "--filter=[Only run test names matching the Lua pattern]: :" "--filter-out=[Do not run test names matching the Lua pattern, takes precedence over --filter]: :" "--exclude-names-file=[Do not run the tests with names listed in the given file, takes precedence over --filter]:files:_files" +"--name=[Run test with the given full name]:files:_files" "--log-success=[Append the name of each successful test to the given file]:file:_files" "-e[Execute Lua statement]: :" "(-v --verbose --no-verbose)"{-v,--verbose}"[Verbose output of errors]" diff --git a/spec/cl_spec.lua b/spec/cl_spec.lua index 5d2817da..c631e09d 100644 --- a/spec/cl_spec.lua +++ b/spec/cl_spec.lua @@ -145,12 +145,12 @@ describe('Tests the busted command-line options', function() it('tests running with --log-success and --exclude-names-file specified', function () local logfile = os.tmpname() - local success, errcnt, out, err = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) + local success, errcnt, out = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) assert.is_false(success) assert.equals(8, errcnt) assert.equals(2, count_successes(out)) -- re-run tests with previously successful tests skipped - success, errcnt, out, err = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) + success, errcnt, out = executeBusted('--pattern=_filter.lua$ --log-success=' .. logfile .. ' --exclude-names-file=' .. logfile) assert.is_false(success) assert.equals(8, errcnt) assert.equals(0, count_successes(out))