Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for output of ANSI-colored text #80

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ cache:
- $TRAVIS_BUILD_DIR/install

script:
- lua -v -lluacov run_unit_tests.lua --shuffle
- lua run_functional_tests.lua --coverage
- lua -v -lluacov run_unit_tests.lua --shuffle --color
- lua run_functional_tests.lua --coverage --color
- luacheck *.lua test/

after_success:
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ build: off

test_script:
- cmd: >-
%LUA% -v run_unit_tests.lua --shuffle
%LUA% -v run_unit_tests.lua --shuffle --color

%LUA% run_functional_tests.lua
%LUA% run_functional_tests.lua --color
48 changes: 33 additions & 15 deletions luaunit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ Options:
-e, --error: Stop on first error
-f, --failure: Stop on first failure or error
-s, --shuffle: Shuffle tests before running them
-o, --output OUTPUT: Set output type to OUTPUT
-o, --output OUTPUT: Set output type to OUTPUT (default: text)
Possible values: text, tap, junit, nil
--color: Enable ANSI color support for text output
-n, --name NAME: For junit only, mandatory name of xml file
-r, --repeat NUM: Execute all tests NUM times, e.g. to trig the JIT
-p, --pattern PATTERN: Execute all test names matching the Lua PATTERN
Expand Down Expand Up @@ -2033,6 +2034,18 @@ JUnitOutput.__class__ = 'JUnitOutput'
-- class TextOutput
----------------------------------------------------------------

--[[
This table holds control sequences to "color" the text output. Initially
those are all empty strings, so that concatenating them won't change the
plain text output. The "--color" option reassigns the fields as needed.
]]
local COLOR = {
reset = "",
bright = "",
green = "",
red = "",
}

--[[

-- Python Non verbose:
Expand Down Expand Up @@ -2157,15 +2170,16 @@ TextOutput.__class__ = 'TextOutput'

function TextOutput:endTest( node )
if node:isPassed() then
io.stdout:write(COLOR.green)
if self.verbosity > M.VERBOSITY_DEFAULT then
io.stdout:write("Ok\n")
else
io.stdout:write(".")
end
else
if self.verbosity > M.VERBOSITY_DEFAULT then
print( node.status )
print( node.msg )
print( COLOR.red .. node.status .. COLOR.reset )
print( COLOR.bright .. node.msg )
--[[
-- find out when to do this:
if self.verbosity > M.VERBOSITY_DEFAULT then
Expand All @@ -2174,24 +2188,21 @@ TextOutput.__class__ = 'TextOutput'
]]
else
-- write only the first character of status
io.stdout:write(string.sub(node.status, 1, 1))
io.stdout:write(COLOR.red, string.sub(node.status, 1, 1))
end
end
end

function TextOutput:displayOneFailedTest( index, fail )
print(index..") "..fail.testName )
print( fail.msg )
print( fail.stackTrace )
print()
io.stdout:write(COLOR.reset)
end

function TextOutput:displayFailedTests()
if self.result.notPassedCount ~= 0 then
print("Failed tests:")
print("-------------")
for i, v in ipairs(self.result.notPassed) do
self:displayOneFailedTest(i, v)
for index, failed in ipairs(self.result.notPassed) do
print( COLOR.bright .. index..") "..failed.testName )
print( COLOR.red .. failed.msg .. COLOR.reset )
print( failed.stackTrace )
print()
end
end
end
Expand All @@ -2203,9 +2214,9 @@ TextOutput.__class__ = 'TextOutput'
print()
end
self:displayFailedTests()
print( M.LuaUnit.statusLine( self.result ) )
print( COLOR.bright .. M.LuaUnit.statusLine( self.result ) .. COLOR.reset)
if self.result.notPassedCount == 0 then
print('OK')
print(COLOR.green .. 'OK' .. COLOR.reset)
end
end

Expand Down Expand Up @@ -2355,6 +2366,13 @@ end
elseif option == '--shuffle' or option == '-s' then
result['shuffle'] = true
return
elseif option == '--color' then
-- activate ANSI control sequences for colored (text) output
COLOR.reset = "\27[0m"
COLOR.bright = "\27[1m"
COLOR.green = "\27[32m"
COLOR.red = "\27[31m"
return
elseif option == '--output' or option == '-o' then
state = SET_OUTPUT
return state
Expand Down
107 changes: 107 additions & 0 deletions run_functional_tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,25 @@ local function check_text_output( fileToRun, options, output, refOutput, refExit
return 0
end

local function check_color_output( fileToRun, options, output, refOutput, refExitCode )
-- remove output
osExpectedCodeExec(refExitCode, '%s %s --output text --color %s > %s',
LUA, fileToRun, options, output)

if options:find( '--verbose' ) then
adjustFile( output, refOutput, 'Started on (.*)')
end
adjustFile( output, refOutput, 'Ran .* tests in (%d.%d*) seconds' )
-- For Lua 5.3: stack trace uses "method" instead of "function"
adjustFile( output, refOutput, '.*%.lua:%d+: in (%S*) .*', true, false )

if not osExec([[diff -NPw -u -I " *\.[/\\]luaunit.lua:[0123456789]\+:.*" %s %s]], refOutput, output) then
error('Text Output mismatch for file : '..output)
end
-- report('Text Output ok: '..output)
return 0
end

local function check_nil_output( fileToRun, options, output, refOutput, refExitCode )
-- remove output
osExpectedCodeExec(refExitCode, '%s %s --output nil %s > %s',
Expand Down Expand Up @@ -413,6 +432,65 @@ function testTextQuiet()
'test/ref/errFailPassTextQuiet-failures.txt', 5 ) )
end

-- check "color" output

function testColorDefault()
lu.assertEquals( 0,
check_color_output('example_with_luaunit.lua', '',
'test/exampleColorDefault.txt',
'test/ref/exampleColorDefault.txt', 12 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '',
'test/errFailPassColorDefault.txt',
'test/ref/errFailPassColorDefault.txt', 10 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '-p Succ',
'test/errFailPassColorDefault-success.txt',
'test/ref/errFailPassColorDefault-success.txt', 0 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '-p Succ -p Fail',
'test/errFailPassColorDefault-failures.txt',
'test/ref/errFailPassColorDefault-failures.txt', 5 ) )
end

function testColorVerbose()
lu.assertEquals( 0,
check_color_output('example_with_luaunit.lua', '--verbose',
'test/exampleColorVerbose.txt',
'test/ref/exampleColorVerbose.txt', 12 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--verbose',
'test/errFailPassColorVerbose.txt',
'test/ref/errFailPassColorVerbose.txt', 10 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--verbose -p Succ',
'test/errFailPassColorVerbose-success.txt',
'test/ref/errFailPassColorVerbose-success.txt', 0 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--verbose -p Succ -p Fail',
'test/errFailPassColorVerbose-failures.txt',
'test/ref/errFailPassColorVerbose-failures.txt', 5 ) )
end

function testColorQuiet()
lu.assertEquals( 0,
check_color_output('example_with_luaunit.lua', '--quiet',
'test/exampleColorQuiet.txt',
'test/ref/exampleColorQuiet.txt', 12 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--quiet',
'test/errFailPassColorQuiet.txt',
'test/ref/errFailPassColorQuiet.txt', 10 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--quiet -p Succ',
'test/errFailPassColorQuiet-success.txt',
'test/ref/errFailPassColorQuiet-success.txt', 0 ) )
lu.assertEquals( 0,
check_color_output('test/test_with_err_fail_pass.lua', '--quiet -p Succ -p Fail',
'test/errFailPassColorQuiet-failures.txt',
'test/ref/errFailPassColorQuiet-failures.txt', 5 ) )
end

-- check nil output

function testNilDefault()
Expand Down Expand Up @@ -574,6 +652,12 @@ local filesToGenerateExampleText = {
{ 'example_with_luaunit.lua', '--verbose', '--output text', 'test/ref/exampleTextVerbose.txt' },
}

local filesToGenerateExampleColor = {
{ 'example_with_luaunit.lua', '--color', '--output text', 'test/ref/exampleColorDefault.txt' },
{ 'example_with_luaunit.lua', '--quiet --color', '--output text', 'test/ref/exampleColorQuiet.txt' },
{ 'example_with_luaunit.lua', '--verbose --color', '--output text', 'test/ref/exampleColorVerbose.txt' },
}

local filesToGenerateExampleNil = {
{ 'example_with_luaunit.lua', '', '--output nil', 'test/ref/exampleNilDefault.txt' },
}
Expand Down Expand Up @@ -639,6 +723,27 @@ local filesToGenerateErrFailPassText = {
'--output text', 'test/ref/errFailPassTextVerbose-failures.txt' },
}

local filesToGenerateErrFailPassColor = {
{ 'test/test_with_err_fail_pass.lua', '--color',
'--output text', 'test/ref/errFailPassColorDefault.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ --color',
'--output text', 'test/ref/errFailPassColorDefault-success.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ -p Fail --color',
'--output text', 'test/ref/errFailPassColorDefault-failures.txt' },
{ 'test/test_with_err_fail_pass.lua', '--quiet --color',
'--output text', 'test/ref/errFailPassColorQuiet.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ --quiet --color',
'--output text', 'test/ref/errFailPassColorQuiet-success.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ -p Fail --quiet --color',
'--output text', 'test/ref/errFailPassColorQuiet-failures.txt' },
{ 'test/test_with_err_fail_pass.lua', '--verbose --color',
'--output text', 'test/ref/errFailPassColorVerbose.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ --verbose --color',
'--output text', 'test/ref/errFailPassColorVerbose-success.txt' },
{ 'test/test_with_err_fail_pass.lua', '-p Succ -p Fail --verbose --color',
'--output text', 'test/ref/errFailPassColorVerbose-failures.txt' },
}

local filesToGenerateTestXml = {
{ 'test/test_with_xml.lua', '', '--output junit --name test/ref/testWithXmlDefault.xml', 'test/ref/testWithXmlDefault.txt' },
{ 'test/test_with_xml.lua', '--verbose', '--output junit --name test/ref/testWithXmlVerbose.xml', 'test/ref/testWithXmlVerbose.txt' },
Expand All @@ -662,9 +767,11 @@ local filesToGenerateListsComp = {
}

local filesSetIndex = {
ErrFailPassColor=filesToGenerateErrFailPassColor,
ErrFailPassText=filesToGenerateErrFailPassText,
ErrFailPassTap=filesToGenerateErrFailPassTap,
ErrFailPassXml=filesToGenerateErrFailPassXml,
ExampleColor=filesToGenerateExampleColor,
ExampleNil=filesToGenerateExampleNil,
ExampleText=filesToGenerateExampleText,
ExampleTap=filesToGenerateExampleTap,
Expand Down
29 changes: 29 additions & 0 deletions test/ref/errFailPassColorDefault-failures.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
..FF..FFF.
Failed tests:
-------------
1) TestAnotherThing.test3_Fail1
test/test_with_err_fail_pass.lua:49: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:49: in function 'TestAnotherThing.test3_Fail1'

2) TestAnotherThing.test3_Fail2
test/test_with_err_fail_pass.lua:53: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:53: in function 'TestAnotherThing.test3_Fail2'

3) TestSomething.test2_Fail1
test/test_with_err_fail_pass.lua:15: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:15: in function 'TestSomething.test2_Fail1'

4) TestSomething.test2_Fail2
test/test_with_err_fail_pass.lua:19: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:19: in function 'TestSomething.test2_Fail2'

5) testFuncFail1
test/test_with_err_fail_pass.lua:62: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:62: in function 'testFuncFail1'

Ran 10 tests in 0.001 seconds, 5 successes, 5 failures, 5 non-selected
3 changes: 3 additions & 0 deletions test/ref/errFailPassColorDefault-success.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.....
Ran 5 tests in 0.000 seconds, 5 successes, 0 failures, 10 non-selected
OK
54 changes: 54 additions & 0 deletions test/ref/errFailPassColorDefault.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
..EEFF..FFEEEF.
Failed tests:
-------------
1) TestAnotherThing.test2_Err1
test/test_with_err_fail_pass.lua:41: attempt to perform arithmetic on a table value
stack traceback:
[C]: in function 'xpcall'

2) TestAnotherThing.test2_Err2
test/test_with_err_fail_pass.lua:45: attempt to perform arithmetic on a table value
stack traceback:
[C]: in function 'xpcall'

3) TestAnotherThing.test3_Fail1
test/test_with_err_fail_pass.lua:49: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:49: in function 'TestAnotherThing.test3_Fail1'

4) TestAnotherThing.test3_Fail2
test/test_with_err_fail_pass.lua:53: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:53: in function 'TestAnotherThing.test3_Fail2'

5) TestSomething.test2_Fail1
test/test_with_err_fail_pass.lua:15: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:15: in function 'TestSomething.test2_Fail1'

6) TestSomething.test2_Fail2
test/test_with_err_fail_pass.lua:19: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:19: in function 'TestSomething.test2_Fail2'

7) TestSomething.test3_Err1
test/test_with_err_fail_pass.lua:23: attempt to perform arithmetic on a table value
stack traceback:
[C]: in function 'xpcall'

8) TestSomething.test3_Err2
test/test_with_err_fail_pass.lua:27: attempt to perform arithmetic on a table value
stack traceback:
[C]: in function 'xpcall'

9) testFuncErr1
test/test_with_err_fail_pass.lua:66: attempt to perform arithmetic on a table value
stack traceback:
[C]: in function 'xpcall'

10) testFuncFail1
test/test_with_err_fail_pass.lua:62: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:62: in function 'testFuncFail1'

Ran 15 tests in 0.001 seconds, 5 successes, 5 failures, 5 errors
29 changes: 29 additions & 0 deletions test/ref/errFailPassColorQuiet-failures.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
..FF..FFF.
Failed tests:
-------------
1) TestAnotherThing.test3_Fail1
test/test_with_err_fail_pass.lua:49: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:49: in function 'TestAnotherThing.test3_Fail1'

2) TestAnotherThing.test3_Fail2
test/test_with_err_fail_pass.lua:53: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:53: in function 'TestAnotherThing.test3_Fail2'

3) TestSomething.test2_Fail1
test/test_with_err_fail_pass.lua:15: expected: 0, actual: 2
stack traceback:
test/test_with_err_fail_pass.lua:15: in function 'TestSomething.test2_Fail1'

4) TestSomething.test2_Fail2
test/test_with_err_fail_pass.lua:19: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:19: in function 'TestSomething.test2_Fail2'

5) testFuncFail1
test/test_with_err_fail_pass.lua:62: expected: 0, actual: 3
stack traceback:
test/test_with_err_fail_pass.lua:62: in function 'testFuncFail1'

Ran 10 tests in 0.001 seconds, 5 successes, 5 failures, 5 non-selected
3 changes: 3 additions & 0 deletions test/ref/errFailPassColorQuiet-success.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.....
Ran 5 tests in 0.000 seconds, 5 successes, 0 failures, 10 non-selected
OK
Loading