The old style of merging all of a function's variable declarations into
a single statement made some sense back in the days of var, but there's
no reason to keep doing it now that we use const and let.
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.
}
This will allow us to add support for custom object formatters, which
will be a per-runable resource like custom matchers, by injecting them
into the pretty-printer.
This makes it easier to write high quality matchers and asymmetric equality
testers, and is also a step toward supporting custom object formatters.
Previously, Jasmine passed custom object formatters as the second argument
to matcher factories and as and the second argument to asymmetric equality
testers' `asymmetricMatch` method. Matchers and asymmetric equality testers
were responsible for passing the custom object formatters to methods like
`matchersUtil#equals`:
function toEqual(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
// ...
result.pass = util.equals(actual, expected, customEqualityTesters, diffBuilder);
And:
ArrayContaining.prototype.asymmetricMatch = function(other, customTesters) {
// ...
for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i];
if (!j$.matchersUtil.contains(other, item, customTesters)) {
return false;
}
}
With this change, that is no longer necessary. Matchers and asymmetric
equality testers can ignore the existence of custom equality testers and
still fully support them:
function toEqual(util) {
return {
compare: function(actual, expected) {
// ...
result.pass = util.equals(actual, expected, diffBuilder);
And:
ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
// ...
for (var i = 0; i < this.sample.length; i++) {
var item = this.sample[i];
if (!matchersUtil.contains(other, item)) {
return false;
}
}
The old interfaces are still supported, for now, but will be deprecated
in a future commit and removed in the next major release after that.
In addition to making matchers and custom equality testers simpler,
this change sets the stage for adding support for custom object
formatters. Those will be architecturally similar to custom equality
testers, and by injecting a `MatchersUtil` instance everywhere we can
add them without requiring user code to pass them around as used to be
the case with custom object formatters.
This makes it easier to see where each failure message begins and ends.
Before:
Some context: a
multiline
message
After:
Some context:
a
multiline
message
By deferring the evaluation of these messages, we can avoid the
expensive creation of them when in the majority use case (tests are
passing) they are not needed.
These failure messages were causing performance problems with larger
objects needed to be pretty printed as discussed in #520 and brought up
by @rdy.
[fixes#65925900][fixes#520]
- Passing in a 'negativeCompare' will cause that function to be used when it is a 'not' assertion
- Otherwise, the reversal of the compare's result will be used instead
[finishes #59703824]
- Will replace rake core_specs.
- Remove obsolete dependencies & files -- most of these were for build tasks we
are no longer using. Notably, rspec and spec_helper were deleted.
Jasmine spies now have a 'and' property which allows the user to
change the spy's execution strategy-- such as '.and.callReturn(4)'
and a 'calls' property which allows inspection of the calls a spy
has received.
* This is a breaking change *
There is a CallTracker that keeps track of all calls and arguments
and a SpyStrategy which determines what the spy should do when it
is called.