1 | (function(global) {
|
2 | var UNDEFINED,
|
3 | exportObject;
|
4 |
|
5 | if (typeof module !== "undefined" && module.exports) {
|
6 | exportObject = exports;
|
7 | } else {
|
8 | exportObject = global.jasmineReporters = global.jasmineReporters || {};
|
9 | }
|
10 |
|
11 | function elapsed(start, end) { return (end - start)/1000; }
|
12 | function isFailed(obj) { return obj.status === "failed"; }
|
13 | function isSkipped(obj) { return obj.status === "pending"; }
|
14 | function isDisabled(obj) { return obj.status === "disabled"; }
|
15 | function extend(dupe, obj) {
|
16 | for (var prop in obj) {
|
17 | if (obj.hasOwnProperty(prop)) {
|
18 | dupe[prop] = obj[prop];
|
19 | }
|
20 | }
|
21 | return dupe;
|
22 | }
|
23 | function log(str) {
|
24 | var con = global.console || console;
|
25 | if (con && con.log && str && str.length) {
|
26 | con.log(str);
|
27 | }
|
28 | }
|
29 |
|
30 |
|
31 | |
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | var DEFAULT_VERBOSITY = 2,
|
46 | ATTRIBUTES_TO_ANSI = {
|
47 | "off": 0,
|
48 | "bold": 1,
|
49 | "red": 31,
|
50 | "green": 32,
|
51 | "yellow": 33,
|
52 | "blue": 34,
|
53 | "magenta": 35,
|
54 | "cyan": 36
|
55 | };
|
56 |
|
57 | exportObject.TerminalReporter = function(options) {
|
58 | var self = this;
|
59 | self.started = false;
|
60 | self.finished = false;
|
61 |
|
62 |
|
63 | options = options || {};
|
64 | self.verbosity = typeof options.verbosity === "number" ? options.verbosity : DEFAULT_VERBOSITY;
|
65 | self.color = options.color;
|
66 | self.showStack = options.showStack;
|
67 |
|
68 | var indent_string = " ",
|
69 | startTime,
|
70 | currentSuite = null,
|
71 | totalSpecsExecuted = 0,
|
72 | totalSpecsSkipped = 0,
|
73 | totalSpecsDisabled = 0,
|
74 | totalSpecsFailed = 0,
|
75 | totalSpecsDefined,
|
76 |
|
77 | fakeFocusedSuite = {
|
78 | id: "focused",
|
79 | description: "focused specs",
|
80 | fullName: "focused specs"
|
81 | };
|
82 |
|
83 | var __suites = {}, __specs = {};
|
84 | function getSuite(suite) {
|
85 | __suites[suite.id] = extend(__suites[suite.id] || {}, suite);
|
86 | return __suites[suite.id];
|
87 | }
|
88 | function getSpec(spec, suite) {
|
89 | __specs[spec.id] = extend(__specs[spec.id] || {}, spec);
|
90 | var ret = __specs[spec.id];
|
91 | if (suite && !ret._suite) {
|
92 | ret._suite = suite;
|
93 | ret._depth = suite._depth+1;
|
94 | suite._specs++;
|
95 | }
|
96 | return ret;
|
97 | }
|
98 |
|
99 | self.jasmineStarted = function(summary) {
|
100 | totalSpecsDefined = summary && summary.totalSpecsDefined || NaN;
|
101 | startTime = exportObject.startTime = new Date();
|
102 | self.started = true;
|
103 | };
|
104 | self.suiteStarted = function(suite) {
|
105 | suite = getSuite(suite);
|
106 | suite._specs = 0;
|
107 | suite._nestedSpecs = 0;
|
108 | suite._failures = 0;
|
109 | suite._nestedFailures = 0;
|
110 | suite._skipped = 0;
|
111 | suite._nestedSkipped = 0;
|
112 | suite._disabled = 0;
|
113 | suite._nestedDisabled = 0;
|
114 | suite._depth = currentSuite ? currentSuite._depth+1 : 1;
|
115 | suite._parent = currentSuite;
|
116 | currentSuite = suite;
|
117 | if (self.verbosity > 2) {
|
118 | log(indentWithLevel(suite._depth, inColor(suite.description, "bold")));
|
119 | }
|
120 | };
|
121 | self.specStarted = function(spec) {
|
122 | if (!currentSuite) {
|
123 |
|
124 | self.suiteStarted(fakeFocusedSuite);
|
125 | }
|
126 | spec = getSpec(spec, currentSuite);
|
127 | if (self.verbosity > 2) {
|
128 | log(indentWithLevel(spec._depth, spec.description + " ..."));
|
129 | }
|
130 | };
|
131 | self.specDone = function(spec) {
|
132 | spec = getSpec(spec, currentSuite);
|
133 | var failed = false,
|
134 | skipped = false,
|
135 | disabled = false,
|
136 | color = "green",
|
137 | resultText = "";
|
138 | if (isSkipped(spec)) {
|
139 | skipped = true;
|
140 | color = "cyan";
|
141 | spec._suite._skipped++;
|
142 | totalSpecsSkipped++;
|
143 | }
|
144 | if (isFailed(spec)) {
|
145 | failed = true;
|
146 | color = "red";
|
147 | spec._suite._failures++;
|
148 | totalSpecsFailed++;
|
149 | }
|
150 | if (isDisabled(spec)) {
|
151 | disabled = true;
|
152 | color = "yellow";
|
153 | spec._suite._disabled++;
|
154 | totalSpecsDisabled++;
|
155 | }
|
156 | totalSpecsExecuted++;
|
157 |
|
158 | if (self.verbosity === 2) {
|
159 | resultText = failed ? "F" : skipped ? "S" : disabled ? "D" : ".";
|
160 | } else if (self.verbosity > 2) {
|
161 | resultText = " " + (failed ? "Failed" : skipped ? "Skipped" : disabled ? "Disabled" : "Passed");
|
162 | }
|
163 | log(inColor(resultText, color));
|
164 |
|
165 | if (skipped && spec.pendingReason) {
|
166 | if (self.verbosity > 2) {
|
167 | log(indentWithLevel(spec._depth, inColor(spec.pendingReason, color)));
|
168 | }
|
169 | else {
|
170 | log(inColor(spec.pendingReason, color));
|
171 | }
|
172 | }
|
173 |
|
174 | if (failed) {
|
175 | if (self.verbosity === 1) {
|
176 | log(spec.fullName);
|
177 | } else if (self.verbosity === 2) {
|
178 | log(" ");
|
179 | log(indentWithLevel(spec._depth, spec.fullName));
|
180 | }
|
181 |
|
182 | for (var i = 0; i < spec.failedExpectations.length; i++) {
|
183 | log(inColor(indentWithLevel(spec._depth, indent_string + spec.failedExpectations[i].message), color));
|
184 | if (self.showStack){
|
185 | logStackLines(spec._depth, spec.failedExpectations[i].stack.split("\n"));
|
186 | }
|
187 | }
|
188 | }
|
189 | };
|
190 | self.suiteDone = function(suite) {
|
191 | suite = getSuite(suite);
|
192 | if (suite._parent === UNDEFINED) {
|
193 |
|
194 | self.suiteStarted(suite);
|
195 | }
|
196 | if (suite._parent) {
|
197 | suite._parent._specs += suite._specs + suite._nestedSpecs;
|
198 | suite._parent._failures += suite._failures + suite._nestedFailures;
|
199 | suite._parent._skipped += suite._skipped + suite._nestedSkipped;
|
200 | suite._parent._disabled += suite._disabled + suite._nestedDisabled;
|
201 |
|
202 | }
|
203 | currentSuite = suite._parent;
|
204 | if (self.verbosity < 3) {
|
205 | return;
|
206 | }
|
207 |
|
208 | var total = suite._specs + suite._nestedSpecs,
|
209 | failed = suite._failures + suite._nestedFailures,
|
210 | skipped = suite._skipped + suite._nestedSkipped,
|
211 | disabled = suite._disabled + suite._nestedDisabled,
|
212 | passed = total - failed - skipped,
|
213 | color = failed ? "red+bold" : "green+bold",
|
214 | str = passed + " of " + total + " passed (" + skipped + " skipped, " + disabled + " disabled)";
|
215 | log(indentWithLevel(suite._depth, inColor(str+".", color)));
|
216 | };
|
217 | self.jasmineDone = function() {
|
218 | if (currentSuite) {
|
219 |
|
220 | self.suiteDone(fakeFocusedSuite);
|
221 | }
|
222 | var now = new Date(),
|
223 | dur = elapsed(startTime, now),
|
224 | total = totalSpecsDefined || totalSpecsExecuted,
|
225 | disabled = total - totalSpecsExecuted + totalSpecsDisabled,
|
226 | skipped = totalSpecsSkipped,
|
227 | spec_str = total + (total === 1 ? " spec, " : " specs, "),
|
228 | fail_str = totalSpecsFailed + (totalSpecsFailed === 1 ? " failure, " : " failures, "),
|
229 | skip_str = skipped + " skipped, ",
|
230 | disabled_str = disabled + " disabled in ",
|
231 | summary_str = spec_str + fail_str + skip_str + disabled_str + dur + "s.",
|
232 | result_str = (totalSpecsFailed && "FAILURE: " || "SUCCESS: ") + summary_str,
|
233 | result_color = totalSpecsFailed && "red+bold" || "green+bold";
|
234 |
|
235 | if (self.verbosity === 2) {
|
236 | log("");
|
237 | }
|
238 |
|
239 | if (self.verbosity > 0) {
|
240 | log(inColor(result_str, result_color));
|
241 | }
|
242 |
|
243 |
|
244 | self.finished = true;
|
245 |
|
246 | exportObject.endTime = now;
|
247 | };
|
248 | function indentWithLevel(level, string) {
|
249 | if (!string || !string.length) {
|
250 | return "";
|
251 | }
|
252 | return new Array(level).join(indent_string) + string;
|
253 | }
|
254 | function logStackLines(depth, lines) {
|
255 | lines.forEach(function(line){
|
256 | log(inColor(indentWithLevel(depth, indent_string + line), "magenta"));
|
257 | });
|
258 | }
|
259 | function inColor(string, color) {
|
260 | var color_attributes = color && color.split("+"),
|
261 | ansi_string = "",
|
262 | i;
|
263 |
|
264 | if (!string || !string.length) {
|
265 | return "";
|
266 | } else if (!self.color || !color_attributes) {
|
267 | return string;
|
268 | }
|
269 |
|
270 | for(i = 0; i < color_attributes.length; i++) {
|
271 | ansi_string += "\u001b[" + ATTRIBUTES_TO_ANSI[color_attributes[i]] + "m";
|
272 | }
|
273 | ansi_string += string + "\u001b[" + ATTRIBUTES_TO_ANSI["off"] + "m";
|
274 |
|
275 | return ansi_string;
|
276 | }
|
277 | };
|
278 | })(this);
|