1 |
|
2 | var jasmineReporters = require("../index");
|
3 | var DOMParser = require("@xmldom/xmldom").DOMParser;
|
4 |
|
5 | var env, suite, subSuite, subSubSuite, siblingSuite,
|
6 | reporter, writeCalls, suiteId=0, specId=0, noop=function(){};
|
7 | function fakeSpec(ste, name) {
|
8 | var s = new jasmine.Spec({
|
9 | env: env,
|
10 | id: specId++,
|
11 | description: name,
|
12 | queueableFn: {fn: noop},
|
13 | });
|
14 | ste.addChild(s);
|
15 | return s;
|
16 | }
|
17 | function fakeSuite(name, parentSuite) {
|
18 | var s = new jasmine.Suite({
|
19 | env: env,
|
20 | id: suiteId++,
|
21 | description: name,
|
22 | parentSuite: parentSuite || jasmine.createSpy("pretend top suite")
|
23 | });
|
24 | if (parentSuite) {
|
25 | parentSuite.addChild(s);
|
26 | }
|
27 | else {
|
28 |
|
29 | env._suites = env._suites || [];
|
30 | env._suites.push(s);
|
31 | }
|
32 | return s;
|
33 | }
|
34 |
|
35 | function setupReporterWithOptions(options) {
|
36 | reporter = new jasmineReporters.NUnitXmlReporter(options);
|
37 | reporter.writeFile = jasmine.createSpy();
|
38 | }
|
39 |
|
40 |
|
41 | function triggerRunnerEvents() {
|
42 | reporter.jasmineStarted();
|
43 | for (var i=0; i<env._suites.length; i++) {
|
44 | var s = env._suites[i];
|
45 | triggerSuiteEvents(s);
|
46 | }
|
47 | reporter.jasmineDone();
|
48 |
|
49 |
|
50 | writeCalls = reporter.writeFile.calls.all();
|
51 | for (i=0; i<writeCalls.length; i++) {
|
52 | writeCalls[i].output = writeCalls[i].args[0];
|
53 | writeCalls[i].xmldoc = xmlDocumentFromString(writeCalls[i].output);
|
54 | }
|
55 | }
|
56 | function triggerSuiteEvents(ste) {
|
57 | reporter.suiteStarted(ste.result);
|
58 | var thing;
|
59 | for (var i=0; i<ste.children.length; i++) {
|
60 | thing = ste.children[i];
|
61 | if (thing instanceof jasmine.Suite) {
|
62 | triggerSuiteEvents(thing);
|
63 | } else {
|
64 | reporter.specStarted(thing.result);
|
65 | reporter.specDone(thing.result);
|
66 | }
|
67 | }
|
68 | reporter.suiteDone(ste.result);
|
69 | }
|
70 |
|
71 | function xmlDocumentFromString(str) {
|
72 | return (new DOMParser()).parseFromString(str, "text/xml");
|
73 | }
|
74 |
|
75 | describe("NUnitXmlReporter", function(){
|
76 |
|
77 | beforeEach(function(){
|
78 | env = new jasmine.Env();
|
79 | suite = fakeSuite("ParentSuite");
|
80 | subSuite = fakeSuite("SubSuite", suite);
|
81 | subSubSuite = fakeSuite("SubSubSuite", subSuite);
|
82 | siblingSuite = fakeSuite("SiblingSuite With Invalid Chars & < > \" ' | : \\ /");
|
83 | fakeSpec(suite, "should be a dummy with invalid characters: & < >");
|
84 | var failedSpec = fakeSpec(subSubSuite, "should be failed");
|
85 | failedSpec.result.status = "failed";
|
86 | failedSpec.result.failedExpectations.push({
|
87 | passed: false,
|
88 | message: "Expected true to be false.",
|
89 | expected: false,
|
90 | actual: true,
|
91 | matcherName: "toBe",
|
92 | stack: 'Stack trace! Stack trackes are cool & can have "special" characters <3\n\n Neat: yes.'
|
93 | });
|
94 | fakeSpec(subSuite, "should be one level down");
|
95 | fakeSpec(subSubSuite, "(1) should be two levels down");
|
96 | fakeSpec(subSubSuite, "(2) should be two levels down");
|
97 | fakeSpec(subSubSuite, "(3) should be two levels down");
|
98 | fakeSpec(siblingSuite, "should be a sibling of Parent");
|
99 | setupReporterWithOptions({reportName: "<Bad Character Report>"});
|
100 | });
|
101 |
|
102 | describe("constructor", function(){
|
103 | beforeEach(function() {
|
104 | setupReporterWithOptions();
|
105 | });
|
106 | it("should default path to an empty string", function(){
|
107 | expect(reporter.savePath).toBe("");
|
108 | });
|
109 | it("should allow a custom path to be provided", function() {
|
110 | setupReporterWithOptions({savePath:"/tmp"});
|
111 | expect(reporter.savePath).toBe("/tmp");
|
112 | });
|
113 | it("should default filename to 'nunitresults.xml'", function(){
|
114 | expect(reporter.filename).toBe("nunitresults.xml");
|
115 | });
|
116 | it("should allow a custom filename to be provided", function() {
|
117 | setupReporterWithOptions({filename:"results.xml"});
|
118 | expect(reporter.filename).toBe("results.xml");
|
119 | });
|
120 | it("should default reportName to 'Jasmine Results'", function(){
|
121 | expect(reporter.reportName).toBe("Jasmine Results");
|
122 | });
|
123 | it("should allow a custom reportName to be provided", function() {
|
124 | setupReporterWithOptions({reportName:"Test Results"});
|
125 | expect(reporter.reportName).toBe("Test Results");
|
126 | });
|
127 | });
|
128 |
|
129 | describe("generated xml output", function(){
|
130 | var output, xmldoc;
|
131 |
|
132 | beforeEach(function(){
|
133 | triggerRunnerEvents();
|
134 | output = writeCalls[0].output;
|
135 | xmldoc = writeCalls[0].xmldoc;
|
136 | });
|
137 | it("should escape invalid xml chars from report name", function() {
|
138 | expect(output).toContain('name="<Bad Character Report>"');
|
139 | });
|
140 | it("should escape invalid xml chars from suite names", function() {
|
141 | expect(output).toContain('name="SiblingSuite With Invalid Chars & < > " ' | : \\ /"');
|
142 | });
|
143 | it("should escape invalid xml chars from spec names", function() {
|
144 | expect(output).toContain('name="should be a dummy with invalid characters: & < >');
|
145 | });
|
146 | describe("xml structure", function() {
|
147 | var rootNode, suites, specs;
|
148 | beforeEach(function() {
|
149 | rootNode = xmldoc.getElementsByTagName("test-results")[0];
|
150 | suites = rootNode.getElementsByTagName("test-suite");
|
151 | specs = rootNode.getElementsByTagName("test-case");
|
152 | });
|
153 | it("should report the date / time that the tests were run", function() {
|
154 | expect(rootNode.getAttribute("date")).toMatch(/\d{4}-\d{2}-\d{2}/);
|
155 | expect(rootNode.getAttribute("time")).toMatch(/\d{2}:\d{2}:\d{2}/);
|
156 | });
|
157 | it("should report the appropriate number of suites", function() {
|
158 | expect(suites.length).toBe(4);
|
159 | });
|
160 | it("should order suites appropriately", function() {
|
161 | expect(suites[0].getAttribute("name")).toContain("ParentSuite");
|
162 | expect(suites[1].getAttribute("name")).toContain("SubSuite");
|
163 | expect(suites[2].getAttribute("name")).toContain("SubSubSuite");
|
164 | expect(suites[3].getAttribute("name")).toContain("SiblingSuite");
|
165 | });
|
166 | it("should nest suites appropriately", function() {
|
167 | expect(suites[0].parentNode).toBe(rootNode);
|
168 | expect(suites[1].parentNode).toBe(suites[0].getElementsByTagName("results")[0]);
|
169 | expect(suites[2].parentNode).toBe(suites[1].getElementsByTagName("results")[0]);
|
170 | expect(suites[3].parentNode).toBe(rootNode);
|
171 | });
|
172 | it("should report the execution time for test specs", function() {
|
173 | var time;
|
174 | for (var i = 0; i < specs.length; i++) {
|
175 | time = specs[i].getAttribute("time");
|
176 | expect(time.length).toBeGreaterThan(0);
|
177 | expect(time).not.toContain(":");
|
178 | }
|
179 | });
|
180 | it("should include a test-case for each spec and report the total number of specs on the root node", function() {
|
181 | expect(rootNode.getAttribute("total")).toBe(specs.length.toString());
|
182 | });
|
183 | describe("passed specs", function() {
|
184 | it("should indicate that the test case was successful", function() {
|
185 | expect(specs[1].getAttribute("success")).toBe("true");
|
186 | });
|
187 | });
|
188 | describe("failed specs", function() {
|
189 | var failedSpec;
|
190 | beforeEach(function() {
|
191 | failedSpec = rootNode.getElementsByTagName("message")[0].parentNode.parentNode;
|
192 | });
|
193 | it("should indicate that the test case was not successful", function() {
|
194 | expect(failedSpec.getAttribute("success")).toBe("false");
|
195 | });
|
196 | it("should include the error for failed specs", function() {
|
197 | expect(failedSpec.getElementsByTagName("message")[0].textContent).toBe("Expected true to be false.");
|
198 | });
|
199 | it("should include the stack trace for failed specs", function() {
|
200 | expect(failedSpec.getElementsByTagName("stack-trace")[0].textContent).toContain('cool & can have "special" characters <3');
|
201 | });
|
202 | it("should report the failure on ancestor suite nodes", function() {
|
203 | var parentSuite = failedSpec.parentNode.parentNode;
|
204 | var grandparentSuite = parentSuite.parentNode.parentNode;
|
205 | expect(parentSuite.getAttribute("success")).toBe("false");
|
206 | expect(grandparentSuite.getAttribute("success")).toBe("false");
|
207 | });
|
208 | it("should report the number of failed specs on the root node", function() {
|
209 | expect(rootNode.getAttribute("failures")).toBe("1");
|
210 | });
|
211 | });
|
212 | });
|
213 | });
|
214 | });
|
215 |
|