oojspec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,324 @@
1
+ (function () {
2
+ var isNodeJS = typeof module === "object" && typeof require === "function";
3
+
4
+ if (isNodeJS) {
5
+ buster = require("buster-core");
6
+ buster.stackFilter = require("../stack-filter");
7
+ var util = require("util");
8
+
9
+ try {
10
+ var jsdom = require("jsdom").jsdom;
11
+ } catch (e) {
12
+ // Is handled when someone actually tries using the HTML reporter
13
+ // on node without jsdom
14
+ }
15
+ }
16
+
17
+ var htmlReporter = {
18
+ create: function (opt) {
19
+ var reporter = buster.create(this);
20
+ opt = opt || {};
21
+ reporter.contexts = [];
22
+ reporter.doc = getDoc(opt);
23
+ var cssPath = opt.cssPath;
24
+ if (!cssPath && opt.detectCssPath) cssPath = busterTestPath(reporter.doc) + "buster-test.css";
25
+ reporter.setRoot(opt.root || reporter.doc.body, cssPath);
26
+ reporter.io = opt.io || (isNodeJS && require("util"));
27
+
28
+ return reporter;
29
+ },
30
+
31
+ setRoot: function (root, cssPath) {
32
+ this.root = root;
33
+ this.root.className += " buster-test";
34
+ var body = this.doc.body;
35
+
36
+ if (this.root == body) {
37
+ var head = this.doc.getElementsByTagName("head")[0];
38
+ head.parentNode.className += " buster-test";
39
+
40
+ head.appendChild(el(this.doc, "meta", {
41
+ "name": "viewport",
42
+ "content": "width=device-width, initial-scale=1.0"
43
+ }));
44
+
45
+ head.appendChild(el(this.doc, "meta", {
46
+ "http-equiv": "Content-Type",
47
+ "content": "text/html; charset=utf-8"
48
+ }));
49
+
50
+ if (cssPath) addCSS(head, cssPath);
51
+ insertTitle(this.doc, body, this.doc.title || "Buster.JS Test case");
52
+ insertLogo(this.doc.getElementsByTagName("h1")[0]);
53
+ }
54
+ },
55
+
56
+ listen: function (runner) {
57
+ runner.bind(this, {
58
+ "context:start": "contextStart", "context:end": "contextEnd",
59
+ "test:success": "testSuccess", "test:failure": "testFailure",
60
+ "test:error": "testError", "test:timeout": "testTimeout",
61
+ "test:deferred": "testDeferred", "suite:end": "addStats"
62
+ });
63
+
64
+ if (runner.console) {
65
+ runner.console.bind(this, "log");
66
+ }
67
+
68
+ return this;
69
+ },
70
+
71
+ contextStart: function (context) {
72
+ if (this.contexts.length == 0) {
73
+ this.root.appendChild(el(this.doc, "h2", { text: context.name }));
74
+ }
75
+
76
+ this.startedAt = new Date();
77
+ this.contexts.push(context.name);
78
+ },
79
+
80
+ contextEnd: function (context) {
81
+ this.contexts.pop();
82
+ this._list = null;
83
+ },
84
+
85
+ testSuccess: function (test) {
86
+ var li = addListItem.call(this, "h3", test, "success");
87
+ this.addMessages(li);
88
+ },
89
+
90
+ testFailure: function (test) {
91
+ var li = addListItem.call(this, "h3", test, "failure");
92
+ this.addMessages(li);
93
+ addException(li, test.error);
94
+ },
95
+
96
+ testError: function (test) {
97
+ var li = addListItem.call(this, "h3", test, "error");
98
+ this.addMessages(li);
99
+ addException(li, test.error);
100
+ },
101
+
102
+ testDeferred: function (test) {
103
+ var li = addListItem.call(this, "h3", test, "deferred");
104
+ },
105
+
106
+ testTimeout: function (test) {
107
+ var li = addListItem.call(this, "h3", test, "timeout");
108
+ var source = test.error && test.error.source;
109
+ if (source) {
110
+ li.firstChild.innerHTML += " (" + source + " timed out)";
111
+ }
112
+ this.addMessages(li);
113
+ },
114
+
115
+ log: function (msg) {
116
+ this.messages = this.messages || [];
117
+ this.messages.push(msg);
118
+ },
119
+
120
+ addMessages: function (li) {
121
+ var messages = this.messages || [];
122
+ var html = "";
123
+
124
+ if (messages.length == 0) {
125
+ return;
126
+ }
127
+
128
+ for (var i = 0, l = messages.length; i < l; ++i) {
129
+ html += "<li class=\"" + messages[i].level + "\">";
130
+ html += messages[i].message + "</li>";
131
+ }
132
+
133
+ li.appendChild(el(this.doc, "ul", {
134
+ className: "messages",
135
+ innerHTML: html
136
+ }));
137
+
138
+ this.messages = [];
139
+ },
140
+
141
+ success: function (stats) {
142
+ return stats.failures == 0 && stats.errors == 0 &&
143
+ stats.tests > 0 && stats.assertions > 0;
144
+ },
145
+
146
+ addStats: function (stats) {
147
+ var diff = (new Date() - this.startedAt) / 1000;
148
+
149
+ var className = "stats " + (this.success(stats) ? "success" : "failure");
150
+ var statsEl = el(this.doc, "div", { className: className });
151
+
152
+ var h1 = this.doc.getElementsByTagName("h1")[0];
153
+ this.root.insertBefore(statsEl, h1.nextSibling);
154
+
155
+ statsEl.appendChild(el(this.doc, "h2", {
156
+ text: this.success(stats) ? "Tests OK" : "Test failures!"
157
+ }));
158
+
159
+ var html = "";
160
+ html += "<li>" + pluralize(stats.contexts, "test case") + "</li>";
161
+ html += "<li>" + pluralize(stats.tests, "test") + "</li>";
162
+ html += "<li>" + pluralize(stats.assertions, "assertion") + "</li>";
163
+ html += "<li>" + pluralize(stats.failures, "failure") + "</li>";
164
+ html += "<li>" + pluralize(stats.errors, "error") + "</li>";
165
+ html += "<li>" + pluralize(stats.timeouts, "timeout") + "</li>";
166
+
167
+ if (stats.deferred > 0) {
168
+ html += "<li>" + stats.deferred + " deferred</li>";
169
+ }
170
+
171
+ statsEl.appendChild(el(this.doc, "ul", { innerHTML: html }));
172
+ statsEl.appendChild(el(this.doc, "p", {
173
+ className: "time",
174
+ innerHTML: "Finished in " + diff + "s"
175
+ }));
176
+
177
+ this.writeIO();
178
+ },
179
+
180
+ list: function () {
181
+ if (!this._list) {
182
+ this._list = el(this.doc, "ul", { className: "test-results" });
183
+ this.root.appendChild(this._list);
184
+ }
185
+
186
+ return this._list;
187
+ },
188
+
189
+ writeIO: function () {
190
+ if (!this.io) return;
191
+ this.io.puts(this.doc.doctype.toString());
192
+ this.io.puts(this.doc.innerHTML);
193
+ }
194
+ };
195
+
196
+ function getDoc(options) {
197
+ return options && options.document ||
198
+ (typeof document != "undefined" ? document : createDocument());
199
+ }
200
+
201
+ function addCSS(head, cssPath) {
202
+ if (isNodeJS) {
203
+ var fs = require("fs");
204
+ var path = require("path");
205
+
206
+ head.appendChild(el(head.ownerDocument, "style", {
207
+ type: "text/css",
208
+ innerHTML: fs.readFileSync(path.join(__dirname, "../../../resources/buster-test.css"))
209
+ }));
210
+ } else {
211
+ head.appendChild(el(document, "link", {
212
+ rel: "stylesheet",
213
+ type: "text/css",
214
+ media: "all",
215
+ href: cssPath
216
+ }));
217
+ }
218
+ }
219
+
220
+ function insertTitle(doc, body, title) {
221
+ if (doc.getElementsByTagName("h1").length == 0) {
222
+ body.insertBefore(el(doc, "h1", {
223
+ innerHTML: "<span class=\"title\">" + title + "</span>"
224
+ }), body.firstChild);
225
+ }
226
+ }
227
+
228
+ function insertLogo(h1) {
229
+ h1.innerHTML = "<span class=\"buster-logo\"></span>" + h1.innerHTML;
230
+ }
231
+
232
+ function createDocument() {
233
+ if (!jsdom) {
234
+ util.puts("Unable to load jsdom, html reporter will not work " +
235
+ "for node runs. Spectacular fail coming up.");
236
+ }
237
+ var dom = jsdom("<!DOCTYPE html><html><head></head><body></body></html>");
238
+ return dom.createWindow().document;
239
+ }
240
+
241
+ function pluralize(num, phrase) {
242
+ num = typeof num == "undefined" ? 0 : num;
243
+ return num + " " + (num == 1 ? phrase : phrase + "s");
244
+ }
245
+
246
+ function el(doc, tagName, properties) {
247
+ var el = doc.createElement(tagName), value;
248
+
249
+ for (var prop in properties) {
250
+ value = properties[prop];
251
+
252
+ if (prop == "http-equiv") {
253
+ el.setAttribute(prop, value);
254
+ }
255
+
256
+ if (prop == "text") {
257
+ prop = "innerHTML";
258
+ }
259
+
260
+ el[prop] = value;
261
+ }
262
+
263
+ return el;
264
+ }
265
+
266
+ function addListItem(tagName, test, className) {
267
+ var prefix = tagName ? "<" + tagName + ">" : "";
268
+ var suffix = tagName ? "</" + tagName + ">" : "";
269
+ var name = this.contexts.slice(1).join(" ") + " " + test.name;
270
+
271
+ var item = el(this.doc, "li", {
272
+ className: className,
273
+ text: prefix + name.replace(/^\s+|\s+$/, "") + suffix
274
+ });
275
+
276
+ this.list().appendChild(item);
277
+ return item;
278
+ }
279
+
280
+ function addException(li, error) {
281
+ if (!error) {
282
+ return;
283
+ }
284
+
285
+ var name = error.name == "AssertionError" ? "" : error.name + ": ";
286
+
287
+ li.appendChild(el(li.ownerDocument || document, "p", {
288
+ innerHTML: name + error.message,
289
+ className: "error-message"
290
+ }));
291
+
292
+ var stack = buster.stackFilter(error.stack) || [];
293
+
294
+ if (stack.length > 0) {
295
+ if (stack[0].indexOf(error.message) >= 0) {
296
+ stack.shift();
297
+ }
298
+
299
+ li.appendChild(el(li.ownerDocument || document, "ul", {
300
+ className: "stack",
301
+ innerHTML: "<li>" + stack.join("</li><li>") + "</li>"
302
+ }));
303
+ }
304
+ }
305
+
306
+ function busterTestPath(document) {
307
+ var scripts = document.getElementsByTagName("script");
308
+
309
+ for (var i = 0, l = scripts.length; i < l; ++i) {
310
+ if (/buster-test\.js$/.test(scripts[i].src)) {
311
+ return scripts[i].src.replace("buster-test.js", "");
312
+ }
313
+ }
314
+
315
+ return "";
316
+ }
317
+
318
+ if (typeof module == "object" && module.exports) {
319
+ module.exports = htmlReporter;
320
+ } else {
321
+ buster.reporters = buster.reporters || {};
322
+ buster.reporters.html = htmlReporter;
323
+ }
324
+ }());
@@ -0,0 +1,63 @@
1
+ if (typeof module === "object" && typeof require === "function") {
2
+ var buster = require("buster-core");
3
+ }
4
+
5
+ buster.stackFilter = function (stack, cwd) {
6
+ var lines = (stack || "").split("\n");
7
+ var stackLines = [], line, replacer = "./";
8
+
9
+ if (typeof cwd == "string") {
10
+ cwd = cwd.replace(/\/?$/, "/");
11
+ }
12
+
13
+ if (cwd instanceof RegExp && !/\/\/$/.test(cwd)) {
14
+ replacer = ".";
15
+ }
16
+
17
+ for (var i = 0, l = lines.length; i < l; ++i) {
18
+ if (/(\d+)?:\d+\)?$/.test(lines[i])) {
19
+ if (!buster.stackFilter.match(lines[i])) {
20
+ line = lines[i].replace(/^\s+|\s+$/g, "");
21
+
22
+ if (cwd) {
23
+ line = line.replace(cwd, replacer);
24
+ }
25
+
26
+ stackLines.push(line);
27
+ }
28
+ }
29
+ }
30
+
31
+ return stackLines;
32
+ };
33
+
34
+ var regexpes = {};
35
+
36
+ buster.stackFilter.match = function (line) {
37
+ var filters = buster.stackFilter.filters;
38
+
39
+ for (var i = 0, l = filters.length; i < l; ++i) {
40
+ if (!regexpes[filters[i]]) {
41
+ regexpes[filters[i]] = new RegExp(filters[i]);
42
+ }
43
+
44
+ if (regexpes[filters[i]].test(line)) {
45
+ return true;
46
+ }
47
+ }
48
+
49
+ return false;
50
+ }
51
+
52
+ buster.stackFilter.filters = ["buster-assertions/lib",
53
+ "buster-test/lib",
54
+ "buster-util/lib",
55
+ "buster-core/lib",
56
+ "node.js",
57
+ "/buster/lib",
58
+ "/buster/node_modules",
59
+ "static/runner.js"/* JsTestDriver */];
60
+
61
+ if (typeof module != "undefined") {
62
+ module.exports = buster.stackFilter;
63
+ }
@@ -0,0 +1,201 @@
1
+ .buster-test,
2
+ html.buster-test {
3
+ margin: 0;
4
+ padding: 0;
5
+ }
6
+
7
+ .buster-test,
8
+ body.buster-test {
9
+ font-family: Georgia, Times, serif;
10
+ font-size: 16px;
11
+ padding: 0 12px;
12
+ }
13
+
14
+ .buster-test h2 {
15
+ display: inline-block;
16
+ font-weight: normal;
17
+ margin: 0 0 0.25em;
18
+ }
19
+
20
+ .buster-test ul {
21
+ margin: 0 0 1em 2em;
22
+ padding: 0;
23
+ }
24
+
25
+ .buster-test ul + ul {
26
+ margin-top: -1em;
27
+ }
28
+
29
+ .buster-test ul li {
30
+ list-style: none;
31
+ }
32
+
33
+ .buster-test li h3 {
34
+ display: inline-block;
35
+ font-size: 1.2em;
36
+ margin: 0 0 .25em;
37
+ padding: 0;
38
+ }
39
+
40
+ .buster-test li ul,
41
+ .buster-test li p {
42
+ margin: 0 0 0.5em 2em;
43
+ }
44
+
45
+ .buster-test .success h3:before {
46
+ color: #3c3;
47
+ content: "✓";
48
+ padding-right: 6px;
49
+ }
50
+
51
+ .buster-test .timeout h3,
52
+ .buster-test .failure h3,
53
+ .buster-test .error-message,
54
+ .buster-test .stats.failure {
55
+ color: #c33;
56
+ }
57
+
58
+ .buster-test .stats.success {
59
+ color: #3c3;
60
+ }
61
+
62
+ .buster-test .error h3,
63
+ .buster-test .error .error-message {
64
+ color: #cc3;
65
+ }
66
+
67
+ .buster-test .failure h3:before,
68
+ .buster-test .error h3:before {
69
+ content: "✖";
70
+ padding-right: 6px;
71
+ }
72
+
73
+ .buster-test .deferred h3 {
74
+ color: #33c;
75
+ }
76
+
77
+ .buster-test .deferred h3:before {
78
+ content: "✎";
79
+ padding-right: 6px;
80
+ }
81
+
82
+ .buster-test .stats ul {
83
+ margin: 0 0 1em;
84
+ }
85
+
86
+ .buster-test .stats h2 {
87
+ margin: 0 0 .25em;
88
+ }
89
+
90
+ .buster-test .stats li {
91
+ display: inline;
92
+ padding-right: 1em;
93
+ }
94
+
95
+ .buster-test p,
96
+ .buster-test li {
97
+ line-height: 1.5;
98
+ }
99
+
100
+ .buster-test h1,
101
+ .buster-test h2,
102
+ .buster-test h3,
103
+ .buster-test h4,
104
+ .buster-test h5,
105
+ .buster-test h6,
106
+ .buster-test p {
107
+ font-weight: normal;
108
+ margin: 0 0 1em;
109
+ }
110
+
111
+ .buster-test ul {
112
+ margin: 0 0 1em 15px;
113
+ }
114
+
115
+ /* Masthead */
116
+ .buster-test h1 {
117
+ background: #333;
118
+
119
+ background: -webkit-gradient(
120
+ linear,
121
+ left top,
122
+ left bottom,
123
+ from(#5f5f5f),
124
+ to(#222)
125
+ );
126
+
127
+ background: -moz-linear-gradient(
128
+ top center,
129
+ #5f5f5f,
130
+ #222
131
+ );
132
+
133
+ /* For Internet Explorer 5.5 - 7 */
134
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff5f5f5f, endColorstr=#ff222222);
135
+ /* For Internet Explorer 8 */
136
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#ff5f5f5f, endColorstr=#ff222222)";
137
+ zoom: 1;
138
+
139
+ border-bottom: 4px solid #c0c6cc;
140
+ box-shadow: 0 0 10px #ddd;
141
+ -moz-box-shadow: 0 0 10px #ddd;
142
+ -webkit-box-shadow: 0 0 10px #ddd;
143
+ color: #fff;
144
+ font-size: 2em;
145
+ margin: 0 -12px 1em;
146
+ overflow: auto;
147
+ padding: 6px 12px;
148
+ }
149
+
150
+ .buster-test h1 a {
151
+ color: #fff;
152
+ padding-right: 1em;
153
+ text-decoration: none;
154
+ }
155
+
156
+ .buster-test h1 .buster-logo {
157
+ background-repeat: no-repeat;
158
+ background-image: url(data:image/png;base64,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);
159
+ float: left;
160
+ height: 71px;
161
+ margin-right: 20px;
162
+ width: 200px;
163
+ }
164
+
165
+ .buster-test h1 .title {
166
+ border-left: 1px solid #aaa;
167
+ float: left;
168
+ padding: 30px 0 0 20px;
169
+ }
170
+
171
+ .buster-test .messages li:before {
172
+ background: #f0f0f0;
173
+ border-radius: 6px;
174
+ -moz-border-radius: 6px;
175
+ -webkit-border-radius: 6px;
176
+ border: 1px solid #ccc;
177
+ display: inline-block;
178
+ font-family: monospace;
179
+ font-size: 10px;
180
+ font-variant: small-caps;
181
+ margin-right: 1em;
182
+ padding: 0 4px;
183
+ }
184
+
185
+ .buster-test .log:before {
186
+ content: "LOG";
187
+ }
188
+
189
+ .buster-test .info:before {
190
+ content: "INFO";
191
+ }
192
+
193
+ .buster-test .messages .warn:before {
194
+ content: "WARN";
195
+ border-color: #cc3;
196
+ }
197
+
198
+ .buster-test .messages .error:before {
199
+ content: "ERR";
200
+ border-color: #c00;
201
+ }