UNPKG

8.8 kBJavaScriptView Raw
1'use strict';
2
3var tape = require('../');
4var tap = require('tap');
5var concat = require('concat-stream');
6var tapParser = require('tap-parser');
7var yaml = require('js-yaml');
8
9tap.test('preserves stack trace with newlines', function (tt) {
10 tt.plan(3);
11
12 var test = tape.createHarness();
13 var stream = test.createStream();
14 var parser = stream.pipe(tapParser());
15 var stackTrace = 'foo\n bar';
16
17 parser.once('assert', function (data) {
18 tt.deepEqual(data, {
19 ok: false,
20 id: 1,
21 name: 'Error: Preserve stack',
22 diag: {
23 stack: stackTrace,
24 operator: 'error',
25 at: data.diag.at // we don't care about this one
26 }
27 });
28 });
29
30 stream.pipe(concat(function (body) {
31 var strippedBody = stripAt(body.toString('utf8'));
32 tt.deepEqual(strippedBody.split('\n'), [
33 'TAP version 13',
34 '# multiline stack trace',
35 'not ok 1 Error: Preserve stack',
36 ' ---',
37 ' operator: error',
38 ' stack: |-',
39 ' foo',
40 ' bar',
41 ' ...',
42 '',
43 '1..1',
44 '# tests 1',
45 '# pass 0',
46 '# fail 1',
47 ''
48 ]);
49
50 tt.deepEqual(getDiag(strippedBody), {
51 stack: stackTrace,
52 operator: 'error'
53 });
54 }));
55
56 test('multiline stack trace', function (t) {
57 t.plan(1);
58 var err = new Error('Preserve stack');
59 err.stack = stackTrace;
60 t.error(err);
61 });
62});
63
64tap.test('parses function info from original stack', function (tt) {
65 tt.plan(4);
66
67 var test = tape.createHarness();
68 test.createStream();
69
70 test._results._watch = function (t) {
71 t.on('result', function (res) {
72 tt.equal('Test.testFunctionNameParsing', res.functionName);
73 tt.match(res.file, /stackTrace.js/i);
74 tt.ok(Number(res.line) > 0);
75 tt.ok(Number(res.column) > 0);
76 });
77 };
78
79 test('t.equal stack trace', function testFunctionNameParsing(t) {
80 t.equal(true, false, 'true should be false');
81 t.end();
82 });
83});
84
85tap.test('parses function info from original stack for anonymous function', function (tt) {
86 tt.plan(4);
87
88 var test = tape.createHarness();
89 test.createStream();
90
91 test._results._watch = function (t) {
92 t.on('result', function (res) {
93 tt.equal('Test.<anonymous>', res.functionName);
94 tt.match(res.file, /stackTrace.js/i);
95 tt.ok(Number(res.line) > 0);
96 tt.ok(Number(res.column) > 0);
97 });
98 };
99
100 test('t.equal stack trace', function (t) {
101 t.equal(true, false, 'true should be false');
102 t.end();
103 });
104});
105
106if (typeof Promise === 'function' && typeof Promise.resolve === 'function') {
107
108 tap.test('parses function info from original stack for Promise scenario', function (tt) {
109 tt.plan(4);
110
111 var test = tape.createHarness();
112 test.createStream();
113
114 test._results._watch = function (t) {
115 t.on('result', function (res) {
116 tt.equal('onfulfilled', res.functionName);
117 tt.match(res.file, /stackTrace.js/i);
118 tt.ok(Number(res.line) > 0);
119 tt.ok(Number(res.column) > 0);
120 });
121 };
122
123 test('t.equal stack trace', function testFunctionNameParsing(t) {
124 new Promise(function (resolve) {
125 resolve();
126 }).then(function onfulfilled() {
127 t.equal(true, false, 'true should be false');
128 t.end();
129 });
130 });
131 });
132
133 tap.test('parses function info from original stack for Promise scenario with anonymous function', function (tt) {
134 tt.plan(4);
135
136 var test = tape.createHarness();
137 test.createStream();
138
139 test._results._watch = function (t) {
140 t.on('result', function (res) {
141 tt.equal('<anonymous>', res.functionName);
142 tt.match(res.file, /stackTrace.js/i);
143 tt.ok(Number(res.line) > 0);
144 tt.ok(Number(res.column) > 0);
145 });
146 };
147
148 test('t.equal stack trace', function testFunctionNameParsing(t) {
149 new Promise(function (resolve) {
150 resolve();
151 }).then(function () {
152 t.equal(true, false, 'true should be false');
153 t.end();
154 });
155 });
156 });
157
158}
159
160tap.test('preserves stack trace for failed assertions', function (tt) {
161 tt.plan(6);
162
163 var test = tape.createHarness();
164 var stream = test.createStream();
165 var parser = stream.pipe(tapParser());
166
167 var stack = '';
168 parser.once('assert', function (data) {
169 tt.equal(typeof data.diag.at, 'string');
170 tt.equal(typeof data.diag.stack, 'string');
171 var at = data.diag.at || '';
172 stack = data.diag.stack || '';
173 tt.ok((/^Error: true should be false(\n {4}at .+)+/).exec(stack), 'stack should be a stack');
174 tt.deepEqual(data, {
175 ok: false,
176 id: 1,
177 name: 'true should be false',
178 diag: {
179 at: at,
180 stack: stack,
181 operator: 'equal',
182 expected: false,
183 actual: true
184 }
185 });
186 });
187
188 stream.pipe(concat(function (body) {
189 var strippedBody = stripAt(body.toString('utf8'));
190 tt.deepEqual(strippedBody.split('\n'), [].concat(
191 'TAP version 13',
192 '# t.equal stack trace',
193 'not ok 1 true should be false',
194 ' ---',
195 ' operator: equal',
196 ' expected: false',
197 ' actual: true',
198 ' stack: |-',
199 stack.split('\n').map(function (x) { return ' ' + x; }),
200 ' ...',
201 '',
202 '1..1',
203 '# tests 1',
204 '# pass 0',
205 '# fail 1',
206 ''
207 ));
208
209 tt.deepEqual(getDiag(strippedBody), {
210 stack: stack,
211 operator: 'equal',
212 expected: false,
213 actual: true
214 });
215 }));
216
217 test('t.equal stack trace', function (t) {
218 t.plan(1);
219 t.equal(true, false, 'true should be false');
220 });
221});
222
223tap.test('preserves stack trace for failed assertions where actual===falsy', function (tt) {
224 tt.plan(6);
225
226 var test = tape.createHarness();
227 var stream = test.createStream();
228 var parser = stream.pipe(tapParser());
229
230 var stack = '';
231 parser.once('assert', function (data) {
232 tt.equal(typeof data.diag.at, 'string');
233 tt.equal(typeof data.diag.stack, 'string');
234 var at = data.diag.at || '';
235 stack = data.diag.stack || '';
236 tt.ok((/^Error: false should be true(\n {4}at .+)+/).exec(stack), 'stack should be a stack');
237 tt.deepEqual(data, {
238 ok: false,
239 id: 1,
240 name: 'false should be true',
241 diag: {
242 at: at,
243 stack: stack,
244 operator: 'equal',
245 expected: true,
246 actual: false
247 }
248 });
249 });
250
251 stream.pipe(concat(function (body) {
252 var strippedBody = stripAt(body.toString('utf8'));
253 tt.deepEqual(strippedBody.split('\n'), [].concat(
254 'TAP version 13',
255 '# t.equal stack trace',
256 'not ok 1 false should be true',
257 ' ---',
258 ' operator: equal',
259 ' expected: true',
260 ' actual: false',
261 ' stack: |-',
262 stack.split('\n').map(function (x) { return ' ' + x; }),
263 ' ...',
264 '',
265 '1..1',
266 '# tests 1',
267 '# pass 0',
268 '# fail 1',
269 ''
270 ));
271
272 tt.deepEqual(getDiag(strippedBody), {
273 stack: stack,
274 operator: 'equal',
275 expected: true,
276 actual: false
277 });
278 }));
279
280 test('t.equal stack trace', function (t) {
281 t.plan(1);
282 t.equal(false, true, 'false should be true');
283 });
284});
285
286function getDiag(body) {
287 var yamlStart = body.indexOf(' ---');
288 var yamlEnd = body.indexOf(' ...\n');
289 var diag = body.slice(yamlStart, yamlEnd).split('\n').map(function (line) {
290 return line.slice(2);
291 }).join('\n');
292
293 // Get rid of 'at' variable (which has a line number / path of its own that's difficult to check).
294 var withStack = yaml.safeLoad(diag);
295 delete withStack.at;
296 return withStack;
297}
298
299function stripAt(body) {
300 return body.replace(/^\s*at:\s+Test.*$\n/m, '');
301}