unexpected
Advanced tools
Comparing version
@@ -51,2 +51,18 @@ /*global namespace*/ | ||
expect.addAssertion('[not] to be close to', function (expect, subject, value, epsilon) { | ||
this.errorMode = 'bubble'; | ||
if (typeof epsilon !== 'number') { | ||
epsilon = 1e-9; | ||
} | ||
try { | ||
expect(Math.abs(subject - value), '[not] to be less than or equal to', epsilon); | ||
} catch (e) { | ||
expect.fail('expected {0} {1} {2} (epsilon: {3})', | ||
expect.inspect(subject), | ||
this.testDescription, | ||
expect.inspect(value), | ||
epsilon.toExponential()); | ||
} | ||
}); | ||
expect.addAssertion('[not] to be (a|an)', function (expect, subject, type) { | ||
@@ -115,3 +131,8 @@ if ('string' === typeof type) { | ||
forEach(getKeys(properties), function (property) { | ||
expect(subject, 'to have [own] property', property, properties[property]); | ||
var value = properties[property]; | ||
if (typeof value === 'undefined') { | ||
expect(subject, 'not to have [own] property', property); | ||
} else { | ||
expect(subject, 'to have [own] property', property, value); | ||
} | ||
}); | ||
@@ -213,24 +234,24 @@ } catch (e) { | ||
expect.addAssertion('<', 'to be (<|less than|below)', function (expect, subject, value) { | ||
expect(subject < value, 'to be true'); | ||
expect.addAssertion('<', '[not] to be (<|less than|below)', function (expect, subject, value) { | ||
expect(subject < value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('<=', 'to be (<=|less than or equal to)', function (expect, subject, value) { | ||
expect(subject <= value, 'to be true'); | ||
expect.addAssertion('<=', '[not] to be (<=|less than or equal to)', function (expect, subject, value) { | ||
expect(subject <= value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('>', 'to be (>|greater than|above)', function (expect, subject, value) { | ||
expect(subject > value, 'to be true'); | ||
expect.addAssertion('>', '[not] to be (>|greater than|above)', function (expect, subject, value) { | ||
expect(subject > value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('>=', 'to be (>=|greater than or equal to)', function (expect, subject, value) { | ||
expect(subject >= value, 'to be true'); | ||
expect.addAssertion('>=', '[not] to be (>=|greater than or equal to)', function (expect, subject, value) { | ||
expect(subject >= value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('to be positive', function (expect, subject) { | ||
expect(subject, '>', 0); | ||
expect.addAssertion('[not] to be positive', function (expect, subject) { | ||
expect(subject, '[not] to be >', 0); | ||
}); | ||
expect.addAssertion('to be negative', function (expect, subject) { | ||
expect(subject, '<', 0); | ||
expect.addAssertion('[not] to be negative', function (expect, subject) { | ||
expect(subject, '[not] to be <', 0); | ||
}); | ||
@@ -280,3 +301,3 @@ | ||
} else if (this.flags.not) { | ||
expect.fail('threw: {0}', e.message); | ||
expect.fail('threw: {0}', expect.inspect(e.message)); | ||
} | ||
@@ -401,2 +422,24 @@ thrown = true; | ||
}); | ||
expect.addAssertion('to be canonical', function (expect, subject, stack) { | ||
stack = stack || []; | ||
var i; | ||
for (i = 0 ; i < stack.length ; i += 1) { | ||
if (stack[i] === subject) { | ||
return; | ||
} | ||
} | ||
if (subject && typeof subject === 'object') { | ||
var keys = getKeys(subject); | ||
for (i = 0 ; i < keys.length - 1 ; i += 1) { | ||
expect(keys[i], 'to be less than', keys[i + 1]); | ||
} | ||
stack.push(subject); | ||
forEach(keys, function (key) { | ||
expect(subject[key], 'to be canonical', stack); | ||
}); | ||
stack.pop(subject); | ||
} | ||
}); | ||
}()); |
@@ -122,7 +122,4 @@ /*global namespace*/ | ||
Unexpected.prototype.format = function (message, args) { | ||
args = map(args, function (arg) { | ||
return this.inspect(arg); | ||
}, this); | ||
message = message.replace(/\{(\d+)\}/g, function (match, n) { | ||
return args[n] || match; | ||
return n in args ? args[n] : match; | ||
}); | ||
@@ -161,9 +158,17 @@ return message; | ||
var handler = Array.prototype.slice.call(arguments, -1)[0]; | ||
var isSeenByExpandedPattern = {}; | ||
forEach(patterns, function (pattern) { | ||
ensureValidPattern(pattern); | ||
forEach(expandPattern(pattern), function (expandedPattern) { | ||
assertions[expandedPattern.text] = { | ||
handler: handler, | ||
flags: expandedPattern.flags | ||
}; | ||
if (expandedPattern.text in assertions) { | ||
if (!isSeenByExpandedPattern[expandedPattern.text]) { | ||
throw new Error('Cannot redefine assertion: ' + expandedPattern.text); | ||
} | ||
} else { | ||
isSeenByExpandedPattern[expandedPattern.text] = true; | ||
assertions[expandedPattern.text] = { | ||
handler: handler, | ||
flags: expandedPattern.flags | ||
}; | ||
} | ||
}); | ||
@@ -341,4 +346,3 @@ }); | ||
testDescriptionString = trim(testDescriptionString.replace(/\[(!?)([^\]]+)\] ?/g, function (match, negate, flag) { | ||
negate = !!negate; | ||
return flags[flag] !== negate ? flag + ' ' : ''; | ||
return Boolean(flags[flag]) !== Boolean(negate) ? flag + ' ' : ''; | ||
})); | ||
@@ -345,0 +349,0 @@ |
@@ -84,5 +84,11 @@ /*global namespace*/ | ||
getKeysOfDefinedProperties: function (object) { | ||
return filter(getKeys(object), function (key) { | ||
var keys = filter(getKeys(object), function (key) { | ||
return typeof object[key] !== 'undefined'; | ||
}); | ||
// The 'message' property of Error instances is enumerable for some reason, but we want | ||
// to include it in the set when comparing: | ||
if (Object.prototype.toString.call(object) === '[object Error]') { | ||
keys.push('message'); | ||
} | ||
return keys; | ||
}, | ||
@@ -89,0 +95,0 @@ |
{ | ||
"name": "unexpected", | ||
"version": "3.2.3", | ||
"version": "3.2.4", | ||
"author": "Sune Sloth Simonsen <sune@we-knowhow.dk>", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -125,2 +125,9 @@ # Unexpected | ||
**canonical**: asserts that an object has its properties defined in sorted order at all levels | ||
```js | ||
expect({ a: 123, b: 456 }, 'to be canonical'); | ||
expect([456, { a: 123 }], 'to be canonical'); | ||
``` | ||
**a** / **an**: asserts `typeof` with support for `array` type and `instanceof` | ||
@@ -169,2 +176,15 @@ | ||
**close to**: asserts that the difference between two numbers is <= epsilon | ||
```js | ||
expect(1.5, 'to be close to', 1.500001, 1e-5); | ||
expect(1.5, 'not to be close to', 1.499, 1e-4); | ||
``` | ||
epsilon defaults to 1e-9 if omitted: | ||
```js | ||
expect(1.5, 'to be close to', 1.5000000001); | ||
``` | ||
**match**: asserts `String` regular expression match | ||
@@ -171,0 +191,0 @@ |
@@ -154,5 +154,11 @@ (function () { | ||
getKeysOfDefinedProperties: function (object) { | ||
return filter(getKeys(object), function (key) { | ||
var keys = filter(getKeys(object), function (key) { | ||
return typeof object[key] !== 'undefined'; | ||
}); | ||
// The 'message' property of Error instances is enumerable for some reason, but we want | ||
// to include it in the set when comparing: | ||
if (Object.prototype.toString.call(object) === '[object Error]') { | ||
keys.push('message'); | ||
} | ||
return keys; | ||
}, | ||
@@ -356,7 +362,4 @@ | ||
Unexpected.prototype.format = function (message, args) { | ||
args = map(args, function (arg) { | ||
return this.inspect(arg); | ||
}, this); | ||
message = message.replace(/\{(\d+)\}/g, function (match, n) { | ||
return args[n] || match; | ||
return n in args ? args[n] : match; | ||
}); | ||
@@ -395,9 +398,17 @@ return message; | ||
var handler = Array.prototype.slice.call(arguments, -1)[0]; | ||
var isSeenByExpandedPattern = {}; | ||
forEach(patterns, function (pattern) { | ||
ensureValidPattern(pattern); | ||
forEach(expandPattern(pattern), function (expandedPattern) { | ||
assertions[expandedPattern.text] = { | ||
handler: handler, | ||
flags: expandedPattern.flags | ||
}; | ||
if (expandedPattern.text in assertions) { | ||
if (!isSeenByExpandedPattern[expandedPattern.text]) { | ||
throw new Error('Cannot redefine assertion: ' + expandedPattern.text); | ||
} | ||
} else { | ||
isSeenByExpandedPattern[expandedPattern.text] = true; | ||
assertions[expandedPattern.text] = { | ||
handler: handler, | ||
flags: expandedPattern.flags | ||
}; | ||
} | ||
}); | ||
@@ -575,4 +586,3 @@ }); | ||
testDescriptionString = trim(testDescriptionString.replace(/\[(!?)([^\]]+)\] ?/g, function (match, negate, flag) { | ||
negate = !!negate; | ||
return flags[flag] !== negate ? flag + ' ' : ''; | ||
return Boolean(flags[flag]) !== Boolean(negate) ? flag + ' ' : ''; | ||
})); | ||
@@ -801,3 +811,7 @@ | ||
expect.addAssertion('[not] to be', function (expect, subject, value) { | ||
expect(subject === value, '[not] to be truthy'); | ||
if (typeof subject === 'string' && typeof value === 'string') { | ||
expect(subject, '[not] to equal', value); | ||
} else { | ||
expect(subject === value, '[not] to be truthy'); | ||
} | ||
}); | ||
@@ -829,2 +843,18 @@ | ||
expect.addAssertion('[not] to be close to', function (expect, subject, value, epsilon) { | ||
this.errorMode = 'bubble'; | ||
if (typeof epsilon !== 'number') { | ||
epsilon = 1e-9; | ||
} | ||
try { | ||
expect(Math.abs(subject - value), '[not] to be less than or equal to', epsilon); | ||
} catch (e) { | ||
expect.fail('expected {0} {1} {2} (epsilon: {3})', | ||
expect.inspect(subject), | ||
this.testDescription, | ||
expect.inspect(value), | ||
epsilon.toExponential()); | ||
} | ||
}); | ||
expect.addAssertion('[not] to be (a|an)', function (expect, subject, type) { | ||
@@ -893,3 +923,8 @@ if ('string' === typeof type) { | ||
forEach(getKeys(properties), function (property) { | ||
expect(subject, 'to have [own] property', property, properties[property]); | ||
var value = properties[property]; | ||
if (typeof value === 'undefined') { | ||
expect(subject, 'not to have [own] property', property); | ||
} else { | ||
expect(subject, 'to have [own] property', property, value); | ||
} | ||
}); | ||
@@ -991,24 +1026,24 @@ } catch (e) { | ||
expect.addAssertion('<', 'to be (<|less than|below)', function (expect, subject, value) { | ||
expect(subject < value, 'to be true'); | ||
expect.addAssertion('<', '[not] to be (<|less than|below)', function (expect, subject, value) { | ||
expect(subject < value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('<=', 'to be (<=|less than or equal to)', function (expect, subject, value) { | ||
expect(subject <= value, 'to be true'); | ||
expect.addAssertion('<=', '[not] to be (<=|less than or equal to)', function (expect, subject, value) { | ||
expect(subject <= value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('>', 'to be (>|greater than|above)', function (expect, subject, value) { | ||
expect(subject > value, 'to be true'); | ||
expect.addAssertion('>', '[not] to be (>|greater than|above)', function (expect, subject, value) { | ||
expect(subject > value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('>=', 'to be (>=|greater than or equal to)', function (expect, subject, value) { | ||
expect(subject >= value, 'to be true'); | ||
expect.addAssertion('>=', '[not] to be (>=|greater than or equal to)', function (expect, subject, value) { | ||
expect(subject >= value, '[not] to be true'); | ||
}); | ||
expect.addAssertion('to be positive', function (expect, subject) { | ||
expect(subject, '>', 0); | ||
expect.addAssertion('[not] to be positive', function (expect, subject) { | ||
expect(subject, '[not] to be >', 0); | ||
}); | ||
expect.addAssertion('to be negative', function (expect, subject) { | ||
expect(subject, '<', 0); | ||
expect.addAssertion('[not] to be negative', function (expect, subject) { | ||
expect(subject, '[not] to be <', 0); | ||
}); | ||
@@ -1058,3 +1093,3 @@ | ||
} else if (this.flags.not) { | ||
expect.fail('threw: {0}', e.message); | ||
expect.fail('threw: {0}', expect.inspect(e.message)); | ||
} | ||
@@ -1179,2 +1214,24 @@ thrown = true; | ||
}); | ||
expect.addAssertion('to be canonical', function (expect, subject, stack) { | ||
stack = stack || []; | ||
var i; | ||
for (i = 0 ; i < stack.length ; i += 1) { | ||
if (stack[i] === subject) { | ||
return; | ||
} | ||
} | ||
if (subject && typeof subject === 'object') { | ||
var keys = getKeys(subject); | ||
for (i = 0 ; i < keys.length - 1 ; i += 1) { | ||
expect(keys[i], 'to be less than', keys[i + 1]); | ||
} | ||
stack.push(subject); | ||
forEach(keys, function (key) { | ||
expect(subject[key], 'to be canonical', stack); | ||
}); | ||
stack.pop(subject); | ||
} | ||
}); | ||
}()); | ||
@@ -1181,0 +1238,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
340440
4.36%6898
4.12%654
3.15%