Previously, a custom matcher library that wanted to remain compatible with
Jasmine <= 3.5.x could not know whether or not Jasmine expected it to pass
custom equality testers to MatchersUtil#contains. Passing them would produce
a deprecation warning in newer versions and not passing them would break
compatibility with older versions. Now we use matcher factory arity to
determine whether to pass custom equality testers to the factory, which
allows libraries to do something like this:
function matcherFactory(util) {
const customEqualityTesters = arguments[1];
// customEqualityTesters will be undefined in newer versions of Jasmine
// and defined in older versions that expect it to be passed back to
// MatchersUtil#equals.
}
104 lines
2.8 KiB
JavaScript
104 lines
2.8 KiB
JavaScript
getJasmineRequireObj().Expector = function(j$) {
|
|
function Expector(options) {
|
|
this.matchersUtil = options.matchersUtil || {
|
|
buildFailureMessage: function() {}
|
|
};
|
|
this.customEqualityTesters = options.customEqualityTesters || [];
|
|
this.actual = options.actual;
|
|
this.addExpectationResult = options.addExpectationResult || function() {};
|
|
this.filters = new j$.ExpectationFilterChain();
|
|
}
|
|
|
|
Expector.prototype.instantiateMatcher = function(
|
|
matcherName,
|
|
matcherFactory,
|
|
args
|
|
) {
|
|
this.matcherName = matcherName;
|
|
this.args = Array.prototype.slice.call(args, 0);
|
|
this.expected = this.args.slice(0);
|
|
|
|
this.args.unshift(this.actual);
|
|
|
|
// TODO: Remove support for passing customEqualityTesters in the next major release.
|
|
var matcher;
|
|
|
|
if (matcherFactory.length >= 2) {
|
|
matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters);
|
|
} else {
|
|
matcher = matcherFactory(this.matchersUtil);
|
|
}
|
|
|
|
var comparisonFunc = this.filters.selectComparisonFunc(matcher);
|
|
return comparisonFunc || matcher.compare;
|
|
};
|
|
|
|
Expector.prototype.buildMessage = function(result) {
|
|
var self = this;
|
|
|
|
if (result.pass) {
|
|
return '';
|
|
}
|
|
|
|
var msg = this.filters.buildFailureMessage(
|
|
result,
|
|
this.matcherName,
|
|
this.args,
|
|
this.matchersUtil,
|
|
defaultMessage
|
|
);
|
|
return this.filters.modifyFailureMessage(msg || defaultMessage());
|
|
|
|
function defaultMessage() {
|
|
if (!result.message) {
|
|
var args = self.args.slice();
|
|
args.unshift(false);
|
|
args.unshift(self.matcherName);
|
|
return self.matchersUtil.buildFailureMessage.apply(
|
|
self.matchersUtil,
|
|
args
|
|
);
|
|
} else if (j$.isFunction_(result.message)) {
|
|
return result.message();
|
|
} else {
|
|
return result.message;
|
|
}
|
|
}
|
|
};
|
|
|
|
Expector.prototype.compare = function(matcherName, matcherFactory, args) {
|
|
var matcherCompare = this.instantiateMatcher(
|
|
matcherName,
|
|
matcherFactory,
|
|
args
|
|
);
|
|
return matcherCompare.apply(null, this.args);
|
|
};
|
|
|
|
Expector.prototype.addFilter = function(filter) {
|
|
var result = Object.create(this);
|
|
result.filters = this.filters.addFilter(filter);
|
|
return result;
|
|
};
|
|
|
|
Expector.prototype.processResult = function(result, errorForStack) {
|
|
var message = this.buildMessage(result);
|
|
|
|
if (this.expected.length === 1) {
|
|
this.expected = this.expected[0];
|
|
}
|
|
|
|
this.addExpectationResult(result.pass, {
|
|
matcherName: this.matcherName,
|
|
passed: result.pass,
|
|
message: message,
|
|
error: errorForStack ? undefined : result.error,
|
|
errorForStack: errorForStack || undefined,
|
|
actual: this.actual,
|
|
expected: this.expected // TODO: this may need to be arrayified/sliced
|
|
});
|
|
};
|
|
|
|
return Expector;
|
|
};
|