# The XML node associated to the module
var testsuite: HTMLTag
+ # The name of the suite
+ var name: String
+
# Markdown processor used to parse markdown comments and extract code.
var mdproc = new MarkdownProcessor
# Populate `blocks` from the markdown decorator
mdproc.process(mdoc.content.join("\n"))
-
- toolcontext.check_errors
end
# All extracted docunits
var docunits = new Array[DocUnit]
+ fun show_status
+ do
+ toolcontext.show_unit_status(name, docunits)
+ end
+
fun mark_done(du: DocUnit)
do
du.is_done = true
+ toolcontext.clear_progress_bar
+ toolcontext.show_unit(du)
+ show_status
end
# Execute all the docunits
fun run_tests
do
+ if docunits.is_empty then
+ 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
testsuite.add du.to_xml
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
- var msg = content.trunc(8192).filter_nonprintable
+ # 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 = content
- toolcontext.warning(du.location, "error", "ERROR: {du.full_name} (in {file}): Runtime error\n{msg}")
- toolcontext.modelbuilder.failed_entities += 1
- end
- mark_done(du)
- toolcontext.check_errors
+ 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
end
var content = "{file}.out1".to_path.read_all
- var msg = content.trunc(8192).filter_nonprintable
+ du.raw_output = content
if res != 0 then
- du.error = content
- toolcontext.warning(du.location, "failure", "FAILURE: {du.full_name} (in {file}):\n{msg}")
+ du.error = "Compilation error in {file}"
toolcontext.modelbuilder.failed_entities += 1
else if res2 != 0 then
- du.error = content
- toolcontext.warning(du.location, "error", "ERROR: {du.full_name} (in {file}):\n{msg}")
+ du.error = "Runtime error in {file}"
toolcontext.modelbuilder.failed_entities += 1
end
- mark_done(du)
- toolcontext.check_errors
end
# Create and fill the header of a unit file `file`.
if mmodule != null then
opts.add "-I {mmodule.filepath.dirname}"
end
- var cmd = "{nitc} --ignore-visibility --no-color '{file}' {opts.join(" ")} >'{file}.out1' 2>&1 </dev/null -o '{file}.bin'"
+ var cmd = "{nitc} --ignore-visibility --no-color -q '{file}' {opts.join(" ")} >'{file}.out1' 2>&1 </dev/null -o '{file}.bin'"
var res = toolcontext.safe_exec(cmd)
return res
end
message = "Error: Invalid Nit code."
end
- executor.toolcontext.warning(location, "invalid-block", "{message} To suppress this message, enclose the block with a fence tagged `nitish` or `raw` (see `man nitdoc`).")
- executor.toolcontext.modelbuilder.failed_entities += 1
-
var du = new_docunit
du.block += code
du.error_location = location
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
var prefix = toolcontext.test_dir
prefix = prefix.join_path(mmodule.to_s)
- var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts, "Docunits of module {mmodule.full_name}")
do
total_entities += 1
var prefix = toolcontext.test_dir
prefix = prefix.join_path(mgroup.to_s)
- var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, o, ts, "Docunits of group {mgroup.full_name}")
total_entities += 1
var mdoc = mgroup.mdoc
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)
ts.attr("package", file)
var prefix = toolcontext.test_dir / "file"
- var d2m = new NitUnitExecutor(toolcontext, prefix, null, ts)
+ var d2m = new NitUnitExecutor(toolcontext, prefix, null, ts, "Docunits of file {file}")
total_entities += 1
doc_entities += 1