nitunit: add --no-time to avoid time and improve reproductible results
[nit.git] / src / nitunit.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Testing tool.
16 # see `testing/README`
17 module nitunit
18
19 import testing
20
21 var toolcontext = new ToolContext
22
23 toolcontext.option_context.add_option(toolcontext.opt_full, toolcontext.opt_output, toolcontext.opt_dir, toolcontext.opt_noact, toolcontext.opt_pattern, toolcontext.opt_autosav, toolcontext.opt_gen_unit, toolcontext.opt_gen_force, toolcontext.opt_gen_private, toolcontext.opt_gen_show, toolcontext.opt_nitc)
24 toolcontext.tooldescription = "Usage: nitunit [OPTION]... <file.nit>...\nExecutes the unit tests from Nit source files."
25
26 toolcontext.process_options(args)
27 var args = toolcontext.option_context.rest
28
29 if toolcontext.opt_gen_unit.value then
30 if toolcontext.opt_pattern.value != null then
31 print "Option --pattern cannot be used with --gen-suite"
32 exit(0)
33 end
34 else
35 if toolcontext.opt_gen_force.value then
36 print "Option --force must be used with --gen-suite"
37 exit(0)
38 end
39 if toolcontext.opt_gen_private.value then
40 print "Option --private must be used with --gen-suite"
41 exit(0)
42 end
43 if toolcontext.opt_gen_show.value then
44 print "Option --only-show must be used with --gen-suite"
45 exit(0)
46 end
47 end
48
49 var model = new Model
50 var modelbuilder = new ModelBuilder(model, toolcontext)
51
52 var module_files = modelbuilder.filter_nit_source(args)
53
54 var mmodules = modelbuilder.parse_full(module_files)
55 modelbuilder.run_phases
56
57 if toolcontext.opt_gen_unit.value then
58 modelbuilder.gen_test_unit(mmodules.first)
59 exit(0)
60 end
61
62 # When testing `nitunit`, disable time.
63 if "NIT_TESTING".environ != "" then
64 toolcontext.opt_no_time.value = true
65 end
66
67 "NIT_TESTING".setenv("true")
68 "NIT_TESTING_ID".setenv(pid.to_s)
69 "SRAND".setenv("0")
70
71 var test_dir = toolcontext.test_dir
72 test_dir.mkdir
73 "# This file prevents the Nit modules of the directory to be part of the package".write_to_file(test_dir / "packages.ini")
74
75 var page = new HTMLTag("testsuites")
76
77 if toolcontext.opt_full.value then mmodules = model.mmodules
78
79 for a in args do
80 if not a.file_exists then
81 toolcontext.fatal_error(null, "Error: cannot load file or module `{a}`.")
82 end
83 # Try to load the file as a markdown document
84 var mdoc = modelbuilder.load_markdown(a)
85 page.add modelbuilder.test_mdoc(mdoc)
86 end
87
88 for a in module_files do
89 var g = modelbuilder.identify_group(a)
90 if g == null then continue
91 page.add modelbuilder.test_group(g)
92 end
93
94 for m in mmodules do
95 page.add modelbuilder.test_markdown(m)
96 var ts = modelbuilder.test_unit(m)
97 if ts != null then page.add ts
98 end
99
100 var file = toolcontext.opt_output.value
101 if file == null then file = "nitunit.xml"
102 page.write_to_file(file)
103
104 # Print results
105 printn "Docunits: Entities: {modelbuilder.total_entities}; Documented ones: {modelbuilder.doc_entities}; With nitunits: {modelbuilder.unit_entities}"
106 if modelbuilder.unit_entities == 0 or toolcontext.opt_noact.value then
107 print ""
108 else
109 printn "; Failures: "
110 var cpt = modelbuilder.failed_entities
111 if toolcontext.opt_no_color.value then
112 print cpt
113 else if cpt == 0 then
114 print "0".green.bold
115 else
116 print cpt.to_s.red.bold
117 end
118 end
119 printn "Test suites: Classes: {modelbuilder.total_classes}; Test Cases: {modelbuilder.total_tests}"
120 if modelbuilder.total_tests == 0 or toolcontext.opt_noact.value then
121 print ""
122 else
123 printn "; Failures: "
124 var cpt = modelbuilder.failed_tests
125 if toolcontext.opt_no_color.value then
126 print cpt
127 else if cpt == 0 then
128 print "0".green.bold
129 else
130 print cpt.to_s.red.bold
131 end
132 end
133
134 var total = modelbuilder.unit_entities + modelbuilder.total_tests
135 var fail = modelbuilder.failed_entities + modelbuilder.failed_tests
136 if toolcontext.opt_noact.value then
137 # nothing
138 else if total == 0 then
139 var head = "[NOTHING]"
140 if not toolcontext.opt_no_color.value then
141 head = head.yellow
142 end
143 print "{head} No unit tests to execute."
144 else if fail == 0 then
145 var head = "[SUCCESS]"
146 if not toolcontext.opt_no_color.value then
147 head = head.green.bold
148 end
149 print "{head} All {total} tests passed."
150 else
151 var head = "[FAILURE]"
152 if not toolcontext.opt_no_color.value then
153 head = head.red.bold
154 end
155 print "{head} {fail}/{total} tests failed."
156
157 print "`{test_dir}` is not removed for investigation."
158 exit 1
159 end
160
161 test_dir.rmdir