Skip to content

Commit

Permalink
Merge pull request #155 from unexpectedjs/feature/use-type-system-in-…
Browse files Browse the repository at this point in the history
…to-satisfy

Use type system in to satisfy
  • Loading branch information
papandreou committed May 18, 2015
2 parents 8e0ffc2 + 00e9d80 commit 747e1ec
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 119 deletions.
244 changes: 126 additions & 118 deletions lib/assertions.js
Expand Up @@ -619,14 +619,19 @@ module.exports = function (expect) {
}
});
});
} else if (this.flags.assertion) {
}

if (this.flags.assertion) {
this.errorMode = 'bubble'; // to satisfy assertion 'to be a number' => to be a number
if (typeof value === 'string') {
return expect.apply(expect, Array.prototype.slice.call(arguments, 1));
} else {
return expect.apply(expect, [subject, this.flags.exhaustively ? 'to exhaustively satisfy' : 'to satisfy'].concat(Array.prototype.slice.call(arguments, 2)));
}
} else if (value && value._expectIt) {
}

var valueType = expect.findTypeOf(value);
if (valueType.is('expect.it')) {
return expect.withError(function () {
return value(subject);
}, function (e) {
Expand All @@ -639,150 +644,153 @@ module.exports = function (expect) {
}
});
});
} else if (typeof value === 'function') {
}

if (valueType.is('function')) {
return expect.promise(function () {
return value(subject);
});
} else if (isRegExp(value)) {
expect(subject, 'to match', value);
} else {
var subjectType = expect.findTypeOf(subject),
commonType = expect.findCommonType(subject, value),
valueType = expect.findTypeOf(value),
bothAreArrayLike = commonType.is('array-like');
if (commonType.is('array-like') || commonType.is('object')) {
expect(subject, 'to be an object');
var promiseByKey = {};
var keys = valueType.getKeys(value);
keys.forEach(function (key, index) {
promiseByKey[key] = expect.promise(function () {
if (typeof value[key] === 'function') {
return value[key](subject[key]);
} else {
return expect(subject[key], 'to [exhaustively] satisfy', value[key]);
}
});
});
}

if (valueType.is('regexp')) {
return expect(subject, 'to match', value);
}

var flags = this.flags;
var subjectType = expect.findTypeOf(subject),
commonType = expect.findCommonType(subject, value),
bothAreArrayLike = commonType.is('array-like');
if (commonType.is('array-like') || commonType.is('object')) {
expect(subject, 'to be an object');
var promiseByKey = {};
var keys = valueType.getKeys(value);
keys.forEach(function (key, index) {
promiseByKey[key] = expect.promise(function () {
if (typeof value[key] === 'function') {
return value[key](subject[key]);
} else {
return expect(subject[key], 'to [exhaustively] satisfy', value[key]);
}
});
});

return expect.promise.all([
expect.promise(function () {
if (commonType.is('array-like') || flags.exhaustively) {
expect(subject, 'to only have keys', keys);
}
}),
expect.promise.all(promiseByKey)
]).caught(function () {
return expect.promise.settle(promiseByKey).then(function () {
expect.fail({
diff: function (output, diff, inspect, equal) {
var result = {
diff: output,
inline: true
};

var valueType = expect.findTypeOf(value),
keyIndex = {};
subjectType.getKeys(subject).concat(valueType.getKeys(value)).forEach(function (key) {
if (!(key in keyIndex)) {
keyIndex[key] = key;
}
});
var flags = this.flags;

var keys = Object.keys(keyIndex);
return expect.promise.all([
expect.promise(function () {
if (commonType.is('array-like') || flags.exhaustively) {
expect(subject, 'to only have keys', keys);
}
}),
expect.promise.all(promiseByKey)
]).caught(function () {
return expect.promise.settle(promiseByKey).then(function () {
expect.fail({
diff: function (output, diff, inspect, equal) {
var result = {
diff: output,
inline: true
};

if (bothAreArrayLike && subjectType.name !== 'array') {
output.text(subjectType.name);
var valueType = expect.findTypeOf(value),
keyIndex = {};
subjectType.getKeys(subject).concat(valueType.getKeys(value)).forEach(function (key) {
if (!(key in keyIndex)) {
keyIndex[key] = key;
}
output.text(bothAreArrayLike ? '[' : '{').nl().indentLines();
});

keys.forEach(function (key, index) {
output.i().block(function () {
var valueOutput;
var annotation = output.clone();
var conflicting;
var keys = Object.keys(keyIndex);

if (promiseByKey[key] && promiseByKey[key].isRejected()) {
conflicting = promiseByKey[key].reason();
}
var arrayItemOutOfRange = bothAreArrayLike && (index >= subject.length || index >= value.length);
if (bothAreArrayLike && subjectType.name !== 'array') {
output.text(subjectType.name);
}
output.text(bothAreArrayLike ? '[' : '{').nl().indentLines();

var isInlineDiff = true;
keys.forEach(function (key, index) {
output.i().block(function () {
var valueOutput;
var annotation = output.clone();
var conflicting;

if (!(key in value)) {
if (commonType.is('array-like') || flags.exhaustively) {
annotation.error('should be removed');
} else {
conflicting = null;
}
} else if (conflicting || arrayItemOutOfRange) {
var keyDiff = conflicting && conflicting.createDiff && conflicting.createDiff(output.clone(), diff, inspect, equal);
isInlineDiff = !keyDiff || keyDiff.inline ;
if (typeof value[key] === 'function') {
isInlineDiff = false;
annotation.append(conflicting.output);
} else if (!keyDiff || (keyDiff && !keyDiff.inline)) {
annotation.error((conflicting && conflicting.label) || 'should satisfy').sp()
.block(inspect(value[key]));

if (keyDiff) {
annotation.nl().append(keyDiff.diff);
}
} else {
valueOutput = keyDiff.diff;
}
}
if (promiseByKey[key] && promiseByKey[key].isRejected()) {
conflicting = promiseByKey[key].reason();
}
var arrayItemOutOfRange = bothAreArrayLike && (index >= subject.length || index >= value.length);

var isInlineDiff = true;

var last = index === keys.length - 1;
if (!valueOutput) {
if (bothAreArrayLike && key >= subject.length) {
valueOutput = output.clone();
} else {
valueOutput = inspect(subject[key], conflicting ? Infinity : 1);
if (!(key in value)) {
if (commonType.is('array-like') || flags.exhaustively) {
annotation.error('should be removed');
} else {
conflicting = null;
}
} else if (conflicting || arrayItemOutOfRange) {
var keyDiff = conflicting && conflicting.createDiff && conflicting.createDiff(output.clone(), diff, inspect, equal);
isInlineDiff = !keyDiff || keyDiff.inline ;
if (typeof value[key] === 'function') {
isInlineDiff = false;
annotation.append(conflicting.output);
} else if (!keyDiff || (keyDiff && !keyDiff.inline)) {
annotation.error((conflicting && conflicting.label) || 'should satisfy').sp()
.block(inspect(value[key]));

if (keyDiff) {
annotation.nl().append(keyDiff.diff);
}
} else {
valueOutput = keyDiff.diff;
}
}

if (!bothAreArrayLike) {
this.key(key).text(':');
var last = index === keys.length - 1;
if (!valueOutput) {
if (bothAreArrayLike && key >= subject.length) {
valueOutput = output.clone();
} else {
valueOutput = inspect(subject[key], conflicting ? Infinity : 1);
}
valueOutput.amend('text', last ? '' : ',');
}

if (!bothAreArrayLike) {
this.key(key).text(':');
}
valueOutput.amend('text', last ? '' : ',');

if (!bothAreArrayLike) {
if (valueOutput.isBlock() && valueOutput.isMultiline()) {
this.indentLines();
this.nl().i();
} else {
this.sp();
}
}

if (isInlineDiff) {
this.append(valueOutput);
if (!bothAreArrayLike) {
if (valueOutput.isBlock() && valueOutput.isMultiline()) {
this.indentLines();
this.nl().i();
} else {
this.block(valueOutput);
}
if (!annotation.isEmpty()) {
this.sp(valueOutput.isEmpty() ? 0 : 1).annotationBlock(annotation);
this.sp();
}
}).nl();
});
}

output.outdentLines().text(bothAreArrayLike ? ']' : '}');
if (isInlineDiff) {
this.append(valueOutput);
} else {
this.block(valueOutput);
}
if (!annotation.isEmpty()) {
this.sp(valueOutput.isEmpty() ? 0 : 1).annotationBlock(annotation);
}
}).nl();
});

if (!bothAreArrayLike) {
result.diff = utils.wrapConstructorNameAroundOutput(result.diff, subject);
}
output.outdentLines().text(bothAreArrayLike ? ']' : '}');

return result;
if (!bothAreArrayLike) {
result.diff = utils.wrapConstructorNameAroundOutput(result.diff, subject);
}
});

return result;
}
});
});
} else {
expect(subject, 'to equal', value);
}
});
} else {
expect(subject, 'to equal', value);
}
});

Expand Down
2 changes: 1 addition & 1 deletion test/mocha.opts
@@ -1,4 +1,4 @@
--reporter spec
--recursive
--check-leaks
--require ./test/common.js
--require ./test/common

0 comments on commit 747e1ec

Please sign in to comment.