• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const errcode = require('../index');
4const expect = require('expect.js');
5
6describe('errcode', () => {
7    describe('string as first argument', () => {
8        it('should throw an error', () => {
9            expect(() => { errcode('my message'); }).to.throwError((err) => {
10                expect(err).to.be.a(TypeError);
11            });
12        });
13    });
14
15    describe('error as first argument', () => {
16        it('should accept an error and do nothing', () => {
17            const myErr = new Error('my message');
18            const err = errcode(myErr);
19
20            expect(err).to.be(myErr);
21            expect(err.hasOwnProperty(err.code)).to.be(false);
22        });
23
24        it('should accept an error and add a code', () => {
25            const myErr = new Error('my message');
26            const err = errcode(myErr, 'ESOME');
27
28            expect(err).to.be(myErr);
29            expect(err.code).to.be('ESOME');
30        });
31
32        it('should accept an error object and add code & properties', () => {
33            const myErr = new Error('my message');
34            const err = errcode(myErr, 'ESOME', { foo: 'bar', bar: 'foo' });
35
36            expect(err).to.be.an(Error);
37            expect(err.code).to.be('ESOME');
38            expect(err.foo).to.be('bar');
39            expect(err.bar).to.be('foo');
40        });
41
42        it('should create an error object without code but with properties', () => {
43            const myErr = new Error('my message');
44            const err = errcode(myErr, { foo: 'bar', bar: 'foo' });
45
46            expect(err).to.be.an(Error);
47            expect(err.code).to.be(undefined);
48            expect(err.foo).to.be('bar');
49            expect(err.bar).to.be('foo');
50        });
51
52        it('should set a non-writable field', () => {
53            const myErr = new Error('my message');
54
55            Object.defineProperty(myErr, 'code', {
56                value: 'derp',
57                writable: false,
58            });
59            const err = errcode(myErr, 'ERR_WAT');
60
61            expect(err).to.be.an(Error);
62            expect(err.stack).to.equal(myErr.stack);
63            expect(err.code).to.be('ERR_WAT');
64        });
65
66        it('should add a code to frozen object', () => {
67            const myErr = new Error('my message');
68            const err = errcode(Object.freeze(myErr), 'ERR_WAT');
69
70            expect(err).to.be.an(Error);
71            expect(err.stack).to.equal(myErr.stack);
72            expect(err.code).to.be('ERR_WAT');
73        });
74
75        it('should to set a field that throws at assignment time', () => {
76            const myErr = new Error('my message');
77
78            Object.defineProperty(myErr, 'code', {
79                enumerable: true,
80                set() {
81                    throw new Error('Nope!');
82                },
83                get() {
84                    return 'derp';
85                },
86            });
87            const err = errcode(myErr, 'ERR_WAT');
88
89            expect(err).to.be.an(Error);
90            expect(err.stack).to.equal(myErr.stack);
91            expect(err.code).to.be('ERR_WAT');
92        });
93
94        it('should retain error type', () => {
95            const myErr = new TypeError('my message');
96
97            Object.defineProperty(myErr, 'code', {
98                value: 'derp',
99                writable: false,
100            });
101            const err = errcode(myErr, 'ERR_WAT');
102
103            expect(err).to.be.a(TypeError);
104            expect(err.stack).to.equal(myErr.stack);
105            expect(err.code).to.be('ERR_WAT');
106        });
107
108        it('should add a code to a class that extends Error', () => {
109            class CustomError extends Error {
110                set code(val) {
111                    throw new Error('Nope!');
112                }
113            }
114
115            const myErr = new CustomError('my message');
116
117            Object.defineProperty(myErr, 'code', {
118                value: 'derp',
119                writable: false,
120                configurable: false,
121            });
122            const err = errcode(myErr, 'ERR_WAT');
123
124            expect(err).to.be.a(CustomError);
125            expect(err.stack).to.equal(myErr.stack);
126            expect(err.code).to.be('ERR_WAT');
127
128            // original prototype chain should be intact
129            expect(() => {
130                const otherErr = new CustomError('my message');
131
132                otherErr.code = 'derp';
133            }).to.throwError();
134        });
135
136        it('should support errors that are not Errors', () => {
137            const err = errcode({
138                message: 'Oh noes!',
139            }, 'ERR_WAT');
140
141            expect(err.message).to.be('Oh noes!');
142            expect(err.code).to.be('ERR_WAT');
143        });
144    });
145
146    describe('falsy first arguments', () => {
147        it('should not allow passing null as the first argument', () => {
148            expect(() => { errcode(null); }).to.throwError((err) => {
149                expect(err).to.be.a(TypeError);
150            });
151        });
152
153        it('should not allow passing undefined as the first argument', () => {
154            expect(() => { errcode(undefined); }).to.throwError((err) => {
155                expect(err).to.be.a(TypeError);
156            });
157        });
158    });
159});
160