Coverage

63%
61
39
22

/home/ubuntu/src/github.com/dalekjs/dalek-reporter-json/index.js

63%
61
39
22
LineHitsSource
1/*!
2 *
3 * Copyright (c) 2013 Sebastian Golasch
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 */
24
251'use strict';
26
27// ext. libs
281var fs = require('fs');
291var path = require('path');
30
31// int. global
321var reporter = null;
33
34/**
35 * The JSON reporter can produce a file with the results of your testrun.
36 *
37 * The reporter can be installed with the following command:
38 * ```
39 * $ npm install dalek-reporter-json --save-dev
40 * ```
41 *
42 * The file will follow the following format. This is a first draft and will
43 * definitly change in future versions.
44 *
45 * ```javascript
46 * {
47 * "tests": [
48 * {
49 * "id": "test806",
50 * "name": "Can get !url (OK, TDD style, message, chained)",
51 * "browser": "Chrome",
52 * "status": true,
53 * "passedAssertions": 1,
54 * "failedAssertions": 0,
55 * "actions": [
56 * {
57 * "value": "http://localhost:5000/index.html",
58 * "type": "open",
59 * "uuid": "6ea84fc0-58bf-4e1f-bb9c-f035c6e6fae2",
60 * "kind": "action",
61 * "isAction": true
62 * },
63 * {
64 * "success": true,
65 * "expected": "http://localhost:5000/guinea.html",
66 * "value": "http://localhost:5000/index.html",
67 * "message": "Url is not whatever",
68 * "type": "url",
69 * "kind": "assertion",
70 * "isAssertion": true
71 * }
72 * ]
73 * }
74 * ],
75 * "elapsedTime": {
76 * "minutes": 1,
77 * "seconds": 43.328535046
78 * },
79 * "status": true,
80 * "assertions": 1,
81 * "assertionsFailed": 0,
82 * "assertionsPassed": 1
83 * }
84 * ```
85 *
86 * By default the file will be written to `report/dalek.json`,
87 * you can change this by adding a config option to the your Dalekfile
88 *
89 * ```javascript
90 * "json-reporter": {
91 * "dest": "your/folder/your_file.json"
92 * }
93 * ```
94 *
95 * @class Reporter
96 * @constructor
97 * @part JSON
98 * @api
99 */
100
1011function Reporter (opts) {
1021 this.events = opts.events;
1031 this.config = opts.config;
1041 this.data = {};
1051 this.actionQueue = [];
1061 this.data.tests = [];
1071 this.browser = null;
108
1091 var defaultReportFolder = 'report';
1101 this.dest = this.config.get('json-reporter') && this.config.get('json-reporter').dest ? this.config.get('json-reporter').dest : defaultReportFolder;
111
1121 this.startListening();
113}
114
115/**
116 * @module Reporter
117 */
118
1191module.exports = function (opts) {
1206 if (reporter === null) {
1211 reporter = new Reporter(opts);
122 }
123
1246 return reporter;
125};
126
1271Reporter.prototype = {
128
129 /**
130 * Connects to all the event listeners
131 *
132 * @method startListening
133 * @chainable
134 */
135
136 startListening: function () {
1371 this.events.on('report:run:browser', this.runBrowser.bind(this));
1381 this.events.on('report:assertion', this.assertion.bind(this));
1391 this.events.on('report:action', this.action.bind(this));
1401 this.events.on('report:test:started', this.testStarted.bind(this));
1411 this.events.on('report:test:finished', this.testFinished.bind(this));
1421 this.events.on('report:runner:finished', this.runnerFinished.bind(this));
1431 return this;
144 },
145
146 /**
147 * Stores the current browser name
148 *
149 * @method runBrowser
150 * @param {string} browser Browser name
151 * @chainable
152 */
153
154 runBrowser: function (browser) {
1553 this.browser = browser;
1563 return this;
157 },
158
159 /**
160 * Generates JSON for an action
161 *
162 * @method action
163 * @param {object} data Event data
164 * @chainable
165 */
166
167 action: function (data) {
1681 data.kind = 'action';
1691 this.actionQueue.push(data);
1701 return this;
171 },
172
173 /**
174 * Generates JSON for an assertion
175 *
176 * @method assertion
177 * @param {object} data Event data
178 * @chainable
179 */
180
181 assertion: function (data) {
1821 data.kind = 'assertion';
1831 this.actionQueue.push(data);
1841 return this;
185 },
186
187 /**
188 * Sets up a new testcase
189 *
190 * @method testStarted
191 * @param {object} data Event data
192 * @chainable
193 */
194
195 testStarted: function (data) {
1961 this.currentTest = data;
1971 this.actionQueue = [];
1981 return this;
199 },
200
201 /**
202 * Writes data for a finished testcase
203 *
204 * @method testFinished
205 * @param {object} data Event data
206 * @chainable
207 */
208
209 testFinished: function (data) {
2101 this.data.tests.push({
211 id: data.id,
212 name: data.name,
213 browser: this.browser,
214 status: data.status,
215 passedAssertions: data.passedAssertions,
216 failedAssertions: data.failedAssertions,
217 actions: this.actionQueue
218 });
2191 return this;
220 },
221
222 /**
223 * Serializes JSON and writes file to the file system
224 *
225 * @method runnerFinished
226 * @param {object} data Event data
227 * @chainable
228 */
229
230 runnerFinished: function (data) {
2310 this.data.elapsedTime = data.elapsedTime;
2320 this.data.status = data.status;
2330 this.data.assertions = data.assertions;
2340 this.data.assertionsFailed = data.assertionsFailed;
2350 this.data.assertionsPassed = data.assertionsPassed;
236
2370 var contents = JSON.stringify(this.data, false, 4);
238
2390 if (path.extname(this.dest) !== '.json') {
2400 this.dest = this.dest + '/dalek.json';
241 }
242
2430 this.events.emit('report:written', {type: 'json', dest: this.dest});
2440 this._recursiveMakeDirSync(path.dirname(this.dest.replace(path.basename(this.dest, ''))));
2450 fs.writeFileSync(this.dest, contents, 'utf8');
2460 return this;
247 },
248
249 /**
250 * Helper method to generate deeper nested directory structures
251 *
252 * @method _recursiveMakeDirSync
253 * @param {string} path PAth to create
254 */
255
256 _recursiveMakeDirSync: function (path) {
2570 var pathSep = require('path').sep;
2580 var dirs = path.split(pathSep);
2590 var root = '';
260
2610 while (dirs.length > 0) {
2620 var dir = dirs.shift();
2630 if (dir === '') {
2640 root = pathSep;
265 }
2660 if (!fs.existsSync(root + dir)) {
2670 fs.mkdirSync(root + dir);
268 }
2690 root += dir + pathSep;
270 }
271 }
272};
273