forked from xjamundx/jshint-junit-reporter
-
Notifications
You must be signed in to change notification settings - Fork 2
/
reporter.js
134 lines (104 loc) · 3.05 KB
/
reporter.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*jshint node:true */
"use strict";
var fs = require('fs');
var suite = 'jshint';
var wrStream;
var outputFile;
function encode(s) {
var pairs = {
"&": "&",
'"': """,
"'": "'",
"<": "<",
">": ">"
};
for (var r in pairs) {
if (typeof(s) !== "undefined") {
s = s.replace(new RegExp(r, "g"), pairs[r]);
}
}
return s || "";
}
function failure_message(failures) {
var count = failures.length;
if (count === 1) {
return "1 JSHINT Failure";
} else {
return count + " JSHint Failures";
}
}
function failure_details(failures) {
var msg = [];
var item;
for (var i = 0; i < failures.length; i++) {
item = failures[i];
msg.push(i+1 + ". line " + item.line + ", char " + item.character + ": " + encode(item.reason));
}
return msg.join("\n");
}
//jsxhint stores the files in a tmp dir
//this means the data list and the results array don't match
//to remedy we can loop through list and remove the non-matching string
function getMatchingResultFileName(file, failureList) {
for (var failureFile in failureList) {
//if the end of the file provided identically matches that in the failures list
//the files will be the same just 1 has a bunch of tmpdir rubbish at the front.
//return the failureFile link
if (file.indexOf(failureFile) === (file.length-failureFile.length)) {
return failureFile;
}
}
return file;
}
exports.reporter = function (results, data, opts) {
var out = [];
var files = {};
opts = opts || {};
opts.outputFile = opts.outputFile || null;
if (opts.outputFile && !outputFile)
outputFile = opts.outputFile;
results.forEach(function (result) {
result.file = result.file.replace(/^\.\//, '');
if (!files[result.file]) {
files[result.file] = [];
}
files[result.file].push(result.error);
});
out.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
out.push("<testsuite name=\"" + suite + "\" tests=\"" + (data.length || 0) + "\" failures=\"" + results.length + "\" errors=\"0\">");
// we need at least 1 empty test
if (!results.length) {
out.push("\t<testcase name=\"" + suite + "\" />");
}
for (var i = 0; i < data.length; i++) {
var fileName = data[i].file;
//so this works with jsxhint as well
//jsxhint puts the files into a cache dir
//but doesn't change the location of the results to match
//so we have to work around it
if (fileName.indexOf('/jsxhint/') > -1) {
fileName = getMatchingResultFileName(fileName, files);
}
//jshint seems to shove itself at the start in some versions
if (fileName !== 'jshint') {
//has an error
if (files[fileName]) {
out.push("\t<testcase name=\"" + fileName + "\">");
out.push("\t\t<failure message=\"" + failure_message(files[fileName]) + "\">");
out.push(failure_details(files[fileName]));
out.push("\t\t</failure>");
out.push("\t</testcase>");
} else {
out.push("\t<testcase name=\"" + fileName + "\" />");
}
}
}
out.push("</testsuite>");
if (outputFile) {
fs.writeFileSync(outputFile, out.join('\n'));
} else {
out = out.join("\n") + "\n";
process.stdout.write(out);
}
return out;
};