1 | 'use strict';
|
2 |
|
3 | var tape = require('../');
|
4 | var tap = require('tap');
|
5 | var concat = require('concat-stream');
|
6 | var tapParser = require('tap-parser');
|
7 | var yaml = require('js-yaml');
|
8 |
|
9 | tap.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 | delete data.diag.at;
|
19 | tt.deepEqual(data, {
|
20 | ok: false,
|
21 | id: 1,
|
22 | name: 'Error: Preserve stack',
|
23 | diag: {
|
24 | stack: stackTrace,
|
25 | operator: 'error'
|
26 | }
|
27 | });
|
28 | });
|
29 |
|
30 | stream.pipe(concat(function (body) {
|
31 | var body = body.toString('utf8');
|
32 | body = stripAt(body);
|
33 | tt.equal(
|
34 | body,
|
35 | 'TAP version 13\n'
|
36 | + '# multiline stack trace\n'
|
37 | + 'not ok 1 Error: Preserve stack\n'
|
38 | + ' ---\n'
|
39 | + ' operator: error\n'
|
40 | + ' stack: |-\n'
|
41 | + ' foo\n'
|
42 | + ' bar\n'
|
43 | + ' ...\n'
|
44 | + '\n'
|
45 | + '1..1\n'
|
46 | + '# tests 1\n'
|
47 | + '# pass 0\n'
|
48 | + '# fail 1\n'
|
49 | );
|
50 |
|
51 | tt.deepEqual(getDiag(body), {
|
52 | stack: stackTrace,
|
53 | operator: 'error'
|
54 | });
|
55 | }));
|
56 |
|
57 | test('multiline stack trace', function (t) {
|
58 | t.plan(1);
|
59 | var err = new Error('Preserve stack');
|
60 | err.stack = stackTrace;
|
61 | t.error(err);
|
62 | });
|
63 | });
|
64 |
|
65 | tap.test('parses function name from original stack', function (tt) {
|
66 | tt.plan(1);
|
67 |
|
68 | var test = tape.createHarness();
|
69 | test.createStream();
|
70 |
|
71 | test._results._watch = function (t) {
|
72 | t.on('result', function (res) {
|
73 | tt.equal('Test.testFunctionNameParsing', res.functionName);
|
74 | });
|
75 | };
|
76 |
|
77 | test('t.equal stack trace', function testFunctionNameParsing(t) {
|
78 | t.equal(true, false, 'true should be false');
|
79 | t.end();
|
80 | });
|
81 | });
|
82 |
|
83 | tap.test('parses function name from original stack for anonymous function', function (tt) {
|
84 | tt.plan(1);
|
85 |
|
86 | var test = tape.createHarness();
|
87 | test.createStream();
|
88 |
|
89 | test._results._watch = function (t) {
|
90 | t.on('result', function (res) {
|
91 | tt.equal('Test.<anonymous>', res.functionName);
|
92 | });
|
93 | };
|
94 |
|
95 | test('t.equal stack trace', function (t) {
|
96 | t.equal(true, false, 'true should be false');
|
97 | t.end();
|
98 | });
|
99 | });
|
100 |
|
101 | tap.test('preserves stack trace for failed assertions', function (tt) {
|
102 | tt.plan(6);
|
103 |
|
104 | var test = tape.createHarness();
|
105 | var stream = test.createStream();
|
106 | var parser = stream.pipe(tapParser());
|
107 |
|
108 | var stack = '';
|
109 | parser.once('assert', function (data) {
|
110 | tt.equal(typeof data.diag.at, 'string');
|
111 | tt.equal(typeof data.diag.stack, 'string');
|
112 | var at = data.diag.at || '';
|
113 | stack = data.diag.stack || '';
|
114 | tt.ok(/^Error: true should be false(\n at .+)+/.exec(stack), 'stack should be a stack');
|
115 | tt.deepEqual(data, {
|
116 | ok: false,
|
117 | id: 1,
|
118 | name: 'true should be false',
|
119 | diag: {
|
120 | at: at,
|
121 | stack: stack,
|
122 | operator: 'equal',
|
123 | expected: false,
|
124 | actual: true
|
125 | }
|
126 | });
|
127 | });
|
128 |
|
129 | stream.pipe(concat(function (body) {
|
130 | var body = body.toString('utf8');
|
131 | body = stripAt(body);
|
132 | tt.equal(
|
133 | body,
|
134 | 'TAP version 13\n'
|
135 | + '# t.equal stack trace\n'
|
136 | + 'not ok 1 true should be false\n'
|
137 | + ' ---\n'
|
138 | + ' operator: equal\n'
|
139 | + ' expected: false\n'
|
140 | + ' actual: true\n'
|
141 | + ' stack: |-\n'
|
142 | + ' '
|
143 | + stack.replace(/\n/g, '\n ') + '\n'
|
144 | + ' ...\n'
|
145 | + '\n'
|
146 | + '1..1\n'
|
147 | + '# tests 1\n'
|
148 | + '# pass 0\n'
|
149 | + '# fail 1\n'
|
150 | );
|
151 |
|
152 | tt.deepEqual(getDiag(body), {
|
153 | stack: stack,
|
154 | operator: 'equal',
|
155 | expected: false,
|
156 | actual: true
|
157 | });
|
158 | }));
|
159 |
|
160 | test('t.equal stack trace', function (t) {
|
161 | t.plan(1);
|
162 | t.equal(true, false, 'true should be false');
|
163 | });
|
164 | });
|
165 |
|
166 | tap.test('preserves stack trace for failed assertions where actual===falsy', function (tt) {
|
167 | tt.plan(6);
|
168 |
|
169 | var test = tape.createHarness();
|
170 | var stream = test.createStream();
|
171 | var parser = stream.pipe(tapParser());
|
172 |
|
173 | var stack = '';
|
174 | parser.once('assert', function (data) {
|
175 | tt.equal(typeof data.diag.at, 'string');
|
176 | tt.equal(typeof data.diag.stack, 'string');
|
177 | var at = data.diag.at || '';
|
178 | stack = data.diag.stack || '';
|
179 | tt.ok(/^Error: false should be true(\n at .+)+/.exec(stack), 'stack should be a stack');
|
180 | tt.deepEqual(data, {
|
181 | ok: false,
|
182 | id: 1,
|
183 | name: 'false should be true',
|
184 | diag: {
|
185 | at: at,
|
186 | stack: stack,
|
187 | operator: 'equal',
|
188 | expected: true,
|
189 | actual: false
|
190 | }
|
191 | });
|
192 | });
|
193 |
|
194 | stream.pipe(concat(function (body) {
|
195 | var body = body.toString('utf8');
|
196 | body = stripAt(body);
|
197 | tt.equal(
|
198 | body,
|
199 | 'TAP version 13\n'
|
200 | + '# t.equal stack trace\n'
|
201 | + 'not ok 1 false should be true\n'
|
202 | + ' ---\n'
|
203 | + ' operator: equal\n'
|
204 | + ' expected: true\n'
|
205 | + ' actual: false\n'
|
206 | + ' stack: |-\n'
|
207 | + ' '
|
208 | + stack.replace(/\n/g, '\n ') + '\n'
|
209 | + ' ...\n'
|
210 | + '\n'
|
211 | + '1..1\n'
|
212 | + '# tests 1\n'
|
213 | + '# pass 0\n'
|
214 | + '# fail 1\n'
|
215 | );
|
216 |
|
217 | tt.deepEqual(getDiag(body), {
|
218 | stack: stack,
|
219 | operator: 'equal',
|
220 | expected: true,
|
221 | actual: false
|
222 | });
|
223 | }));
|
224 |
|
225 | test('t.equal stack trace', function (t) {
|
226 | t.plan(1);
|
227 | t.equal(false, true, 'false should be true');
|
228 | });
|
229 | });
|
230 |
|
231 | function getDiag(body) {
|
232 | var yamlStart = body.indexOf(' ---');
|
233 | var yamlEnd = body.indexOf(' ...\n');
|
234 | var diag = body.slice(yamlStart, yamlEnd).split('\n').map(function (line) {
|
235 | return line.slice(2);
|
236 | }).join('\n');
|
237 |
|
238 |
|
239 |
|
240 | var withStack = yaml.safeLoad(diag);
|
241 | delete withStack.at;
|
242 | return withStack;
|
243 | }
|
244 |
|
245 | function stripAt(body) {
|
246 | return body.replace(/^\s*at:\s+Test.*$\n/m, '');
|
247 | }
|