fe8fb7bc22a266ceaabd0ad3e5071e38866456ba
[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 page.add modelbuilder.test_mdoc(mdoc)
88 end
89
90 for a in module_files do
91 var g = modelbuilder.identify_group(a)
92 if g == null then continue
93 page.add modelbuilder.test_group(g)
94 end
95
96 for m in mmodules do
97 page.add modelbuilder.test_markdown(m)
98 var ts = modelbuilder.test_unit(m)
99 if ts != null then page.add ts
100 end
101
102 var file = toolcontext.opt_output.value
103 if file == null then file = "nitunit.xml"
104 page.write_to_file(file)
105
106 # Print results
107 printn "Docunits: Entities: {modelbuilder.total_entities}; Documented ones: {modelbuilder.doc_entities}; With nitunits: {modelbuilder.unit_entities}"
108 if modelbuilder.unit_entities == 0 or toolcontext.opt_noact.value then
109 print ""
110 else
111 printn "; Failures: "
112 var cpt = modelbuilder.failed_entities
113 if toolcontext.opt_no_color.value then
114 print cpt
115 else if cpt == 0 then
116 print "0".green.bold
117 else
118 print cpt.to_s.red.bold
119 end
120 end
121 printn "Test suites: Classes: {modelbuilder.total_classes}; Test Cases: {modelbuilder.total_tests}"
122 if modelbuilder.total_tests == 0 or toolcontext.opt_noact.value then
123 print ""
124 else
125 printn "; Failures: "
126 var cpt = modelbuilder.failed_tests
127 if toolcontext.opt_no_color.value then
128 print cpt
129 else if cpt == 0 then
130 print "0".green.bold
131 else
132 print cpt.to_s.red.bold
133 end
134 end
135
136 var total = modelbuilder.unit_entities + modelbuilder.total_tests
137 var fail = modelbuilder.failed_entities + modelbuilder.failed_tests
138 if toolcontext.opt_noact.value then
139 # nothing
140 else if total == 0 then
141 var head = "[NOTHING]"
142 if not toolcontext.opt_no_color.value then
143 head = head.yellow
144 end
145 print "{head} No unit tests to execute."
146 else if fail == 0 then
147 var head = "[SUCCESS]"
148 if not toolcontext.opt_no_color.value then
149 head = head.green.bold
150 end
151 print "{head} All {total} tests passed."
152 else
153 var head = "[FAILURE]"
154 if not toolcontext.opt_no_color.value then
155 head = head.red.bold
156 end
157 print "{head} {fail}/{total} tests failed."
158
159 print "`{test_dir}` is not removed for investigation."
160 exit 1
161 end
162
163 test_dir.rmdir