error.reporting.test.js
8.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* Module dependencies.
*/
var pug = require('../');
var assert = require('assert');
var fs = require('fs');
// Shortcut
function getError(str, options){
try {
pug.render(str, options);
} catch (ex) {
return ex;
}
throw new Error('Input was supposed to result in an error.');
}
function getFileError(name, options){
try {
pug.renderFile(name, options);
} catch (ex) {
return ex;
}
throw new Error('Input was supposed to result in an error.');
}
describe('error reporting', function () {
describe('compile time errors', function () {
describe('with no filename', function () {
it('includes detail of where the error was thrown', function () {
var err = getError('foo(')
expect(err.message).toMatch(/Pug:1/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a filename', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getError('foo(', {filename: 'test.pug'})
expect(err.message).toMatch(/test\.pug:1/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a layout without block declaration (syntax)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.layout.syntax.error.pug', {})
expect(err.message).toMatch(/[\\\/]layout.syntax.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a layout without block declaration (locals)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.layout.locals.error.pug', {})
expect(err.message).toMatch(/[\\\/]layout.locals.error.pug:2/);
expect(err.message).toMatch(/is not a function/);
});
});
describe('with a include (syntax)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.include.syntax.error.pug', {})
expect(err.message).toMatch(/[\\\/]include.syntax.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a include (locals)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.include.locals.error.pug', {})
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a layout (without block) with an include (syntax)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.layout.with.include.syntax.error.pug', {})
expect(err.message).toMatch(/[\\\/]include.syntax.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('with a layout (without block) with an include (locals)', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/compile.with.layout.with.include.locals.error.pug', {})
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});
});
describe('block that is never actually used', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/invalid-block-in-extends.pug', {});
expect(err.message).toMatch(/invalid-block-in-extends.pug:6/);;
expect(err.message).toMatch(/content/);;
});
});
describe('Unexpected character', function () {
it('includes details of where the error was thrown', function () {
var err = getError('ul?', {});
expect(err.message).toMatch(/unexpected text \"\?\"/);
});
});
describe('Include filtered', function () {
it('includes details of where the error was thrown', function () {
var err = getError('include:verbatim()!', {});
assert(err.message.indexOf('unexpected text "!"') !== -1);
var err = getError('include:verbatim ', {});
assert(err.message.indexOf('missing path for include') !== -1);
});
});
describe('mixin block followed by a lot of blank lines', function () {
it('reports the correct line number', function () {
var err = getError('mixin test\n block\n\ndiv()Test');
var line = /Pug\:(\d+)/.exec(err.message);
assert(line, 'Line number must be included in error message');
assert(line[1] === '4', 'The error should be reported on line 4, not line ' + line[1]);
});
});
});
describe('runtime errors', function () {
describe('with no filename and `compileDebug` left undefined', function () {
it('just reports the line number', function () {
var sentinel = new Error('sentinel');
var err = getError('-foo()', {foo: function () { throw sentinel; }})
expect(err.message).toMatch(/on line 1/);
});
});
describe('with no filename and `compileDebug` set to `true`', function () {
it('includes detail of where the error was thrown', function () {
var sentinel = new Error('sentinel');
var err = getError('-foo()', {foo: function () { throw sentinel; }, compileDebug: true})
expect(err.message).toMatch(/Pug:1/);
expect(err.message).toMatch(/-foo\(\)/);
});
});
describe('with a filename that does not correspond to a real file and `compileDebug` left undefined', function () {
it('just reports the line number', function () {
var sentinel = new Error('sentinel');
var err = getError('-foo()', {foo: function () { throw sentinel; }, filename: 'fake.pug'})
expect(err.message).toMatch(/on line 1/);
});
});
describe('with a filename that corresponds to a real file and `compileDebug` left undefined', function () {
it('includes detail of where the error was thrown including the filename', function () {
var sentinel = new Error('sentinel');
var path = __dirname + '/fixtures/runtime.error.pug'
var err = getError(fs.readFileSync(path, 'utf8'), {foo: function () { throw sentinel; }, filename: path})
expect(err.message).toMatch(/fixtures[\\\/]runtime\.error\.pug:1/);
expect(err.message).toMatch(/-foo\(\)/);
});
});
describe('in a mixin', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/runtime.with.mixin.error.pug', {})
expect(err.message).toMatch(/mixin.error.pug:2/);
expect(err.message).toMatch(/Cannot read property 'length' of null/);
});
});
describe('in a layout', function () {
it('includes detail of where the error was thrown including the filename', function () {
var err = getFileError(__dirname + '/fixtures/runtime.layout.error.pug', {})
expect(err.message).toMatch(/layout.with.runtime.error.pug:3/);
expect(err.message).toMatch(/Cannot read property 'length' of undefined/);
});
});
});
describe('deprecated features', function () {
it('warns about element-with-multiple-attributes', function () {
var consoleWarn = console.warn;
var log = '';
console.warn = function (str) {
log += str;
};
var res = pug.renderFile(__dirname + '/fixtures/element-with-multiple-attributes.pug');
console.warn = consoleWarn;
expect(log).toMatch(/element-with-multiple-attributes.pug, line 1:/);;
expect(log).toMatch(/You should not have pug tags with multiple attributes/);;
expect(res).toBe('<div attr="val" foo="bar"></div>');
});
});
describe('if you throw something that isn\'t an error', function () {
it('just rethrows without modification', function () {
var err = getError('- throw "foo"');
expect(err).toBe('foo');
});
});
describe('import without a filename for a basedir', function () {
it('throws an error', function () {
var err = getError('include foo.pug');
expect(err.message).toMatch(/the "filename" option is required to use/);;
var err = getError('include /foo.pug');
expect(err.message).toMatch(/the "basedir" option is required to use/);;
})
});
});