chai 4.3.2 → 4.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/chai.js +883 -405
- package/index.mjs +1 -0
- package/lib/chai/core/assertions.js +1 -1
- package/lib/chai/utils/inspect.js +6 -349
- package/lib/chai.js +1 -1
- package/package.json +3 -2
package/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import chai from './index.js';
|
|
|
2
2
|
|
|
3
3
|
export const expect = chai.expect;
|
|
4
4
|
export const version = chai.version;
|
|
5
|
+
export const Assertion = chai.Assertion;
|
|
5
6
|
export const AssertionError = chai.AssertionError;
|
|
6
7
|
export const util = chai.util;
|
|
7
8
|
export const config = chai.config;
|
|
@@ -1580,7 +1580,7 @@ module.exports = function (chai, _) {
|
|
|
1580
1580
|
, errorMessage
|
|
1581
1581
|
, shouldThrow = true
|
|
1582
1582
|
, range = (startType === 'date' && finishType === 'date')
|
|
1583
|
-
? start.
|
|
1583
|
+
? start.toISOString() + '..' + finish.toISOString()
|
|
1584
1584
|
: start + '..' + finish;
|
|
1585
1585
|
|
|
1586
1586
|
if (doLength && objType !== 'map' && objType !== 'set') {
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js
|
|
3
3
|
|
|
4
4
|
var getName = require('get-func-name');
|
|
5
|
-
var
|
|
6
|
-
var getEnumerableProperties = require('./getEnumerableProperties');
|
|
5
|
+
var loupe = require('loupe');
|
|
7
6
|
var config = require('../config');
|
|
8
7
|
|
|
9
8
|
module.exports = inspect;
|
|
@@ -24,353 +23,11 @@ module.exports = inspect;
|
|
|
24
23
|
* @name inspect
|
|
25
24
|
*/
|
|
26
25
|
function inspect(obj, showHidden, depth, colors) {
|
|
27
|
-
var
|
|
26
|
+
var options = {
|
|
27
|
+
colors: colors,
|
|
28
|
+
depth: (typeof depth === 'undefined' ? 2 : depth),
|
|
28
29
|
showHidden: showHidden,
|
|
29
|
-
|
|
30
|
-
stylize: function (str) { return str; }
|
|
30
|
+
truncate: config.truncateThreshold ? config.truncateThreshold : Infinity,
|
|
31
31
|
};
|
|
32
|
-
return
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Returns true if object is a DOM element.
|
|
36
|
-
var isDOMElement = function (object) {
|
|
37
|
-
if (typeof HTMLElement === 'object') {
|
|
38
|
-
return object instanceof HTMLElement;
|
|
39
|
-
} else {
|
|
40
|
-
return object &&
|
|
41
|
-
typeof object === 'object' &&
|
|
42
|
-
'nodeType' in object &&
|
|
43
|
-
object.nodeType === 1 &&
|
|
44
|
-
typeof object.nodeName === 'string';
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
function formatValue(ctx, value, recurseTimes) {
|
|
49
|
-
// Provide a hook for user-specified inspect functions.
|
|
50
|
-
// Check that value is an object with an inspect function on it
|
|
51
|
-
if (value && typeof value.inspect === 'function' &&
|
|
52
|
-
// Filter out the util module, it's inspect function is special
|
|
53
|
-
value.inspect !== exports.inspect &&
|
|
54
|
-
// Also filter out any prototype objects using the circular check.
|
|
55
|
-
!(value.constructor && value.constructor.prototype === value)) {
|
|
56
|
-
var ret = value.inspect(recurseTimes, ctx);
|
|
57
|
-
if (typeof ret !== 'string') {
|
|
58
|
-
ret = formatValue(ctx, ret, recurseTimes);
|
|
59
|
-
}
|
|
60
|
-
return ret;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Primitive types cannot have properties
|
|
64
|
-
var primitive = formatPrimitive(ctx, value);
|
|
65
|
-
if (primitive) {
|
|
66
|
-
return primitive;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// If this is a DOM element, try to get the outer HTML.
|
|
70
|
-
if (isDOMElement(value)) {
|
|
71
|
-
if ('outerHTML' in value) {
|
|
72
|
-
return value.outerHTML;
|
|
73
|
-
// This value does not have an outerHTML attribute,
|
|
74
|
-
// it could still be an XML element
|
|
75
|
-
} else {
|
|
76
|
-
// Attempt to serialize it
|
|
77
|
-
try {
|
|
78
|
-
if (document.xmlVersion) {
|
|
79
|
-
var xmlSerializer = new XMLSerializer();
|
|
80
|
-
return xmlSerializer.serializeToString(value);
|
|
81
|
-
} else {
|
|
82
|
-
// Firefox 11- do not support outerHTML
|
|
83
|
-
// It does, however, support innerHTML
|
|
84
|
-
// Use the following to render the element
|
|
85
|
-
var ns = "http://www.w3.org/1999/xhtml";
|
|
86
|
-
var container = document.createElementNS(ns, '_');
|
|
87
|
-
|
|
88
|
-
container.appendChild(value.cloneNode(false));
|
|
89
|
-
var html = container.innerHTML
|
|
90
|
-
.replace('><', '>' + value.innerHTML + '<');
|
|
91
|
-
container.innerHTML = '';
|
|
92
|
-
return html;
|
|
93
|
-
}
|
|
94
|
-
} catch (err) {
|
|
95
|
-
// This could be a non-native DOM implementation,
|
|
96
|
-
// continue with the normal flow:
|
|
97
|
-
// printing the element as if it is an object.
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Look up the keys of the object.
|
|
103
|
-
var visibleKeys = getEnumerableProperties(value);
|
|
104
|
-
var keys = ctx.showHidden ? getProperties(value) : visibleKeys;
|
|
105
|
-
|
|
106
|
-
var name, nameSuffix;
|
|
107
|
-
|
|
108
|
-
// Some type of object without properties can be shortcut.
|
|
109
|
-
// In IE, errors have a single `stack` property, or if they are vanilla `Error`,
|
|
110
|
-
// a `stack` plus `description` property; ignore those for consistency.
|
|
111
|
-
if (keys.length === 0 || (isError(value) && (
|
|
112
|
-
(keys.length === 1 && keys[0] === 'stack') ||
|
|
113
|
-
(keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack')
|
|
114
|
-
))) {
|
|
115
|
-
if (typeof value === 'function') {
|
|
116
|
-
name = getName(value);
|
|
117
|
-
nameSuffix = name ? ': ' + name : '';
|
|
118
|
-
return ctx.stylize('[Function' + nameSuffix + ']', 'special');
|
|
119
|
-
}
|
|
120
|
-
if (isRegExp(value)) {
|
|
121
|
-
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|
122
|
-
}
|
|
123
|
-
if (isDate(value)) {
|
|
124
|
-
return ctx.stylize(Date.prototype.toUTCString.call(value), 'date');
|
|
125
|
-
}
|
|
126
|
-
if (isError(value)) {
|
|
127
|
-
return formatError(value);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
var base = ''
|
|
132
|
-
, array = false
|
|
133
|
-
, typedArray = false
|
|
134
|
-
, braces = ['{', '}'];
|
|
135
|
-
|
|
136
|
-
if (isTypedArray(value)) {
|
|
137
|
-
typedArray = true;
|
|
138
|
-
braces = ['[', ']'];
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Make Array say that they are Array
|
|
142
|
-
if (isArray(value)) {
|
|
143
|
-
array = true;
|
|
144
|
-
braces = ['[', ']'];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Make functions say that they are functions
|
|
148
|
-
if (typeof value === 'function') {
|
|
149
|
-
name = getName(value);
|
|
150
|
-
nameSuffix = name ? ': ' + name : '';
|
|
151
|
-
base = ' [Function' + nameSuffix + ']';
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Make RegExps say that they are RegExps
|
|
155
|
-
if (isRegExp(value)) {
|
|
156
|
-
base = ' ' + RegExp.prototype.toString.call(value);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Make dates with properties first say the date
|
|
160
|
-
if (isDate(value)) {
|
|
161
|
-
base = ' ' + Date.prototype.toUTCString.call(value);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Make error with message first say the error
|
|
165
|
-
if (isError(value)) {
|
|
166
|
-
return formatError(value);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (keys.length === 0 && (!array || value.length == 0)) {
|
|
170
|
-
return braces[0] + base + braces[1];
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (recurseTimes < 0) {
|
|
174
|
-
if (isRegExp(value)) {
|
|
175
|
-
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
|
176
|
-
} else {
|
|
177
|
-
return ctx.stylize('[Object]', 'special');
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
ctx.seen.push(value);
|
|
182
|
-
|
|
183
|
-
var output;
|
|
184
|
-
if (array) {
|
|
185
|
-
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
|
186
|
-
} else if (typedArray) {
|
|
187
|
-
return formatTypedArray(value);
|
|
188
|
-
} else {
|
|
189
|
-
output = keys.map(function(key) {
|
|
190
|
-
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
|
191
|
-
});
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
ctx.seen.pop();
|
|
195
|
-
|
|
196
|
-
return reduceToSingleString(output, base, braces);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function formatPrimitive(ctx, value) {
|
|
200
|
-
switch (typeof value) {
|
|
201
|
-
case 'undefined':
|
|
202
|
-
return ctx.stylize('undefined', 'undefined');
|
|
203
|
-
|
|
204
|
-
case 'string':
|
|
205
|
-
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
|
206
|
-
.replace(/'/g, "\\'")
|
|
207
|
-
.replace(/\\"/g, '"') + '\'';
|
|
208
|
-
return ctx.stylize(simple, 'string');
|
|
209
|
-
|
|
210
|
-
case 'number':
|
|
211
|
-
if (value === 0 && (1/value) === -Infinity) {
|
|
212
|
-
return ctx.stylize('-0', 'number');
|
|
213
|
-
}
|
|
214
|
-
return ctx.stylize('' + value, 'number');
|
|
215
|
-
|
|
216
|
-
case 'boolean':
|
|
217
|
-
return ctx.stylize('' + value, 'boolean');
|
|
218
|
-
|
|
219
|
-
case 'symbol':
|
|
220
|
-
return ctx.stylize(value.toString(), 'symbol');
|
|
221
|
-
}
|
|
222
|
-
// For some reason typeof null is "object", so special case here.
|
|
223
|
-
if (value === null) {
|
|
224
|
-
return ctx.stylize('null', 'null');
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
function formatError(value) {
|
|
229
|
-
return '[' + Error.prototype.toString.call(value) + ']';
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
|
233
|
-
var output = [];
|
|
234
|
-
for (var i = 0, l = value.length; i < l; ++i) {
|
|
235
|
-
if (Object.prototype.hasOwnProperty.call(value, String(i))) {
|
|
236
|
-
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|
237
|
-
String(i), true));
|
|
238
|
-
} else {
|
|
239
|
-
output.push('');
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
keys.forEach(function(key) {
|
|
244
|
-
if (!key.match(/^\d+$/)) {
|
|
245
|
-
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
|
246
|
-
key, true));
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
return output;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function formatTypedArray(value) {
|
|
253
|
-
var str = '[ ';
|
|
254
|
-
|
|
255
|
-
for (var i = 0; i < value.length; ++i) {
|
|
256
|
-
if (str.length >= config.truncateThreshold - 7) {
|
|
257
|
-
str += '...';
|
|
258
|
-
break;
|
|
259
|
-
}
|
|
260
|
-
str += value[i] + ', ';
|
|
261
|
-
}
|
|
262
|
-
str += ' ]';
|
|
263
|
-
|
|
264
|
-
// Removing trailing `, ` if the array was not truncated
|
|
265
|
-
if (str.indexOf(', ]') !== -1) {
|
|
266
|
-
str = str.replace(', ]', ' ]');
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
return str;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
|
273
|
-
var name;
|
|
274
|
-
var propDescriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
275
|
-
var str;
|
|
276
|
-
|
|
277
|
-
if (propDescriptor) {
|
|
278
|
-
if (propDescriptor.get) {
|
|
279
|
-
if (propDescriptor.set) {
|
|
280
|
-
str = ctx.stylize('[Getter/Setter]', 'special');
|
|
281
|
-
} else {
|
|
282
|
-
str = ctx.stylize('[Getter]', 'special');
|
|
283
|
-
}
|
|
284
|
-
} else {
|
|
285
|
-
if (propDescriptor.set) {
|
|
286
|
-
str = ctx.stylize('[Setter]', 'special');
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
if (visibleKeys.indexOf(key) < 0) {
|
|
291
|
-
name = '[' + key + ']';
|
|
292
|
-
}
|
|
293
|
-
if (!str) {
|
|
294
|
-
if (ctx.seen.indexOf(value[key]) < 0) {
|
|
295
|
-
if (recurseTimes === null) {
|
|
296
|
-
str = formatValue(ctx, value[key], null);
|
|
297
|
-
} else {
|
|
298
|
-
str = formatValue(ctx, value[key], recurseTimes - 1);
|
|
299
|
-
}
|
|
300
|
-
if (str.indexOf('\n') > -1) {
|
|
301
|
-
if (array) {
|
|
302
|
-
str = str.split('\n').map(function(line) {
|
|
303
|
-
return ' ' + line;
|
|
304
|
-
}).join('\n').substr(2);
|
|
305
|
-
} else {
|
|
306
|
-
str = '\n' + str.split('\n').map(function(line) {
|
|
307
|
-
return ' ' + line;
|
|
308
|
-
}).join('\n');
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
str = ctx.stylize('[Circular]', 'special');
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (typeof name === 'undefined') {
|
|
316
|
-
if (array && key.match(/^\d+$/)) {
|
|
317
|
-
return str;
|
|
318
|
-
}
|
|
319
|
-
name = JSON.stringify('' + key);
|
|
320
|
-
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
|
321
|
-
name = name.substr(1, name.length - 2);
|
|
322
|
-
name = ctx.stylize(name, 'name');
|
|
323
|
-
} else {
|
|
324
|
-
name = name.replace(/'/g, "\\'")
|
|
325
|
-
.replace(/\\"/g, '"')
|
|
326
|
-
.replace(/(^"|"$)/g, "'");
|
|
327
|
-
name = ctx.stylize(name, 'string');
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
return name + ': ' + str;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function reduceToSingleString(output, base, braces) {
|
|
335
|
-
var length = output.reduce(function(prev, cur) {
|
|
336
|
-
return prev + cur.length + 1;
|
|
337
|
-
}, 0);
|
|
338
|
-
|
|
339
|
-
if (length > 60) {
|
|
340
|
-
return braces[0] +
|
|
341
|
-
(base === '' ? '' : base + '\n ') +
|
|
342
|
-
' ' +
|
|
343
|
-
output.join(',\n ') +
|
|
344
|
-
' ' +
|
|
345
|
-
braces[1];
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
function isTypedArray(ar) {
|
|
352
|
-
// Unfortunately there's no way to check if an object is a TypedArray
|
|
353
|
-
// We have to check if it's one of these types
|
|
354
|
-
return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar)));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
function isArray(ar) {
|
|
358
|
-
return Array.isArray(ar) ||
|
|
359
|
-
(typeof ar === 'object' && objectToString(ar) === '[object Array]');
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function isRegExp(re) {
|
|
363
|
-
return typeof re === 'object' && objectToString(re) === '[object RegExp]';
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
function isDate(d) {
|
|
367
|
-
return typeof d === 'object' && objectToString(d) === '[object Date]';
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
function isError(e) {
|
|
371
|
-
return typeof e === 'object' && objectToString(e) === '[object Error]';
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function objectToString(o) {
|
|
375
|
-
return Object.prototype.toString.call(o);
|
|
32
|
+
return loupe.inspect(obj, options);
|
|
376
33
|
}
|
package/lib/chai.js
CHANGED
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"Veselin Todorov <hi@vesln.com>",
|
|
18
18
|
"John Firebaugh <john.firebaugh@gmail.com>"
|
|
19
19
|
],
|
|
20
|
-
"version": "4.3.
|
|
20
|
+
"version": "4.3.6",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
23
|
"url": "https://github.com/chaijs/chai"
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"require": "./index.js",
|
|
32
32
|
"import": "./index.mjs"
|
|
33
33
|
},
|
|
34
|
-
"
|
|
34
|
+
"./*": "./*"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"test": "make test"
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"check-error": "^1.0.2",
|
|
45
45
|
"deep-eql": "^3.0.1",
|
|
46
46
|
"get-func-name": "^2.0.0",
|
|
47
|
+
"loupe": "^2.3.1",
|
|
47
48
|
"pathval": "^1.1.1",
|
|
48
49
|
"type-detect": "^4.0.5"
|
|
49
50
|
},
|