1 | 'use strict';
|
2 |
|
3 | var tape = require('../');
|
4 | var tap = require('tap');
|
5 | var concat = require('concat-stream');
|
6 | var inspect = require('object-inspect');
|
7 | var assign = require('object.assign');
|
8 |
|
9 | var stripFullStack = require('./common').stripFullStack;
|
10 |
|
11 | var getter = function () { return 'message'; };
|
12 | var messageGetterError = Object.defineProperty(
|
13 | { custom: 'error' },
|
14 | 'message',
|
15 | {
|
16 | configurable: true,
|
17 | enumerable: true,
|
18 | get: getter
|
19 | }
|
20 | );
|
21 | var thrower = function () { throw messageGetterError; };
|
22 |
|
23 | tap.test('failures', function (tt) {
|
24 | tt.plan(1);
|
25 |
|
26 | var test = tape.createHarness();
|
27 | test.createStream().pipe(concat(function (body) {
|
28 | tt.same(stripFullStack(body.toString('utf8')), [
|
29 | 'TAP version 13',
|
30 | '# non functions',
|
31 | 'ok 1 should throw',
|
32 | 'ok 2 should throw',
|
33 | 'ok 3 should throw',
|
34 | 'ok 4 should throw',
|
35 | 'ok 5 should throw',
|
36 | 'ok 6 should throw',
|
37 | 'ok 7 should throw',
|
38 | 'ok 8 should throw',
|
39 | '# function',
|
40 | 'not ok 9 should throw',
|
41 | ' ---',
|
42 | ' operator: throws',
|
43 | ' expected: undefined',
|
44 | ' actual: undefined',
|
45 | ' at: Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
46 | ' stack: |-',
|
47 | ' Error: should throw',
|
48 | ' [... stack stripped ...]',
|
49 | ' at Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
50 | ' [... stack stripped ...]',
|
51 | ' ...',
|
52 | '# custom error messages',
|
53 | 'ok 10 "message" is enumerable',
|
54 | "ok 11 { custom: 'error', message: 'message' }",
|
55 | 'ok 12 getter is still the same',
|
56 | '# throws null',
|
57 | 'ok 13 throws null',
|
58 | '# wrong type of error',
|
59 | 'not ok 14 throws actual',
|
60 | ' ---',
|
61 | ' operator: throws',
|
62 | ' expected: |-',
|
63 | ' [Function: TypeError]',
|
64 | ' actual: |-',
|
65 | ' { [RangeError: actual!] ' + ('cause' in Error.prototype ? '[cause]: undefined, ' : '') + "message: 'actual!' }",
|
66 | ' at: Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
67 | ' stack: |-',
|
68 | ' RangeError: actual!',
|
69 | ' at Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
70 | ' [... stack stripped ...]',
|
71 | ' ...',
|
72 | '# object',
|
73 | 'ok 15 object properties are validated',
|
74 | '# object with regexes',
|
75 | 'ok 16 object with regex values is validated',
|
76 | '# similar error object',
|
77 | 'ok 17 throwing a similar error',
|
78 | '# validate with regex',
|
79 | 'ok 18 regex against toString of error',
|
80 | '# custom error validation',
|
81 | 'ok 19 error is SyntaxError',
|
82 | 'ok 20 error matches /value/',
|
83 | 'ok 21 unexpected error',
|
84 | '# throwing primitives',
|
85 | 'ok 22 primitive: null',
|
86 | 'ok 23 primitive: undefined',
|
87 | 'ok 24 primitive: 0',
|
88 | 'ok 25 primitive: NaN',
|
89 | 'ok 26 primitive: 42',
|
90 | 'ok 27 primitive: Infinity',
|
91 | 'ok 28 primitive: \'\'',
|
92 | 'ok 29 primitive: \'foo\'',
|
93 | 'ok 30 primitive: true',
|
94 | 'ok 31 primitive: false',
|
95 | '# ambiguous arguments',
|
96 | 'ok 32 Second',
|
97 | 'ok 33 Second',
|
98 | 'ok 34 Second',
|
99 | 'ok 35 should throw',
|
100 | 'not ok 36 should throw',
|
101 | ' ---',
|
102 | ' operator: throws',
|
103 | ' expected: |-',
|
104 | ' \'/Second$/\'',
|
105 | ' actual: |-',
|
106 | ' { [Error: First] ' + ('cause' in Error.prototype ? '[cause]: undefined, ' : '') + 'message: \'First\' }',
|
107 | ' at: Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
108 | ' stack: |-',
|
109 | ' Error: First',
|
110 | ' at throwingFirst ($TEST/throws.js:$LINE:$COL)',
|
111 | ' [... stack stripped ...]',
|
112 | ' at Test.<anonymous> ($TEST/throws.js:$LINE:$COL)',
|
113 | ' [... stack stripped ...]',
|
114 | ' ...',
|
115 | '',
|
116 | '1..36',
|
117 | '# tests 36',
|
118 | '# pass 33',
|
119 | '# fail 3',
|
120 | ''
|
121 | ]);
|
122 | }));
|
123 |
|
124 | test('non functions', function (t) {
|
125 | t.plan(8);
|
126 | t.throws();
|
127 | t.throws(null);
|
128 | t.throws(true);
|
129 | t.throws(false);
|
130 | t.throws('abc');
|
131 | t.throws(/a/g);
|
132 | t.throws([]);
|
133 | t.throws({});
|
134 | });
|
135 |
|
136 | test('function', function (t) {
|
137 | t.plan(1);
|
138 | t.throws(function () {});
|
139 | });
|
140 |
|
141 | test('custom error messages', function (t) {
|
142 | t.plan(3);
|
143 | t.equal(Object.prototype.propertyIsEnumerable.call(messageGetterError, 'message'), true, '"message" is enumerable');
|
144 | t.throws(thrower, "{ custom: 'error', message: 'message' }");
|
145 | t.equal(Object.getOwnPropertyDescriptor(messageGetterError, 'message').get, getter, 'getter is still the same');
|
146 | });
|
147 |
|
148 | test('throws null', function (t) {
|
149 | t.plan(1);
|
150 | t.throws(function () { throw null; }, 'throws null');
|
151 | t.end();
|
152 | });
|
153 |
|
154 | test('wrong type of error', function (t) {
|
155 | t.plan(1);
|
156 | var actual = new RangeError('actual!');
|
157 | t.throws(function () { throw actual; }, TypeError, 'throws actual');
|
158 | t.end();
|
159 | });
|
160 |
|
161 |
|
162 | var err = new TypeError('Wrong value');
|
163 | err.code = 404;
|
164 | err.foo = 'bar';
|
165 | err.info = {
|
166 | nested: true,
|
167 | baz: 'text'
|
168 | };
|
169 | err.reg = /abc/i;
|
170 |
|
171 | test('object', function (t) {
|
172 | t.plan(1);
|
173 |
|
174 | t.throws(
|
175 | function () { throw err; },
|
176 | {
|
177 | name: 'TypeError',
|
178 | message: 'Wrong value',
|
179 | info: {
|
180 | nested: true,
|
181 | baz: 'text'
|
182 | }
|
183 |
|
184 |
|
185 |
|
186 | },
|
187 | 'object properties are validated'
|
188 | );
|
189 |
|
190 | t.end();
|
191 | });
|
192 |
|
193 | test('object with regexes', function (t) {
|
194 | t.plan(1);
|
195 | t.throws(
|
196 | function () { throw err; },
|
197 | {
|
198 |
|
199 |
|
200 |
|
201 | name: /^TypeError$/,
|
202 | message: /Wrong/,
|
203 | foo: 'bar',
|
204 | info: {
|
205 | nested: true,
|
206 |
|
207 | baz: 'text'
|
208 | },
|
209 |
|
210 |
|
211 |
|
212 | reg: /abc/i
|
213 | },
|
214 | 'object with regex values is validated'
|
215 | );
|
216 | t.end();
|
217 | });
|
218 |
|
219 | test('similar error object', function (t) {
|
220 | t.plan(1);
|
221 | t.throws(
|
222 | function () {
|
223 | var otherErr = new TypeError('Not found');
|
224 |
|
225 | assign(otherErr, err);
|
226 | throw otherErr;
|
227 | },
|
228 |
|
229 |
|
230 | err,
|
231 | 'throwing a similar error'
|
232 | );
|
233 | t.end();
|
234 | });
|
235 |
|
236 | test('validate with regex', function (t) {
|
237 | t.plan(1);
|
238 | t.throws(
|
239 | function () { throw new Error('Wrong value'); },
|
240 | /^Error: Wrong value$/,
|
241 | 'regex against toString of error'
|
242 | );
|
243 | t.end();
|
244 | });
|
245 |
|
246 | test('custom error validation', function (t) {
|
247 | t.plan(3);
|
248 | t.throws(
|
249 | function () { throw new SyntaxError('Wrong value'); },
|
250 | function (error) {
|
251 | t.ok(error instanceof SyntaxError, 'error is SyntaxError');
|
252 | t.ok((/value/).test(error), 'error matches /value/');
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 | return true;
|
259 | },
|
260 | 'unexpected error'
|
261 | );
|
262 | t.end();
|
263 | });
|
264 |
|
265 | test('throwing primitives', function (t) {
|
266 | [null, undefined, 0, NaN, 42, Infinity, '', 'foo', true, false].forEach(function (primitive) {
|
267 | t.throws(function () { throw primitive; }, 'primitive: ' + inspect(primitive));
|
268 | });
|
269 |
|
270 | t.end();
|
271 | });
|
272 |
|
273 | test('ambiguous arguments', function (t) {
|
274 | function throwingFirst() {
|
275 | throw new Error('First');
|
276 | }
|
277 |
|
278 | function throwingSecond() {
|
279 | throw new Error('Second');
|
280 | }
|
281 |
|
282 | function notThrowing() {}
|
283 |
|
284 |
|
285 |
|
286 |
|
287 | t.throws(throwingFirst, 'Second');
|
288 |
|
289 |
|
290 |
|
291 | t.throws(throwingSecond, 'Second');
|
292 |
|
293 |
|
294 |
|
295 | t.doesNotThrow(notThrowing, 'Second');
|
296 |
|
297 |
|
298 |
|
299 |
|
300 | t.throws(throwingSecond, /Second$/);
|
301 |
|
302 |
|
303 | t.throws(throwingFirst, /Second$/);
|
304 |
|
305 | t.end();
|
306 | });
|
307 | });
|