nitunit: more verbose on execution
[nit.git] / src / nitunit.nit
index f31b405..1015621 100644 (file)
@@ -23,8 +23,6 @@ import parser_util
 class NitUnitExecutor
        super Doc2Mdwn
 
-       var toolcontext: ToolContext
-
        # The name of the module to import
        var modname: String
 
@@ -37,7 +35,7 @@ class NitUnitExecutor
        # Initialize a new e
        init(toolcontext: ToolContext, prefix: String, modname: String, testsuite: HTMLTag)
        do
-               self.toolcontext = toolcontext
+               super(toolcontext)
                self.prefix = prefix
                self.modname = modname
                self.testsuite = testsuite
@@ -72,10 +70,12 @@ class NitUnitExecutor
        do
                block.clear
 
-               work(ndoc)
+               work(ndoc.to_mdoc)
 
                if block.is_empty then return
 
+               toolcontext.modelbuilder.unit_entities += 1
+
                cpt += 1
                var file = "{prefix}{cpt}.nit"
 
@@ -95,7 +95,13 @@ class NitUnitExecutor
                end
                f.close
 
-               var cmd = "../bin/nitg --no-color '{file}' -I . >'{file}.out1' 2>&1 </dev/null -o '{file}.bin'"
+               var nit_dir = toolcontext.nit_dir
+               var nitg = "{nit_dir}/bin/nitg"
+               if nit_dir == null or not nitg.file_exists then
+                       toolcontext.error(null, "Cannot find nitg. Set envvar NIT_DIR.")
+                       toolcontext.check_errors
+               end
+               var cmd = "{nitg} --ignore-visibility --no-color '{file}' -I . >'{file}.out1' 2>&1 </dev/null -o '{file}.bin'"
                var res = sys.system(cmd)
                var res2 = 0
                if res == 0 then
@@ -120,11 +126,13 @@ class NitUnitExecutor
                        ne.attr("message", msg)
                        tc.add ne
                        toolcontext.warning(ndoc.location, "FAILURE: {tc.attrs["classname"]}.{tc.attrs["name"]} (in {file}): {msg}")
+                       toolcontext.modelbuilder.failed_entities += 1
                else if res2 != 0 then
                        var ne = new HTMLTag("error")
                        ne.attr("message", msg)
                        tc.add ne
                        toolcontext.warning(ndoc.location, "ERROR: {tc.attrs["classname"]}.{tc.attrs["name"]} (in {file}): {msg}")
+                       toolcontext.modelbuilder.failed_entities += 1
                end
                toolcontext.check_errors
 
@@ -149,17 +157,29 @@ class SearchAssertVisitor
 end
 
 redef class ModelBuilder
+       var total_entities = 0
+       var doc_entities = 0
+       var unit_entities = 0
+       var failed_entities = 0
+
        fun test_markdown(mmodule: MModule): HTMLTag
        do
+               var ts = new HTMLTag("testsuite")
                toolcontext.info("nitunit: {mmodule}", 2)
+               if not mmodule2nmodule.has_key(mmodule) then return ts
+
+               var nmodule = mmodule2nmodule[mmodule]
+               assert nmodule != null
+
+               # what module to import in the unit test.
+               # try to detect the main module of the project
+               # TODO do things correctly once the importation of arbitraty nested module is legal
                var o = mmodule
-               var d = o.public_owner
-               while d != null do
-                       o = d
-                       d = o.public_owner
+               var g = o.mgroup
+               if g != null then
+                       o = get_mmodule_by_name(nmodule, g, g.mproject.name).as(not null)
                end
 
-               var ts = new HTMLTag("testsuite")
                ts.attr("package", mmodule.full_name)
 
                var prefix = toolcontext.opt_dir.value
@@ -169,39 +189,42 @@ redef class ModelBuilder
 
                var tc
 
-               if mmodule2nmodule.has_key(mmodule) then
-                       var nmodule = mmodule2nmodule[mmodule]
-                       do
-                               var nmoduledecl = nmodule.n_moduledecl
-                               if nmoduledecl == null then break label x
-                               var ndoc = nmoduledecl.n_doc
-                               if ndoc == null then break label x
-                               tc = new HTMLTag("testcase")
-                               # NOTE: jenkins expects a '.' in the classname attr
-                               tc.attr("classname", mmodule.full_name + ".<module>")
-                               tc.attr("name", "<module>")
-                               d2m.extract(ndoc, tc)
-                       end label x
-                       for nclassdef in nmodule.n_classdefs do
-                               var mclassdef = nclassdef.mclassdef.as(not null)
-                               if nclassdef isa AStdClassdef then
-                                       var ndoc = nclassdef.n_doc
-                                       if ndoc != null then
-                                               tc = new HTMLTag("testcase")
-                                               tc.attr("classname", mmodule.full_name + "." + mclassdef.mclass.full_name)
-                                               tc.attr("name", "<class>")
-                                               d2m.extract(ndoc, tc)
-                                       end
+               do
+                       total_entities += 1
+                       var nmoduledecl = nmodule.n_moduledecl
+                       if nmoduledecl == null then break label x
+                       var ndoc = nmoduledecl.n_doc
+                       if ndoc == null then break label x
+                       doc_entities += 1
+                       tc = new HTMLTag("testcase")
+                       # NOTE: jenkins expects a '.' in the classname attr
+                       tc.attr("classname", mmodule.full_name + ".<module>")
+                       tc.attr("name", "<module>")
+                       d2m.extract(ndoc, tc)
+               end label x
+               for nclassdef in nmodule.n_classdefs do
+                       var mclassdef = nclassdef.mclassdef.as(not null)
+                       if nclassdef isa AStdClassdef then
+                               total_entities += 1
+                               var ndoc = nclassdef.n_doc
+                               if ndoc != null then
+                                       doc_entities += 1
+                                       tc = new HTMLTag("testcase")
+                                       tc.attr("classname", mmodule.full_name + "." + mclassdef.mclass.full_name)
+                                       tc.attr("name", "<class>")
+                                       d2m.extract(ndoc, tc)
                                end
-                               for npropdef in nclassdef.n_propdefs do
-                                       var mpropdef = npropdef.mpropdef.as(not null)
-                                       var ndoc = npropdef.n_doc
-                                       if ndoc != null then
-                                               tc = new HTMLTag("testcase")
-                                               tc.attr("classname", mmodule.full_name + "." + mclassdef.mclass.full_name)
-                                               tc.attr("name", mpropdef.mproperty.full_name)
-                                               d2m.extract(ndoc, tc)
-                                       end
+                       end
+                       for npropdef in nclassdef.n_propdefs do
+                               var mpropdef = npropdef.mpropdef.as(not null)
+                               total_entities += 1
+                               var ndoc = npropdef.n_doc
+                               if ndoc != null then
+                                       doc_entities += 1
+                                       tc = new HTMLTag("testcase")
+                                       tc.attr("classname", mmodule.full_name + "." + mclassdef.mclass.full_name)
+                                       tc.attr("name", mpropdef.mproperty.full_name)
+                                       d2m.extract(ndoc, tc)
                                end
                        end
                end
@@ -219,15 +242,10 @@ end
 var toolcontext = new ToolContext
 
 toolcontext.option_context.add_option(toolcontext.opt_full, toolcontext.opt_output, toolcontext.opt_dir)
+toolcontext.tooldescription = "Usage: nitunit [OPTION]... <file.nit>...\nExecutes the unit tests from Nit source files."
 
-
-toolcontext.process_options
+toolcontext.process_options(args)
 var args = toolcontext.option_context.rest
-if args.is_empty or toolcontext.opt_help.value then
-       print "usage: nitunit [options] file.nit..."
-       toolcontext.option_context.usage
-       return
-end
 
 var model = new Model
 var modelbuilder = new ModelBuilder(model, toolcontext)
@@ -245,4 +263,12 @@ end
 
 var file = toolcontext.opt_output.value
 if file == null then file = "nitunit.xml"
-page.save(file)
+page.write_to_file(file)
+print "Results saved in {file}"
+
+if modelbuilder.unit_entities == 0 then
+       print "No nitunits found"
+else if modelbuilder.failed_entities == 0 then
+       print "Success"
+end
+print "Entities: {modelbuilder.total_entities}; Documented ones: {modelbuilder.doc_entities}; With nitunits: {modelbuilder.unit_entities}; Failures: {modelbuilder.failed_entities}"