Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

unexpected

Package Overview
Dependencies
Maintainers
2
Versions
330
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

unexpected - npm Package Compare versions

Comparing version 5.0.0-beta3 to 5.0.0-beta30

coverage/lcov-report/lib/styles.js.html

32

Development.md

@@ -14,20 +14,16 @@ # Development

* *src/unexpected-license.js*:<br>
The license file
* *src/unexpected-namespace.js*:<br>
The internal namespace definition
* *src/unexpected-es4-compatible.js*:<br>
ES5 functions shimmed to work in a ES4 compatible environment
* *src/unexpected-utils.js*:<br>
* *lib/index.js*:<br>
The entry point for the library.
* *lib/Unexpected.js*:<br>
The core of the library.
* *lib/Assertion.js*:<br>
The class that assertions are instantiated from.
* *lib/utils.js*:<br>
Utility functions
* *src/unexpected-equal.js*:<br>
Deep-equality
* *src/unexpected-inspect.js*:<br>
Object inspect
* *src/unexpected-core.js*:<br>
The core part of Unexpected
* *src/unexpected-assertions.js*:<br>
The core assertions provided by Unexpected
* *src/unexpected-module.js*:<br>
The module definitions
* *lib/styles.js*:<br>
MagicPen styles for controling the output.
* *lib/types.js*:<br>
Type definitions for every type Unexpected understands.
* *lib/assertions.js*:<br>
All assertions that is included in the core library.

@@ -38,3 +34,3 @@ ## Running tests in the console

make test
make test-production
make test-phantomjs
```

@@ -41,0 +37,0 @@

function Assertion(expect, subject, testDescription, flags, alternations, args) {
this.expect = expect;
this.obj = subject; // deprecated
this.equal = expect.equal.bind(expect); // deprecated
this.eql = this.equal; // deprecated
this.inspect = expect.inspect.bind(expect); // deprecated
this.subject = subject;

@@ -25,7 +21,17 @@ this.testDescription = testDescription;

if (this.args.length > 0) {
var previousArgWasMagicPen = false;
this.args.forEach(function (arg, index) {
var isMagicPen = arg && arg.isMagicPen;
if (0 < index) {
argsOutput.text(', ');
if (!isMagicPen && !previousArgWasMagicPen) {
argsOutput.text(',');
}
argsOutput.text(' ');
}
argsOutput.append(expect.inspect(arg));
if (isMagicPen) {
argsOutput.append(arg);
} else {
argsOutput.append(expect.inspect(arg));
}
previousArgWasMagicPen = isMagicPen;
}, this);

@@ -68,2 +74,8 @@ }

Assertion.prototype.shift = function (expect, subject, assertionIndex) {
var rest = this.args.slice(assertionIndex);
this.args[assertionIndex] = expect.output.clone().error(this.args[assertionIndex]);
expect.apply(expect, [subject].concat(rest));
};
Assertion.prototype.throwStandardError = function () {

@@ -76,10 +88,2 @@ var err = new Error();

Assertion.prototype.assert = function (condition) {
var not = !!this.flags.not;
condition = !!condition;
if (condition === not) {
this.throwStandardError();
}
};
module.exports = Assertion;

@@ -8,3 +8,7 @@ var utils = require('./utils');

expect.addAssertion('[not] to be (ok|truthy)', function (expect, subject) {
this.assert(subject);
var not = !!this.flags.not;
var condition = !!subject;
if (condition === not) {
expect.fail();
}
});

@@ -45,3 +49,3 @@

expect.addAssertion('number', '[not] to be NaN', function (expect, subject) {
expect(isNaN(subject), '[not] to be true');
expect(isNaN(subject), '[not] to be truthy');
});

@@ -67,10 +71,7 @@

if ('string' === typeof type) {
// typeof with support for 'array'
expect('array' === type ? isArray(subject) :
'object' === type ? 'object' === typeof subject && null !== subject :
/^reg(?:exp?|ular expression)$/.test(type) ? isRegExp(subject) :
type === typeof subject,
'[not] to be true');
var subjectType = expect.findTypeOf(subject);
type = /^reg(?:exp?|ular expression)$/.test(type) ? 'regexp' : type;
expect(subjectType.is(type), '[not] to be truthy');
} else {
expect(subject instanceof type, '[not] to be true');
expect(subject instanceof type, '[not] to be truthy');
}

@@ -86,3 +87,3 @@

expect.addAssertion(['string', 'array-like', 'object'], 'to be (the empty|an empty|a non-empty) (string|array|object)', function (expect, subject) {
expect.addAssertion(['string', 'arrayLike'], 'to be (the empty|an empty|a non-empty) (string|array)', function (expect, subject) {
expect(subject, 'to be a', this.alternations[1]);

@@ -93,22 +94,26 @@ expect(subject, this.alternations[0] === 'a non-empty' ? 'not to be empty' : 'to be empty');

expect.addAssertion('[not] to match', function (expect, subject, regexp) {
subject = String(subject);
try {
expect(String(subject).match(regexp), '[not] to be truthy');
} catch (e) {
if (e._isUnexpected && this.flags.not) {
e.createDiff = function (output) {
var lastIndex = 0;
function flushUntilIndex(i) {
if (i > lastIndex) {
output.text(subject.substring(lastIndex, i));
lastIndex = i;
if (e._isUnexpected) {
e.label = 'should match';
if (this.flags.not) {
e.createDiff = function (output) {
var lastIndex = 0;
function flushUntilIndex(i) {
if (i > lastIndex) {
output.text(subject.substring(lastIndex, i));
lastIndex = i;
}
}
}
subject.replace(new RegExp(regexp.source, 'g'), function ($0, index) {
flushUntilIndex(index);
lastIndex += $0.length;
output.diffRemovedHighlight($0);
});
flushUntilIndex(subject.length);
return {diff: output};
};
subject.replace(new RegExp(regexp.source, 'g'), function ($0, index) {
flushUntilIndex(index);
lastIndex += $0.length;
output.diffRemovedHighlight($0);
});
flushUntilIndex(subject.length);
return {diff: output};
};
}
}

@@ -196,3 +201,3 @@ expect.fail(e);

expect.addAssertion(['string', 'object'], 'to be non-empty', function (expect, subject) {
expect.addAssertion(['string', 'arrayLike'], 'to be non-empty', function (expect, subject) {
expect(subject, 'not to be empty');

@@ -248,3 +253,3 @@ });

expect.addAssertion('array-like', '[not] to contain', function (expect, subject) {
expect.addAssertion('arrayLike', '[not] to contain', function (expect, subject) {
var args = Array.prototype.slice.call(arguments, 2);

@@ -270,3 +275,3 @@ try {

expect.addAssertion('number', '[not] to be finite', function (expect, subject) {
expect(isFinite(subject), '[not] to be true');
expect(isFinite(subject), '[not] to be truthy');
});

@@ -280,19 +285,19 @@

this.args = [start + '..' + finish];
expect(subject >= start && subject <= finish, '[not] to be true');
expect(subject >= start && subject <= finish, '[not] to be truthy');
});
expect.addAssertion(['number', 'string'], ['<', '[not] to be (<|less than|below)'], function (expect, subject, value) {
expect(subject < value, '[not] to be true');
expect(subject < value, '[not] to be truthy');
});
expect.addAssertion(['number', 'string'], ['<=', '[not] to be (<=|less than or equal to)'], function (expect, subject, value) {
expect(subject <= value, '[not] to be true');
expect(subject <= value, '[not] to be truthy');
});
expect.addAssertion(['number', 'string'], ['>', '[not] to be (>|greater than|above)'], function (expect, subject, value) {
expect(subject > value, '[not] to be true');
expect(subject > value, '[not] to be truthy');
});
expect.addAssertion(['number', 'string'], ['>=', '[not] to be (>=|greater than or equal to)'], function (expect, subject, value) {
expect(subject >= value, '[not] to be true');
expect(subject >= value, '[not] to be truthy');
});

@@ -310,8 +315,11 @@

try {
expect(expect.equal(value, subject), '[not] to be true');
expect(expect.equal(value, subject), '[not] to be truthy');
} catch (e) {
if (!this.flags.not && e._isUnexpected) {
e.createDiff = function (output, diff) {
return diff(subject, value);
};
if (e._isUnexpected) {
e.label = 'should equal';
if (!this.flags.not) {
e.createDiff = function (output, diff) {
return diff(subject, value);
};
}
}

@@ -359,8 +367,12 @@ expect.fail(e);

// the matching.
expect(thrown, 'to be true');
expect(thrown, 'to be truthy');
} else {
expect(thrown, '[not] to be true');
expect(thrown, '[not] to be truthy');
}
});
expect.addAssertion('function', 'to have arity', function (expect, subject, value) {
expect(subject.length, 'to equal', value);
});
expect.addAssertion('object', 'to be (a|an) [non-empty] (map|hash|object) whose values satisfy', function (expect, subject) {

@@ -374,3 +386,3 @@ var extraArgs = Array.prototype.slice.call(arguments, 2);

if (this.flags['non-empty']) {
expect(subject, 'to be non-empty');
expect(subject, 'not to equal', {});
}

@@ -390,3 +402,3 @@ this.errorMode = 'bubble';

}
});
}, this);

@@ -424,3 +436,3 @@ var errorKeys = Object.keys(errors);

expect.addAssertion('array-like', 'to be (a|an) [non-empty] array whose items satisfy', function (expect, subject) { // ...
expect.addAssertion('arrayLike', 'to be (a|an) [non-empty] array whose items satisfy', function (expect, subject) { // ...
var extraArgs = Array.prototype.slice.call(arguments, 2);

@@ -435,6 +447,6 @@ if (extraArgs.length === 0) {

this.errorMode = 'bubble';
expect.apply(expect, [subject, 'to be an map whose values satisfy'].concat(extraArgs));
expect.apply(expect, [subject, 'to be a map whose values satisfy'].concat(extraArgs));
});
expect.addAssertion('array-like', 'to be (a|an) [non-empty] array of (strings|numbers|booleans|arrays|objects|functions|regexps|regexes|regular expressions)', function (expect, subject) {
expect.addAssertion('arrayLike', 'to be (a|an) [non-empty] array of (strings|numbers|booleans|arrays|objects|functions|regexps|regexes|regular expressions)', function (expect, subject) {
if (this.flags['non-empty']) {

@@ -455,3 +467,3 @@ expect(subject, 'to be non-empty');

if (this.flags['non-empty']) {
expect(subject, 'to be non-empty');
expect(subject, 'not to equal', {});
}

@@ -522,2 +534,21 @@ this.errorMode = 'bubble';

expect.addAssertion('Error', 'to [exhaustively] satisfy [assertion]', function (expect, subject, value) {
var valueType = expect.findTypeOf(value);
if (valueType.is('Error')) {
expect(subject, 'to equal', value);
} else if (valueType.is('object')) {
var keys = valueType.getKeys(value);
keys.forEach(function (key) {
expect(subject[key], 'to [exhaustively] satisfy', value[key]);
});
if (this.flags.exhaustively) {
expect(utils.getKeysOfDefinedProperties(subject), 'to have length', keys.filter(function (key) {
return typeof value[key] !== 'undefined';
}).length);
}
} else {
expect(subject.message, 'to [exhaustively] satisfy', value);
}
});
expect.addAssertion('[not] to [exhaustively] satisfy [assertion]', function (expect, subject, value) {

@@ -537,4 +568,17 @@ if (this.flags.not) {

expect.apply(expect, Array.prototype.slice.call(arguments, 1));
} else if (value && value._expectIt) {
try {
value(subject);
} catch (e) {
if (e._isUnexpected) {
e.createDiff = function (output, diff, inspect, equal) {
return {
diff: output.append(e.output),
inline: false
};
};
}
expect.fail(e);
}
} else if (typeof value === 'function') {
// FIXME: If expect.it, it should be possible to produce a better error message
value(subject);

@@ -545,10 +589,11 @@ } else if (isRegExp(value)) {

var type = expect.findTypeOf(subject, value);
if (type.is('array-like') || type.is('object')) {
if (type.is('arrayLike') || type.is('object')) {
try {
expect(subject, 'to be an object');
type.getKeys(value).forEach(function (key) {
var keys = type.getKeys(value);
keys.forEach(function (key) {
expect(subject[key], 'to [exhaustively] satisfy', value[key]);
});
if (this.flags.exhaustively) {
expect(subject, 'to only have keys', Object.keys(value));
expect(subject, 'to only have keys', keys);
}

@@ -583,2 +628,5 @@ } catch (e) {

} catch (e) {
if (!e._isUnexpected && !value[key]._expectIt) {
expect.fail(e);
}
conflicting = e;

@@ -594,4 +642,15 @@ }

var keyDiff = conflicting.createDiff && conflicting.createDiff(output.clone(), diff, inspect, equal);
if (!keyDiff || (keyDiff && !keyDiff.inline)) {
annotation.error('should satisfy: ')
if (value[key] && value[key]._expectIt) {
if (keyDiff && keyDiff.diff) {
annotation.append(keyDiff.diff);
} else {
annotation.error('should satisfy ').append(inspect(value[key])).nl();
if (conflicting._isUnexpected) {
annotation.append(conflicting.output);
} else {
annotation.error(conflicting.message);
}
}
} else if (!keyDiff || (keyDiff && !keyDiff.inline)) {
annotation.error(conflicting.label || 'should satisfy').sp()
.block(inspect(value[key]));

@@ -626,3 +685,5 @@

}
this.block(annotation.prependLinesWith('error', ' // '));
if (!annotation.isEmpty()) {
this.sp().annotationBlock(annotation);
}
}).nl();

@@ -643,2 +704,46 @@ });

});
function wrapDiffWithTypePrefixAndSuffix(e, type) {
if (e._isUnexpected) {
var createDiff = e.createDiff;
e.createDiff = function (output) { // ...
type.prefix.call(e, output);
var result = createDiff.apply(this, arguments);
type.suffix.call(e, output);
return result;
};
}
return e;
}
expect.addAssertion('wrapperObject', 'to [exhaustively] satisfy', function (expect, subject, value) {
var valueType = expect.findTypeOf(value);
if (valueType.is('wrapperObject')) {
var type = expect.findTypeOf(subject, value);
expect(type.is('wrapperObject'), 'to be truthy');
try {
expect(type.unwrap(subject), 'to [exhaustively] satisfy', type.unwrap(value));
} catch (e) {
expect.fail(wrapDiffWithTypePrefixAndSuffix(e, type));
}
} else {
var subjectType = expect.findTypeOf(subject);
expect(subjectType.is('wrapperObject'), 'to be truthy');
try {
expect(subjectType.unwrap(subject), 'to [exhaustively] satisfy', value);
} catch (e) {
e.label = 'should satisfy';
expect.fail(wrapDiffWithTypePrefixAndSuffix(e, subjectType));
}
}
});
expect.addAssertion('function', 'when called with', function (expect, subject, args) { // ...
this.shift(expect, subject.apply(subject, args), 1);
});
expect.addAssertion('array', 'when passed as parameters to', function (expect, subject, fn) { // ...
this.shift(expect, fn.apply(fn, subject), 1);
});
};
var Unexpected = require('./Unexpected');
module.exports = Unexpected.create()
.installPlugin(require('./colors'))
.installPlugin(require('./styles'))
.installPlugin(require('./types'))
.installPlugin(require('./assertions'));

@@ -16,5 +16,5 @@ var utils = require('./utils');

inspect: function (value, depth, output, inspect) {
output.append(this.prefix);
output.append(this.prefix(output.clone()));
output.append(inspect(this.unwrap(value)));
return output.append(this.suffix);
return output.append(this.suffix(output.clone()));
},

@@ -25,10 +25,8 @@ diff: function (actual, expected, output, diff, inspect) {

var comparison = diff(actual, expected);
if (!comparison) {
return null;
}
if (comparison.inline) {
var prefixOutput = this.prefix(output.clone());
var suffixOutput = this.suffix(output.clone());
if (comparison && comparison.inline) {
return {
inline: true,
diff: output.append(this.prefix).append(comparison.diff).append(this.suffix)
diff: output.append(prefixOutput).append(comparison.diff).append(suffixOutput)
};

@@ -38,15 +36,14 @@ } else {

inline: true,
diff: output.append(this.prefix).nl()
diff: output.append(prefixOutput).nl()
.indentLines()
.i().block(function () {
this.append(inspect(actual)).block(function () {
this.error('should be: ').block(inspect(expected)).nl()
.append(comparison.diff);
this.prependLinesWith(function () {
this.error(' // ');
});
this.append(inspect(actual)).sp().annotationBlock(function () {
this.error('should be ').block(inspect(expected));
if (comparison) {
this.nl().append(comparison.diff);
}
});
}).nl()
.outdentLines()
.append(this.suffix)
.append(suffixOutput)
};

@@ -120,3 +117,9 @@ }

if (hasGetter || !hasSetter) {
propertyOutput.sp().append(inspect(obj[key]));
var value = obj[key];
var inspectedValue = inspect(value);
if (value && value._expectIt) {
propertyOutput.sp().block(inspectedValue);
} else {
propertyOutput.sp().append(inspectedValue);
}
}

@@ -209,3 +212,3 @@

if (!keyDiff || (keyDiff && !keyDiff.inline)) {
annotation.error('should be: ')
annotation.error('should be ')
.block(inspect(expected[key]));

@@ -240,3 +243,5 @@

}
this.block(annotation.prependLinesWith('error', ' // '));
if (!annotation.isEmpty()) {
this.sp().annotationBlock(annotation);
}
}).nl();

@@ -285,3 +290,3 @@ });

expect.addType({
name: 'array-like',
name: 'arrayLike',
base: 'object',

@@ -303,9 +308,17 @@ identify: function (obj) {

},
prefix: function (output) {
return output.text('[');
},
suffix: function (output) {
return output.text(']');
},
inspect: function (arr, depth, output, inspect) {
var prefixOutput = this.prefix(output.clone(), arr);
var suffixOutput = this.suffix(output.clone(), arr);
if (arr.length === 0) {
return output.text('[]');
return output.append(prefixOutput).append(suffixOutput);
}
if (depth === 1) {
return output.text('[...]');
return output.append(prefixOutput).text('...').append(suffixOutput);
}

@@ -336,3 +349,3 @@

if (multipleLines) {
output.text('[').nl().indentLines();
output.append(prefixOutput).nl().indentLines();

@@ -343,5 +356,5 @@ inspectedItems.forEach(function (inspectedItem, index) {

output.outdentLines().text(']');
output.outdentLines().append(suffixOutput);
} else {
output.text('[ ');
output.append(prefixOutput).sp();
inspectedItems.forEach(function (inspectedItem, index) {

@@ -354,3 +367,3 @@ output.append(inspectedItem);

});
output.text(' ]');
output.sp().append(suffixOutput);
}

@@ -411,8 +424,12 @@ return output;

removedItems = 0;
actual.forEach(function (_, index) {
removedItems += removesByIndex[index] || 0;
removeTable[index] = removedItems;
});
function updateRemoveTable() {
removedItems = 0;
actual.forEach(function (_, index) {
removedItems += removesByIndex[index] || 0;
removeTable[index] = removedItems;
});
}
updateRemoveTable();
var moves = itemsDiff.filter(function (diffItem) {

@@ -435,10 +452,5 @@ return diffItem.type === 'move';

removesByIndex[diffItem.from] = movedItems;
updateRemoveTable();
});
removedItems = 0;
actual.forEach(function (_, index) {
removedItems += removesByIndex[index] || 0;
removeTable[index] = removedItems;
});
var inserts = itemsDiff.filter(function (diffItem) {

@@ -467,5 +479,4 @@ return diffItem.type === 'insert';

});
output.append(this.prefix(output.clone())).nl().indentLines();
output.text('[').nl().indentLines();
mutatedArray.forEach(function (diffItem, index) {

@@ -477,6 +488,7 @@ output.i().block(function () {

if (type === 'insert') {
this.error('missing: ').block(inspect(diffItem.value))
.prependLinesWith('error', '// ');
this.annotationBlock(function () {
this.error('missing ').block(inspect(diffItem.value));
});
} else if (type === 'remove') {
this.block(inspect(diffItem.value).text(last ? '' : ',').error(' // should be removed'));
this.block(inspect(diffItem.value).text(last ? ' ' : ', ').error('// should be removed'));
} else if (equal(diffItem.value, diffItem.expected)) {

@@ -489,11 +501,9 @@ this.block(inspect(diffItem.value).text(last ? '' : ','));

} else if (valueDiff) {
this.block(inspect(diffItem.value).text(last ? '' : ',')).block(function () {
this.error('should be: ').append(inspect(diffItem.expected)).nl()
.append(valueDiff.diff)
.prependLinesWith('error', ' // ');
this.block(inspect(diffItem.value).text(last ? ' ' : ', ')).annotationBlock(function () {
this.error('should be ').block(inspect(diffItem.expected)).nl()
.append(valueDiff.diff);
});
} else {
this.block(inspect(diffItem.value).text(last ? '' : ',')).block(function () {
this.error('should be: ').append(inspect(diffItem.expected))
.prependLinesWith('error', ' // ');
this.block(inspect(diffItem.value).text(last ? ' ' : ', ')).annotationBlock(function () {
this.error('should be ').block(inspect(diffItem.expected));
});

@@ -505,3 +515,3 @@ }

output.outdentLines().text(']');
output.outdentLines().append(this.suffix(output.clone()));

@@ -514,3 +524,3 @@ return result;

name: 'array',
base: 'array-like',
base: 'arrayLike',
identify: function (arr) {

@@ -523,3 +533,9 @@ return utils.isArray(arr);

name: 'arguments',
base: 'array-like',
base: 'arrayLike',
prefix: function (output) {
return output.text('arguments(', 'cyan');
},
suffix: function (output) {
return output.text(')', 'cyan');
},
identify: function (obj) {

@@ -577,9 +593,12 @@ return Object.prototype.toString.call(obj) === '[object Arguments]';

},
inspect: function (f, depth, output) {
inspect: function (f, depth, output, inspect) {
var source = f.toString();
var name;
var args;
var body;
var matchSource = source.match(/^function (\w*)?\s*\(([^\)]*)\)\s*\{([\s\S]*?( *)?)\}$/);
if (matchSource) {
var name = matchSource[1];
var args = matchSource[2];
var body = matchSource[3];
name = matchSource[1];
args = matchSource[2];
body = matchSource[3];
var bodyIndent = matchSource[4] || '';

@@ -597,9 +616,8 @@ if (!/\\\n/.test(body)) {

}
output.code('function ' + name + '(' + args + ') {' + body + '}', 'javascript');
} else {
if (f.name) {
output.sp().code(f.name, 'javascript');
}
output.text('(...) {...}');
name = f.name || '';
args = ' /*...*/ ';
body = ' /*...*/ ';
}
output.code('function ' + name + '(' + args + ') {' + body + '}', 'javascript');
return output;

@@ -617,7 +635,15 @@ }

output.text('expect.it(');
var orBranch = false;
f._expectations.forEach(function (expectation, index) {
if (0 < index) {
output.text(').and(');
if (expectation === f._OR) {
orBranch = true;
return;
}
if (orBranch) {
output.text(')\n .or(');
} else if (0 < index) {
output.text(')\n .and(');
}
var args = Array.prototype.slice.call(expectation);

@@ -630,2 +656,3 @@ args.forEach(function (arg, i) {

});
orBranch = false;
});

@@ -666,3 +693,3 @@

name: 'binaryArray',
base: 'array-like',
base: 'arrayLike',
digitWidth: 2,

@@ -700,3 +727,3 @@ hexDumpWidth: 16,

hexChars += leftPad(octet.toString(16).toUpperCase(), this.digitWidth, '0') + ' ';
asciiChars += String.fromCharCode(octet);
asciiChars += String.fromCharCode(octet).replace(/\n/g, '␊').replace(/\r/g, '␍');
} else if (this.digitWidth === 2) {

@@ -730,38 +757,12 @@ hexChars += ' ';

},
diffLimit: 512,
diff: function (actual, expected, output, diff, inspect) {
var result = {
diff: utils.diffStrings(this.hexDump(actual), this.hexDump(expected), output, {type: 'Chars', markUpSpecialCharacters: false})
};
for (var i = 0 ; i < result.diff.output.length ; i += 1) {
var isInAsciiChars = false;
for (var j = 0 ; j < result.diff.output[i].length ; j += 1) {
var obj = result.diff.output[i][j];
var replacement = '';
for (var k = 0 ; k < obj.args[0].length ; k += 1) {
var ch = obj.args[0].charAt(k);
if (ch === '│') {
isInAsciiChars = true;
} else if (isInAsciiChars) {
if (/[\x00-\x1f\x7f-\xff]/.test(ch)) {
ch = '.';
}
} else if (ch === ' ' && /\bbg/.test(obj.args[1])) {
var leftover = obj.args[0].substr(k + 1);
if (replacement) {
obj.args[0] = replacement;
j += 1;
}
replacement = '';
result.diff.output[i].splice(j, 0, {style: 'text', args: [' ', 'white']});
k = 0;
ch = ' ';
if (leftover.length > 0) {
result.diff.output[i].splice(j + 1, 0, {style: 'text', args: [leftover, obj.args[1]]});
}
obj = result.diff.output[i][j];
}
replacement += ch;
}
obj.args[0] = replacement;
}
var result = {diff: output};
if (Math.max(actual.length, expected.length) > this.diffLimit) {
result.diff.comment('Diff suppressed due to size > ' + this.diffLimit);
} else {
result.diff = utils.diffStrings(this.hexDump(actual), this.hexDump(expected), output, {type: 'Chars', markUpSpecialCharacters: false})
.replaceText(/[\x00-\x1f\x7f-\xff␊␍]/g, '.').replaceText(/[│ ]/g, function (styles, content) {
this.text(content);
});
}

@@ -824,2 +825,5 @@ return result;

return typeof value === 'number';
},
inspect: function (value, depth, output) {
return output.number(value);
}

@@ -826,0 +830,0 @@ });

@@ -1,2 +0,2 @@

/*global window*/
/*global setTimeout*/
var Assertion = require('./Assertion');

@@ -50,27 +50,109 @@ var utils = require('./utils');

function createExpectIt(expect, expectations) {
function expectIt(subject) {
var evaluation = expectations.map(function (expectation) {
var OR = {};
function getOrGroups(expectations) {
var orGroups = [[]];
expectations.forEach(function (expectation) {
if (expectation === OR) {
orGroups.push([]);
} else {
orGroups[orGroups.length - 1].push(expectation);
}
});
return orGroups;
}
function evaluateGroup(expect, subject, orGroup) {
var failedGroup = false;
return orGroup.map(function (expectation) {
var args = Array.prototype.slice.call(expectation);
args.unshift(subject);
var evaluation = { expectation: args };
if (!failedGroup) {
evaluation.evaluated = true;
try {
var args = Array.prototype.slice.call(expectation);
args.unshift(subject);
expect.apply(expect, args);
return null;
} catch (e) {
return e;
if (!e._isUnexpected) {
throw e;
}
failedGroup = true;
evaluation.failure = e;
}
}).filter(function (e) {
return e;
});
}
if (evaluation.length > 0) {
expect.fail(function (output) {
evaluation.forEach(function (failedExpectation, index) {
if (index > 0) {
output.text(' and').nl();
return evaluation;
});
}
function writeGroupEvaluationsToOutput(expect, output, groupEvaluations) {
var hasOrClauses = groupEvaluations.length > 1;
var hasAndClauses = groupEvaluations.some(function (groupEvaluation) {
return groupEvaluation.length > 1;
});
groupEvaluations.forEach(function (groupEvaluation, i) {
if (i > 0) {
if (hasAndClauses) {
output.nl();
} else {
output.sp();
}
output.comment('or').nl();
}
groupEvaluation.forEach(function (evaluation, j) {
if (j > 0) {
output.comment(' and').nl();
}
if (evaluation.failure) {
if (hasAndClauses || hasOrClauses) {
output.error('⨯ ');
}
output.append(evaluation.failure.output);
if (!evaluation.failure._hasSerializedErrorMessage) {
var comparison = buildDiff(expect, evaluation.failure);
if (comparison) {
output.nl(2).append(comparison.diff);
}
}
} else {
var style = evaluation.evaluated ? 'success' : 'text';
var expectation = evaluation.expectation;
if (evaluation.evaluated) {
output.success('✓ ');
} else {
output.sp(2);
}
output.append(failedExpectation.output);
output[style]('expected ');
output.text(expect.inspect(expectation[0])).sp();
output[style](expectation[1]);
expectation.slice(2).forEach(function (v) {
output.sp().append(expect.inspect(v));
});
}
});
});
}
function createExpectIt(expect, expectations) {
var orGroups = getOrGroups(expectations);
function expectIt(subject) {
var groupEvaluations = orGroups.map(function (orGroup) {
return evaluateGroup(expect, subject, orGroup);
});
var failed = groupEvaluations.every(function (groupEvaluation) {
return groupEvaluation.some(function (evaluation) {
return evaluation.failure;
});
});
if (failed) {
expect.fail(function (output) {
writeGroupEvaluationsToOutput(expect, output, groupEvaluations);
});
}

@@ -80,2 +162,3 @@ }

expectIt._expectations = expectations;
expectIt._OR = OR;
expectIt.and = function () {

@@ -86,2 +169,7 @@ var copiedExpectations = expectations.slice();

};
expectIt.or = function () {
var copiedExpectations = expectations.slice();
copiedExpectations.push(OR, arguments);
return createExpectIt(expect, copiedExpectations);
};
return expectIt;

@@ -178,3 +266,5 @@ }

error.output = output;
this.setErrorMessage(error);
if (nestingLevel === 0) {
this.setErrorMessage(error);
}
throw error;

@@ -303,2 +393,3 @@ };

function errorWithMessage(e, message) {
delete e._hasSerializedErrorMessage;
var newError = cloneError(e);

@@ -309,8 +400,25 @@ newError.output = message;

function handleNestedExpects(e, assertion) {
function buildDiff(expect, err) {
return err.createDiff && err.createDiff(expect.output.clone(), function (actual, expected) {
return expect.diff(actual, expected);
}, function (v, depth) {
return expect.inspect(v, depth || Infinity);
}, function (actual, expected) {
return expect.equal(actual, expected);
});
}
function handleNestedExpects(expect, e, assertion) {
switch (assertion.errorMode) {
case 'nested':
var newError = errorWithMessage(e, assertion.standardErrorMessage().nl()
.indentLines()
.i().block(e.output));
var comparison = buildDiff(expect, e);
var message = assertion.standardErrorMessage().nl()
.indentLines()
.i().block(function (output) {
output.append(e.output);
if (comparison) {
output.nl(2).append(comparison.diff);
}
});
var newError = errorWithMessage(e, message);
delete newError.createDiff;

@@ -322,2 +430,13 @@ return newError;

return errorWithMessage(e, e.output);
case 'diff':
return errorWithMessage(e, e.output.clone().append(function (output) {
var comparison = buildDiff(expect, e);
delete e.createDiff;
if (comparison && comparison.diff) {
output.append(comparison.diff);
} else {
output.append(e.output);
}
}));
default:

@@ -354,27 +473,23 @@ throw new Error("Unknown error mode: '" + assertion.errorMode + "'");

Unexpected.prototype.setErrorMessage = function (err) {
var outputFormat = this.outputFormat();
var message = err.output.clone().append(err.output);
if (!err._hasSerializedErrorMessage) {
var outputFormat = this.outputFormat();
var message = err.output.clone().append(err.output);
if (err.createDiff) {
var that = this;
var comparison = err.createDiff(message.clone(), function (actual, expected) {
return that.diff(actual, expected);
}, function (v, depth) {
return that.inspect(v, depth || Infinity);
}, function (actual, expected) {
return that.equal(actual, expected);
});
var comparison = buildDiff(this.expect, err);
if (comparison) {
message.nl(2).blue('Diff:').nl(2).append(comparison.diff);
message.nl(2).append(comparison.diff);
}
}
delete err.createDiff;
if (outputFormat === 'html') {
outputFormat = typeof window !== 'undefined' && window.mochaPhantomJS ? 'ansi' : 'text';
err.htmlMessage = message.toString('html');
if (outputFormat === 'html') {
outputFormat = 'text';
err.htmlMessage = message.toString('html');
}
err.output = message;
err.message = '\n' + message.toString(outputFormat);
err._hasSerializedErrorMessage = true;
}
err.output = message;
err.message = '\n' + message.toString(outputFormat);
};
var nestingLevel = 0;
Unexpected.prototype.expect = function expect(subject, testDescriptionString) {

@@ -399,28 +514,37 @@ var that = this;

var nestingLevel = 0;
var callInNestedContext = function (callback) {
if (nestingLevel === 0) {
setTimeout(function () {
nestingLevel = 0;
}, 0);
}
nestingLevel += 1;
try {
callback();
nestingLevel -= 1;
} catch (e) {
nestingLevel -= 1;
if (e._isUnexpected) {
truncateStack(e, wrappedExpect);
if (nestingLevel === 0) {
var wrappedError = handleNestedExpects(e, assertion);
var wrappedError = handleNestedExpects(wrappedExpect, e, assertion);
if (nestingLevel === 1) {
that.setErrorMessage(wrappedError);
throw wrappedError;
}
throw wrappedError;
}
throw e;
} finally {
nestingLevel -= 1;
}
};
var wrappedExpect = function wrappedExpect(subject, testDescriptionString) {
testDescriptionString = testDescriptionString.replace(/\[(!?)([^\]]+)\] ?/g, function (match, negate, flag) {
var wrappedExpect = function wrappedExpect() {
var subject = arguments[0];
var testDescriptionString = arguments[1].replace(/\[(!?)([^\]]+)\] ?/g, function (match, negate, flag) {
return Boolean(flags[flag]) !== Boolean(negate) ? flag + ' ' : '';
}).trim();
var args = Array.prototype.slice.call(arguments, 2);
var args = new Array(arguments.length - 2);
for (var i = 0; i < arguments.length - 2; i += 1) {
args[i] = arguments[i + 2];
}
callInNestedContext(function () {

@@ -446,2 +570,3 @@ that.expect.apply(that, [subject, testDescriptionString].concat(args));

wrappedExpect.format = this.format;
wrappedExpect.it = this.it.bind(this);

@@ -448,0 +573,0 @@ var args = Array.prototype.slice.call(arguments, 2);

@@ -68,8 +68,8 @@ var stringDiff = require('diff');

extend: function (target) {
var sources = Array.prototype.slice.call(arguments, 1);
sources.forEach(function (source) {
for (var i = 1; i < arguments.length; i += 1) {
var source = arguments[i];
Object.keys(source).forEach(function (key) {
target[key] = source[key];
});
});
}
return target;

@@ -167,11 +167,11 @@ },

if (specialCharRegexp.test(part)) {
output.write(specialCharStyle || baseStyle, utils.escapeChar(part));
output[specialCharStyle || baseStyle](utils.escapeChar(part));
} else {
output.write(baseStyle, part);
output[baseStyle](part);
}
});
return output;
} else {
output.write(baseStyle, text);
output[baseStyle](text);
}
return output;
}

@@ -178,0 +178,0 @@

{
"name": "unexpected",
"version": "5.0.0-beta3",
"version": "5.0.0-beta30",
"author": "Sune Sloth Simonsen <sune@we-knowhow.dk>",

@@ -23,19 +23,19 @@ "keywords": [

"arraydiff": "0.1.1",
"diff": "=1.0.8",
"diff": "1.1.0",
"leven": "1.0.0",
"magicpen": "=2.1.0"
"magicpen": "^3.1.1"
},
"devDependencies": {
"browserify": "=5.9.1",
"browserify": "5.9.1",
"bundle-collapser": "^1.1.0",
"coveralls": "^2.11.1",
"es5-shim": "4.0.3",
"istanbul": "^0.3.0",
"es5-shim": "4.0.5",
"istanbul": "0.3.5",
"jshint": "2.5.6",
"mocha": "=1.21.4",
"mocha-phantomjs": "=3.5.0",
"mocha": "2.0.1",
"mocha-phantomjs": "3.5.1",
"mocha-slow-reporter": "*",
"phantomjs": "=1.9.7-15",
"phantomjs": "1.9.12",
"serve": "*"
}
}
# Unexpected
Minimalistic BDD assertion toolkit inspired by
Extensible BDD assertion toolkit inspired by
[expect.js](https://github.com/LearnBoost/expect.js)

@@ -19,3 +19,3 @@

[Run the test in the browser](http://sunesimonsen.github.io/unexpected/test/tests.production.html)
[Run the test in the browser](http://sunesimonsen.github.io/unexpected/test/tests.html)

@@ -176,7 +176,3 @@ ## Features

expect(NaN, 'to be NaN');
expect({}, 'to be NaN');
expect(2, 'not to be NaN');
expect(null, 'not to be NaN');
expect(undefined, 'to be NaN');
expect("String", 'to be NaN');
```

@@ -210,3 +206,2 @@

expect('hello world', 'to contain', 'world');
expect(null, 'not to contain', 'world');
```

@@ -222,3 +217,3 @@

**empty**: asserts that an array is empty or not
**empty**: asserts that an array or array-like object (identified by the presence of a `length` property) is empty

@@ -228,6 +223,5 @@ ```js

expect('', 'to be empty');
expect({}, 'to be empty');
expect({ length: 0, duck: 'typing' }, 'to be empty');
expect({ my: 'object' }, 'not to be empty');
expect([1,2,3], 'not to be empty');
expect({ length: 0, duck: 'typing' }, 'to be empty');
```

@@ -252,3 +246,3 @@

expect({ a: 'a', b: { c: 'c' }, d: 'd' }, 'to have own properties', ['a', 'b']);
expect({ a: 'a', b: { c: 'c' }, d: 'd' }, 'to not have properties', ['k', 'l']);
expect({ a: 'a', b: { c: 'c' }, d: 'd' }, 'not to have properties', ['k', 'l']);
expect({ a: 'a', b: { c: 'c' }, d: 'd' }, 'to have properties', {

@@ -267,3 +261,2 @@ a: 'a',

```js
expect(null, 'not to have key', 'a');
expect({ a: 'b' }, 'to have key', 'a');

@@ -290,2 +283,8 @@ expect({ a: 'b' }, 'not to have key', 'b');

**arity**: asserts that the `Function` takes the given number of arguments
```js
expect(Math.max, 'to have arity', 2);
```
**finite/infinite**: asserts a finite or infinite number

@@ -297,3 +296,2 @@

expect(Infinity, 'to be infinite');
expect(false, 'not to be infinite');
```

@@ -365,3 +363,3 @@

**array whose items satify**: will run an assertion function for each items in an array
**array whose items satisfy**: will run an assertion function for each items in an array

@@ -383,3 +381,3 @@ ```js

Using this assertion result in very detailed error reporting show in the below example:
Using this assertion result in very detailed error reporting as shown in the below example:

@@ -399,12 +397,44 @@ ```js

failed expectation in [ [ 0, 1, 2 ], [ 4, '5', 6 ], [ 7, 8, '9' ] ]:
1: failed expectation in [ 4, '5', 6 ]:
1: expected '5' to be a 'number'
2: failed expectation in [ 7, 8, '9' ]:
2: expected '9' to be a 'number'
1: failed expectation in [ 4, '5', 6 ]:
1: expected '5' to be a number
2: failed expectation in [ 7, 8, '9' ]:
2: expected '9' to be a number
```
**map whose keys satify**: will run an assertion function for each key in a map
**satisfy**: match against a spec
All properties and nested objects mentioned in the right-hand side object are
required to be present. Primitive values are compared with `to equal` semantics:
```js
expect({ hey: { there: true } }, 'to satisfy', { hey: {} });
```
To disallow additional properties in the subject, use `to exhaustively satisfy`:
```js
expect({ hey: { there: true } }, 'to exhaustively satisfy', { hey: { there: true } });
```
Regular expressions and functions in the right-hand side object will be run
against the corresponding values in the subject:
```js
expect({ bar: 'quux', baz: true }, 'to satisfy', { bar: /QU*X/i });
```
Can be combined with `expect.it` to create complex specifications that delegate to
existing assertions:
```js
expect({foo: 123, baz: 'bogus'}, 'to satisfy', {
foo: expect.it('to be a number').and('to be greater than', 10),
baz: expect.it('not to match', /^boh/)
});
```
**map whose keys satisfy**: will run an assertion function for each key in a map
```js
expect({ foo: 0, bar: 1, baz: 2, qux: 3 },

@@ -420,3 +450,3 @@ 'to be a map whose keys satisfy', function (key) {

Using this assertion result in very detailed error reporting show in the below example:
Using this assertion result in very detailed error reporting as shown in the below example:

@@ -434,6 +464,6 @@ ```js

failed expectation on keys foo, bar, baz, qux, quux:
quux: expected 'quux' to have length 3
quux: expected 'quux' to have length 3
```
**map whose values satify**: will run an assertion function for each value in a map
**map whose values satisfy**: will run an assertion function for each value in a map

@@ -451,3 +481,3 @@ ```js

Using this assertion result in very detailed error reporting show in the below example:
Using this assertion result in very detailed error reporting as shown in the below example:

@@ -467,9 +497,11 @@ ```js

failed expectation in
{ foo: [ 0, 1, 2 ],
{
foo: [ 0, 1, 2 ],
bar: [ 4, '5', 6 ],
baz: [ 7, 8, '9' ] }:
bar: failed expectation in [ 4, '5', 6 ]:
1: expected '5' to be a 'number'
baz: failed expectation in [ 7, 8, '9' ]:
2: expected '9' to be a 'number'
baz: [ 7, 8, '9' ]
}:
bar: failed expectation in [ 4, '5', 6 ]:
1: expected '5' to be a number
baz: failed expectation in [ 7, 8, '9' ]:
2: expected '9' to be a number
```

@@ -586,3 +618,3 @@

expected [ 4, 3, 1, 2 ] to be sorted
expected [ 4, 3, 1, 2 ] to equal [ 1, 2, 3, 4 ]
expected [ 4, 3, 1, 2 ] to equal [ 1, 2, 3, 4 ]
```

@@ -593,3 +625,3 @@

[unexpected-assertions.js](https://github.com/sunesimonsen/unexpected/blob/master/lib/unexpected-assertions.js)
[lib/assertions.js](https://github.com/sunesimonsen/unexpected/blob/master/lib/assertions.js)

@@ -631,9 +663,11 @@ ### expect.installPlugin(plugin)

```js
describe('test suite', function () {
it('should expose a function', function () {
expect(add, 'to be a', 'function');
});
describe('math.js', function () {
describe('add', function () {
it('is a function', function () {
expect(add, 'to be a', 'function');
});
it('should do math', function () {
expect(add(1, 3), 'to be', 4);
it('does addition on numbers', function () {
expect(add(1, 3), 'to be', 4);
});
});

@@ -640,0 +674,0 @@ });

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc