The results are printed progressively instead of at the end of each test-suite.
The progress bar in therefore displayed below the results.
See it in action: https://asciinema.org/a/17u9jwts0nz5dfpxp8p9aab0f
Pull-Request: #2156
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>
# Show a single-line status to use as a progression.
#
- # Note that the line starts with `'\r'` and is not ended by a `'\n'`.
+ # If `has_progress_bar` is true, then the output is a progress bar.
+ # The printed the line starts with `'\r'` and is not ended by a `'\n'`.
# So it is expected that:
# * no other output is printed between two calls
# * the last `show_unit_status` is followed by a new-line
- fun show_unit_status(name: String, tests: SequenceRead[UnitTest], more_message: nullable String)
+ #
+ # If `has_progress_bar` is false, then only the first and last state is shown
+ fun show_unit_status(name: String, tests: SequenceRead[UnitTest])
do
var esc = 27.code_point.to_s
- var line = "\r{esc}[K* {name} ["
+ var line = "\r\x1B[K==== {name} ["
var done = tests.length
+ var fails = 0
for t in tests do
if not t.is_done then
line += " "
line += ".".green.bold
else
line += "X".red.bold
+ fails += 1
end
end
- if opt_no_color.value then
+ if not has_progress_bar then
if done == 0 then
- print "* {name} ({tests.length} tests)"
+ print "==== {name} | tests: {tests.length}"
end
return
end
- line += "] {done}/{tests.length}"
- if more_message != null then
- line += " " + more_message
+ if done < tests.length then
+ line += "] {done}/{tests.length}"
+ else
+ line += "] tests: {tests.length} "
+ if fails == 0 then
+ line += "OK".green.bold
+ else
+ line += "KO: {fails}".red.bold
+ end
end
printn "{line}"
end
- # Shoe the full description of the test-case.
+ # Is a progress bar printed?
+ #
+ # true if color (because and non-verbose mode
+ # (because verbose mode messes up with the progress bar).
+ fun has_progress_bar: Bool
+ do
+ return not opt_no_color.value and opt_verbose.value <= 0
+ end
+
+ # Clear the line if `has_progress_bar` (no-op else)
+ fun clear_progress_bar
+ do
+ if has_progress_bar then printn "\r\x1B[K"
+ end
+
+ # Show the full description of the test-case.
#
# The output honors `--no-color`.
#
# All extracted docunits
var docunits = new Array[DocUnit]
- fun show_status(more_message: nullable String)
+ fun show_status
do
- toolcontext.show_unit_status(name, docunits, more_message)
+ toolcontext.show_unit_status(name, docunits)
end
fun mark_done(du: DocUnit)
do
du.is_done = true
- show_status(du.full_name + " " + du.status_tag)
+ toolcontext.clear_progress_bar
+ toolcontext.show_unit(du)
+ show_status
end
# Execute all the docunits
return
end
+ # Try to group each nitunit into a single source file to fasten the compilation
var simple_du = new Array[DocUnit]
show_status
for du in docunits do
# Skip existing errors
if du.error != null then
- mark_done(du)
continue
end
var ast = toolcontext.parse_something(du.block)
if ast isa AExpr then
simple_du.add du
+ end
+ end
+ test_simple_docunits(simple_du)
+
+ # Now test them in order
+ for du in docunits do
+ if du.error != null then
+ # Nothing to execute. Conclude
+ else if du.test_file != null then
+ # Already compiled. Execute it.
+ execute_simple_docunit(du)
else
+ # Need to try to compile it, then execute it
test_single_docunit(du)
end
+ mark_done(du)
end
- test_simple_docunits(simple_du)
-
+ # Final status
show_status
print ""
for du in docunits do
- toolcontext.show_unit(du)
- end
-
- for du in docunits do
testsuite.add du.to_xml
end
end
if res != 0 then
# Compilation error.
- # Fall-back to individual modes:
- for du in dus do
- test_single_docunit(du)
- end
+ # They will be executed independently
return
end
+ # Compilation was a success.
+ # Store what need to be executed for each one.
i = 0
for du in dus do
i += 1
- toolcontext.info("Execute doc-unit {du.full_name} in {file} {i}", 1)
- var res2 = toolcontext.safe_exec("{file.to_program_name}.bin {i} >'{file}.out1' 2>&1 </dev/null")
- du.was_exec = true
+ du.test_file = file
+ du.test_arg = i
+ end
+ end
- var content = "{file}.out1".to_path.read_all
- du.raw_output = content
+ # Execute a docunit compiled by `test_single_docunit`
+ fun execute_simple_docunit(du: DocUnit)
+ do
+ var file = du.test_file.as(not null)
+ var i = du.test_arg.as(not null)
+ toolcontext.info("Execute doc-unit {du.full_name} in {file} {i}", 1)
+ var res2 = toolcontext.safe_exec("{file.to_program_name}.bin {i} >'{file}.out1' 2>&1 </dev/null")
+ du.was_exec = true
- if res2 != 0 then
- du.error = "Runtime error in {file} with argument {i}"
- toolcontext.modelbuilder.failed_entities += 1
- end
- mark_done(du)
+ var content = "{file}.out1".to_path.read_all
+ du.raw_output = content
+
+ if res2 != 0 then
+ du.error = "Runtime error in {file} with argument {i}"
+ toolcontext.modelbuilder.failed_entities += 1
end
end
du.error = "Runtime error in {file}"
toolcontext.modelbuilder.failed_entities += 1
end
- mark_done(du)
end
# Create and fill the header of a unit file `file`.
var mdoc = executor.mdoc
assert mdoc != null
- var next_number = 0
+ var next_number = 1
var name = executor.xml_name
if executor.docunits.not_empty and executor.docunits.last.mdoc == mdoc then
next_number = executor.docunits.last.number + 1
- name += "+" + next_number.to_s
+ name += "#" + next_number.to_s
end
var res = new DocUnit(mdoc, next_number, "", executor.xml_classname, name)
# The numbering of self in mdoc (starting with 0)
var number: Int
+ # The generated Nit source file that contains the unit-test
+ #
+ # Note that a same generated file can be used for multiple tests.
+ # See `test_arg` that is used to distinguish them
+ var test_file: nullable String = null
+
+ # The command-line argument to use when executing the test, if any.
+ var test_arg: nullable Int = null
+
redef fun full_name do
var mentity = mdoc.original_mentity
if mentity != null then
- return mentity.full_name
+ var res = mentity.full_name
+ if number > 1 then
+ res += "#{number}"
+ end
+ return res
else
return xml_classname + "." + xml_name
end
fun test_mdoc(mdoc: MDoc): HTMLTag
do
var ts = new HTMLTag("testsuite")
- var file = mdoc.location.to_s
+ var file = mdoc.location.file.filename
toolcontext.info("nitunit: doc-unit file {file}", 2)
# Test to be executed after the whole test suite.
var after_module: nullable TestCase = null
- fun show_status(more_message: nullable String)
+ fun show_status
do
- toolcontext.show_unit_status("Test-suite of module " + mmodule.full_name, test_cases, more_message)
+ toolcontext.show_unit_status("Test-suite of module " + mmodule.full_name, test_cases)
end
# Execute the test suite
if not before_module == null then before_module.run
for case in test_cases do
case.run
- show_status(case.full_name + " " + case.status_tag)
+ toolcontext.clear_progress_bar
+ toolcontext.show_unit(case)
+ show_status
end
- show_status
- print ""
-
var after_module = self.after_module
if not after_module == null then after_module.run
- for case in test_cases do
- toolcontext.show_unit(case)
- end
+
+ show_status
+ print ""
end
# Write the test unit for `self` in a nit compilable file.
-* Docunits of module test_nitunit::test_nitunit (4 tests)
-
+==== Docunits of module test_nitunit::test_nitunit | tests: 4
[OK] test_nitunit::test_nitunit
[KO] test_nitunit$X
test_nitunit.nit:21,7--22,0: Runtime error in nitunit.out/test_nitunit-2.nit
[KO] test_nitunit$X$foo1
test_nitunit.nit:28,15: Syntax Error: unexpected operator '!'.
-* Test-suite of module test_test_nitunit::test_test_nitunit (3 tests)
+==== Test-suite of module test_test_nitunit::test_test_nitunit | tests: 3
[OK] test_test_nitunit$TestX$test_foo
[KO] test_test_nitunit$TestX$test_foo1
test_test_nitunit.nit:36,2--40,4: Runtime Error in file nitunit.out/gen_test_test_nitunit.nit
Runtime error: Assert failed (test_test_nitunit.nit:39)
[OK] test_test_nitunit$TestX$test_foo2
+
Docunits: Entities: 27; Documented ones: 4; With nitunits: 4; Failures: 3
Test suites: Classes: 1; Test Cases: 3; Failures: 1
[FAILURE] 4/7 tests failed.
-* Docunits of module test_nitunit2::test_nitunit2 (3 tests)
-
+==== Docunits of module test_nitunit2::test_nitunit2 | tests: 3
[OK] test_nitunit2::test_nitunit2$core::Sys$foo1
[OK] test_nitunit2::test_nitunit2$core::Sys$bar2
[OK] test_nitunit2::test_nitunit2$core::Sys$foo3
+
Docunits: Entities: 4; Documented ones: 3; With nitunits: 3; Failures: 0
Test suites: Classes: 0; Test Cases: 0
[SUCCESS] All 3 tests passed.
-* Docunits of module test_doc2::test_doc2 (3 tests)
-
+==== Docunits of module test_doc2::test_doc2 | tests: 3
[OK] test_doc2::test_doc2$core::Sys$foo1
[OK] test_doc2::test_doc2$core::Sys$foo2
[OK] test_doc2::test_doc2$core::Sys$foo3
+
Docunits: Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 0
Test suites: Classes: 0; Test Cases: 0
[SUCCESS] All 3 tests passed.
-* Docunits of group test_nitunit3> (2 tests)
-
+==== Docunits of group test_nitunit3> | tests: 2
[KO] test_nitunit3>
test_nitunit3/README.md:4,2--15,0: Runtime error in nitunit.out/test_nitunit3-0.nit with argument 1
Output
Runtime error: Assert failed (nitunit.out/test_nitunit3-0.nit:7)
-[KO] test_nitunit3>
+[KO] test_nitunit3>#2
test_nitunit3/README.md:7,3--5: Syntax Error: unexpected malformed character '\].
-* Docunits of module test_nitunit3::test_nitunit3 (1 tests)
+==== Docunits of module test_nitunit3::test_nitunit3 | tests: 1
[OK] test_nitunit3::test_nitunit3
+
Docunits: Entities: 2; Documented ones: 2; With nitunits: 3; Failures: 2
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 2/3 tests failed.
<testsuites><testsuite package="test_nitunit3>"><testcase classname="nitunit.test_nitunit3>" name="<group>"><error>Runtime error in nitunit.out/test_nitunit3-0.nit with argument 1</error><system-err>Runtime error: Assert failed (nitunit.out/test_nitunit3-0.nit:7)
</system-err><system-out>assert false
assert true
-</system-out></testcase><testcase classname="nitunit.test_nitunit3>" name="<group>+1"><failure>Syntax Error: unexpected malformed character '\].</failure><system-out>;'\][]
+</system-out></testcase><testcase classname="nitunit.test_nitunit3>" name="<group>#2"><failure>Syntax Error: unexpected malformed character '\].</failure><system-out>;'\][]
</system-out></testcase></testsuite><testsuite package="test_nitunit3::test_nitunit3"><testcase classname="nitunit.test_nitunit3::test_nitunit3.<module>" name="<module>"><system-err></system-err><system-out>assert true
</system-out></testcase></testsuite><testsuite></testsuite></testsuites>
\ No newline at end of file
-* Docunits of file test_nitunit_md.md:1,0--15,0 (1 tests)
-
-[KO] nitunit.<file>.test_nitunit_md.md:1,0--15,0
+==== Docunits of file test_nitunit_md.md | tests: 1
+[KO] nitunit.<file>.test_nitunit_md.md
test_nitunit_md.md:4,2--16,0: Runtime error in nitunit.out/file-0.nit with argument 1
Output
Runtime error: Assert failed (nitunit.out/file-0.nit:8)
+
Docunits: Entities: 1; Documented ones: 1; With nitunits: 1; Failures: 1
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 1/1 tests failed.
`nitunit.out` is not removed for investigation.
-<testsuites><testsuite package="test_nitunit_md.md:1,0--15,0"><testcase classname="nitunit.<file>" name="test_nitunit_md.md:1,0--15,0"><error>Runtime error in nitunit.out/file-0.nit with argument 1</error><system-err>Runtime error: Assert failed (nitunit.out/file-0.nit:8)
+<testsuites><testsuite package="test_nitunit_md.md"><testcase classname="nitunit.<file>" name="test_nitunit_md.md"><error>Runtime error in nitunit.out/file-0.nit with argument 1</error><system-err>Runtime error: Assert failed (nitunit.out/file-0.nit:8)
</system-err><system-out>var a = 1
assert 1 == 1
assert false
-* Docunits of module test_doc3::test_doc3 (3 tests)
-
+==== Docunits of module test_doc3::test_doc3 | tests: 3
[KO] test_doc3::test_doc3$core::Sys$foo1
test_doc3.nit:17,9--15: Syntax Error: unexpected identifier 'garbage'.
[KO] test_doc3::test_doc3$core::Sys$foo2
test_doc3.nit:23,4--10: Syntax Error: unexpected identifier 'garbage'.
[KO] test_doc3::test_doc3$core::Sys$foo3
test_doc3.nit:30,4--10: Syntax Error: unexpected identifier 'garbage'.
+
Docunits: Entities: 6; Documented ones: 5; With nitunits: 3; Failures: 3
Test suites: Classes: 0; Test Cases: 0
[FAILURE] 3/3 tests failed.
-* Test-suite of module test_nitunit4::test_nitunit4 (3 tests)
-
+==== Test-suite of module test_nitunit4::test_nitunit4 | tests: 3
[KO] test_nitunit4$TestTestSuite$test_foo
test_nitunit4/test_nitunit4.nit:22,2--26,4: Runtime Error in file nitunit.out/gen_test_nitunit4.nit
Output
+Tested method
+After Test
+
Docunits: Entities: 12; Documented ones: 0; With nitunits: 0
Test suites: Classes: 1; Test Cases: 3; Failures: 2
[FAILURE] 2/3 tests failed.