1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | var nodeunit = require('../nodeunit'),
|
12 | utils = require('../utils'),
|
13 | fs = require('fs'),
|
14 | track = require('../track'),
|
15 | path = require('path'),
|
16 | AssertionError = require('../assert').AssertionError;
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | exports.info = "Nested test reporter";
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | exports.run = function (files, options, callback) {
|
33 |
|
34 | if (!options) {
|
35 |
|
36 | var content = fs.readFileSync(
|
37 | __dirname + '/../../bin/nodeunit.json',
|
38 | 'utf8'
|
39 | );
|
40 | options = JSON.parse(content);
|
41 | }
|
42 |
|
43 | var error = function (str) {
|
44 | return options.error_prefix + str + options.error_suffix;
|
45 | };
|
46 | var ok = function (str) {
|
47 | return options.ok_prefix + str + options.ok_suffix;
|
48 | };
|
49 | var bold = function (str) {
|
50 | return options.bold_prefix + str + options.bold_suffix;
|
51 | };
|
52 | var assertion_message = function (str) {
|
53 | return options.assertion_prefix + str + options.assertion_suffix;
|
54 | };
|
55 | var fail_indicator = process.platform === 'win32' ? '\u00D7' : '✖';
|
56 |
|
57 | var spaces_per_indent = options.spaces_per_indent || 4;
|
58 |
|
59 | var start = new Date().getTime();
|
60 | var paths = files.map(function (p) {
|
61 | return path.resolve(p);
|
62 | });
|
63 | var tracker = track.createTracker(function (tracker) {
|
64 | var i, names;
|
65 | if (tracker.unfinished()) {
|
66 | console.log('');
|
67 | console.log(error(bold(
|
68 | 'FAILURES: Undone tests (or their setups/teardowns): '
|
69 | )));
|
70 | names = tracker.names();
|
71 | for (i = 0; i < names.length; i += 1) {
|
72 | console.log('- ' + names[i]);
|
73 | }
|
74 | console.log('');
|
75 | console.log('To fix this, make sure all tests call test.done()');
|
76 | process.reallyExit(tracker.unfinished());
|
77 | }
|
78 | });
|
79 |
|
80 |
|
81 |
|
82 | tracker.already_printed = {};
|
83 |
|
84 | var pass_text = function (txt) {
|
85 |
|
86 | return bold(ok(txt + " (pass)"));
|
87 | };
|
88 |
|
89 | var fail_text = function (txt) {
|
90 | return bold(error(txt + " (fail) " + fail_indicator + " "));
|
91 | };
|
92 |
|
93 | var status_text = function (txt, status) {
|
94 | if (status === 'pass') {
|
95 | return pass_text(txt);
|
96 | } else {
|
97 | return fail_text(txt);
|
98 | }
|
99 | };
|
100 |
|
101 | |
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | var name_slice = function (name_arr, end_index) {
|
108 | return name_arr.slice(0, end_index + 1).join(",");
|
109 | };
|
110 |
|
111 | var indent = (function () {
|
112 | var txt = '';
|
113 | var i;
|
114 | for (i = 0; i < spaces_per_indent; i++) {
|
115 | txt += ' ';
|
116 | }
|
117 | return txt;
|
118 | }());
|
119 |
|
120 |
|
121 | var add_indent = function (txt, indent_level) {
|
122 | var k;
|
123 | for (k = 0; k < indent_level; k++) {
|
124 | txt += indent;
|
125 | }
|
126 | return txt;
|
127 | };
|
128 |
|
129 |
|
130 | var is_testCase = function (name_arr, index) {
|
131 | return index === name_arr.length - 1 ? false : true;
|
132 | };
|
133 |
|
134 | var testCase_line = function (txt) {
|
135 | return txt + "\n";
|
136 | };
|
137 |
|
138 | |
139 |
|
140 |
|
141 |
|
142 |
|
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 | var print_status = function (name_arr, status) {
|
150 | var txt = '';
|
151 | var _name_slice, part, i;
|
152 | for (i = 0; i < name_arr.length; i++) {
|
153 | _name_slice = name_slice(name_arr, i);
|
154 | part = name_arr[i];
|
155 | if (!tracker.already_printed[_name_slice]) {
|
156 | txt = add_indent(txt, i);
|
157 | if (is_testCase(name_arr, i)) {
|
158 | txt += testCase_line(part);
|
159 | } else {
|
160 | txt += status_text(part, status);
|
161 | }
|
162 | tracker.already_printed[_name_slice] = true;
|
163 | }
|
164 | }
|
165 | console.log(txt);
|
166 | };
|
167 |
|
168 | nodeunit.runFiles(paths, {
|
169 | testspec: options.testspec,
|
170 | testFullSpec: options.testFullSpec,
|
171 | moduleStart: function (name) {
|
172 | console.log('\n' + bold(name));
|
173 | },
|
174 | testDone: function (name, assertions) {
|
175 | tracker.remove(name);
|
176 |
|
177 | if (!assertions.failures()) {
|
178 | print_status(name, 'pass');
|
179 | } else {
|
180 | print_status(name, 'fail');
|
181 | assertions.forEach(function (a) {
|
182 | if (a.failed()) {
|
183 | a = utils.betterErrors(a);
|
184 | if (a.error instanceof AssertionError && a.message) {
|
185 | console.log(
|
186 | 'Assertion Message: ' +
|
187 | assertion_message(a.message)
|
188 | );
|
189 | }
|
190 | console.log(a.error.stack + '\n');
|
191 | }
|
192 | });
|
193 | }
|
194 | },
|
195 | done: function (assertions, end) {
|
196 | end = end || new Date().getTime();
|
197 | var duration = end - start;
|
198 | if (assertions.failures()) {
|
199 | console.log(
|
200 | '\n' + bold(error('FAILURES: ')) + assertions.failures() +
|
201 | '/' + assertions.length + ' assertions failed (' +
|
202 | assertions.duration + 'ms)'
|
203 | );
|
204 | } else {
|
205 | console.log(
|
206 | '\n' + bold(ok('OK: ')) + assertions.length +
|
207 | ' assertions (' + assertions.duration + 'ms)'
|
208 | );
|
209 | }
|
210 |
|
211 | if (callback) callback(assertions.failures() ? new Error('We have got test failures.') : undefined);
|
212 | },
|
213 | testStart: function (name) {
|
214 | tracker.put(name);
|
215 | }
|
216 | });
|
217 | };
|