Merge: doc: fixed some typos and other misc. corrections
[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 frontend
20 import testing
21
22 var toolcontext = new ToolContext
23 toolcontext.keep_going = true
24
25 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)
26 toolcontext.tooldescription = "Usage: nitunit [OPTION]... <file.nit>...\nExecutes the unit tests from Nit source files."
27
28 toolcontext.process_options(args)
29 var args = toolcontext.option_context.rest
30
31 if toolcontext.opt_gen_unit.value then
32 if toolcontext.opt_pattern.value != null then
33 print "Option --pattern cannot be used with --gen-suite"
34 exit(0)
35 end
36 else
37 if toolcontext.opt_gen_force.value then
38 print "Option --force must be used with --gen-suite"
39 exit(0)
40 end
41 if toolcontext.opt_gen_private.value then
42 print "Option --private must be used with --gen-suite"
43 exit(0)
44 end
45 if toolcontext.opt_gen_show.value then
46 print "Option --only-show must be used with --gen-suite"
47 exit(0)
48 end
49 end
50
51 var model = new Model
52 var modelbuilder = new ModelBuilder(model, toolcontext)
53
54 var module_files = modelbuilder.filter_nit_source(args)
55
56 var mmodules = modelbuilder.parse_full(module_files)
57 modelbuilder.run_phases
58
59 if toolcontext.opt_gen_unit.value then
60 modelbuilder.gen_test_unit(mmodules.first)
61 exit(0)
62 end
63
64 # When testing `nitunit`, disable time.
65 if "NIT_TESTING".environ != "" then
66 toolcontext.opt_no_time.value = true
67 end
68
69 "NIT_TESTING".setenv("true")
70 "NIT_TESTING_ID".setenv(pid.to_s)
71 "SRAND".setenv("0")
72
73 var test_dir = toolcontext.test_dir
74 test_dir.mkdir
75 "# This file prevents the Nit modules of the directory to be part of the package".write_to_file(test_dir / "packages.ini")
76
77 var page = new HTMLTag("testsuites")
78
79 if toolcontext.opt_full.value then mmodules = model.mmodules
80
81 for a in args do
82 if not a.file_exists then
83 toolcontext.fatal_error(null, "Error: cannot load file or module `{a}`.")
84 end
85 # Try to load the file as a markdown document
86 var mdoc = modelbuilder.load_markdown(a)
87 var ts = modelbuilder.test_mdoc(mdoc)
88 if not ts.children.is_empty then page.add ts
89 end
90
91 for a in module_files do
92 var g = modelbuilder.identify_group(a)
93 if g == null then continue
94 var ts = modelbuilder.test_group(g)
95 if not ts.children.is_empty then page.add ts
96 end
97
98 for m in mmodules do
99 var ts
100 ts = modelbuilder.test_markdown(m)
101 if not ts.children.is_empty then page.add ts
102 ts = modelbuilder.test_unit(m)
103 if ts != null and not ts.children.is_empty then page.add ts
104 end
105
106 var file = toolcontext.opt_output.value
107 if file == null then file = "nitunit.xml"
108 page.write_to_file(file)
109
110 # Print results
111 printn "Docunits: Entities: {modelbuilder.total_entities}; Documented ones: {modelbuilder.doc_entities}; With nitunits: {modelbuilder.unit_entities}"
112 if modelbuilder.unit_entities == 0 or toolcontext.opt_noact.value then
113 print ""
114 else
115 printn "; Failures: "
116 var cpt = modelbuilder.failed_entities
117 if toolcontext.opt_no_color.value then
118 print cpt
119 else if cpt == 0 then
120 print "0".green.bold
121 else
122 print cpt.to_s.red.bold
123 end
124 end
125 printn "Test suites: Classes: {modelbuilder.total_classes}; Test Cases: {modelbuilder.total_tests}"
126 if modelbuilder.total_tests == 0 or toolcontext.opt_noact.value then
127 print ""
128 else
129 printn "; Failures: "
130 var cpt = modelbuilder.failed_tests
131 if toolcontext.opt_no_color.value then
132 print cpt
133 else if cpt == 0 then
134 print "0".green.bold
135 else
136 print cpt.to_s.red.bold
137 end
138 end
139
140 var total = modelbuilder.unit_entities + modelbuilder.total_tests
141 var fail = modelbuilder.failed_entities + modelbuilder.failed_tests
142 if toolcontext.opt_noact.value then
143 # nothing
144 else if total == 0 then
145 var head = "[NOTHING]"
146 if not toolcontext.opt_no_color.value then
147 head = head.yellow
148 end
149 print "{head} No unit tests to execute."
150 else if fail == 0 then
151 var head = "[SUCCESS]"
152 if not toolcontext.opt_no_color.value then
153 head = head.green.bold
154 end
155 print "{head} All {total} tests passed."
156 else
157 var head = "[FAILURE]"
158 if not toolcontext.opt_no_color.value then
159 head = head.red.bold
160 end
161 print "{head} {fail}/{total} tests failed."
162
163 print "`{test_dir}` is not removed for investigation."
164 exit 1
165 end
166
167 test_dir.rmdir