import modelize
private import parser_util
import html
+import console
redef class ToolContext
# opt --full
var is_done: Bool = false is writable
# Error message occurred during test-case execution (or compilation).
+ #
+ # e.g.: `Runtime Error`
var error: nullable String = null is writable
# Was the test case executed at least once?
# The location where the error occurred, if it makes sense.
var error_location: nullable Location = null is writable
+ # A colorful `[OK]` or `[KO]`.
+ fun status_tag: String do
+ if not is_done then
+ return "[ ]"
+ else if error != null then
+ return "[KO]".red.bold
+ else
+ return "[OK]".green.bold
+ end
+ end
+
+ # The full (color) description of the test-case.
+ #
+ # `more message`, if any, is added after the error message.
+ fun to_screen(more_message: nullable String): String do
+ var res
+ var error = self.error
+ if error != null then
+ if more_message != null then error += " " + more_message
+ var loc = error_location or else location
+ res = "{status_tag} {full_name}\n {loc.to_s.yellow}: {error}\n{loc.colored_line("1;31")}"
+ var output = self.raw_output
+ if output != null then
+ res += "\n Output\n\t{output.chomp.replace("\n", "\n\t")}\n"
+ end
+ else
+ res = "{status_tag} {full_name}"
+ if more_message != null then res += more_message
+ end
+ return res
+ end
+
# Return a `<testcase>` XML node in format compatible with Jenkins unit tests.
fun to_xml: HTMLTag do
var tc = new HTMLTag("testcase")
var error = self.error
if error != null then
if was_exec then
- tc.open("error").append("Runtime Error")
+ tc.open("error").append(error)
else
- tc.open("failure").append("Compilation Error")
+ tc.open("failure").append(error)
end
- tc.open("system-err").append(error.trunc(8192).filter_nonprintable)
+ end
+ var output = self.raw_output
+ if output != null then
+ tc.open("system-err").append(output.trunc(8192).filter_nonprintable)
end
return tc
end
# Populate `blocks` from the markdown decorator
mdproc.process(mdoc.content.join("\n"))
-
- toolcontext.check_errors
end
# All extracted docunits
test_simple_docunits(simple_du)
for du in docunits do
+ print du.to_screen
+ end
+
+ for du in docunits do
testsuite.add du.to_xml
end
end
du.was_exec = true
var content = "{file}.out1".to_path.read_all
- var msg = content.trunc(8192).filter_nonprintable
+ du.raw_output = content
if res2 != 0 then
- du.error = content
- toolcontext.warning(du.location, "error", "ERROR: {du.full_name} (in {file}): Runtime error\n{msg}")
+ du.error = "Runtime error in {file} with argument {i}"
toolcontext.modelbuilder.failed_entities += 1
end
mark_done(du)
- toolcontext.check_errors
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`.
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
for case in test_cases do case.run
var after_module = self.after_module
if not after_module == null then after_module.run
+ for case in test_cases do
+ print case.to_screen
+ end
end
# Write the test unit for `self` in a nit compilable file.
var test_file = test_suite.test_file
var res_name = "{test_file}_{method_name.escape_to_c}"
var res = toolcontext.safe_exec("{test_file}.bin {method_name} > '{res_name}.out1' 2>&1 </dev/null")
- var f = new FileReader.open("{res_name}.out1")
- var msg = f.read_all
- f.close
+ self.raw_output = "{res_name}.out1".to_path.read_all
# set test case result
- var loc = test_method.location
if res != 0 then
- error = msg
- toolcontext.warning(loc, "failure",
- "ERROR: {method_name} (in file {test_file}.nit): {msg}")
+ error = "Runtime Error in file {test_file}.nit"
toolcontext.modelbuilder.failed_tests += 1
else
+ # no error, check with res file, if any.
var mmodule = test_method.mclassdef.mmodule
var file = mmodule.filepath
if file != null then
toolcontext.info("Diff output with {sav}", 1)
res = toolcontext.safe_exec("diff -u --label 'expected:{sav}' --label 'got:{res_name}.out1' '{sav}' '{res_name}.out1' > '{res_name}.diff' 2>&1 </dev/null")
if res != 0 then
- msg = "Diff\n" + "{res_name}.diff".to_path.read_all
- error = msg
- toolcontext.warning(loc, "failure",
- "ERROR: {method_name} (in file {test_file}.nit): {msg}")
+ self.raw_output = "Diff\n" + "{res_name}.diff".to_path.read_all
+ error = "Difference with expected output: diff -u {sav} {res_name}.out1"
toolcontext.modelbuilder.failed_tests += 1
end
else
end
end
is_done = true
- toolcontext.check_errors
end
redef fun xml_classname do