Merge remote-tracking branch 'upstream/main' into array_buffer
# Conflicts: # spec/core/matchers/matchersUtilSpec.js
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
getJasmineRequireObj().CallTracker = function(j$) {
|
||||
|
||||
/**
|
||||
* @namespace Spy#calls
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function CallTracker() {
|
||||
var calls = [];
|
||||
var opts = {};
|
||||
|
||||
this.track = function(context) {
|
||||
if(opts.cloneArgs) {
|
||||
if (opts.cloneArgs) {
|
||||
context.args = j$.util.cloneArgs(context.args);
|
||||
}
|
||||
calls.push(context);
|
||||
@@ -17,6 +17,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Check whether this spy has been invoked.
|
||||
* @name Spy#calls#any
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Boolean}
|
||||
*/
|
||||
@@ -27,6 +28,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get the number of invocations of this spy.
|
||||
* @name Spy#calls#count
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Integer}
|
||||
*/
|
||||
@@ -37,6 +39,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get the arguments that were passed to a specific invocation of this spy.
|
||||
* @name Spy#calls#argsFor
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Integer} index The 0-based invocation index.
|
||||
* @return {Array}
|
||||
@@ -49,6 +52,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get the raw calls array for this spy.
|
||||
* @name Spy#calls#all
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Spy.callData[]}
|
||||
*/
|
||||
@@ -59,12 +63,13 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get all of the arguments for each invocation of this spy in the order they were received.
|
||||
* @name Spy#calls#allArgs
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Array}
|
||||
*/
|
||||
this.allArgs = function() {
|
||||
var callArgs = [];
|
||||
for(var i = 0; i < calls.length; i++){
|
||||
for (var i = 0; i < calls.length; i++) {
|
||||
callArgs.push(calls[i].args);
|
||||
}
|
||||
|
||||
@@ -74,6 +79,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get the first invocation of this spy.
|
||||
* @name Spy#calls#first
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {ObjecSpy.callData}
|
||||
*/
|
||||
@@ -84,6 +90,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Get the most recent invocation of this spy.
|
||||
* @name Spy#calls#mostRecent
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {ObjecSpy.callData}
|
||||
*/
|
||||
@@ -94,6 +101,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Reset this spy as if it has never been called.
|
||||
* @name Spy#calls#reset
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
*/
|
||||
this.reset = function() {
|
||||
@@ -103,12 +111,12 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
/**
|
||||
* Set this spy to do a shallow clone of arguments passed to each invocation.
|
||||
* @name Spy#calls#saveArgumentsByValue
|
||||
* @since 2.5.0
|
||||
* @function
|
||||
*/
|
||||
this.saveArgumentsByValue = function() {
|
||||
opts.cloneArgs = true;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return CallTracker;
|
||||
|
||||
@@ -3,8 +3,8 @@ getJasmineRequireObj().clearStack = function(j$) {
|
||||
|
||||
function messageChannelImpl(global, setTimeout) {
|
||||
var channel = new global.MessageChannel(),
|
||||
head = {},
|
||||
tail = head;
|
||||
head = {},
|
||||
tail = head;
|
||||
|
||||
var taskRunning = false;
|
||||
channel.port1.onmessage = function() {
|
||||
@@ -42,7 +42,7 @@ getJasmineRequireObj().clearStack = function(j$) {
|
||||
var currentCallCount = 0;
|
||||
var realSetTimeout = global.setTimeout;
|
||||
var setTimeoutImpl = function clearStack(fn) {
|
||||
Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]);
|
||||
Function.prototype.apply.apply(realSetTimeout, [global, [fn, 0]]);
|
||||
};
|
||||
|
||||
if (j$.isFunction_(global.setImmediate)) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
getJasmineRequireObj().Clock = function() {
|
||||
|
||||
/* global process */
|
||||
var NODE_JS = typeof process !== 'undefined' && process.versions && typeof process.versions.node === 'string';
|
||||
var NODE_JS =
|
||||
typeof process !== 'undefined' &&
|
||||
process.versions &&
|
||||
typeof process.versions.node === 'string';
|
||||
|
||||
/**
|
||||
* _Note:_ Do not construct this directly, Jasmine will make one during booting. You can get the current clock with {@link jasmine.clock}.
|
||||
@@ -31,12 +33,15 @@ getJasmineRequireObj().Clock = function() {
|
||||
/**
|
||||
* Install the mock clock over the built-in methods.
|
||||
* @name Clock#install
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Clock}
|
||||
*/
|
||||
self.install = function() {
|
||||
if(!originalTimingFunctionsIntact()) {
|
||||
throw new Error('Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?');
|
||||
if (!originalTimingFunctionsIntact()) {
|
||||
throw new Error(
|
||||
'Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?'
|
||||
);
|
||||
}
|
||||
replace(global, fakeTimingFunctions);
|
||||
timer = fakeTimingFunctions;
|
||||
@@ -49,6 +54,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
/**
|
||||
* Uninstall the mock clock, returning the built-in methods to their places.
|
||||
* @name Clock#uninstall
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
*/
|
||||
self.uninstall = function() {
|
||||
@@ -65,6 +71,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
*
|
||||
* The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes.
|
||||
* @name Clock#withMock
|
||||
* @since 2.3.0
|
||||
* @function
|
||||
* @param {Function} closure The function to be called.
|
||||
*/
|
||||
@@ -80,6 +87,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
/**
|
||||
* Instruct the installed Clock to also mock the date returned by `new Date()`
|
||||
* @name Clock#mockDate
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @param {Date} [initialDate=now] The `Date` to provide.
|
||||
*/
|
||||
@@ -88,11 +96,17 @@ getJasmineRequireObj().Clock = function() {
|
||||
};
|
||||
|
||||
self.setTimeout = function(fn, delay, params) {
|
||||
return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
|
||||
return Function.prototype.apply.apply(timer.setTimeout, [
|
||||
global,
|
||||
arguments
|
||||
]);
|
||||
};
|
||||
|
||||
self.setInterval = function(fn, delay, params) {
|
||||
return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
|
||||
return Function.prototype.apply.apply(timer.setInterval, [
|
||||
global,
|
||||
arguments
|
||||
]);
|
||||
};
|
||||
|
||||
self.clearTimeout = function(id) {
|
||||
@@ -106,24 +120,31 @@ getJasmineRequireObj().Clock = function() {
|
||||
/**
|
||||
* Tick the Clock forward, running any enqueued timeouts along the way
|
||||
* @name Clock#tick
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @param {int} millis The number of milliseconds to tick.
|
||||
*/
|
||||
self.tick = function(millis) {
|
||||
if (installed) {
|
||||
delayedFunctionScheduler.tick(millis, function(millis) { mockDate.tick(millis); });
|
||||
delayedFunctionScheduler.tick(millis, function(millis) {
|
||||
mockDate.tick(millis);
|
||||
});
|
||||
} else {
|
||||
throw new Error('Mock clock is not installed, use jasmine.clock().install()');
|
||||
throw new Error(
|
||||
'Mock clock is not installed, use jasmine.clock().install()'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function originalTimingFunctionsIntact() {
|
||||
return global.setTimeout === realTimingFunctions.setTimeout &&
|
||||
return (
|
||||
global.setTimeout === realTimingFunctions.setTimeout &&
|
||||
global.clearTimeout === realTimingFunctions.clearTimeout &&
|
||||
global.setInterval === realTimingFunctions.setInterval &&
|
||||
global.clearInterval === realTimingFunctions.clearInterval;
|
||||
global.clearInterval === realTimingFunctions.clearInterval
|
||||
);
|
||||
}
|
||||
|
||||
function replace(dest, source) {
|
||||
@@ -134,12 +155,22 @@ getJasmineRequireObj().Clock = function() {
|
||||
|
||||
function setTimeout(fn, delay) {
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
|
||||
return delayedFunctionScheduler.scheduleFunction(
|
||||
fn,
|
||||
delay,
|
||||
argSlice(arguments, 2)
|
||||
);
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2), false, timeout);
|
||||
delayedFunctionScheduler.scheduleFunction(
|
||||
fn,
|
||||
delay,
|
||||
argSlice(arguments, 2),
|
||||
false,
|
||||
timeout
|
||||
);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
@@ -150,12 +181,23 @@ getJasmineRequireObj().Clock = function() {
|
||||
|
||||
function setInterval(fn, interval) {
|
||||
if (!NODE_JS) {
|
||||
return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
|
||||
return delayedFunctionScheduler.scheduleFunction(
|
||||
fn,
|
||||
interval,
|
||||
argSlice(arguments, 2),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
var timeout = new FakeTimeout();
|
||||
|
||||
delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true, timeout);
|
||||
delayedFunctionScheduler.scheduleFunction(
|
||||
fn,
|
||||
interval,
|
||||
argSlice(arguments, 2),
|
||||
true,
|
||||
timeout
|
||||
);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
@@ -174,11 +216,11 @@ getJasmineRequireObj().Clock = function() {
|
||||
*/
|
||||
function FakeTimeout() {}
|
||||
|
||||
FakeTimeout.prototype.ref = function () {
|
||||
FakeTimeout.prototype.ref = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
FakeTimeout.prototype.unref = function () {
|
||||
FakeTimeout.prototype.unref = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
@@ -15,11 +15,20 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
currentTime = endTime;
|
||||
};
|
||||
|
||||
self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
|
||||
self.scheduleFunction = function(
|
||||
funcToCall,
|
||||
millis,
|
||||
params,
|
||||
recurring,
|
||||
timeoutKey,
|
||||
runAtMillis
|
||||
) {
|
||||
var f;
|
||||
if (typeof(funcToCall) === 'string') {
|
||||
if (typeof funcToCall === 'string') {
|
||||
/* jshint evil: true */
|
||||
f = function() { return eval(funcToCall); };
|
||||
f = function() {
|
||||
return eval(funcToCall);
|
||||
};
|
||||
/* jshint evil: false */
|
||||
} else {
|
||||
f = funcToCall;
|
||||
@@ -27,7 +36,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
|
||||
millis = millis || 0;
|
||||
timeoutKey = timeoutKey || ++delayedFnCount;
|
||||
runAtMillis = runAtMillis || (currentTime + millis);
|
||||
runAtMillis = runAtMillis || currentTime + millis;
|
||||
|
||||
var funcToSchedule = {
|
||||
runAtMillis: runAtMillis,
|
||||
@@ -43,7 +52,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
} else {
|
||||
scheduledFunctions[runAtMillis] = [funcToSchedule];
|
||||
scheduledLookup.push(runAtMillis);
|
||||
scheduledLookup.sort(function (a, b) {
|
||||
scheduledLookup.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
}
|
||||
@@ -56,7 +65,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
|
||||
for (var runAtMillis in scheduledFunctions) {
|
||||
var funcs = scheduledFunctions[runAtMillis];
|
||||
var i = indexOfFirstToPass(funcs, function (func) {
|
||||
var i = indexOfFirstToPass(funcs, function(func) {
|
||||
return func.timeoutKey === timeoutKey;
|
||||
});
|
||||
|
||||
@@ -92,7 +101,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
|
||||
function deleteFromLookup(key) {
|
||||
var value = Number(key);
|
||||
var i = indexOfFirstToPass(scheduledLookup, function (millis) {
|
||||
var i = indexOfFirstToPass(scheduledLookup, function(millis) {
|
||||
return millis === value;
|
||||
});
|
||||
|
||||
@@ -102,12 +111,14 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
}
|
||||
|
||||
function reschedule(scheduledFn) {
|
||||
self.scheduleFunction(scheduledFn.funcToCall,
|
||||
self.scheduleFunction(
|
||||
scheduledFn.funcToCall,
|
||||
scheduledFn.millis,
|
||||
scheduledFn.params,
|
||||
true,
|
||||
scheduledFn.timeoutKey,
|
||||
scheduledFn.runAtMillis + scheduledFn.millis);
|
||||
scheduledFn.runAtMillis + scheduledFn.millis
|
||||
);
|
||||
}
|
||||
|
||||
function forEachFunction(funcsToRun, callback) {
|
||||
@@ -148,11 +159,13 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
funcToRun.funcToCall.apply(null, funcToRun.params || []);
|
||||
});
|
||||
deletedKeys = [];
|
||||
} while (scheduledLookup.length > 0 &&
|
||||
// checking first if we're out of time prevents setTimeout(0)
|
||||
// scheduled in a funcToRun from forcing an extra iteration
|
||||
currentTime !== endTime &&
|
||||
scheduledLookup[0] <= endTime);
|
||||
} while (
|
||||
scheduledLookup.length > 0 &&
|
||||
// checking first if we're out of time prevents setTimeout(0)
|
||||
// scheduled in a funcToRun from forcing an extra iteration
|
||||
currentTime !== endTime &&
|
||||
scheduledLookup[0] <= endTime
|
||||
);
|
||||
|
||||
// ran out of functions to call, but still time left on the clock
|
||||
if (currentTime !== endTime) {
|
||||
|
||||
695
src/core/Env.js
695
src/core/Env.js
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,16 @@
|
||||
getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
|
||||
var ignoredProperties = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description', 'jasmineMessage'];
|
||||
var ignoredProperties = [
|
||||
'name',
|
||||
'message',
|
||||
'stack',
|
||||
'fileName',
|
||||
'sourceURL',
|
||||
'line',
|
||||
'lineNumber',
|
||||
'column',
|
||||
'description',
|
||||
'jasmineMessage'
|
||||
];
|
||||
|
||||
function ExceptionFormatter(options) {
|
||||
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
@@ -49,10 +59,11 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
|
||||
function filterJasmine(stackTrace) {
|
||||
var result = [],
|
||||
jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
|
||||
jasmineMarker =
|
||||
stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
|
||||
|
||||
stackTrace.frames.forEach(function(frame) {
|
||||
if (frame.file && frame.file !== jasmineFile) {
|
||||
if (frame.file !== jasmineFile) {
|
||||
result.push(frame.raw);
|
||||
} else if (result[result.length - 1] !== jasmineMarker) {
|
||||
result.push(jasmineMarker);
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
getJasmineRequireObj().Expectation = function(j$) {
|
||||
var promiseForMessage = {
|
||||
jasmineToString: function() { return 'a promise'; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Matchers that come with Jasmine out of the box.
|
||||
* @namespace matchers
|
||||
@@ -12,7 +8,10 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
|
||||
var customMatchers = options.customMatchers || {};
|
||||
for (var matcherName in customMatchers) {
|
||||
this[matcherName] = wrapSyncCompare(matcherName, customMatchers[matcherName]);
|
||||
this[matcherName] = wrapSyncCompare(
|
||||
matcherName,
|
||||
customMatchers[matcherName]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +19,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
* Add some context for an {@link expect}
|
||||
* @function
|
||||
* @name matchers#withContext
|
||||
* @since 3.3.0
|
||||
* @param {String} message - Additional context to show when the matcher fails
|
||||
* @return {matchers}
|
||||
*/
|
||||
@@ -31,6 +31,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
* Invert the matcher following this {@link expect}
|
||||
* @member
|
||||
* @name matchers#not
|
||||
* @since 1.3.0
|
||||
* @type {matchers}
|
||||
* @example
|
||||
* expect(something).not.toBe(true);
|
||||
@@ -50,11 +51,17 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
this.expector = new j$.Expector(options);
|
||||
|
||||
if (!global.Promise) {
|
||||
throw new Error('expectAsync is unavailable because the environment does not support promises.');
|
||||
throw new Error(
|
||||
'expectAsync is unavailable because the environment does not support promises.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!j$.isPromiseLike(this.expector.actual)) {
|
||||
throw new Error('Expected expectAsync to be called with a promise.');
|
||||
var customAsyncMatchers = options.customAsyncMatchers || {};
|
||||
for (var matcherName in customAsyncMatchers) {
|
||||
this[matcherName] = wrapAsyncCompare(
|
||||
matcherName,
|
||||
customAsyncMatchers[matcherName]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +69,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
* Add some context for an {@link expectAsync}
|
||||
* @function
|
||||
* @name async-matchers#withContext
|
||||
* @since 3.3.0
|
||||
* @param {String} message - Additional context to show when the async matcher fails
|
||||
* @return {async-matchers}
|
||||
*/
|
||||
@@ -100,9 +108,11 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
// frames that are relevant to the user instead of just parts of Jasmine.
|
||||
var errorForStack = j$.util.errorWithStack();
|
||||
|
||||
return this.expector.compare(name, matcherFactory, arguments).then(function(result) {
|
||||
self.expector.processResult(result, errorForStack, promiseForMessage);
|
||||
});
|
||||
return this.expector
|
||||
.compare(name, matcherFactory, arguments)
|
||||
.then(function(result) {
|
||||
self.expector.processResult(result, errorForStack);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -119,7 +129,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function negatedFailureMessage(result, matcherName, args, util) {
|
||||
function negatedFailureMessage(result, matcherName, args, matchersUtil) {
|
||||
if (result.message) {
|
||||
if (j$.isFunction_(result.message)) {
|
||||
return result.message();
|
||||
@@ -131,7 +141,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
args = args.slice();
|
||||
args.unshift(true);
|
||||
args.unshift(matcherName);
|
||||
return util.buildFailureMessage.apply(null, args);
|
||||
return matchersUtil.buildFailureMessage.apply(matchersUtil, args);
|
||||
}
|
||||
|
||||
function negate(result) {
|
||||
@@ -156,7 +166,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
return matcher.compare.apply(this, arguments).then(negate);
|
||||
}
|
||||
|
||||
return defaultNegativeCompare;
|
||||
return matcher.negativeCompare || defaultNegativeCompare;
|
||||
},
|
||||
buildFailureMessage: negatedFailureMessage
|
||||
};
|
||||
@@ -166,9 +176,19 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
}
|
||||
|
||||
ContextAddingFilter.prototype.modifyFailureMessage = function(msg) {
|
||||
return this.message + ': ' + msg;
|
||||
var nl = msg.indexOf('\n');
|
||||
|
||||
if (nl === -1) {
|
||||
return this.message + ': ' + msg;
|
||||
} else {
|
||||
return this.message + ':\n' + indent(msg);
|
||||
}
|
||||
};
|
||||
|
||||
function indent(s) {
|
||||
return s.replace(/^/gm, ' ');
|
||||
}
|
||||
|
||||
return {
|
||||
factory: function(options) {
|
||||
return new Expectation(options || {});
|
||||
|
||||
@@ -12,7 +12,12 @@ getJasmineRequireObj().ExpectationFilterChain = function() {
|
||||
return this.callFirst_('selectComparisonFunc', arguments).result;
|
||||
};
|
||||
|
||||
ExpectationFilterChain.prototype.buildFailureMessage = function(result, matcherName, args, util) {
|
||||
ExpectationFilterChain.prototype.buildFailureMessage = function(
|
||||
result,
|
||||
matcherName,
|
||||
args,
|
||||
matchersUtil
|
||||
) {
|
||||
return this.callFirst_('buildFailureMessage', arguments).result;
|
||||
};
|
||||
|
||||
@@ -39,7 +44,7 @@ getJasmineRequireObj().ExpectationFilterChain = function() {
|
||||
};
|
||||
}
|
||||
|
||||
return {found: false};
|
||||
return { found: false };
|
||||
};
|
||||
|
||||
return ExpectationFilterChain;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//TODO: expectation result may make more sense as a presentation of an expectation.
|
||||
getJasmineRequireObj().buildExpectationResult = function() {
|
||||
getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
function buildExpectationResult(options) {
|
||||
var messageFormatter = options.messageFormatter || function() {},
|
||||
stackFormatter = options.stackFormatter || function() {};
|
||||
@@ -20,9 +20,25 @@ getJasmineRequireObj().buildExpectationResult = function() {
|
||||
passed: options.passed
|
||||
};
|
||||
|
||||
if(!result.passed) {
|
||||
if (!result.passed) {
|
||||
result.expected = options.expected;
|
||||
result.actual = options.actual;
|
||||
|
||||
if (options.error && !j$.isString_(options.error)) {
|
||||
if ('code' in options.error) {
|
||||
result.code = options.error.code;
|
||||
}
|
||||
|
||||
if (
|
||||
options.error.code === 'ERR_ASSERTION' &&
|
||||
options.expected === '' &&
|
||||
options.actual === ''
|
||||
) {
|
||||
result.expected = options.error.expected;
|
||||
result.actual = options.error.actual;
|
||||
result.matcherName = 'assert ' + options.error.operator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
getJasmineRequireObj().Expector = function(j$) {
|
||||
function Expector(options) {
|
||||
this.util = options.util || { buildFailureMessage: function() {} };
|
||||
this.matchersUtil = options.matchersUtil || {
|
||||
buildFailureMessage: function() {}
|
||||
};
|
||||
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||
this.actual = options.actual;
|
||||
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||
this.addExpectationResult = options.addExpectationResult || function() {};
|
||||
this.filters = new j$.ExpectationFilterChain();
|
||||
}
|
||||
|
||||
Expector.prototype.instantiateMatcher = function(matcherName, matcherFactory, args) {
|
||||
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);
|
||||
|
||||
var matcher = matcherFactory(this.util, this.customEqualityTesters);
|
||||
var matcher = matcherFactory(this.matchersUtil, this.customEqualityTesters);
|
||||
var comparisonFunc = this.filters.selectComparisonFunc(matcher);
|
||||
return comparisonFunc || matcher.compare;
|
||||
};
|
||||
@@ -26,7 +32,13 @@ getJasmineRequireObj().Expector = function(j$) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var msg = this.filters.buildFailureMessage(result, this.matcherName, this.args, this.util, defaultMessage);
|
||||
var msg = this.filters.buildFailureMessage(
|
||||
result,
|
||||
this.matcherName,
|
||||
this.args,
|
||||
this.matchersUtil,
|
||||
defaultMessage
|
||||
);
|
||||
return this.filters.modifyFailureMessage(msg || defaultMessage());
|
||||
|
||||
function defaultMessage() {
|
||||
@@ -34,7 +46,10 @@ getJasmineRequireObj().Expector = function(j$) {
|
||||
var args = self.args.slice();
|
||||
args.unshift(false);
|
||||
args.unshift(self.matcherName);
|
||||
return self.util.buildFailureMessage.apply(null, args);
|
||||
return self.matchersUtil.buildFailureMessage.apply(
|
||||
self.matchersUtil,
|
||||
args
|
||||
);
|
||||
} else if (j$.isFunction_(result.message)) {
|
||||
return result.message();
|
||||
} else {
|
||||
@@ -44,7 +59,11 @@ getJasmineRequireObj().Expector = function(j$) {
|
||||
};
|
||||
|
||||
Expector.prototype.compare = function(matcherName, matcherFactory, args) {
|
||||
var matcherCompare = this.instantiateMatcher(matcherName, matcherFactory, args);
|
||||
var matcherCompare = this.instantiateMatcher(
|
||||
matcherName,
|
||||
matcherFactory,
|
||||
args
|
||||
);
|
||||
return matcherCompare.apply(null, this.args);
|
||||
};
|
||||
|
||||
@@ -54,26 +73,22 @@ getJasmineRequireObj().Expector = function(j$) {
|
||||
return result;
|
||||
};
|
||||
|
||||
Expector.prototype.processResult = function(result, errorForStack, actualOverride) {
|
||||
this.args[0] = actualOverride || this.args[0];
|
||||
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
|
||||
}
|
||||
);
|
||||
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;
|
||||
|
||||
@@ -38,7 +38,10 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
var errorTypes = Object.keys(this.originalHandlers);
|
||||
for (var iType = 0; iType < errorTypes.length; iType++) {
|
||||
var errorType = errorTypes[iType];
|
||||
global.process.removeListener(errorType, this.jasmineHandlers[errorType]);
|
||||
global.process.removeListener(
|
||||
errorType,
|
||||
this.jasmineHandlers[errorType]
|
||||
);
|
||||
for (var i = 0; i < this.originalHandlers[errorType].length; i++) {
|
||||
global.process.on(errorType, this.originalHandlers[errorType][i]);
|
||||
}
|
||||
@@ -49,15 +52,42 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
};
|
||||
|
||||
this.install = function install() {
|
||||
if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
|
||||
if (
|
||||
global.process &&
|
||||
global.process.listeners &&
|
||||
j$.isFunction_(global.process.on)
|
||||
) {
|
||||
this.installOne_('uncaughtException', 'Uncaught exception');
|
||||
this.installOne_('unhandledRejection', 'Unhandled promise rejection');
|
||||
} else {
|
||||
var originalHandler = global.onerror;
|
||||
global.onerror = onerror;
|
||||
|
||||
var browserRejectionHandler = function browserRejectionHandler(event) {
|
||||
if (j$.isError_(event.reason)) {
|
||||
event.reason.jasmineMessage =
|
||||
'Unhandled promise rejection: ' + event.reason;
|
||||
global.onerror(event.reason);
|
||||
} else {
|
||||
global.onerror('Unhandled promise rejection: ' + event.reason);
|
||||
}
|
||||
};
|
||||
|
||||
if (global.addEventListener) {
|
||||
global.addEventListener(
|
||||
'unhandledrejection',
|
||||
browserRejectionHandler
|
||||
);
|
||||
}
|
||||
|
||||
this.uninstall = function uninstall() {
|
||||
global.onerror = originalHandler;
|
||||
if (global.removeEventListener) {
|
||||
global.removeEventListener(
|
||||
'unhandledrejection',
|
||||
browserRejectionHandler
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -66,7 +96,11 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
handlers.push(listener);
|
||||
};
|
||||
|
||||
this.popListener = function popListener() {
|
||||
this.popListener = function popListener(listener) {
|
||||
if (!listener) {
|
||||
throw new Error('popListener expects a listener');
|
||||
}
|
||||
|
||||
handlers.pop();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
* @hideconstructor
|
||||
*/
|
||||
function JsApiReporter(options) {
|
||||
var timer = options.timer || j$.noopTimer,
|
||||
status = 'loaded';
|
||||
var timer = options.timer || new j$.Timer(),
|
||||
status = 'loaded';
|
||||
|
||||
this.started = false;
|
||||
this.finished = false;
|
||||
@@ -31,6 +31,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* Get the current status for the Jasmine environment.
|
||||
* @name jsApiReporter#status
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {String} - One of `loaded`, `started`, or `done`
|
||||
*/
|
||||
@@ -54,6 +55,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
*
|
||||
* Retrievable in slices for easier serialization.
|
||||
* @name jsApiReporter#suiteResults
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @param {Number} index - The position in the suites list to start from.
|
||||
* @param {Number} length - Maximum number of suite results to return.
|
||||
@@ -71,6 +73,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* Get all of the suites in a single object, with their `id` as the key.
|
||||
* @name jsApiReporter#suites
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Object} - Map of suite id to {@link SuiteResult}
|
||||
*/
|
||||
@@ -89,6 +92,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
*
|
||||
* Retrievable in slices for easier serialization.
|
||||
* @name jsApiReporter#specResults
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Number} index - The position in the specs list to start from.
|
||||
* @param {Number} length - Maximum number of specs results to return.
|
||||
@@ -101,6 +105,7 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* Get all spec results.
|
||||
* @name jsApiReporter#specs
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {SpecResult[]}
|
||||
*/
|
||||
@@ -111,13 +116,13 @@ getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* Get the number of milliseconds it took for the full Jasmine suite to run.
|
||||
* @name jsApiReporter#executionTime
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @return {Number}
|
||||
*/
|
||||
this.executionTime = function() {
|
||||
return executionTime;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return JsApiReporter;
|
||||
|
||||
@@ -37,7 +37,7 @@ getJasmineRequireObj().MockDate = function() {
|
||||
return self;
|
||||
|
||||
function FakeDate() {
|
||||
switch(arguments.length) {
|
||||
switch (arguments.length) {
|
||||
case 0:
|
||||
return new GlobalDate(currentTime);
|
||||
case 1:
|
||||
@@ -47,16 +47,39 @@ getJasmineRequireObj().MockDate = function() {
|
||||
case 3:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2]);
|
||||
case 4:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
|
||||
return new GlobalDate(
|
||||
arguments[0],
|
||||
arguments[1],
|
||||
arguments[2],
|
||||
arguments[3]
|
||||
);
|
||||
case 5:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4]);
|
||||
return new GlobalDate(
|
||||
arguments[0],
|
||||
arguments[1],
|
||||
arguments[2],
|
||||
arguments[3],
|
||||
arguments[4]
|
||||
);
|
||||
case 6:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5]);
|
||||
return new GlobalDate(
|
||||
arguments[0],
|
||||
arguments[1],
|
||||
arguments[2],
|
||||
arguments[3],
|
||||
arguments[4],
|
||||
arguments[5]
|
||||
);
|
||||
default:
|
||||
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
|
||||
arguments[4], arguments[5], arguments[6]);
|
||||
return new GlobalDate(
|
||||
arguments[0],
|
||||
arguments[1],
|
||||
arguments[2],
|
||||
arguments[3],
|
||||
arguments[4],
|
||||
arguments[5],
|
||||
arguments[6]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +99,7 @@ getJasmineRequireObj().MockDate = function() {
|
||||
FakeDate.parse = GlobalDate.parse;
|
||||
FakeDate.UTC = GlobalDate.UTC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MockDate;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
getJasmineRequireObj().Order = function() {
|
||||
function Order(options) {
|
||||
this.random = 'random' in options ? options.random : true;
|
||||
var seed = this.seed = options.seed || generateSeed();
|
||||
var seed = (this.seed = options.seed || generateSeed());
|
||||
this.sort = this.random ? randomOrder : naturalOrder;
|
||||
|
||||
function naturalOrder(items) {
|
||||
@@ -29,17 +29,16 @@ getJasmineRequireObj().Order = function() {
|
||||
|
||||
function jenkinsHash(key) {
|
||||
var hash, i;
|
||||
for(hash = i = 0; i < key.length; ++i) {
|
||||
for (hash = i = 0; i < key.length; ++i) {
|
||||
hash += key.charCodeAt(i);
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
hash += hash << 10;
|
||||
hash ^= hash >> 6;
|
||||
}
|
||||
hash += (hash << 3);
|
||||
hash ^= (hash >> 11);
|
||||
hash += (hash << 15);
|
||||
hash += hash << 3;
|
||||
hash ^= hash >> 11;
|
||||
hash += hash << 15;
|
||||
return hash;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Order;
|
||||
|
||||
@@ -1,35 +1,51 @@
|
||||
getJasmineRequireObj().pp = function(j$) {
|
||||
|
||||
function PrettyPrinter() {
|
||||
getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
function SinglePrettyPrintRun(customObjectFormatters, pp) {
|
||||
this.customObjectFormatters_ = customObjectFormatters;
|
||||
this.ppNestLevel_ = 0;
|
||||
this.seen = [];
|
||||
this.length = 0;
|
||||
this.stringParts = [];
|
||||
this.pp_ = pp;
|
||||
}
|
||||
|
||||
function hasCustomToString(value) {
|
||||
// value.toString !== Object.prototype.toString if value has no custom toString but is from another context (e.g.
|
||||
// iframe, web worker)
|
||||
return j$.isFunction_(value.toString) && value.toString !== Object.prototype.toString && (value.toString() !== Object.prototype.toString.call(value));
|
||||
try {
|
||||
return (
|
||||
j$.isFunction_(value.toString) &&
|
||||
value.toString !== Object.prototype.toString &&
|
||||
value.toString() !== Object.prototype.toString.call(value)
|
||||
);
|
||||
} catch (e) {
|
||||
// The custom toString() threw.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PrettyPrinter.prototype.format = function(value) {
|
||||
SinglePrettyPrintRun.prototype.format = function(value) {
|
||||
this.ppNestLevel_++;
|
||||
try {
|
||||
if (j$.util.isUndefined(value)) {
|
||||
var customFormatResult = this.applyCustomFormatters_(value);
|
||||
|
||||
if (customFormatResult) {
|
||||
this.emitScalar(customFormatResult);
|
||||
} else if (j$.util.isUndefined(value)) {
|
||||
this.emitScalar('undefined');
|
||||
} else if (value === null) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === 0 && 1/value === -Infinity) {
|
||||
} else if (value === 0 && 1 / value === -Infinity) {
|
||||
this.emitScalar('-0');
|
||||
} else if (value === j$.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString());
|
||||
this.emitScalar(value.jasmineToString(this.pp_));
|
||||
} else if (typeof value === 'string') {
|
||||
this.emitString(value);
|
||||
} else if (j$.isSpy(value)) {
|
||||
this.emitScalar('spy on ' + value.and.identity);
|
||||
} else if (j$.isSpy(value.toString)) {
|
||||
this.emitScalar('spy on ' + value.toString.and.identity);
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
@@ -48,10 +64,23 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.emitMap(value);
|
||||
} else if (j$.isTypedArray_(value)) {
|
||||
this.emitTypedArray(value);
|
||||
} else if (value.toString && typeof value === 'object' && !j$.isArray_(value) && hasCustomToString(value)) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (
|
||||
value.toString &&
|
||||
typeof value === 'object' &&
|
||||
!j$.isArray_(value) &&
|
||||
hasCustomToString(value)
|
||||
) {
|
||||
try {
|
||||
this.emitScalar(value.toString());
|
||||
} catch (e) {
|
||||
this.emitScalar('has-invalid-toString-method');
|
||||
}
|
||||
} else if (j$.util.arrayContains(this.seen, value)) {
|
||||
this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
|
||||
this.emitScalar(
|
||||
'<circular reference: ' +
|
||||
(j$.isArray_(value) ? 'Array' : 'Object') +
|
||||
'>'
|
||||
);
|
||||
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
|
||||
this.seen.push(value);
|
||||
if (j$.isArray_(value)) {
|
||||
@@ -72,7 +101,11 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.iterateObject = function(obj, fn) {
|
||||
SinglePrettyPrintRun.prototype.applyCustomFormatters_ = function(value) {
|
||||
return customFormat(value, this.customObjectFormatters_);
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) {
|
||||
var objKeys = keys(obj, j$.isArray_(obj));
|
||||
var isGetter = function isGetter(prop) {};
|
||||
|
||||
@@ -81,7 +114,6 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
var getter = obj.__lookupGetter__(prop);
|
||||
return !j$.util.isUndefined(getter) && getter !== null;
|
||||
};
|
||||
|
||||
}
|
||||
var length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
for (var i = 0; i < length; i++) {
|
||||
@@ -92,15 +124,15 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
return objKeys.length > length;
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitScalar = function(value) {
|
||||
SinglePrettyPrintRun.prototype.emitScalar = function(value) {
|
||||
this.append(value);
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitString = function(value) {
|
||||
this.append('\'' + value + '\'');
|
||||
SinglePrettyPrintRun.prototype.emitString = function(value) {
|
||||
this.append("'" + value + "'");
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitArray = function(array) {
|
||||
SinglePrettyPrintRun.prototype.emitArray = function(array) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Array');
|
||||
return;
|
||||
@@ -113,7 +145,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
this.format(array[i]);
|
||||
}
|
||||
if(array.length > length){
|
||||
if (array.length > length) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
@@ -129,12 +161,14 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
self.formatProperty(array, property, isGetter);
|
||||
});
|
||||
|
||||
if (truncated) { this.append(', ...'); }
|
||||
if (truncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' ]');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitSet = function(set) {
|
||||
SinglePrettyPrintRun.prototype.emitSet = function(set) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Set');
|
||||
return;
|
||||
@@ -142,7 +176,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append('Set( ');
|
||||
var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var i = 0;
|
||||
set.forEach( function( value, key ) {
|
||||
set.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
@@ -152,14 +186,14 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.format(value);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (set.size > size){
|
||||
}, this);
|
||||
if (set.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitMap = function(map) {
|
||||
SinglePrettyPrintRun.prototype.emitMap = function(map) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Map');
|
||||
return;
|
||||
@@ -167,30 +201,31 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append('Map( ');
|
||||
var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var i = 0;
|
||||
map.forEach( function( value, key ) {
|
||||
map.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format([key,value]);
|
||||
this.format([key, value]);
|
||||
|
||||
i++;
|
||||
}, this );
|
||||
if (map.size > size){
|
||||
}, this);
|
||||
if (map.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitObject = function(obj) {
|
||||
SinglePrettyPrintRun.prototype.emitObject = function(obj) {
|
||||
var ctor = obj.constructor,
|
||||
constructorName;
|
||||
constructorName;
|
||||
|
||||
constructorName = typeof ctor === 'function' && obj instanceof ctor ?
|
||||
j$.fnNameFor(obj.constructor) :
|
||||
'null';
|
||||
constructorName =
|
||||
typeof ctor === 'function' && obj instanceof ctor
|
||||
? j$.fnNameFor(obj.constructor)
|
||||
: 'null';
|
||||
|
||||
this.append(constructorName);
|
||||
|
||||
@@ -212,14 +247,20 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
self.formatProperty(obj, property, isGetter);
|
||||
});
|
||||
|
||||
if (truncated) { this.append(', ...'); }
|
||||
if (truncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' })');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitTypedArray = function(arr) {
|
||||
SinglePrettyPrintRun.prototype.emitTypedArray = function(arr) {
|
||||
var constructorName = j$.fnNameFor(arr.constructor),
|
||||
limitedArray = Array.prototype.slice.call(arr, 0, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH),
|
||||
limitedArray = Array.prototype.slice.call(
|
||||
arr,
|
||||
0,
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
),
|
||||
itemsString = Array.prototype.join.call(limitedArray, ', ');
|
||||
|
||||
if (limitedArray.length !== arr.length) {
|
||||
@@ -229,7 +270,7 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitDomElement = function(el) {
|
||||
SinglePrettyPrintRun.prototype.emitDomElement = function(el) {
|
||||
var tagName = el.tagName.toLowerCase(),
|
||||
attrs = el.attributes,
|
||||
i,
|
||||
@@ -255,17 +296,27 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.append(out);
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
if (isGetter) {
|
||||
this.append('<getter>');
|
||||
} else {
|
||||
this.format(obj[property]);
|
||||
}
|
||||
SinglePrettyPrintRun.prototype.formatProperty = function(
|
||||
obj,
|
||||
property,
|
||||
isGetter
|
||||
) {
|
||||
this.append(property);
|
||||
this.append(': ');
|
||||
if (isGetter) {
|
||||
this.append('<getter>');
|
||||
} else {
|
||||
this.format(obj[property]);
|
||||
}
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.append = function(value) {
|
||||
SinglePrettyPrintRun.prototype.append = function(value) {
|
||||
// This check protects us from the rare case where an object has overriden
|
||||
// `toString()` with an invalid implementation (returning a non-string).
|
||||
if (typeof value !== 'string') {
|
||||
value = Object.prototype.toString.call(value);
|
||||
}
|
||||
|
||||
var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
|
||||
this.length += result.value.length;
|
||||
this.stringParts.push(result.value);
|
||||
@@ -275,7 +326,6 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function truncate(s, maxlen) {
|
||||
if (s.length <= maxlen) {
|
||||
return { value: s, truncated: false };
|
||||
@@ -286,30 +336,33 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
}
|
||||
|
||||
function MaxCharsReachedError() {
|
||||
this.message = 'Exceeded ' + j$.MAX_PRETTY_PRINT_CHARS +
|
||||
this.message =
|
||||
'Exceeded ' +
|
||||
j$.MAX_PRETTY_PRINT_CHARS +
|
||||
' characters while pretty-printing a value';
|
||||
}
|
||||
|
||||
MaxCharsReachedError.prototype = new Error();
|
||||
|
||||
function keys(obj, isArray) {
|
||||
var allKeys = Object.keys ? Object.keys(obj) :
|
||||
(function(o) {
|
||||
var allKeys = Object.keys
|
||||
? Object.keys(obj)
|
||||
: (function(o) {
|
||||
var keys = [];
|
||||
for (var key in o) {
|
||||
if (j$.util.has(o, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
if (j$.util.has(o, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
})(obj);
|
||||
})(obj);
|
||||
|
||||
if (!isArray) {
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
if (allKeys.length === 0) {
|
||||
return allKeys;
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
var extraKeys = [];
|
||||
@@ -321,9 +374,32 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
|
||||
return extraKeys;
|
||||
}
|
||||
return function(value) {
|
||||
var prettyPrinter = new PrettyPrinter();
|
||||
prettyPrinter.format(value);
|
||||
return prettyPrinter.stringParts.join('');
|
||||
|
||||
function customFormat(value, customObjectFormatters) {
|
||||
var i, result;
|
||||
|
||||
for (i = 0; i < customObjectFormatters.length; i++) {
|
||||
result = customObjectFormatters[i](value);
|
||||
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return function(customObjectFormatters) {
|
||||
customObjectFormatters = customObjectFormatters || [];
|
||||
|
||||
var pp = function(value) {
|
||||
var prettyPrinter = new SinglePrettyPrintRun(customObjectFormatters, pp);
|
||||
prettyPrinter.format(value);
|
||||
return prettyPrinter.stringParts.join('');
|
||||
};
|
||||
|
||||
pp.customFormat_ = function(value) {
|
||||
return customFormat(value, customObjectFormatters);
|
||||
};
|
||||
|
||||
return pp;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
var nextid = 1;
|
||||
|
||||
function StopExecutionError() {}
|
||||
StopExecutionError.prototype = new Error();
|
||||
j$.StopExecutionError = StopExecutionError;
|
||||
@@ -18,20 +20,31 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
function emptyFn() {}
|
||||
|
||||
function QueueRunner(attrs) {
|
||||
this.id_ = nextid++;
|
||||
var queueableFns = attrs.queueableFns || [];
|
||||
this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
|
||||
this.firstCleanupIx = queueableFns.length;
|
||||
this.onComplete = attrs.onComplete || emptyFn;
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.clearStack =
|
||||
attrs.clearStack ||
|
||||
function(fn) {
|
||||
fn();
|
||||
};
|
||||
this.onException = attrs.onException || emptyFn;
|
||||
this.userContext = attrs.userContext || new j$.UserContext();
|
||||
this.timeout = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
this.timeout = attrs.timeout || {
|
||||
setTimeout: setTimeout,
|
||||
clearTimeout: clearTimeout
|
||||
};
|
||||
this.fail = attrs.fail || emptyFn;
|
||||
this.globalErrors = attrs.globalErrors || { pushListener: emptyFn, popListener: emptyFn };
|
||||
this.globalErrors = attrs.globalErrors || {
|
||||
pushListener: emptyFn,
|
||||
popListener: emptyFn
|
||||
};
|
||||
this.completeOnFirstError = !!attrs.completeOnFirstError;
|
||||
this.errored = false;
|
||||
|
||||
if (typeof(this.onComplete) !== 'function') {
|
||||
if (typeof this.onComplete !== 'function') {
|
||||
throw new Error('invalid onComplete ' + JSON.stringify(this.onComplete));
|
||||
}
|
||||
this.deprecated = attrs.deprecated;
|
||||
@@ -39,8 +52,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
var self = this;
|
||||
this.handleFinalError = function(error) {
|
||||
self.onException(error);
|
||||
this.handleFinalError = function(message, source, lineno, colno, error) {
|
||||
// Older browsers would send the error as the first parameter. HTML5
|
||||
// specifies the the five parameters above. The error instance should
|
||||
// be preffered, otherwise the call stack would get lost.
|
||||
self.onException(error || message);
|
||||
};
|
||||
this.globalErrors.pushListener(this.handleFinalError);
|
||||
this.run(0);
|
||||
@@ -55,15 +71,22 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
|
||||
QueueRunner.prototype.clearTimeout = function(timeoutId) {
|
||||
Function.prototype.apply.apply(this.timeout.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
Function.prototype.apply.apply(this.timeout.clearTimeout, [
|
||||
j$.getGlobal(),
|
||||
[timeoutId]
|
||||
]);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.setTimeout = function(fn, timeout) {
|
||||
return Function.prototype.apply.apply(this.timeout.setTimeout, [j$.getGlobal(), [fn, timeout]]);
|
||||
return Function.prototype.apply.apply(this.timeout.setTimeout, [
|
||||
j$.getGlobal(),
|
||||
[fn, timeout]
|
||||
]);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.attempt = function attempt(iterativeIndex) {
|
||||
var self = this, completedSynchronously = true,
|
||||
var self = this,
|
||||
completedSynchronously = true,
|
||||
handleError = function handleError(error) {
|
||||
onException(error);
|
||||
next(error);
|
||||
@@ -100,7 +123,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}),
|
||||
errored = false,
|
||||
queueableFn = self.queueableFns[iterativeIndex],
|
||||
timeoutId;
|
||||
timeoutId,
|
||||
maybeThenable;
|
||||
|
||||
next.fail = function nextFail() {
|
||||
self.fail.apply(null, arguments);
|
||||
@@ -114,8 +138,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
var timeoutInterval = queueableFn.timeout || j$.DEFAULT_TIMEOUT_INTERVAL;
|
||||
timeoutId = self.setTimeout(function() {
|
||||
var error = new Error(
|
||||
'Timeout - Async callback was not invoked within ' + timeoutInterval + 'ms ' +
|
||||
(queueableFn.timeout ? '(custom timeout)' : '(set by jasmine.DEFAULT_TIMEOUT_INTERVAL)')
|
||||
'Timeout - Async function did not complete within ' +
|
||||
timeoutInterval +
|
||||
'ms ' +
|
||||
(queueableFn.timeout
|
||||
? '(custom timeout)'
|
||||
: '(set by jasmine.DEFAULT_TIMEOUT_INTERVAL)')
|
||||
);
|
||||
onException(error);
|
||||
next();
|
||||
@@ -124,7 +152,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
|
||||
try {
|
||||
if (queueableFn.fn.length === 0) {
|
||||
var maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
maybeThenable = queueableFn.fn.call(self.userContext);
|
||||
|
||||
if (maybeThenable && j$.isFunction_(maybeThenable.then)) {
|
||||
maybeThenable.then(next, onPromiseRejection);
|
||||
@@ -132,7 +160,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
} else {
|
||||
queueableFn.fn.call(self.userContext, next);
|
||||
maybeThenable = queueableFn.fn.call(self.userContext, next);
|
||||
this.diagnoseConflictingAsync_(queueableFn.fn, maybeThenable);
|
||||
completedSynchronously = false;
|
||||
return { completedSynchronously: false };
|
||||
}
|
||||
@@ -160,8 +189,11 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
self = this,
|
||||
iterativeIndex;
|
||||
|
||||
|
||||
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
|
||||
for (
|
||||
iterativeIndex = recursiveIndex;
|
||||
iterativeIndex < length;
|
||||
iterativeIndex++
|
||||
) {
|
||||
var result = this.attempt(iterativeIndex);
|
||||
|
||||
if (!result.completedSynchronously) {
|
||||
@@ -180,7 +212,29 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
self.globalErrors.popListener(self.handleFinalError);
|
||||
self.onComplete(self.errored && new StopExecutionError());
|
||||
});
|
||||
};
|
||||
|
||||
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
|
||||
if (retval && j$.isFunction_(retval.then)) {
|
||||
// Issue a warning that matches the user's code
|
||||
if (j$.isAsyncFunction_(fn)) {
|
||||
this.deprecated(
|
||||
'An asynchronous before/it/after ' +
|
||||
'function was defined with the async keyword but also took a ' +
|
||||
'done callback. This is not supported and will stop working in' +
|
||||
' the future. Either remove the done callback (recommended) or ' +
|
||||
'remove the async keyword.'
|
||||
);
|
||||
} else {
|
||||
this.deprecated(
|
||||
'An asynchronous before/it/after ' +
|
||||
'function took a done callback but also returned a promise. ' +
|
||||
'This is not supported and will stop working in the future. ' +
|
||||
'Either remove the done callback (recommended) or change the ' +
|
||||
'function to not return a promise.'
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return QueueRunner;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
function ReportDispatcher(methods, queueRunnerFactory) {
|
||||
|
||||
var dispatchedMethods = methods || [];
|
||||
|
||||
for (var i = 0; i < dispatchedMethods.length; i++) {
|
||||
@@ -9,7 +8,7 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
return function() {
|
||||
dispatch(m, arguments);
|
||||
};
|
||||
}(method));
|
||||
})(method);
|
||||
}
|
||||
|
||||
var reporters = [];
|
||||
@@ -31,7 +30,7 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
|
||||
function dispatch(method, args) {
|
||||
if (reporters.length === 0 && fallbackReporter !== null) {
|
||||
reporters.push(fallbackReporter);
|
||||
reporters.push(fallbackReporter);
|
||||
}
|
||||
var onComplete = args[args.length - 1];
|
||||
args = j$.util.argsToArray(args).splice(0, args.length - 1);
|
||||
@@ -57,13 +56,13 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
var thisArgs = j$.util.cloneArgs(args);
|
||||
if (fn.length <= 1) {
|
||||
fns.push({
|
||||
fn: function () {
|
||||
fn: function() {
|
||||
return fn.apply(reporter, thisArgs);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fns.push({
|
||||
fn: function (done) {
|
||||
fn: function(done) {
|
||||
return fn.apply(reporter, thisArgs.concat([done]));
|
||||
}
|
||||
});
|
||||
@@ -73,4 +72,3 @@ getJasmineRequireObj().ReportDispatcher = function(j$) {
|
||||
|
||||
return ReportDispatcher;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,15 +6,32 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.id = attrs.id;
|
||||
this.description = attrs.description || '';
|
||||
this.queueableFn = attrs.queueableFn;
|
||||
this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
|
||||
this.userContext = attrs.userContext || function() { return {}; };
|
||||
this.beforeAndAfterFns =
|
||||
attrs.beforeAndAfterFns ||
|
||||
function() {
|
||||
return { befores: [], afters: [] };
|
||||
};
|
||||
this.userContext =
|
||||
attrs.userContext ||
|
||||
function() {
|
||||
return {};
|
||||
};
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.getSpecName = attrs.getSpecName || function() { return ''; };
|
||||
this.expectationResultFactory = attrs.expectationResultFactory || function() { };
|
||||
this.getSpecName =
|
||||
attrs.getSpecName ||
|
||||
function() {
|
||||
return '';
|
||||
};
|
||||
this.expectationResultFactory =
|
||||
attrs.expectationResultFactory || function() {};
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
this.catchingExceptions =
|
||||
attrs.catchingExceptions ||
|
||||
function() {
|
||||
return true;
|
||||
};
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
this.timer = attrs.timer || new j$.Timer();
|
||||
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
@@ -31,6 +48,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
|
||||
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
|
||||
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
|
||||
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSpecProperty}
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
@@ -41,6 +59,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
deprecationWarnings: [],
|
||||
pendingReason: '',
|
||||
duration: null,
|
||||
properties: null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -57,6 +76,11 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.setSpecProperty = function(key, value) {
|
||||
this.result.properties = this.result.properties || {};
|
||||
this.result.properties[key] = value;
|
||||
};
|
||||
|
||||
Spec.prototype.expect = function(actual) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
@@ -65,7 +89,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.asyncExpectationFactory(actual, this);
|
||||
};
|
||||
|
||||
Spec.prototype.execute = function(onComplete, excluded) {
|
||||
Spec.prototype.execute = function(onComplete, excluded, failSpecWithNoExp) {
|
||||
var self = this;
|
||||
|
||||
var onStart = {
|
||||
@@ -78,7 +102,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
var complete = {
|
||||
fn: function(done) {
|
||||
self.queueableFn.fn = null;
|
||||
self.result.status = self.status(excluded);
|
||||
self.result.status = self.status(excluded, failSpecWithNoExp);
|
||||
self.result.duration = self.timer.elapsed();
|
||||
self.resultCallback(self.result, done);
|
||||
}
|
||||
};
|
||||
@@ -90,12 +115,14 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
isLeaf: true,
|
||||
queueableFns: regularFns,
|
||||
cleanupFns: fns.afters,
|
||||
onException: function () {
|
||||
onException: function() {
|
||||
self.onException.apply(self, arguments);
|
||||
},
|
||||
onComplete: function() {
|
||||
self.result.duration = self.timer.elapsed();
|
||||
onComplete(self.result.status === 'failed' && new j$.StopExecutionError('spec failed'));
|
||||
onComplete(
|
||||
self.result.status === 'failed' &&
|
||||
new j$.StopExecutionError('spec failed')
|
||||
);
|
||||
},
|
||||
userContext: this.userContext()
|
||||
};
|
||||
@@ -121,13 +148,17 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
}, true);
|
||||
this.addExpectationResult(
|
||||
false,
|
||||
{
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
},
|
||||
true
|
||||
);
|
||||
};
|
||||
|
||||
Spec.prototype.pend = function(message) {
|
||||
@@ -142,7 +173,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return this.result;
|
||||
};
|
||||
|
||||
Spec.prototype.status = function(excluded) {
|
||||
Spec.prototype.status = function(excluded, failSpecWithNoExpectations) {
|
||||
if (excluded === true) {
|
||||
return 'excluded';
|
||||
}
|
||||
@@ -151,11 +182,17 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return 'pending';
|
||||
}
|
||||
|
||||
if (this.result.failedExpectations.length > 0) {
|
||||
if (
|
||||
this.result.failedExpectations.length > 0 ||
|
||||
(failSpecWithNoExpectations &&
|
||||
this.result.failedExpectations.length +
|
||||
this.result.passedExpectations.length ===
|
||||
0)
|
||||
) {
|
||||
return 'failed';
|
||||
} else {
|
||||
return 'passed';
|
||||
}
|
||||
|
||||
return 'passed';
|
||||
};
|
||||
|
||||
Spec.prototype.getFullName = function() {
|
||||
@@ -166,13 +203,16 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
if (typeof deprecation === 'string') {
|
||||
deprecation = { message: deprecation };
|
||||
}
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
|
||||
this.result.deprecationWarnings.push(
|
||||
this.expectationResultFactory(deprecation)
|
||||
);
|
||||
};
|
||||
|
||||
var extractCustomPendingMessage = function(e) {
|
||||
var fullMessage = e.toString(),
|
||||
boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
|
||||
boilerplateEnd = boilerplateStart + Spec.pendingSpecExceptionMessage.length;
|
||||
boilerplateStart = fullMessage.indexOf(Spec.pendingSpecExceptionMessage),
|
||||
boilerplateEnd =
|
||||
boilerplateStart + Spec.pendingSpecExceptionMessage.length;
|
||||
|
||||
return fullMessage.substr(boilerplateEnd);
|
||||
};
|
||||
@@ -180,7 +220,11 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
Spec.pendingSpecExceptionMessage = '=> marked Pending';
|
||||
|
||||
Spec.isPendingSpecException = function(e) {
|
||||
return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1);
|
||||
return !!(
|
||||
e &&
|
||||
e.toString &&
|
||||
e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1
|
||||
);
|
||||
};
|
||||
|
||||
return Spec;
|
||||
|
||||
110
src/core/Spy.js
110
src/core/Spy.js
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().Spy = function (j$) {
|
||||
|
||||
getJasmineRequireObj().Spy = function(j$) {
|
||||
var nextOrder = (function() {
|
||||
var order = 0;
|
||||
|
||||
@@ -8,26 +7,38 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
};
|
||||
})();
|
||||
|
||||
var matchersUtil = new j$.MatchersUtil({
|
||||
customTesters: [],
|
||||
pp: j$.makePrettyPrinter()
|
||||
});
|
||||
|
||||
/**
|
||||
* _Note:_ Do not construct this directly, use {@link spyOn}, {@link spyOnProperty}, {@link jasmine.createSpy}, or {@link jasmine.createSpyObj}
|
||||
* @constructor
|
||||
* @name Spy
|
||||
*/
|
||||
function Spy(name, originalFn, customStrategies) {
|
||||
var numArgs = (typeof originalFn === 'function' ? originalFn.length : 0),
|
||||
wrapper = makeFunc(numArgs, function () {
|
||||
return spy.apply(this, Array.prototype.slice.call(arguments));
|
||||
function Spy(
|
||||
name,
|
||||
originalFn,
|
||||
customStrategies,
|
||||
defaultStrategyFn,
|
||||
getPromise
|
||||
) {
|
||||
var numArgs = typeof originalFn === 'function' ? originalFn.length : 0,
|
||||
wrapper = makeFunc(numArgs, function(context, args, invokeNew) {
|
||||
return spy(context, args, invokeNew);
|
||||
}),
|
||||
strategyDispatcher = new SpyStrategyDispatcher({
|
||||
name: name,
|
||||
fn: originalFn,
|
||||
getSpy: function () {
|
||||
getSpy: function() {
|
||||
return wrapper;
|
||||
},
|
||||
customStrategies: customStrategies
|
||||
customStrategies: customStrategies,
|
||||
getPromise: getPromise
|
||||
}),
|
||||
callTracker = new j$.CallTracker(),
|
||||
spy = function () {
|
||||
spy = function(context, args, invokeNew) {
|
||||
/**
|
||||
* @name Spy.callData
|
||||
* @property {object} object - `this` context for the invocation.
|
||||
@@ -35,13 +46,13 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
* @property {Array} args - The arguments passed for this invocation.
|
||||
*/
|
||||
var callData = {
|
||||
object: this,
|
||||
object: context,
|
||||
invocationOrder: nextOrder(),
|
||||
args: Array.prototype.slice.apply(arguments)
|
||||
args: Array.prototype.slice.apply(args)
|
||||
};
|
||||
|
||||
callTracker.track(callData);
|
||||
var returnValue = strategyDispatcher.exec(this, arguments);
|
||||
var returnValue = strategyDispatcher.exec(context, args, invokeNew);
|
||||
callData.returnValue = returnValue;
|
||||
|
||||
return returnValue;
|
||||
@@ -49,22 +60,54 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
|
||||
function makeFunc(length, fn) {
|
||||
switch (length) {
|
||||
case 1 : return function (a) { return fn.apply(this, arguments); };
|
||||
case 2 : return function (a,b) { return fn.apply(this, arguments); };
|
||||
case 3 : return function (a,b,c) { return fn.apply(this, arguments); };
|
||||
case 4 : return function (a,b,c,d) { return fn.apply(this, arguments); };
|
||||
case 5 : return function (a,b,c,d,e) { return fn.apply(this, arguments); };
|
||||
case 6 : return function (a,b,c,d,e,f) { return fn.apply(this, arguments); };
|
||||
case 7 : return function (a,b,c,d,e,f,g) { return fn.apply(this, arguments); };
|
||||
case 8 : return function (a,b,c,d,e,f,g,h) { return fn.apply(this, arguments); };
|
||||
case 9 : return function (a,b,c,d,e,f,g,h,i) { return fn.apply(this, arguments); };
|
||||
default : return function () { return fn.apply(this, arguments); };
|
||||
case 1:
|
||||
return function wrap1(a) {
|
||||
return fn(this, arguments, this instanceof wrap1);
|
||||
};
|
||||
case 2:
|
||||
return function wrap2(a, b) {
|
||||
return fn(this, arguments, this instanceof wrap2);
|
||||
};
|
||||
case 3:
|
||||
return function wrap3(a, b, c) {
|
||||
return fn(this, arguments, this instanceof wrap3);
|
||||
};
|
||||
case 4:
|
||||
return function wrap4(a, b, c, d) {
|
||||
return fn(this, arguments, this instanceof wrap4);
|
||||
};
|
||||
case 5:
|
||||
return function wrap5(a, b, c, d, e) {
|
||||
return fn(this, arguments, this instanceof wrap5);
|
||||
};
|
||||
case 6:
|
||||
return function wrap6(a, b, c, d, e, f) {
|
||||
return fn(this, arguments, this instanceof wrap6);
|
||||
};
|
||||
case 7:
|
||||
return function wrap7(a, b, c, d, e, f, g) {
|
||||
return fn(this, arguments, this instanceof wrap7);
|
||||
};
|
||||
case 8:
|
||||
return function wrap8(a, b, c, d, e, f, g, h) {
|
||||
return fn(this, arguments, this instanceof wrap8);
|
||||
};
|
||||
case 9:
|
||||
return function wrap9(a, b, c, d, e, f, g, h, i) {
|
||||
return fn(this, arguments, this instanceof wrap9);
|
||||
};
|
||||
default:
|
||||
return function wrap() {
|
||||
return fn(this, arguments, this instanceof wrap);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
for (var prop in originalFn) {
|
||||
if (prop === 'and' || prop === 'calls') {
|
||||
throw new Error('Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon');
|
||||
throw new Error(
|
||||
"Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon"
|
||||
);
|
||||
}
|
||||
|
||||
wrapper[prop] = originalFn[prop];
|
||||
@@ -75,6 +118,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
* whenever the spy is called with arguments that don't match any strategy
|
||||
* created with {@link Spy#withArgs}.
|
||||
* @name Spy#and
|
||||
* @since 2.0.0
|
||||
* @example
|
||||
* spyOn(someObj, 'func').and.returnValue(42);
|
||||
*/
|
||||
@@ -83,6 +127,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
* Specifies a strategy to be used for calls to the spy that have the
|
||||
* specified arguments.
|
||||
* @name Spy#withArgs
|
||||
* @since 3.0.0
|
||||
* @function
|
||||
* @param {...*} args - The arguments to match
|
||||
* @type {SpyStrategy}
|
||||
@@ -95,10 +140,13 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
};
|
||||
wrapper.calls = callTracker;
|
||||
|
||||
if (defaultStrategyFn) {
|
||||
defaultStrategyFn(wrapper.and);
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
function SpyStrategyDispatcher(strategyArgs) {
|
||||
var baseStrategy = new j$.SpyStrategy(strategyArgs);
|
||||
var argsStrategies = new StrategyDict(function() {
|
||||
@@ -107,18 +155,24 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
|
||||
this.and = baseStrategy;
|
||||
|
||||
this.exec = function(spy, args) {
|
||||
this.exec = function(spy, args, invokeNew) {
|
||||
var strategy = argsStrategies.get(args);
|
||||
|
||||
if (!strategy) {
|
||||
if (argsStrategies.any() && !baseStrategy.isConfigured()) {
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' received a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
throw new Error(
|
||||
"Spy '" +
|
||||
strategyArgs.name +
|
||||
"' received a call with arguments " +
|
||||
j$.pp(Array.prototype.slice.call(args)) +
|
||||
' but all configured strategies specify other arguments.'
|
||||
);
|
||||
} else {
|
||||
strategy = baseStrategy;
|
||||
}
|
||||
}
|
||||
|
||||
return strategy.exec(spy, args);
|
||||
return strategy.exec(spy, args, invokeNew);
|
||||
};
|
||||
|
||||
this.withArgs = function() {
|
||||
@@ -153,7 +207,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.strategies.length; i++) {
|
||||
if (j$.matchersUtil.equals(args, this.strategies[i].args)) {
|
||||
if (matchersUtil.equals(args, this.strategies[i].args)) {
|
||||
return this.strategies[i].strategy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,55 @@
|
||||
getJasmineRequireObj().SpyFactory = function(j$) {
|
||||
|
||||
function SpyFactory(getCustomStrategies) {
|
||||
function SpyFactory(getCustomStrategies, getDefaultStrategyFn, getPromise) {
|
||||
var self = this;
|
||||
|
||||
this.createSpy = function(name, originalFn) {
|
||||
return j$.Spy(name, originalFn, getCustomStrategies());
|
||||
return j$.Spy(
|
||||
name,
|
||||
originalFn,
|
||||
getCustomStrategies(),
|
||||
getDefaultStrategyFn(),
|
||||
getPromise
|
||||
);
|
||||
};
|
||||
|
||||
this.createSpyObj = function(baseName, methodNames) {
|
||||
var baseNameIsCollection = j$.isObject_(baseName) || j$.isArray_(baseName);
|
||||
this.createSpyObj = function(baseName, methodNames, propertyNames) {
|
||||
var baseNameIsCollection =
|
||||
j$.isObject_(baseName) || j$.isArray_(baseName);
|
||||
|
||||
if (baseNameIsCollection && j$.util.isUndefined(methodNames)) {
|
||||
if (baseNameIsCollection) {
|
||||
propertyNames = methodNames;
|
||||
methodNames = baseName;
|
||||
baseName = 'unknown';
|
||||
}
|
||||
|
||||
var obj = {};
|
||||
var spiesWereSet = false;
|
||||
var spy, descriptor;
|
||||
|
||||
if (j$.isArray_(methodNames)) {
|
||||
for (var i = 0; i < methodNames.length; i++) {
|
||||
obj[methodNames[i]] = self.createSpy(baseName + '.' + methodNames[i]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
} else if (j$.isObject_(methodNames)) {
|
||||
for (var key in methodNames) {
|
||||
if (methodNames.hasOwnProperty(key)) {
|
||||
obj[key] = self.createSpy(baseName + '.' + key);
|
||||
obj[key].and.returnValue(methodNames[key]);
|
||||
spiesWereSet = true;
|
||||
}
|
||||
var methods = normalizeKeyValues(methodNames);
|
||||
for (var i = 0; i < methods.length; i++) {
|
||||
spy = obj[methods[i][0]] = self.createSpy(
|
||||
baseName + '.' + methods[i][0]
|
||||
);
|
||||
if (methods[i].length > 1) {
|
||||
spy.and.returnValue(methods[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!spiesWereSet) {
|
||||
var properties = normalizeKeyValues(propertyNames);
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
descriptor = {
|
||||
enumerable: true,
|
||||
get: self.createSpy(baseName + '.' + properties[i][0] + '.get'),
|
||||
set: self.createSpy(baseName + '.' + properties[i][0] + '.set')
|
||||
};
|
||||
if (properties[i].length > 1) {
|
||||
descriptor.get.and.returnValue(properties[i][1]);
|
||||
descriptor.set.and.returnValue(properties[i][1]);
|
||||
}
|
||||
Object.defineProperty(obj, properties[i][0], descriptor);
|
||||
}
|
||||
|
||||
if (methods.length === 0 && properties.length === 0) {
|
||||
throw 'createSpyObj requires a non-empty array or object of method names to create spies for';
|
||||
}
|
||||
|
||||
@@ -41,5 +57,21 @@ getJasmineRequireObj().SpyFactory = function(j$) {
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeKeyValues(object) {
|
||||
var result = [];
|
||||
if (j$.isArray_(object)) {
|
||||
for (var i = 0; i < object.length; i++) {
|
||||
result.push([object[i]]);
|
||||
}
|
||||
} else if (j$.isObject_(object)) {
|
||||
for (var key in object) {
|
||||
if (object.hasOwnProperty(key)) {
|
||||
result.push([key, object[key]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return SpyFactory;
|
||||
};
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<spyOn>', 'spyOn(<object>, <methodName>)');
|
||||
var spyOnMsg = j$.formatErrorMsg('<spyOn>', 'spyOn(<object>, <methodName>)');
|
||||
var spyOnPropertyMsg = j$.formatErrorMsg(
|
||||
'<spyOnProperty>',
|
||||
'spyOnProperty(<object>, <propName>, [accessType])'
|
||||
);
|
||||
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var global = options.global || j$.getGlobal();
|
||||
var createSpy = options.createSpy;
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
var currentSpies =
|
||||
options.currentSpies ||
|
||||
function() {
|
||||
return [];
|
||||
};
|
||||
|
||||
this.allowRespy = function(allow){
|
||||
this.allowRespy = function(allow) {
|
||||
this.respy = allow;
|
||||
};
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
var getErrorMsg = spyOnMsg;
|
||||
|
||||
if (j$.util.isUndefined(obj) || obj === null) {
|
||||
throw new Error(getErrorMsg('could not find an object to spy upon for ' + methodName + '()'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'could not find an object to spy upon for ' + methodName + '()'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(methodName) || methodName === null) {
|
||||
@@ -26,25 +38,32 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
throw new Error(getErrorMsg(methodName + '() method does not exist'));
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName]) ) {
|
||||
if ( !!this.respy ){
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
if (this.respy) {
|
||||
return obj[methodName];
|
||||
}else {
|
||||
throw new Error(getErrorMsg(methodName + ' has already been spied upon'));
|
||||
} else {
|
||||
throw new Error(
|
||||
getErrorMsg(methodName + ' has already been spied upon')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var descriptor = Object.getOwnPropertyDescriptor(obj, methodName);
|
||||
|
||||
if (descriptor && !(descriptor.writable || descriptor.set)) {
|
||||
throw new Error(getErrorMsg(methodName + ' is not declared writable or has no setter'));
|
||||
throw new Error(
|
||||
getErrorMsg(methodName + ' is not declared writable or has no setter')
|
||||
);
|
||||
}
|
||||
|
||||
var originalMethod = obj[methodName],
|
||||
spiedMethod = createSpy(methodName, originalMethod),
|
||||
restoreStrategy;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(obj, methodName) || (obj === global && methodName === 'onerror')) {
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(obj, methodName) ||
|
||||
(obj === global && methodName === 'onerror')
|
||||
) {
|
||||
restoreStrategy = function() {
|
||||
obj[methodName] = originalMethod;
|
||||
};
|
||||
@@ -65,34 +84,58 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
return spiedMethod;
|
||||
};
|
||||
|
||||
this.spyOnProperty = function (obj, propertyName, accessType) {
|
||||
this.spyOnProperty = function(obj, propertyName, accessType) {
|
||||
var getErrorMsg = spyOnPropertyMsg;
|
||||
|
||||
accessType = accessType || 'get';
|
||||
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + propertyName + '');
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'spyOn could not find an object to spy upon for ' +
|
||||
propertyName +
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(propertyName)) {
|
||||
throw new Error('No property name supplied');
|
||||
throw new Error(getErrorMsg('No property name supplied'));
|
||||
}
|
||||
|
||||
var descriptor = j$.util.getPropertyDescriptor(obj, propertyName);
|
||||
|
||||
if (!descriptor) {
|
||||
throw new Error(propertyName + ' property does not exist');
|
||||
throw new Error(getErrorMsg(propertyName + ' property does not exist'));
|
||||
}
|
||||
|
||||
if (!descriptor.configurable) {
|
||||
throw new Error(propertyName + ' is not declared configurable');
|
||||
throw new Error(
|
||||
getErrorMsg(propertyName + ' is not declared configurable')
|
||||
);
|
||||
}
|
||||
|
||||
if(!descriptor[accessType]) {
|
||||
throw new Error('Property ' + propertyName + ' does not have access type ' + accessType);
|
||||
if (!descriptor[accessType]) {
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Property ' +
|
||||
propertyName +
|
||||
' does not have access type ' +
|
||||
accessType
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (j$.isSpy(descriptor[accessType])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(propertyName + ' has already been spied upon');
|
||||
if (this.respy) {
|
||||
return descriptor[accessType];
|
||||
} else {
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
propertyName + '#' + accessType + ' has already been spied upon'
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
var originalDescriptor = j$.util.clone(descriptor),
|
||||
@@ -122,16 +165,36 @@ getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
this.spyOnAllFunctions = function(obj) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOnAllFunctions could not find an object to spy upon');
|
||||
throw new Error(
|
||||
'spyOnAllFunctions could not find an object to spy upon'
|
||||
);
|
||||
}
|
||||
|
||||
for (var prop in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, prop) && obj[prop] instanceof Function) {
|
||||
var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
|
||||
if ((descriptor.writable || descriptor.set) && descriptor.configurable) {
|
||||
this.spyOn(obj, prop);
|
||||
var pointer = obj,
|
||||
props = [],
|
||||
prop,
|
||||
descriptor;
|
||||
|
||||
while (pointer) {
|
||||
for (prop in pointer) {
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(pointer, prop) &&
|
||||
pointer[prop] instanceof Function
|
||||
) {
|
||||
descriptor = Object.getOwnPropertyDescriptor(pointer, prop);
|
||||
if (
|
||||
(descriptor.writable || descriptor.set) &&
|
||||
descriptor.configurable
|
||||
) {
|
||||
props.push(prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
pointer = Object.getPrototypeOf(pointer);
|
||||
}
|
||||
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
this.spyOn(obj, props[i]);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
|
||||
/**
|
||||
* @interface SpyStrategy
|
||||
*/
|
||||
function SpyStrategy(options) {
|
||||
options = options || {};
|
||||
|
||||
var self = this;
|
||||
|
||||
/**
|
||||
* Get the identifying information for the spy.
|
||||
* @name SpyStrategy#identity
|
||||
* @since 3.0.0
|
||||
* @member
|
||||
* @type {String}
|
||||
*/
|
||||
@@ -17,12 +19,62 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
this.getSpy = options.getSpy || function() {};
|
||||
this.plan = this._defaultPlan = function() {};
|
||||
|
||||
var k, cs = options.customStrategies || {};
|
||||
var k,
|
||||
cs = options.customStrategies || {};
|
||||
for (k in cs) {
|
||||
if (j$.util.has(cs, k) && !this[k]) {
|
||||
this[k] = createCustomPlan(cs[k]);
|
||||
}
|
||||
}
|
||||
|
||||
var getPromise =
|
||||
typeof options.getPromise === 'function'
|
||||
? options.getPromise
|
||||
: function() {};
|
||||
|
||||
var requirePromise = function(name) {
|
||||
var Promise = getPromise();
|
||||
|
||||
if (!Promise) {
|
||||
throw new Error(
|
||||
name +
|
||||
' requires global Promise, or `Promise` configured with `jasmine.getEnv().configure()`'
|
||||
);
|
||||
}
|
||||
|
||||
return Promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return a promise resolving to the specified value when invoked.
|
||||
* @name SpyStrategy#resolveTo
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {*} value The value to return.
|
||||
*/
|
||||
this.resolveTo = function(value) {
|
||||
var Promise = requirePromise('resolveTo');
|
||||
self.plan = function() {
|
||||
return Promise.resolve(value);
|
||||
};
|
||||
return self.getSpy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to return a promise rejecting with the specified value when invoked.
|
||||
* @name SpyStrategy#rejectWith
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {*} value The value to return.
|
||||
*/
|
||||
this.rejectWith = function(value) {
|
||||
var Promise = requirePromise('rejectWith');
|
||||
|
||||
self.plan = function() {
|
||||
return Promise.reject(value);
|
||||
};
|
||||
return self.getSpy();
|
||||
};
|
||||
}
|
||||
|
||||
function createCustomPlan(factory) {
|
||||
@@ -41,15 +93,22 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Execute the current spy strategy.
|
||||
* @name SpyStrategy#exec
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.exec = function(context, args) {
|
||||
return this.plan.apply(context, args);
|
||||
SpyStrategy.prototype.exec = function(context, args, invokeNew) {
|
||||
var contextArgs = [context].concat(
|
||||
args ? Array.prototype.slice.call(args) : []
|
||||
);
|
||||
var target = this.plan.bind.apply(this.plan, contextArgs);
|
||||
|
||||
return invokeNew ? new target() : target();
|
||||
};
|
||||
|
||||
/**
|
||||
* Tell the spy to call through to the real implementation when invoked.
|
||||
* @name SpyStrategy#callThrough
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.callThrough = function() {
|
||||
@@ -60,6 +119,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Tell the spy to return the value when invoked.
|
||||
* @name SpyStrategy#returnValue
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {*} value The value to return.
|
||||
*/
|
||||
@@ -73,12 +133,13 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Tell the spy to return one of the specified values (sequentially) each time the spy is invoked.
|
||||
* @name SpyStrategy#returnValues
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @param {...*} values - Values to be returned on subsequent calls to the spy.
|
||||
*/
|
||||
SpyStrategy.prototype.returnValues = function() {
|
||||
var values = Array.prototype.slice.call(arguments);
|
||||
this.plan = function () {
|
||||
this.plan = function() {
|
||||
return values.shift();
|
||||
};
|
||||
return this.getSpy();
|
||||
@@ -87,11 +148,12 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Tell the spy to throw an error when invoked.
|
||||
* @name SpyStrategy#throwError
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Error|String} something Thing to throw
|
||||
* @param {Error|Object|String} something Thing to throw
|
||||
*/
|
||||
SpyStrategy.prototype.throwError = function(something) {
|
||||
var error = (something instanceof Error) ? something : new Error(something);
|
||||
var error = j$.isString_(something) ? new Error(something) : something;
|
||||
this.plan = function() {
|
||||
throw error;
|
||||
};
|
||||
@@ -101,12 +163,21 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Tell the spy to call a fake implementation when invoked.
|
||||
* @name SpyStrategy#callFake
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Function} fn The function to invoke with the passed parameters.
|
||||
*/
|
||||
SpyStrategy.prototype.callFake = function(fn) {
|
||||
if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
|
||||
throw new Error('Argument passed to callFake should be a function, got ' + fn);
|
||||
if (
|
||||
!(
|
||||
j$.isFunction_(fn) ||
|
||||
j$.isAsyncFunction_(fn) ||
|
||||
j$.isGeneratorFunction_(fn)
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
'Argument passed to callFake should be a function, got ' + fn
|
||||
);
|
||||
}
|
||||
this.plan = fn;
|
||||
return this.getSpy();
|
||||
@@ -115,6 +186,7 @@ getJasmineRequireObj().SpyStrategy = function(j$) {
|
||||
/**
|
||||
* Tell the spy to do nothing when invoked. This is the default.
|
||||
* @name SpyStrategy#stub
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
*/
|
||||
SpyStrategy.prototype.stub = function(fn) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
getJasmineRequireObj().StackTrace = function(j$) {
|
||||
function StackTrace(error) {
|
||||
var lines = error.stack
|
||||
.split('\n')
|
||||
.filter(function(line) { return line !== ''; });
|
||||
var lines = error.stack.split('\n').filter(function(line) {
|
||||
return line !== '';
|
||||
});
|
||||
|
||||
var extractResult = extractMessage(error.message, lines);
|
||||
|
||||
@@ -21,7 +21,12 @@ getJasmineRequireObj().StackTrace = function(j$) {
|
||||
// e.g. " at QueueRunner.run (http://localhost:8888/__jasmine__/jasmine.js:4320:20)"
|
||||
// Note that the "function name" can include a surprisingly large set of
|
||||
// characters, including angle brackets and square brackets.
|
||||
{ re: /^\s*at ([^\)]+) \(([^\)]+)\)$/, fnIx: 1, fileLineColIx: 2, style: 'v8' },
|
||||
{
|
||||
re: /^\s*at ([^\)]+) \(([^\)]+)\)$/,
|
||||
fnIx: 1,
|
||||
fileLineColIx: 2,
|
||||
style: 'v8'
|
||||
},
|
||||
|
||||
// NodeJS alternate form, often mixed in with the Chrome style
|
||||
// e.g. " at /some/path:4320:20
|
||||
@@ -30,7 +35,12 @@ getJasmineRequireObj().StackTrace = function(j$) {
|
||||
// PhantomJS on OS X, Safari, Firefox
|
||||
// e.g. "run@http://localhost:8888/__jasmine__/jasmine.js:4320:27"
|
||||
// or "http://localhost:8888/__jasmine__/jasmine.js:4320:27"
|
||||
{ re: /^(([^@\s]+)@)?([^\s]+)$/, fnIx: 2, fileLineColIx: 3, style: 'webkit' }
|
||||
{
|
||||
re: /^(([^@\s]+)@)?([^\s]+)$/,
|
||||
fnIx: 2,
|
||||
fileLineColIx: 3,
|
||||
style: 'webkit'
|
||||
}
|
||||
];
|
||||
|
||||
// regexes should capture the function name (if any) as group 1
|
||||
@@ -41,11 +51,16 @@ getJasmineRequireObj().StackTrace = function(j$) {
|
||||
var convertedLine = first(framePatterns, function(pattern) {
|
||||
var overallMatch = line.match(pattern.re),
|
||||
fileLineColMatch;
|
||||
if (!overallMatch) { return null; }
|
||||
if (!overallMatch) {
|
||||
return null;
|
||||
}
|
||||
|
||||
fileLineColMatch = overallMatch[pattern.fileLineColIx].match(
|
||||
/^(.*):(\d+):\d+$/);
|
||||
if (!fileLineColMatch) { return null; }
|
||||
/^(.*):(\d+):\d+$/
|
||||
);
|
||||
if (!fileLineColMatch) {
|
||||
return null;
|
||||
}
|
||||
|
||||
style = style || pattern.style;
|
||||
return {
|
||||
@@ -89,7 +104,7 @@ getJasmineRequireObj().StackTrace = function(j$) {
|
||||
}
|
||||
|
||||
function messagePrefixLength(message, stackLines) {
|
||||
if (!stackLines[0].match(/^Error/)) {
|
||||
if (!stackLines[0].match(/^\w*Error/)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,6 +119,6 @@ getJasmineRequireObj().StackTrace = function(j$) {
|
||||
|
||||
return messageLines.length;
|
||||
}
|
||||
|
||||
|
||||
return StackTrace;
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
this.timer = attrs.timer || new j$.Timer();
|
||||
|
||||
this.children = [];
|
||||
|
||||
@@ -27,6 +27,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
|
||||
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
|
||||
* @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
|
||||
* @property {Object} properties - User-supplied properties, if any, that were set using {@link Env#setSuiteProperty}
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
@@ -35,9 +36,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
failedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
duration: null,
|
||||
properties: null
|
||||
};
|
||||
}
|
||||
|
||||
Suite.prototype.setSuiteProperty = function(key, value) {
|
||||
this.result.properties = this.result.properties || {};
|
||||
this.result.properties[key] = value;
|
||||
};
|
||||
|
||||
Suite.prototype.expect = function(actual) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
@@ -48,7 +55,11 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
|
||||
Suite.prototype.getFullName = function() {
|
||||
var fullName = [];
|
||||
for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
|
||||
for (
|
||||
var parentSuite = this;
|
||||
parentSuite;
|
||||
parentSuite = parentSuite.parentSuite
|
||||
) {
|
||||
if (parentSuite.parentSuite) {
|
||||
fullName.unshift(parentSuite.description);
|
||||
}
|
||||
@@ -85,7 +96,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
};
|
||||
|
||||
function removeFns(queueableFns) {
|
||||
for(var i = 0; i < queueableFns.length; i++) {
|
||||
for (var i = 0; i < queueableFns.length; i++) {
|
||||
queueableFns[i].fn = null;
|
||||
}
|
||||
}
|
||||
@@ -124,7 +135,9 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
|
||||
Suite.prototype.sharedUserContext = function() {
|
||||
if (!this.sharedContext) {
|
||||
this.sharedContext = this.parentSuite ? this.parentSuite.clonedSharedUserContext() : new j$.UserContext();
|
||||
this.sharedContext = this.parentSuite
|
||||
? this.parentSuite.clonedSharedUserContext()
|
||||
: new j$.UserContext();
|
||||
}
|
||||
|
||||
return this.sharedContext;
|
||||
@@ -155,11 +168,11 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.result.failedExpectations.push(failedExpectation);
|
||||
};
|
||||
|
||||
Suite.prototype.addExpectationResult = function () {
|
||||
if(isFailure(arguments)) {
|
||||
Suite.prototype.addExpectationResult = function() {
|
||||
if (isFailure(arguments)) {
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
if(this.throwOnExpectationFailure) {
|
||||
if (this.throwOnExpectationFailure) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
}
|
||||
}
|
||||
@@ -169,7 +182,9 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
if (typeof deprecation === 'string') {
|
||||
deprecation = { message: deprecation };
|
||||
}
|
||||
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
|
||||
this.result.deprecationWarnings.push(
|
||||
this.expectationResultFactory(deprecation)
|
||||
);
|
||||
};
|
||||
|
||||
function isFailure(args) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
getJasmineRequireObj().Timer = function() {
|
||||
var defaultNow = (function(Date) {
|
||||
return function() { return new Date().getTime(); };
|
||||
return function() {
|
||||
return new Date().getTime();
|
||||
};
|
||||
})(Date);
|
||||
|
||||
function Timer(options) {
|
||||
@@ -20,10 +22,3 @@ getJasmineRequireObj().Timer = function() {
|
||||
|
||||
return Timer;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().noopTimer = function() {
|
||||
return {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
};
|
||||
@@ -1,16 +1,25 @@
|
||||
getJasmineRequireObj().TreeProcessor = function() {
|
||||
function TreeProcessor(attrs) {
|
||||
var tree = attrs.tree,
|
||||
runnableIds = attrs.runnableIds,
|
||||
queueRunnerFactory = attrs.queueRunnerFactory,
|
||||
nodeStart = attrs.nodeStart || function() {},
|
||||
nodeComplete = attrs.nodeComplete || function() {},
|
||||
orderChildren = attrs.orderChildren || function(node) { return node.children; },
|
||||
excludeNode = attrs.excludeNode || function(node) { return false; },
|
||||
stats = { valid: true },
|
||||
processed = false,
|
||||
defaultMin = Infinity,
|
||||
defaultMax = 1 - Infinity;
|
||||
runnableIds = attrs.runnableIds,
|
||||
queueRunnerFactory = attrs.queueRunnerFactory,
|
||||
nodeStart = attrs.nodeStart || function() {},
|
||||
nodeComplete = attrs.nodeComplete || function() {},
|
||||
failSpecWithNoExpectations = !!attrs.failSpecWithNoExpectations,
|
||||
orderChildren =
|
||||
attrs.orderChildren ||
|
||||
function(node) {
|
||||
return node.children;
|
||||
},
|
||||
excludeNode =
|
||||
attrs.excludeNode ||
|
||||
function(node) {
|
||||
return false;
|
||||
},
|
||||
stats = { valid: true },
|
||||
processed = false,
|
||||
defaultMin = Infinity,
|
||||
defaultMax = 1 - Infinity;
|
||||
|
||||
this.processTree = function() {
|
||||
processNode(tree, true);
|
||||
@@ -59,13 +68,15 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
stats[node.id] = {
|
||||
excluded: excluded,
|
||||
willExecute: !excluded && !node.markedPending,
|
||||
segments: [{
|
||||
index: 0,
|
||||
owner: node,
|
||||
nodes: [node],
|
||||
min: startingMin(executableIndex),
|
||||
max: startingMax(executableIndex)
|
||||
}]
|
||||
segments: [
|
||||
{
|
||||
index: 0,
|
||||
owner: node,
|
||||
nodes: [node],
|
||||
min: startingMin(executableIndex),
|
||||
max: startingMax(executableIndex)
|
||||
}
|
||||
]
|
||||
};
|
||||
} else {
|
||||
var hasExecutableChild = false;
|
||||
@@ -107,14 +118,29 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
return executableIndex === undefined ? defaultMax : executableIndex;
|
||||
}
|
||||
|
||||
function segmentChildren(node, orderedChildren, nodeStats, executableIndex) {
|
||||
var currentSegment = { index: 0, owner: node, nodes: [], min: startingMin(executableIndex), max: startingMax(executableIndex) },
|
||||
result = [currentSegment],
|
||||
lastMax = defaultMax,
|
||||
orderedChildSegments = orderChildSegments(orderedChildren);
|
||||
function segmentChildren(
|
||||
node,
|
||||
orderedChildren,
|
||||
nodeStats,
|
||||
executableIndex
|
||||
) {
|
||||
var currentSegment = {
|
||||
index: 0,
|
||||
owner: node,
|
||||
nodes: [],
|
||||
min: startingMin(executableIndex),
|
||||
max: startingMax(executableIndex)
|
||||
},
|
||||
result = [currentSegment],
|
||||
lastMax = defaultMax,
|
||||
orderedChildSegments = orderChildSegments(orderedChildren);
|
||||
|
||||
function isSegmentBoundary(minIndex) {
|
||||
return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1;
|
||||
return (
|
||||
lastMax !== defaultMax &&
|
||||
minIndex !== defaultMin &&
|
||||
lastMax < minIndex - 1
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < orderedChildSegments.length; i++) {
|
||||
@@ -123,7 +149,13 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
minIndex = childSegment.min;
|
||||
|
||||
if (isSegmentBoundary(minIndex)) {
|
||||
currentSegment = {index: result.length, owner: node, nodes: [], min: defaultMin, max: defaultMax};
|
||||
currentSegment = {
|
||||
index: result.length,
|
||||
owner: node,
|
||||
nodes: [],
|
||||
min: defaultMin,
|
||||
max: defaultMax
|
||||
};
|
||||
result.push(currentSegment);
|
||||
}
|
||||
|
||||
@@ -138,11 +170,11 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
|
||||
function orderChildSegments(children) {
|
||||
var specifiedOrder = [],
|
||||
unspecifiedOrder = [];
|
||||
unspecifiedOrder = [];
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i],
|
||||
segments = stats[child.id].segments;
|
||||
segments = stats[child.id].segments;
|
||||
|
||||
for (var j = 0; j < segments.length; j++) {
|
||||
var seg = segments[j];
|
||||
@@ -173,7 +205,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
};
|
||||
|
||||
queueRunnerFactory({
|
||||
onComplete: function () {
|
||||
onComplete: function() {
|
||||
var args = Array.prototype.slice.call(arguments, [0]);
|
||||
node.cleanupBeforeAfter();
|
||||
nodeComplete(node, node.getResult(), function() {
|
||||
@@ -182,7 +214,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
},
|
||||
queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)),
|
||||
userContext: node.sharedUserContext(),
|
||||
onException: function () {
|
||||
onException: function() {
|
||||
node.onException.apply(node, arguments);
|
||||
}
|
||||
});
|
||||
@@ -190,17 +222,25 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
fn: function(done) { node.execute(done, stats[node.id].excluded); }
|
||||
fn: function(done) {
|
||||
node.execute(
|
||||
done,
|
||||
stats[node.id].excluded,
|
||||
failSpecWithNoExpectations
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function wrapChildren(node, segmentNumber) {
|
||||
var result = [],
|
||||
segmentChildren = stats[node.id].segments[segmentNumber].nodes;
|
||||
segmentChildren = stats[node.id].segments[segmentNumber].nodes;
|
||||
|
||||
for (var i = 0; i < segmentChildren.length; i++) {
|
||||
result.push(executeNode(segmentChildren[i].owner, segmentChildren[i].index));
|
||||
result.push(
|
||||
executeNode(segmentChildren[i].owner, segmentChildren[i].index)
|
||||
);
|
||||
}
|
||||
|
||||
if (!stats[node.id].willExecute) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
getJasmineRequireObj().UserContext = function(j$) {
|
||||
function UserContext() {
|
||||
}
|
||||
function UserContext() {}
|
||||
|
||||
UserContext.fromExisting = function(oldContext) {
|
||||
var context = new UserContext();
|
||||
@@ -14,5 +13,5 @@ getJasmineRequireObj().UserContext = function(j$) {
|
||||
return context;
|
||||
};
|
||||
|
||||
return UserContext;
|
||||
return UserContext;
|
||||
};
|
||||
|
||||
107
src/core/asymmetricEqualityTesterArgCompatShim.js
Normal file
107
src/core/asymmetricEqualityTesterArgCompatShim.js
Normal file
@@ -0,0 +1,107 @@
|
||||
getJasmineRequireObj().asymmetricEqualityTesterArgCompatShim = function(j$) {
|
||||
/*
|
||||
Older versions of Jasmine passed an array of custom equality testers as the
|
||||
second argument to each asymmetric equality tester's `asymmetricMatch`
|
||||
method. Newer versions will pass a `MatchersUtil` instance. The
|
||||
asymmetricEqualityTesterArgCompatShim allows for a graceful migration from
|
||||
the old interface to the new by "being" both an array of custom equality
|
||||
testers and a `MatchersUtil` at the same time.
|
||||
|
||||
This code should be removed in the next major release.
|
||||
*/
|
||||
|
||||
var likelyArrayProps = [
|
||||
'concat',
|
||||
'constructor',
|
||||
'copyWithin',
|
||||
'entries',
|
||||
'every',
|
||||
'fill',
|
||||
'filter',
|
||||
'find',
|
||||
'findIndex',
|
||||
'flat',
|
||||
'flatMap',
|
||||
'forEach',
|
||||
'includes',
|
||||
'indexOf',
|
||||
'join',
|
||||
'keys',
|
||||
'lastIndexOf',
|
||||
'length',
|
||||
'map',
|
||||
'pop',
|
||||
'push',
|
||||
'reduce',
|
||||
'reduceRight',
|
||||
'reverse',
|
||||
'shift',
|
||||
'slice',
|
||||
'some',
|
||||
'sort',
|
||||
'splice',
|
||||
'toLocaleString',
|
||||
'toSource',
|
||||
'toString',
|
||||
'unshift',
|
||||
'values'
|
||||
];
|
||||
|
||||
function asymmetricEqualityTesterArgCompatShim(
|
||||
matchersUtil,
|
||||
customEqualityTesters
|
||||
) {
|
||||
var self = Object.create(matchersUtil),
|
||||
props,
|
||||
i,
|
||||
k;
|
||||
|
||||
copy(self, customEqualityTesters, 'length');
|
||||
|
||||
for (i = 0; i < customEqualityTesters.length; i++) {
|
||||
copy(self, customEqualityTesters, i);
|
||||
}
|
||||
|
||||
var props = arrayProps();
|
||||
|
||||
for (i = 0; i < props.length; i++) {
|
||||
k = props[i];
|
||||
// Skip length (dealt with above), and anything that collides with
|
||||
// MatchesUtil e.g. an Array.prototype.contains method added by user code
|
||||
if (k !== 'length' && !self[k]) {
|
||||
copy(self, Array.prototype, k);
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
function copy(dest, src, propName) {
|
||||
Object.defineProperty(dest, propName, {
|
||||
get: function() {
|
||||
return src[propName];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function arrayProps() {
|
||||
var props, a, k;
|
||||
|
||||
if (!Object.getOwnPropertyDescriptors) {
|
||||
return likelyArrayProps.filter(function(k) {
|
||||
return Array.prototype.hasOwnProperty(k);
|
||||
});
|
||||
}
|
||||
|
||||
props = Object.getOwnPropertyDescriptors(Array.prototype); // eslint-disable-line compat/compat
|
||||
a = [];
|
||||
|
||||
for (k in props) {
|
||||
a.push(k);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
return asymmetricEqualityTesterArgCompatShim;
|
||||
};
|
||||
@@ -1,10 +1,9 @@
|
||||
getJasmineRequireObj().Any = function(j$) {
|
||||
|
||||
function Any(expectedObject) {
|
||||
if (typeof expectedObject === 'undefined') {
|
||||
throw new TypeError(
|
||||
'jasmine.any() expects to be passed a constructor function. ' +
|
||||
'Please pass one or use jasmine.anything() to match any object.'
|
||||
'Please pass one or use jasmine.anything() to match any object.'
|
||||
);
|
||||
}
|
||||
this.expectedObject = expectedObject;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().Anything = function(j$) {
|
||||
|
||||
function Anything() {}
|
||||
|
||||
Anything.prototype.asymmetricMatch = function(other) {
|
||||
|
||||
@@ -3,14 +3,25 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
ArrayContaining.prototype.asymmetricMatch = function(other, customTesters) {
|
||||
ArrayContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
|
||||
if (!j$.isArray_(this.sample)) {
|
||||
throw new Error('You must provide an array to arrayContaining, not ' + j$.pp(this.sample) + '.');
|
||||
throw new Error(
|
||||
'You must provide an array to arrayContaining, not ' +
|
||||
j$.pp(this.sample) +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
|
||||
// If the actual parameter is not an array, we can fail immediately, since it couldn't
|
||||
// possibly be an "array containing" anything. However, we also want an empty sample
|
||||
// array to match anything, so we need to double-check we aren't in that case
|
||||
if (!j$.isArray_(other) && this.sample.length > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.sample.length; i++) {
|
||||
var item = this.sample[i];
|
||||
if (!j$.matchersUtil.contains(other, item, customTesters)) {
|
||||
if (!matchersUtil.contains(other, item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -18,8 +29,8 @@ getJasmineRequireObj().ArrayContaining = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
ArrayContaining.prototype.jasmineToString = function () {
|
||||
return '<jasmine.arrayContaining(' + j$.pp(this.sample) +')>';
|
||||
ArrayContaining.prototype.jasmineToString = function(pp) {
|
||||
return '<jasmine.arrayContaining(' + pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return ArrayContaining;
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
getJasmineRequireObj().ArrayWithExactContents = function(j$) {
|
||||
|
||||
function ArrayWithExactContents(sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
ArrayWithExactContents.prototype.asymmetricMatch = function(other, customTesters) {
|
||||
ArrayWithExactContents.prototype.asymmetricMatch = function(
|
||||
other,
|
||||
matchersUtil
|
||||
) {
|
||||
if (!j$.isArray_(this.sample)) {
|
||||
throw new Error('You must provide an array to arrayWithExactContents, not ' + j$.pp(this.sample) + '.');
|
||||
throw new Error(
|
||||
'You must provide an array to arrayWithExactContents, not ' +
|
||||
j$.pp(this.sample) +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
|
||||
if (this.sample.length !== other.length) {
|
||||
@@ -15,7 +21,7 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
|
||||
|
||||
for (var i = 0; i < this.sample.length; i++) {
|
||||
var item = this.sample[i];
|
||||
if (!j$.matchersUtil.contains(other, item, customTesters)) {
|
||||
if (!matchersUtil.contains(other, item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -23,8 +29,8 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
ArrayWithExactContents.prototype.jasmineToString = function() {
|
||||
return '<jasmine.arrayWithExactContents ' + j$.pp(this.sample) + '>';
|
||||
ArrayWithExactContents.prototype.jasmineToString = function(pp) {
|
||||
return '<jasmine.arrayWithExactContents(' + pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return ArrayWithExactContents;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
getJasmineRequireObj().Empty = function (j$) {
|
||||
|
||||
getJasmineRequireObj().Empty = function(j$) {
|
||||
function Empty() {}
|
||||
|
||||
Empty.prototype.asymmetricMatch = function (other) {
|
||||
Empty.prototype.asymmetricMatch = function(other) {
|
||||
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
|
||||
return other.length === 0;
|
||||
}
|
||||
@@ -17,7 +16,7 @@ getJasmineRequireObj().Empty = function (j$) {
|
||||
return false;
|
||||
};
|
||||
|
||||
Empty.prototype.jasmineToString = function () {
|
||||
Empty.prototype.jasmineToString = function() {
|
||||
return '<jasmine.empty>';
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().Falsy = function(j$) {
|
||||
|
||||
function Falsy() {}
|
||||
|
||||
Falsy.prototype.asymmetricMatch = function(other) {
|
||||
|
||||
43
src/core/asymmetric_equality/MapContaining.js
Normal file
43
src/core/asymmetric_equality/MapContaining.js
Normal file
@@ -0,0 +1,43 @@
|
||||
getJasmineRequireObj().MapContaining = function(j$) {
|
||||
function MapContaining(sample) {
|
||||
if (!j$.isMap(sample)) {
|
||||
throw new Error(
|
||||
'You must provide a map to `mapContaining`, not ' + j$.pp(sample)
|
||||
);
|
||||
}
|
||||
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
MapContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
|
||||
if (!j$.isMap(other)) return false;
|
||||
|
||||
var hasAllMatches = true;
|
||||
j$.util.forEachBreakable(this.sample, function(breakLoop, value, key) {
|
||||
// for each key/value pair in `sample`
|
||||
// there should be at least one pair in `other` whose key and value both match
|
||||
var hasMatch = false;
|
||||
j$.util.forEachBreakable(other, function(oBreakLoop, oValue, oKey) {
|
||||
if (
|
||||
matchersUtil.equals(oKey, key) &&
|
||||
matchersUtil.equals(oValue, value)
|
||||
) {
|
||||
hasMatch = true;
|
||||
oBreakLoop();
|
||||
}
|
||||
});
|
||||
if (!hasMatch) {
|
||||
hasAllMatches = false;
|
||||
breakLoop();
|
||||
}
|
||||
});
|
||||
|
||||
return hasAllMatches;
|
||||
};
|
||||
|
||||
MapContaining.prototype.jasmineToString = function(pp) {
|
||||
return '<jasmine.mapContaining(' + pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return MapContaining;
|
||||
};
|
||||
@@ -1,8 +1,7 @@
|
||||
getJasmineRequireObj().NotEmpty = function (j$) {
|
||||
|
||||
getJasmineRequireObj().NotEmpty = function(j$) {
|
||||
function NotEmpty() {}
|
||||
|
||||
NotEmpty.prototype.asymmetricMatch = function (other) {
|
||||
NotEmpty.prototype.asymmetricMatch = function(other) {
|
||||
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
|
||||
return other.length !== 0;
|
||||
}
|
||||
@@ -18,7 +17,7 @@ getJasmineRequireObj().NotEmpty = function (j$) {
|
||||
return false;
|
||||
};
|
||||
|
||||
NotEmpty.prototype.jasmineToString = function () {
|
||||
NotEmpty.prototype.jasmineToString = function() {
|
||||
return '<jasmine.notEmpty>';
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
|
||||
function ObjectContaining(sample) {
|
||||
this.sample = sample;
|
||||
}
|
||||
@@ -17,7 +16,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
}
|
||||
|
||||
function hasProperty(obj, property) {
|
||||
if (!obj) {
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,12 +27,23 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
return hasProperty(getPrototype(obj), property);
|
||||
}
|
||||
|
||||
ObjectContaining.prototype.asymmetricMatch = function(other, customTesters) {
|
||||
if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
|
||||
ObjectContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
|
||||
if (typeof this.sample !== 'object') {
|
||||
throw new Error(
|
||||
"You must provide an object to objectContaining, not '" +
|
||||
this.sample +
|
||||
"'."
|
||||
);
|
||||
}
|
||||
if (typeof other !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasProperty(other, property) ||
|
||||
!j$.matchersUtil.equals(this.sample[property], other[property], customTesters)) {
|
||||
if (
|
||||
!hasProperty(other, property) ||
|
||||
!matchersUtil.equals(this.sample[property], other[property])
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -41,8 +51,29 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
ObjectContaining.prototype.jasmineToString = function() {
|
||||
return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
|
||||
ObjectContaining.prototype.valuesForDiff_ = function(other, pp) {
|
||||
if (!j$.isObject_(other)) {
|
||||
return {
|
||||
self: this.jasmineToString(pp),
|
||||
other: other
|
||||
};
|
||||
}
|
||||
|
||||
var filteredOther = {};
|
||||
Object.keys(this.sample).forEach(function(k) {
|
||||
// eq short-circuits comparison of objects that have different key sets,
|
||||
// so include all keys even if undefined.
|
||||
filteredOther[k] = other[k];
|
||||
});
|
||||
|
||||
return {
|
||||
self: this.sample,
|
||||
other: filteredOther
|
||||
};
|
||||
};
|
||||
|
||||
ObjectContaining.prototype.jasmineToString = function(pp) {
|
||||
return '<jasmine.objectContaining(' + pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return ObjectContaining;
|
||||
|
||||
41
src/core/asymmetric_equality/SetContaining.js
Normal file
41
src/core/asymmetric_equality/SetContaining.js
Normal file
@@ -0,0 +1,41 @@
|
||||
getJasmineRequireObj().SetContaining = function(j$) {
|
||||
function SetContaining(sample) {
|
||||
if (!j$.isSet(sample)) {
|
||||
throw new Error(
|
||||
'You must provide a set to `setContaining`, not ' + j$.pp(sample)
|
||||
);
|
||||
}
|
||||
|
||||
this.sample = sample;
|
||||
}
|
||||
|
||||
SetContaining.prototype.asymmetricMatch = function(other, matchersUtil) {
|
||||
if (!j$.isSet(other)) return false;
|
||||
|
||||
var hasAllMatches = true;
|
||||
j$.util.forEachBreakable(this.sample, function(breakLoop, item) {
|
||||
// for each item in `sample` there should be at least one matching item in `other`
|
||||
// (not using `matchersUtil.contains` because it compares set members by reference,
|
||||
// not by deep value equality)
|
||||
var hasMatch = false;
|
||||
j$.util.forEachBreakable(other, function(oBreakLoop, oItem) {
|
||||
if (matchersUtil.equals(oItem, item)) {
|
||||
hasMatch = true;
|
||||
oBreakLoop();
|
||||
}
|
||||
});
|
||||
if (!hasMatch) {
|
||||
hasAllMatches = false;
|
||||
breakLoop();
|
||||
}
|
||||
});
|
||||
|
||||
return hasAllMatches;
|
||||
};
|
||||
|
||||
SetContaining.prototype.jasmineToString = function(pp) {
|
||||
return '<jasmine.setContaining(' + pp(this.sample) + ')>';
|
||||
};
|
||||
|
||||
return SetContaining;
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().StringMatching = function(j$) {
|
||||
|
||||
function StringMatching(expected) {
|
||||
if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) {
|
||||
throw new Error('Expected is not a String or a RegExp');
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
getJasmineRequireObj().Truthy = function(j$) {
|
||||
|
||||
function Truthy() {}
|
||||
|
||||
Truthy.prototype.asymmetricMatch = function(other) {
|
||||
|
||||
147
src/core/base.js
147
src/core/base.js
@@ -7,6 +7,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Maximum object depth the pretty printer will print to.
|
||||
* Set this to a lower value to speed up pretty printing if you have large objects.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_DEPTH
|
||||
* @since 1.3.0
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_DEPTH = 8;
|
||||
/**
|
||||
@@ -14,17 +15,20 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* This will also limit the number of keys and values displayed for an object.
|
||||
* Elements past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
* @since 2.7.0
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
|
||||
/**
|
||||
* Maximum number of characters to display when pretty printing objects.
|
||||
* Characters past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_CHARS
|
||||
* @since 2.9.0
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_CHARS = 1000;
|
||||
/**
|
||||
* Default number of milliseconds Jasmine will wait for an asynchronous spec to complete.
|
||||
* @name jasmine.DEFAULT_TIMEOUT_INTERVAL
|
||||
* @since 1.3.0
|
||||
*/
|
||||
j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
|
||||
@@ -36,11 +40,12 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get the currently booted Jasmine Environment.
|
||||
*
|
||||
* @name jasmine.getEnv
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @return {Env}
|
||||
*/
|
||||
j$.getEnv = function(options) {
|
||||
var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
|
||||
var env = (j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options));
|
||||
//jasmine. singletons in here (setTimeout blah blah).
|
||||
return env;
|
||||
};
|
||||
@@ -50,7 +55,9 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
};
|
||||
|
||||
j$.isObject_ = function(value) {
|
||||
return !j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value);
|
||||
return (
|
||||
!j$.util.isUndefined(value) && value !== null && j$.isA_('Object', value)
|
||||
);
|
||||
};
|
||||
|
||||
j$.isString_ = function(value) {
|
||||
@@ -69,8 +76,13 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return j$.isA_('AsyncFunction', value);
|
||||
};
|
||||
|
||||
j$.isGeneratorFunction_ = function(value) {
|
||||
return j$.isA_('GeneratorFunction', value);
|
||||
};
|
||||
|
||||
j$.isTypedArray_ = function(value) {
|
||||
return j$.isA_('Float32Array', value) ||
|
||||
return (
|
||||
j$.isA_('Float32Array', value) ||
|
||||
j$.isA_('Float64Array', value) ||
|
||||
j$.isA_('Int16Array', value) ||
|
||||
j$.isA_('Int32Array', value) ||
|
||||
@@ -78,7 +90,8 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
j$.isA_('Uint16Array', value) ||
|
||||
j$.isA_('Uint32Array', value) ||
|
||||
j$.isA_('Uint8Array', value) ||
|
||||
j$.isA_('Uint8ClampedArray', value);
|
||||
j$.isA_('Uint8ClampedArray', value)
|
||||
);
|
||||
};
|
||||
|
||||
j$.isA_ = function(typeName, value) {
|
||||
@@ -102,15 +115,19 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return false;
|
||||
};
|
||||
|
||||
j$.isAsymmetricEqualityTester_ = function(obj) {
|
||||
return obj ? j$.isA_('Function', obj.asymmetricMatch) : false;
|
||||
};
|
||||
|
||||
j$.getType_ = function(value) {
|
||||
return Object.prototype.toString.apply(value);
|
||||
};
|
||||
|
||||
j$.isDomNode = function(obj) {
|
||||
// Node is a function, because constructors
|
||||
return typeof jasmineGlobal.Node !== 'undefined' ?
|
||||
obj instanceof jasmineGlobal.Node :
|
||||
obj !== null &&
|
||||
return typeof jasmineGlobal.Node !== 'undefined'
|
||||
? obj instanceof jasmineGlobal.Node
|
||||
: obj !== null &&
|
||||
typeof obj === 'object' &&
|
||||
typeof obj.nodeType === 'number' &&
|
||||
typeof obj.nodeName === 'string';
|
||||
@@ -118,15 +135,56 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
};
|
||||
|
||||
j$.isMap = function(obj) {
|
||||
return typeof jasmineGlobal.Map !== 'undefined' && obj.constructor === jasmineGlobal.Map;
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj !== 'undefined' &&
|
||||
typeof jasmineGlobal.Map !== 'undefined' &&
|
||||
obj.constructor === jasmineGlobal.Map
|
||||
);
|
||||
};
|
||||
|
||||
j$.isSet = function(obj) {
|
||||
return typeof jasmineGlobal.Set !== 'undefined' && obj.constructor === jasmineGlobal.Set;
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj !== 'undefined' &&
|
||||
typeof jasmineGlobal.Set !== 'undefined' &&
|
||||
obj.constructor === jasmineGlobal.Set
|
||||
);
|
||||
};
|
||||
|
||||
j$.isWeakMap = function(obj) {
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj !== 'undefined' &&
|
||||
typeof jasmineGlobal.WeakMap !== 'undefined' &&
|
||||
obj.constructor === jasmineGlobal.WeakMap
|
||||
);
|
||||
};
|
||||
|
||||
j$.isURL = function(obj) {
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj !== 'undefined' &&
|
||||
typeof jasmineGlobal.URL !== 'undefined' &&
|
||||
obj.constructor === jasmineGlobal.URL
|
||||
);
|
||||
};
|
||||
|
||||
j$.isDataView = function(obj) {
|
||||
return (
|
||||
obj !== null &&
|
||||
typeof obj !== 'undefined' &&
|
||||
typeof jasmineGlobal.DataView !== 'undefined' &&
|
||||
obj.constructor === jasmineGlobal.DataView
|
||||
);
|
||||
};
|
||||
|
||||
j$.isPromise = function(obj) {
|
||||
return typeof jasmineGlobal.Promise !== 'undefined' && !!obj && obj.constructor === jasmineGlobal.Promise;
|
||||
return (
|
||||
typeof jasmineGlobal.Promise !== 'undefined' &&
|
||||
!!obj &&
|
||||
obj.constructor === jasmineGlobal.Promise
|
||||
);
|
||||
};
|
||||
|
||||
j$.isPromiseLike = function(obj) {
|
||||
@@ -138,7 +196,8 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return func.name;
|
||||
}
|
||||
|
||||
var matches = func.toString().match(/^\s*function\s*(\w+)\s*\(/) ||
|
||||
var matches =
|
||||
func.toString().match(/^\s*function\s*(\w+)\s*\(/) ||
|
||||
func.toString().match(/^\s*\[object\s*(\w+)Constructor\]/);
|
||||
|
||||
return matches ? matches[1] : '<anonymous>';
|
||||
@@ -148,6 +207,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is an instance of the specified class/constructor.
|
||||
* @name jasmine.any
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @param {Constructor} clazz - The constructor to check against.
|
||||
*/
|
||||
@@ -159,6 +219,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is not `null` and not `undefined`.
|
||||
* @name jasmine.anything
|
||||
* @since 2.2.0
|
||||
* @function
|
||||
*/
|
||||
j$.anything = function() {
|
||||
@@ -169,38 +230,51 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is `true` or anything truthy.
|
||||
* @name jasmine.truthy
|
||||
* @since 3.1.0
|
||||
* @function
|
||||
*/
|
||||
j$.truthy = function() {return new j$.Truthy();};
|
||||
j$.truthy = function() {
|
||||
return new j$.Truthy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is `null`, `undefined`, `0`, `false` or anything falsey.
|
||||
* @name jasmine.falsy
|
||||
* @since 3.1.0
|
||||
* @function
|
||||
*/
|
||||
j$.falsy = function() {return new j$.Falsy();};
|
||||
j$.falsy = function() {
|
||||
return new j$.Falsy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is empty.
|
||||
* @name jasmine.empty
|
||||
* @since 3.1.0
|
||||
* @function
|
||||
*/
|
||||
j$.empty = function() {return new j$.Empty();};
|
||||
j$.empty = function() {
|
||||
return new j$.Empty();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared is not empty.
|
||||
* @name jasmine.notEmpty
|
||||
* @since 3.1.0
|
||||
* @function
|
||||
*/
|
||||
j$.notEmpty = function() {return new j$.NotEmpty();};
|
||||
j$.notEmpty = function() {
|
||||
return new j$.NotEmpty();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value being compared contains at least the keys and values.
|
||||
* @name jasmine.objectContaining
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @param {Object} sample - The subset of properties that _must_ be in the actual.
|
||||
*/
|
||||
@@ -212,6 +286,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value is a `String` that matches the `RegExp` or `String`.
|
||||
* @name jasmine.stringMatching
|
||||
* @since 2.2.0
|
||||
* @function
|
||||
* @param {RegExp|String} expected
|
||||
*/
|
||||
@@ -223,6 +298,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value is an `Array` that contains at least the elements in the sample.
|
||||
* @name jasmine.arrayContaining
|
||||
* @since 2.2.0
|
||||
* @function
|
||||
* @param {Array} sample
|
||||
*/
|
||||
@@ -234,6 +310,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if the actual value is an `Array` that contains all of the elements in the sample in any order.
|
||||
* @name jasmine.arrayWithExactContents
|
||||
* @since 2.8.0
|
||||
* @function
|
||||
* @param {Array} sample
|
||||
*/
|
||||
@@ -241,11 +318,47 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return new j$.ArrayWithExactContents(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if every key/value pair in the sample passes the deep equality comparison
|
||||
* with at least one key/value pair in the actual value being compared
|
||||
* @name jasmine.mapContaining
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {Map} sample - The subset of items that _must_ be in the actual.
|
||||
*/
|
||||
j$.mapContaining = function(sample) {
|
||||
return new j$.MapContaining(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
|
||||
* that will succeed if every item in the sample passes the deep equality comparison
|
||||
* with at least one item in the actual value being compared
|
||||
* @name jasmine.setContaining
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {Set} sample - The subset of items that _must_ be in the actual.
|
||||
*/
|
||||
j$.setContaining = function(sample) {
|
||||
return new j$.SetContaining(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines whether the provided function is a Jasmine spy.
|
||||
* @name jasmine.isSpy
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Function} putativeSpy - The function to check.
|
||||
* @return {Boolean}
|
||||
*/
|
||||
j$.isSpy = function(putativeSpy) {
|
||||
if (!putativeSpy) {
|
||||
return false;
|
||||
}
|
||||
return putativeSpy.and instanceof j$.SpyStrategy &&
|
||||
putativeSpy.calls instanceof j$.CallTracker;
|
||||
return (
|
||||
putativeSpy.and instanceof j$.SpyStrategy &&
|
||||
putativeSpy.calls instanceof j$.CallTracker
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -7,4 +7,4 @@ getJasmineRequireObj().errors = function() {
|
||||
return {
|
||||
ExpectationFailed: ExpectationFailed
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,19 +1,69 @@
|
||||
getJasmineRequireObj().DiffBuilder = function(j$) {
|
||||
return function DiffBuilder() {
|
||||
var path = new j$.ObjectPath(),
|
||||
mismatches = [];
|
||||
return function DiffBuilder(config) {
|
||||
var prettyPrinter = (config || {}).prettyPrinter || j$.makePrettyPrinter(),
|
||||
mismatches = new j$.MismatchTree(),
|
||||
path = new j$.ObjectPath(),
|
||||
actualRoot = undefined,
|
||||
expectedRoot = undefined;
|
||||
|
||||
return {
|
||||
record: function (actual, expected, formatter) {
|
||||
formatter = formatter || defaultFormatter;
|
||||
mismatches.push(formatter(actual, expected, path));
|
||||
setRoots: function(actual, expected) {
|
||||
actualRoot = actual;
|
||||
expectedRoot = expected;
|
||||
},
|
||||
|
||||
getMessage: function () {
|
||||
return mismatches.join('\n');
|
||||
recordMismatch: function(formatter) {
|
||||
mismatches.add(path, formatter);
|
||||
},
|
||||
|
||||
withPath: function (pathComponent, block) {
|
||||
getMessage: function() {
|
||||
var messages = [];
|
||||
|
||||
mismatches.traverse(function(path, isLeaf, formatter) {
|
||||
var actualCustom,
|
||||
expectedCustom,
|
||||
useCustom,
|
||||
derefResult = dereferencePath(
|
||||
path,
|
||||
actualRoot,
|
||||
expectedRoot,
|
||||
prettyPrinter
|
||||
),
|
||||
actual = derefResult.actual,
|
||||
expected = derefResult.expected;
|
||||
|
||||
if (formatter) {
|
||||
messages.push(formatter(actual, expected, path, prettyPrinter));
|
||||
return true;
|
||||
}
|
||||
|
||||
actualCustom = prettyPrinter.customFormat_(actual);
|
||||
expectedCustom = prettyPrinter.customFormat_(expected);
|
||||
useCustom = !(
|
||||
j$.util.isUndefined(actualCustom) &&
|
||||
j$.util.isUndefined(expectedCustom)
|
||||
);
|
||||
|
||||
if (useCustom) {
|
||||
messages.push(
|
||||
wrapPrettyPrinted(actualCustom, expectedCustom, path)
|
||||
);
|
||||
return false; // don't recurse further
|
||||
}
|
||||
|
||||
if (isLeaf) {
|
||||
messages.push(
|
||||
defaultFormatter(actual, expected, path, prettyPrinter)
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return messages.join('\n');
|
||||
},
|
||||
|
||||
withPath: function(pathComponent, block) {
|
||||
var oldPath = path;
|
||||
path = path.add(pathComponent);
|
||||
block();
|
||||
@@ -21,13 +71,48 @@ getJasmineRequireObj().DiffBuilder = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
function defaultFormatter (actual, expected, path) {
|
||||
return 'Expected ' +
|
||||
path + (path.depth() ? ' = ' : '') +
|
||||
j$.pp(actual) +
|
||||
function defaultFormatter(actual, expected, path, prettyPrinter) {
|
||||
return wrapPrettyPrinted(
|
||||
prettyPrinter(actual),
|
||||
prettyPrinter(expected),
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
function wrapPrettyPrinted(actual, expected, path) {
|
||||
return (
|
||||
'Expected ' +
|
||||
path +
|
||||
(path.depth() ? ' = ' : '') +
|
||||
actual +
|
||||
' to equal ' +
|
||||
j$.pp(expected) +
|
||||
'.';
|
||||
expected +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
function dereferencePath(objectPath, actual, expected, pp) {
|
||||
function handleAsymmetricExpected() {
|
||||
if (
|
||||
j$.isAsymmetricEqualityTester_(expected) &&
|
||||
j$.isFunction_(expected.valuesForDiff_)
|
||||
) {
|
||||
var asymmetricResult = expected.valuesForDiff_(actual, pp);
|
||||
expected = asymmetricResult.self;
|
||||
actual = asymmetricResult.other;
|
||||
}
|
||||
}
|
||||
|
||||
var i;
|
||||
handleAsymmetricExpected();
|
||||
|
||||
for (i = 0; i < objectPath.components.length; i++) {
|
||||
actual = actual[objectPath.components[i]];
|
||||
expected = expected[objectPath.components[i]];
|
||||
handleAsymmetricExpected();
|
||||
}
|
||||
|
||||
return { actual: actual, expected: expected };
|
||||
}
|
||||
};
|
||||
|
||||
61
src/core/matchers/MismatchTree.js
Normal file
61
src/core/matchers/MismatchTree.js
Normal file
@@ -0,0 +1,61 @@
|
||||
getJasmineRequireObj().MismatchTree = function(j$) {
|
||||
/*
|
||||
To be able to apply custom object formatters at all possible levels of an
|
||||
object graph, DiffBuilder needs to be able to know not just where the
|
||||
mismatch occurred but also all ancestors of the mismatched value in both
|
||||
the expected and actual object graphs. MismatchTree maintains that context
|
||||
and provides it via the traverse method.
|
||||
*/
|
||||
function MismatchTree(path) {
|
||||
this.path = path || new j$.ObjectPath([]);
|
||||
this.formatter = undefined;
|
||||
this.children = [];
|
||||
this.isMismatch = false;
|
||||
}
|
||||
|
||||
MismatchTree.prototype.add = function(path, formatter) {
|
||||
var key, child;
|
||||
|
||||
if (path.depth() === 0) {
|
||||
this.formatter = formatter;
|
||||
this.isMismatch = true;
|
||||
} else {
|
||||
key = path.components[0];
|
||||
path = path.shift();
|
||||
child = this.child(key);
|
||||
|
||||
if (!child) {
|
||||
child = new MismatchTree(this.path.add(key));
|
||||
this.children.push(child);
|
||||
}
|
||||
|
||||
child.add(path, formatter);
|
||||
}
|
||||
};
|
||||
|
||||
MismatchTree.prototype.traverse = function(visit) {
|
||||
var i,
|
||||
hasChildren = this.children.length > 0;
|
||||
|
||||
if (this.isMismatch || hasChildren) {
|
||||
if (visit(this.path, !hasChildren, this.formatter)) {
|
||||
for (i = 0; i < this.children.length; i++) {
|
||||
this.children[i].traverse(visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MismatchTree.prototype.child = function(key) {
|
||||
var i, pathEls;
|
||||
|
||||
for (i = 0; i < this.children.length; i++) {
|
||||
pathEls = this.children[i].path.components;
|
||||
if (pathEls[pathEls.length - 1] === key) {
|
||||
return this.children[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return MismatchTree;
|
||||
};
|
||||
@@ -4,7 +4,8 @@ getJasmineRequireObj().NullDiffBuilder = function(j$) {
|
||||
withPath: function(_, block) {
|
||||
block();
|
||||
},
|
||||
record: function() {}
|
||||
setRoots: function() {},
|
||||
recordMismatch: function() {}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -15,6 +15,10 @@ getJasmineRequireObj().ObjectPath = function(j$) {
|
||||
return new ObjectPath(this.components.concat([component]));
|
||||
};
|
||||
|
||||
ObjectPath.prototype.shift = function() {
|
||||
return new ObjectPath(this.components.slice(1));
|
||||
};
|
||||
|
||||
ObjectPath.prototype.depth = function() {
|
||||
return this.components.length;
|
||||
};
|
||||
@@ -28,7 +32,7 @@ getJasmineRequireObj().ObjectPath = function(j$) {
|
||||
return '.' + prop;
|
||||
}
|
||||
|
||||
return '[\'' + prop + '\']';
|
||||
return "['" + prop + "']";
|
||||
}
|
||||
|
||||
function map(array, fn) {
|
||||
|
||||
30
src/core/matchers/async/toBePending.js
Normal file
30
src/core/matchers/async/toBePending.js
Normal file
@@ -0,0 +1,30 @@
|
||||
/* eslint-disable compat/compat */
|
||||
getJasmineRequireObj().toBePending = function(j$) {
|
||||
/**
|
||||
* Expect a promise to be pending, i.e. the promise is neither resolved nor rejected.
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBePending
|
||||
* @since 3.6
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBePending();
|
||||
*/
|
||||
return function toBePending() {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
if (!j$.isPromiseLike(actual)) {
|
||||
throw new Error('Expected toBePending to be called on a promise.');
|
||||
}
|
||||
var want = {};
|
||||
return Promise.race([actual, Promise.resolve(want)]).then(
|
||||
function(got) {
|
||||
return { pass: want === got };
|
||||
},
|
||||
function() {
|
||||
return { pass: false };
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -4,17 +4,25 @@ getJasmineRequireObj().toBeRejected = function(j$) {
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBeRejected
|
||||
* @since 3.1.0
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBeRejected();
|
||||
* @example
|
||||
* return expectAsync(aPromise).toBeRejected();
|
||||
*/
|
||||
return function toBeResolved(util) {
|
||||
return function toBeRejected() {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
if (!j$.isPromiseLike(actual)) {
|
||||
throw new Error('Expected toBeRejected to be called on a promise.');
|
||||
}
|
||||
return actual.then(
|
||||
function() { return {pass: false}; },
|
||||
function() { return {pass: true}; }
|
||||
function() {
|
||||
return { pass: false };
|
||||
},
|
||||
function() {
|
||||
return { pass: true };
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,41 +4,55 @@ getJasmineRequireObj().toBeRejectedWith = function(j$) {
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBeRejectedWith
|
||||
* @since 3.3.0
|
||||
* @param {Object} expected - Value that the promise is expected to be rejected with
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBeRejectedWith({prop: 'value'});
|
||||
* @example
|
||||
* return expectAsync(aPromise).toBeRejectedWith({prop: 'value'});
|
||||
*/
|
||||
return function toBeRejectedWith(util, customEqualityTesters) {
|
||||
return function toBeRejectedWith(matchersUtil) {
|
||||
return {
|
||||
compare: function(actualPromise, expectedValue) {
|
||||
if (!j$.isPromiseLike(actualPromise)) {
|
||||
throw new Error(
|
||||
'Expected toBeRejectedWith to be called on a promise.'
|
||||
);
|
||||
}
|
||||
|
||||
function prefix(passed) {
|
||||
return 'Expected a promise ' +
|
||||
return (
|
||||
'Expected a promise ' +
|
||||
(passed ? 'not ' : '') +
|
||||
'to be rejected with ' + j$.pp(expectedValue);
|
||||
'to be rejected with ' +
|
||||
matchersUtil.pp(expectedValue)
|
||||
);
|
||||
}
|
||||
|
||||
return actualPromise.then(
|
||||
function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: prefix(false) + ' but it was resolved.'
|
||||
};
|
||||
},
|
||||
function(actualValue) {
|
||||
if (util.equals(actualValue, expectedValue, customEqualityTesters)) {
|
||||
return {
|
||||
pass: true,
|
||||
message: prefix(true) + '.'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
pass: false,
|
||||
message: prefix(false) + ' but it was rejected with ' + j$.pp(actualValue) + '.'
|
||||
message: prefix(false) + ' but it was resolved.'
|
||||
};
|
||||
},
|
||||
function(actualValue) {
|
||||
if (matchersUtil.equals(actualValue, expectedValue)) {
|
||||
return {
|
||||
pass: true,
|
||||
message: prefix(true) + '.'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
pass: false,
|
||||
message:
|
||||
prefix(false) +
|
||||
' but it was rejected with ' +
|
||||
matchersUtil.pp(actualValue) +
|
||||
'.'
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
122
src/core/matchers/async/toBeRejectedWithError.js
Normal file
122
src/core/matchers/async/toBeRejectedWithError.js
Normal file
@@ -0,0 +1,122 @@
|
||||
getJasmineRequireObj().toBeRejectedWithError = function(j$) {
|
||||
/**
|
||||
* Expect a promise to be rejected with a value matched to the expected
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBeRejectedWithError
|
||||
* @since 3.5.0
|
||||
* @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.
|
||||
* @param {RegExp|String} [message] - The message that should be set on the thrown `Error`
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, 'Error message');
|
||||
* await expectAsync(aPromise).toBeRejectedWithError(MyCustomError, /Error message/);
|
||||
* await expectAsync(aPromise).toBeRejectedWithError(MyCustomError);
|
||||
* await expectAsync(aPromise).toBeRejectedWithError('Error message');
|
||||
* return expectAsync(aPromise).toBeRejectedWithError(/Error message/);
|
||||
*/
|
||||
return function toBeRejectedWithError(matchersUtil) {
|
||||
return {
|
||||
compare: function(actualPromise, arg1, arg2) {
|
||||
if (!j$.isPromiseLike(actualPromise)) {
|
||||
throw new Error(
|
||||
'Expected toBeRejectedWithError to be called on a promise.'
|
||||
);
|
||||
}
|
||||
|
||||
var expected = getExpectedFromArgs(arg1, arg2, matchersUtil);
|
||||
|
||||
return actualPromise.then(
|
||||
function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: 'Expected a promise to be rejected but it was resolved.'
|
||||
};
|
||||
},
|
||||
function(actualValue) {
|
||||
return matchError(actualValue, expected, matchersUtil);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function matchError(actual, expected, matchersUtil) {
|
||||
if (!j$.isError_(actual)) {
|
||||
return fail(expected, 'rejected with ' + matchersUtil.pp(actual));
|
||||
}
|
||||
|
||||
if (!(actual instanceof expected.error)) {
|
||||
return fail(
|
||||
expected,
|
||||
'rejected with type ' + j$.fnNameFor(actual.constructor)
|
||||
);
|
||||
}
|
||||
|
||||
var actualMessage = actual.message;
|
||||
|
||||
if (
|
||||
actualMessage === expected.message ||
|
||||
typeof expected.message === 'undefined'
|
||||
) {
|
||||
return pass(expected);
|
||||
}
|
||||
|
||||
if (
|
||||
expected.message instanceof RegExp &&
|
||||
expected.message.test(actualMessage)
|
||||
) {
|
||||
return pass(expected);
|
||||
}
|
||||
|
||||
return fail(expected, 'rejected with ' + matchersUtil.pp(actual));
|
||||
}
|
||||
|
||||
function pass(expected) {
|
||||
return {
|
||||
pass: true,
|
||||
message:
|
||||
'Expected a promise not to be rejected with ' +
|
||||
expected.printValue +
|
||||
', but it was.'
|
||||
};
|
||||
}
|
||||
|
||||
function fail(expected, message) {
|
||||
return {
|
||||
pass: false,
|
||||
message:
|
||||
'Expected a promise to be rejected with ' +
|
||||
expected.printValue +
|
||||
' but it was ' +
|
||||
message +
|
||||
'.'
|
||||
};
|
||||
}
|
||||
|
||||
function getExpectedFromArgs(arg1, arg2, matchersUtil) {
|
||||
var error, message;
|
||||
|
||||
if (isErrorConstructor(arg1)) {
|
||||
error = arg1;
|
||||
message = arg2;
|
||||
} else {
|
||||
error = Error;
|
||||
message = arg1;
|
||||
}
|
||||
|
||||
return {
|
||||
error: error,
|
||||
message: message,
|
||||
printValue:
|
||||
j$.fnNameFor(error) +
|
||||
(typeof message === 'undefined' ? '' : ': ' + matchersUtil.pp(message))
|
||||
};
|
||||
}
|
||||
|
||||
function isErrorConstructor(value) {
|
||||
return (
|
||||
typeof value === 'function' &&
|
||||
(value === Error || j$.isError_(value.prototype))
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -4,17 +4,26 @@ getJasmineRequireObj().toBeResolved = function(j$) {
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBeResolved
|
||||
* @since 3.1.0
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBeResolved();
|
||||
* @example
|
||||
* return expectAsync(aPromise).toBeResolved();
|
||||
*/
|
||||
return function toBeResolved(util) {
|
||||
return function toBeResolved() {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
if (!j$.isPromiseLike(actual)) {
|
||||
throw new Error('Expected toBeResolved to be called on a promise.');
|
||||
}
|
||||
|
||||
return actual.then(
|
||||
function() { return {pass: true}; },
|
||||
function() { return {pass: false}; }
|
||||
function() {
|
||||
return { pass: true };
|
||||
},
|
||||
function() {
|
||||
return { pass: false };
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,41 +4,53 @@ getJasmineRequireObj().toBeResolvedTo = function(j$) {
|
||||
* @function
|
||||
* @async
|
||||
* @name async-matchers#toBeResolvedTo
|
||||
* @since 3.1.0
|
||||
* @param {Object} expected - Value that the promise is expected to resolve to
|
||||
* @example
|
||||
* await expectAsync(aPromise).toBeResolvedTo({prop: 'value'});
|
||||
* @example
|
||||
* return expectAsync(aPromise).toBeResolvedTo({prop: 'value'});
|
||||
*/
|
||||
return function toBeResolvedTo(util, customEqualityTesters) {
|
||||
return function toBeResolvedTo(matchersUtil) {
|
||||
return {
|
||||
compare: function(actualPromise, expectedValue) {
|
||||
if (!j$.isPromiseLike(actualPromise)) {
|
||||
throw new Error('Expected toBeResolvedTo to be called on a promise.');
|
||||
}
|
||||
|
||||
function prefix(passed) {
|
||||
return 'Expected a promise ' +
|
||||
return (
|
||||
'Expected a promise ' +
|
||||
(passed ? 'not ' : '') +
|
||||
'to be resolved to ' + j$.pp(expectedValue);
|
||||
'to be resolved to ' +
|
||||
matchersUtil.pp(expectedValue)
|
||||
);
|
||||
}
|
||||
|
||||
return actualPromise.then(
|
||||
function(actualValue) {
|
||||
if (util.equals(actualValue, expectedValue, customEqualityTesters)) {
|
||||
return {
|
||||
pass: true,
|
||||
message: prefix(true) + '.'
|
||||
};
|
||||
} else {
|
||||
if (matchersUtil.equals(actualValue, expectedValue)) {
|
||||
return {
|
||||
pass: true,
|
||||
message: prefix(true) + '.'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
pass: false,
|
||||
message:
|
||||
prefix(false) +
|
||||
' but it was resolved to ' +
|
||||
matchersUtil.pp(actualValue) +
|
||||
'.'
|
||||
};
|
||||
}
|
||||
},
|
||||
function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: prefix(false) + ' but it was resolved to ' + j$.pp(actualValue) + '.'
|
||||
message: prefix(false) + ' but it was rejected.'
|
||||
};
|
||||
}
|
||||
},
|
||||
function() {
|
||||
return {
|
||||
pass: false,
|
||||
message: prefix(false) + ' but it was rejected.'
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,99 +1,201 @@
|
||||
getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
// TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
|
||||
getJasmineRequireObj().MatchersUtil = function(j$) {
|
||||
// TODO: convert all uses of j$.pp to use the injected pp
|
||||
|
||||
return {
|
||||
equals: equals,
|
||||
/**
|
||||
* _Note:_ Do not construct this directly. Jasmine will construct one and
|
||||
* pass it to matchers and asymmetric equality testers.
|
||||
* @name MatchersUtil
|
||||
* @classdesc Utilities for use in implementing matchers
|
||||
* @constructor
|
||||
*/
|
||||
function MatchersUtil(options) {
|
||||
options = options || {};
|
||||
this.customTesters_ = options.customTesters || [];
|
||||
/**
|
||||
* Formats a value for use in matcher failure messages and similar contexts,
|
||||
* taking into account the current set of custom value formatters.
|
||||
* @function
|
||||
* @name MatchersUtil#pp
|
||||
* @since 3.6.0
|
||||
* @param {*} value The value to pretty-print
|
||||
* @return {string} The pretty-printed value
|
||||
*/
|
||||
this.pp = options.pp || function() {};
|
||||
}
|
||||
|
||||
contains: function(haystack, needle, customTesters) {
|
||||
customTesters = customTesters || [];
|
||||
/**
|
||||
* Determines whether `haystack` contains `needle`, using the same comparison
|
||||
* logic as {@link MatchersUtil#equals}.
|
||||
* @function
|
||||
* @name MatchersUtil#contains
|
||||
* @since 2.0.0
|
||||
* @param {*} haystack The collection to search
|
||||
* @param {*} needle The value to search for
|
||||
* @param [customTesters] An array of custom equality testers
|
||||
* @returns {boolean} True if `needle` was found in `haystack`
|
||||
*/
|
||||
MatchersUtil.prototype.contains = function(haystack, needle, customTesters) {
|
||||
if (j$.isSet(haystack)) {
|
||||
return haystack.has(needle);
|
||||
}
|
||||
|
||||
if ((Object.prototype.toString.apply(haystack) === '[object Set]')) {
|
||||
return haystack.has(needle);
|
||||
}
|
||||
|
||||
if ((Object.prototype.toString.apply(haystack) === '[object Array]') ||
|
||||
(!!haystack && !haystack.indexOf))
|
||||
{
|
||||
for (var i = 0; i < haystack.length; i++) {
|
||||
if (equals(haystack[i], needle, customTesters)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!haystack && haystack.indexOf(needle) >= 0;
|
||||
},
|
||||
|
||||
buildFailureMessage: function() {
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
matcherName = args[0],
|
||||
isNot = args[1],
|
||||
actual = args[2],
|
||||
expected = args.slice(3),
|
||||
englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
|
||||
|
||||
var message = 'Expected ' +
|
||||
j$.pp(actual) +
|
||||
(isNot ? ' not ' : ' ') +
|
||||
englishyPredicate;
|
||||
|
||||
if (expected.length > 0) {
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
if (i > 0) {
|
||||
message += ',';
|
||||
}
|
||||
message += ' ' + j$.pp(expected[i]);
|
||||
if (
|
||||
Object.prototype.toString.apply(haystack) === '[object Array]' ||
|
||||
(!!haystack && !haystack.indexOf)
|
||||
) {
|
||||
for (var i = 0; i < haystack.length; i++) {
|
||||
if (this.equals(haystack[i], needle, customTesters)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return message + '.';
|
||||
return !!haystack && haystack.indexOf(needle) >= 0;
|
||||
};
|
||||
|
||||
MatchersUtil.prototype.buildFailureMessage = function() {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
matcherName = args[0],
|
||||
isNot = args[1],
|
||||
actual = args[2],
|
||||
expected = args.slice(3),
|
||||
englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) {
|
||||
return ' ' + s.toLowerCase();
|
||||
});
|
||||
|
||||
var message =
|
||||
'Expected ' +
|
||||
self.pp(actual) +
|
||||
(isNot ? ' not ' : ' ') +
|
||||
englishyPredicate;
|
||||
|
||||
if (expected.length > 0) {
|
||||
for (var i = 0; i < expected.length; i++) {
|
||||
if (i > 0) {
|
||||
message += ',';
|
||||
}
|
||||
message += ' ' + self.pp(expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return message + '.';
|
||||
};
|
||||
|
||||
MatchersUtil.prototype.asymmetricDiff_ = function(
|
||||
a,
|
||||
b,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
) {
|
||||
if (j$.isFunction_(b.valuesForDiff_)) {
|
||||
var values = b.valuesForDiff_(a, this.pp);
|
||||
this.eq_(
|
||||
values.other,
|
||||
values.self,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
);
|
||||
} else {
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
};
|
||||
|
||||
function isAsymmetric(obj) {
|
||||
return obj && j$.isA_('Function', obj.asymmetricMatch);
|
||||
}
|
||||
MatchersUtil.prototype.asymmetricMatch_ = function(
|
||||
a,
|
||||
b,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
) {
|
||||
var asymmetricA = j$.isAsymmetricEqualityTester_(a),
|
||||
asymmetricB = j$.isAsymmetricEqualityTester_(b),
|
||||
shim,
|
||||
result;
|
||||
|
||||
function asymmetricMatch(a, b, customTesters, diffBuilder) {
|
||||
var asymmetricA = isAsymmetric(a),
|
||||
asymmetricB = isAsymmetric(b),
|
||||
result;
|
||||
|
||||
if (asymmetricA && asymmetricB) {
|
||||
if (asymmetricA === asymmetricB) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
shim = j$.asymmetricEqualityTesterArgCompatShim(this, customTesters);
|
||||
|
||||
if (asymmetricA) {
|
||||
result = a.asymmetricMatch(b, customTesters);
|
||||
result = a.asymmetricMatch(b, shim);
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
if (asymmetricB) {
|
||||
result = b.asymmetricMatch(a, customTesters);
|
||||
result = b.asymmetricMatch(a, shim);
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
this.asymmetricDiff_(a, b, aStack, bStack, customTesters, diffBuilder);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function equals(a, b, customTesters, diffBuilder) {
|
||||
customTesters = customTesters || [];
|
||||
/**
|
||||
* Determines whether two values are deeply equal to each other.
|
||||
* @function
|
||||
* @name MatchersUtil#equals
|
||||
* @since 2.0.0
|
||||
* @param {*} a The first value to compare
|
||||
* @param {*} b The second value to compare
|
||||
* @param [customTesters] An array of custom equality testers
|
||||
* @returns {boolean} True if the values are equal
|
||||
*/
|
||||
MatchersUtil.prototype.equals = function(
|
||||
a,
|
||||
b,
|
||||
customTestersOrDiffBuilder,
|
||||
diffBuilderOrNothing
|
||||
) {
|
||||
var customTesters, diffBuilder;
|
||||
|
||||
if (isDiffBuilder(customTestersOrDiffBuilder)) {
|
||||
diffBuilder = customTestersOrDiffBuilder;
|
||||
} else {
|
||||
customTesters = customTestersOrDiffBuilder;
|
||||
diffBuilder = diffBuilderOrNothing;
|
||||
}
|
||||
|
||||
customTesters = customTesters || this.customTesters_;
|
||||
diffBuilder = diffBuilder || j$.NullDiffBuilder();
|
||||
diffBuilder.setRoots(a, b);
|
||||
|
||||
return eq(a, b, [], [], customTesters, diffBuilder);
|
||||
}
|
||||
return this.eq_(a, b, [], [], customTesters, diffBuilder);
|
||||
};
|
||||
|
||||
// Equality function lovingly adapted from isEqual in
|
||||
// [Underscore](http://underscorejs.org)
|
||||
function eq(a, b, aStack, bStack, customTesters, diffBuilder) {
|
||||
var result = true, i;
|
||||
MatchersUtil.prototype.eq_ = function(
|
||||
a,
|
||||
b,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
) {
|
||||
var result = true,
|
||||
self = this,
|
||||
i;
|
||||
|
||||
var asymmetricResult = asymmetricMatch(a, b, customTesters, diffBuilder);
|
||||
var asymmetricResult = this.asymmetricMatch_(
|
||||
a,
|
||||
b,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
);
|
||||
if (!j$.util.isUndefined(asymmetricResult)) {
|
||||
return asymmetricResult;
|
||||
}
|
||||
@@ -102,7 +204,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
var customTesterResult = customTesters[i](a, b);
|
||||
if (!j$.util.isUndefined(customTesterResult)) {
|
||||
if (!customTesterResult) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return customTesterResult;
|
||||
}
|
||||
@@ -111,18 +213,17 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
if (a instanceof Error && b instanceof Error) {
|
||||
result = a.message == b.message;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
||||
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
||||
if (a === b) {
|
||||
result = a !== 0 || 1 / a == 1 / b;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -130,13 +231,13 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
if (a === null || b === null) {
|
||||
result = a === b;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
var className = Object.prototype.toString.call(a);
|
||||
if (className != Object.prototype.toString.call(b)) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
switch (className) {
|
||||
@@ -146,15 +247,16 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
// equivalent to `new String("5")`.
|
||||
result = a == String(b);
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
case '[object Number]':
|
||||
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
|
||||
// other numeric values.
|
||||
result = a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
|
||||
result =
|
||||
a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
case '[object Date]':
|
||||
@@ -164,7 +266,7 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
// of `NaN` are not equivalent.
|
||||
result = +a == +b;
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
// RegExps are compared by their source patterns and flags.
|
||||
@@ -199,13 +301,15 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
}
|
||||
return result;
|
||||
case '[object RegExp]':
|
||||
return a.source == b.source &&
|
||||
return (
|
||||
a.source == b.source &&
|
||||
a.global == b.global &&
|
||||
a.multiline == b.multiline &&
|
||||
a.ignoreCase == b.ignoreCase;
|
||||
a.ignoreCase == b.ignoreCase
|
||||
);
|
||||
}
|
||||
if (typeof a != 'object' || typeof b != 'object') {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -215,12 +319,12 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
// At first try to use DOM3 method isEqualNode
|
||||
result = a.isEqualNode(b);
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (aIsDomNode || bIsDomNode) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -236,7 +340,9 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
while (length--) {
|
||||
// Linear search. Performance is inversely proportional to the number of
|
||||
// unique nested structures.
|
||||
if (aStack[length] == a) { return bStack[length] == b; }
|
||||
if (aStack[length] == a) {
|
||||
return bStack[length] == b;
|
||||
}
|
||||
}
|
||||
// Add the first object to the stack of traversed objects.
|
||||
aStack.push(a);
|
||||
@@ -250,19 +356,28 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
|
||||
diffBuilder.withPath('length', function() {
|
||||
if (aLength !== bLength) {
|
||||
diffBuilder.record(aLength, bLength);
|
||||
diffBuilder.recordMismatch();
|
||||
result = false;
|
||||
}
|
||||
});
|
||||
|
||||
for (i = 0; i < aLength || i < bLength; i++) {
|
||||
var formatter = false;
|
||||
diffBuilder.withPath(i, function() {
|
||||
if (i >= bLength) {
|
||||
diffBuilder.record(a[i], void 0, actualArrayIsLongerFormatter);
|
||||
diffBuilder.recordMismatch(
|
||||
actualArrayIsLongerFormatter.bind(null, self.pp)
|
||||
);
|
||||
result = false;
|
||||
} else {
|
||||
result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack, customTesters, diffBuilder) && result;
|
||||
result =
|
||||
self.eq_(
|
||||
i < aLength ? a[i] : void 0,
|
||||
i < bLength ? b[i] : void 0,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
diffBuilder
|
||||
) && result;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -271,17 +386,17 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
}
|
||||
} else if (j$.isMap(a) && j$.isMap(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
|
||||
var keysA = [];
|
||||
var keysB = [];
|
||||
a.forEach( function( valueA, keyA ) {
|
||||
keysA.push( keyA );
|
||||
a.forEach(function(valueA, keyA) {
|
||||
keysA.push(keyA);
|
||||
});
|
||||
b.forEach( function( valueB, keyB ) {
|
||||
keysB.push( keyB );
|
||||
b.forEach(function(valueB, keyB) {
|
||||
keysB.push(keyB);
|
||||
});
|
||||
|
||||
// For both sets of keys, check they map to equal values in both maps.
|
||||
@@ -302,33 +417,50 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
// Only use the cmpKey when one of the keys is asymmetric and the corresponding key matches,
|
||||
// otherwise explicitly look up the mapKey in the other Map since we want keys with unique
|
||||
// obj identity (that are otherwise equal) to not match.
|
||||
if (isAsymmetric(mapKey) || isAsymmetric(cmpKey) &&
|
||||
eq(mapKey, cmpKey, aStack, bStack, customTesters, j$.NullDiffBuilder())) {
|
||||
if (
|
||||
j$.isAsymmetricEqualityTester_(mapKey) ||
|
||||
(j$.isAsymmetricEqualityTester_(cmpKey) &&
|
||||
this.eq_(
|
||||
mapKey,
|
||||
cmpKey,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
j$.NullDiffBuilder()
|
||||
))
|
||||
) {
|
||||
mapValueB = b.get(cmpKey);
|
||||
} else {
|
||||
mapValueB = b.get(mapKey);
|
||||
}
|
||||
result = eq(mapValueA, mapValueB, aStack, bStack, customTesters, j$.NullDiffBuilder());
|
||||
result = this.eq_(
|
||||
mapValueA,
|
||||
mapValueB,
|
||||
aStack,
|
||||
bStack,
|
||||
customTesters,
|
||||
j$.NullDiffBuilder()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
} else if (j$.isSet(a) && j$.isSet(b)) {
|
||||
if (a.size != b.size) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
|
||||
var valuesA = [];
|
||||
a.forEach( function( valueA ) {
|
||||
valuesA.push( valueA );
|
||||
a.forEach(function(valueA) {
|
||||
valuesA.push(valueA);
|
||||
});
|
||||
var valuesB = [];
|
||||
b.forEach( function( valueB ) {
|
||||
valuesB.push( valueB );
|
||||
b.forEach(function(valueB) {
|
||||
valuesB.push(valueB);
|
||||
});
|
||||
|
||||
// For both sets, check they are all contained in the other set
|
||||
@@ -352,7 +484,14 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
otherValue = otherValues[l];
|
||||
prevStackSize = baseStack.length;
|
||||
// compare by value equality
|
||||
found = eq(baseValue, otherValue, baseStack, otherStack, customTesters, j$.NullDiffBuilder());
|
||||
found = this.eq_(
|
||||
baseValue,
|
||||
otherValue,
|
||||
baseStack,
|
||||
otherStack,
|
||||
customTesters,
|
||||
j$.NullDiffBuilder()
|
||||
);
|
||||
if (!found && prevStackSize !== baseStack.length) {
|
||||
baseStack.splice(prevStackSize);
|
||||
otherStack.splice(prevStackSize);
|
||||
@@ -363,31 +502,43 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
diffBuilder.record(a, b);
|
||||
diffBuilder.recordMismatch();
|
||||
return false;
|
||||
}
|
||||
} else if (j$.isURL(a) && j$.isURL(b)) {
|
||||
// URLs have no enumrable properties, so the default object comparison
|
||||
// would consider any two URLs to be equal.
|
||||
return a.toString() === b.toString();
|
||||
} else {
|
||||
|
||||
// Objects with different constructors are not equivalent, but `Object`s
|
||||
// or `Array`s from different frames are.
|
||||
var aCtor = a.constructor, bCtor = b.constructor;
|
||||
if (aCtor !== bCtor &&
|
||||
isFunction(aCtor) && isFunction(bCtor) &&
|
||||
a instanceof aCtor && b instanceof bCtor &&
|
||||
!(aCtor instanceof aCtor && bCtor instanceof bCtor)) {
|
||||
|
||||
diffBuilder.record(a, b, constructorsAreDifferentFormatter);
|
||||
var aCtor = a.constructor,
|
||||
bCtor = b.constructor;
|
||||
if (
|
||||
aCtor !== bCtor &&
|
||||
isFunction(aCtor) &&
|
||||
isFunction(bCtor) &&
|
||||
a instanceof aCtor &&
|
||||
b instanceof bCtor &&
|
||||
!(aCtor instanceof aCtor && bCtor instanceof bCtor)
|
||||
) {
|
||||
diffBuilder.recordMismatch(
|
||||
constructorsAreDifferentFormatter.bind(null, this.pp)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Deep compare objects.
|
||||
var aKeys = keys(a, className == '[object Array]'), key;
|
||||
var aKeys = keys(a, className == '[object Array]'),
|
||||
key;
|
||||
size = aKeys.length;
|
||||
|
||||
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
||||
if (keys(b, className == '[object Array]').length !== size) {
|
||||
diffBuilder.record(a, b, objectKeysAreDifferentFormatter);
|
||||
diffBuilder.recordMismatch(
|
||||
objectKeysAreDifferentFormatter.bind(null, this.pp)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -395,13 +546,17 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
key = aKeys[i];
|
||||
// Deep compare each member
|
||||
if (!j$.util.has(b, key)) {
|
||||
diffBuilder.record(a, b, objectKeysAreDifferentFormatter);
|
||||
diffBuilder.recordMismatch(
|
||||
objectKeysAreDifferentFormatter.bind(null, this.pp)
|
||||
);
|
||||
result = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
diffBuilder.withPath(key, function() {
|
||||
if(!eq(a[key], b[key], aStack, bStack, customTesters, diffBuilder)) {
|
||||
if (
|
||||
!self.eq_(a[key], b[key], aStack, bStack, customTesters, diffBuilder)
|
||||
) {
|
||||
result = false;
|
||||
}
|
||||
});
|
||||
@@ -416,26 +571,27 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
bStack.pop();
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
function keys(obj, isArray) {
|
||||
var allKeys = Object.keys ? Object.keys(obj) :
|
||||
(function(o) {
|
||||
var allKeys = Object.keys
|
||||
? Object.keys(obj)
|
||||
: (function(o) {
|
||||
var keys = [];
|
||||
for (var key in o) {
|
||||
if (j$.util.has(o, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
if (j$.util.has(o, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
})(obj);
|
||||
})(obj);
|
||||
|
||||
if (!isArray) {
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
if (allKeys.length === 0) {
|
||||
return allKeys;
|
||||
return allKeys;
|
||||
}
|
||||
|
||||
var extraKeys = [];
|
||||
@@ -448,59 +604,73 @@ getJasmineRequireObj().matchersUtil = function(j$) {
|
||||
return extraKeys;
|
||||
}
|
||||
|
||||
function has(obj, key) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return typeof obj === 'function';
|
||||
}
|
||||
|
||||
function objectKeysAreDifferentFormatter(actual, expected, path) {
|
||||
function objectKeysAreDifferentFormatter(pp, actual, expected, path) {
|
||||
var missingProperties = j$.util.objectDifference(expected, actual),
|
||||
extraProperties = j$.util.objectDifference(actual, expected),
|
||||
missingPropertiesMessage = formatKeyValuePairs(missingProperties),
|
||||
extraPropertiesMessage = formatKeyValuePairs(extraProperties),
|
||||
messages = [];
|
||||
extraProperties = j$.util.objectDifference(actual, expected),
|
||||
missingPropertiesMessage = formatKeyValuePairs(pp, missingProperties),
|
||||
extraPropertiesMessage = formatKeyValuePairs(pp, extraProperties),
|
||||
messages = [];
|
||||
|
||||
if (!path.depth()) {
|
||||
path = 'object';
|
||||
}
|
||||
|
||||
if (missingPropertiesMessage.length) {
|
||||
messages.push('Expected ' + path + ' to have properties' + missingPropertiesMessage);
|
||||
messages.push(
|
||||
'Expected ' + path + ' to have properties' + missingPropertiesMessage
|
||||
);
|
||||
}
|
||||
|
||||
if (extraPropertiesMessage.length) {
|
||||
messages.push('Expected ' + path + ' not to have properties' + extraPropertiesMessage);
|
||||
messages.push(
|
||||
'Expected ' + path + ' not to have properties' + extraPropertiesMessage
|
||||
);
|
||||
}
|
||||
|
||||
return messages.join('\n');
|
||||
}
|
||||
|
||||
function constructorsAreDifferentFormatter(actual, expected, path) {
|
||||
function constructorsAreDifferentFormatter(pp, actual, expected, path) {
|
||||
if (!path.depth()) {
|
||||
path = 'object';
|
||||
}
|
||||
|
||||
return 'Expected ' +
|
||||
path + ' to be a kind of ' +
|
||||
return (
|
||||
'Expected ' +
|
||||
path +
|
||||
' to be a kind of ' +
|
||||
j$.fnNameFor(expected.constructor) +
|
||||
', but was ' + j$.pp(actual) + '.';
|
||||
', but was ' +
|
||||
pp(actual) +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
|
||||
function actualArrayIsLongerFormatter(actual, expected, path) {
|
||||
return 'Unexpected ' +
|
||||
path + (path.depth() ? ' = ' : '') +
|
||||
j$.pp(actual) +
|
||||
' in array.';
|
||||
function actualArrayIsLongerFormatter(pp, actual, expected, path) {
|
||||
return (
|
||||
'Unexpected ' +
|
||||
path +
|
||||
(path.depth() ? ' = ' : '') +
|
||||
pp(actual) +
|
||||
' in array.'
|
||||
);
|
||||
}
|
||||
|
||||
function formatKeyValuePairs(obj) {
|
||||
function formatKeyValuePairs(pp, obj) {
|
||||
var formatted = '';
|
||||
for (var key in obj) {
|
||||
formatted += '\n ' + key + ': ' + j$.pp(obj[key]);
|
||||
formatted += '\n ' + key + ': ' + pp(obj[key]);
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
function isDiffBuilder(obj) {
|
||||
return obj && typeof obj.recordMismatch === 'function';
|
||||
}
|
||||
|
||||
return MatchersUtil;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().nothing = function() {
|
||||
* {@link expect} nothing explicitly.
|
||||
* @function
|
||||
* @name matchers#nothing
|
||||
* @since 2.8.0
|
||||
* @example
|
||||
* expect().nothing();
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
getJasmineRequireObj().requireAsyncMatchers = function(jRequire, j$) {
|
||||
var availableMatchers = [
|
||||
'toBePending',
|
||||
'toBeResolved',
|
||||
'toBeRejected',
|
||||
'toBeResolvedTo',
|
||||
'toBeRejectedWith'
|
||||
'toBeRejectedWith',
|
||||
'toBeRejectedWithError'
|
||||
],
|
||||
matchers = {};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
|
||||
'toBe',
|
||||
'toBeCloseTo',
|
||||
'toBeDefined',
|
||||
'toBeInstanceOf',
|
||||
'toBeFalse',
|
||||
'toBeFalsy',
|
||||
'toBeGreaterThan',
|
||||
@@ -19,15 +20,17 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
|
||||
'toBeUndefined',
|
||||
'toContain',
|
||||
'toEqual',
|
||||
'toHaveSize',
|
||||
'toHaveBeenCalled',
|
||||
'toHaveBeenCalledBefore',
|
||||
'toHaveBeenCalledOnceWith',
|
||||
'toHaveBeenCalledTimes',
|
||||
'toHaveBeenCalledWith',
|
||||
'toHaveClass',
|
||||
'toMatch',
|
||||
'toThrow',
|
||||
'toThrowError',
|
||||
'toThrowMatching',
|
||||
'toThrowMatching'
|
||||
],
|
||||
matchers = {};
|
||||
|
||||
|
||||
@@ -3,21 +3,29 @@ getJasmineRequireObj().toBe = function(j$) {
|
||||
* {@link expect} the actual value to be `===` to the expected value.
|
||||
* @function
|
||||
* @name matchers#toBe
|
||||
* @since 1.3.0
|
||||
* @param {Object} expected - The expected value to compare against.
|
||||
* @example
|
||||
* expect(thing).toBe(realThing);
|
||||
*/
|
||||
function toBe(util) {
|
||||
var tip = ' Tip: To check for deep equality, use .toEqual() instead of .toBe().';
|
||||
function toBe(matchersUtil) {
|
||||
var tip =
|
||||
' Tip: To check for deep equality, use .toEqual() instead of .toBe().';
|
||||
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = {
|
||||
pass: actual === expected,
|
||||
pass: actual === expected
|
||||
};
|
||||
|
||||
if (typeof expected === 'object') {
|
||||
result.message = util.buildFailureMessage('toBe', result.pass, actual, expected) + tip;
|
||||
result.message =
|
||||
matchersUtil.buildFailureMessage(
|
||||
'toBe',
|
||||
result.pass,
|
||||
actual,
|
||||
expected
|
||||
) + tip;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeCloseTo = function() {
|
||||
* {@link expect} the actual value to be within a specified precision of the expected value.
|
||||
* @function
|
||||
* @name matchers#toBeCloseTo
|
||||
* @since 1.3.0
|
||||
* @param {Object} expected - The expected value to compare against.
|
||||
* @param {Number} [precision=2] - The number of decimal points to check.
|
||||
* @example
|
||||
@@ -16,8 +17,13 @@ getJasmineRequireObj().toBeCloseTo = function() {
|
||||
}
|
||||
|
||||
if (expected === null || actual === null) {
|
||||
throw new Error('Cannot use toBeCloseTo with null. Arguments evaluated to: ' +
|
||||
'expect(' + actual + ').toBeCloseTo(' + expected + ').'
|
||||
throw new Error(
|
||||
'Cannot use toBeCloseTo with null. Arguments evaluated to: ' +
|
||||
'expect(' +
|
||||
actual +
|
||||
').toBeCloseTo(' +
|
||||
expected +
|
||||
').'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -26,7 +32,7 @@ getJasmineRequireObj().toBeCloseTo = function() {
|
||||
var maxDelta = Math.pow(10, -precision) / 2;
|
||||
|
||||
return {
|
||||
pass: Math.round(delta * pow) / pow <= maxDelta
|
||||
pass: Math.round(delta * pow) <= maxDelta * pow
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeDefined = function() {
|
||||
* {@link expect} the actual value to be defined. (Not `undefined`)
|
||||
* @function
|
||||
* @name matchers#toBeDefined
|
||||
* @since 1.3.0
|
||||
* @example
|
||||
* expect(result).toBeDefined();
|
||||
*/
|
||||
@@ -10,7 +11,7 @@ getJasmineRequireObj().toBeDefined = function() {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
return {
|
||||
pass: (void 0 !== actual)
|
||||
pass: void 0 !== actual
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeFalse = function() {
|
||||
* {@link expect} the actual value to be `false`.
|
||||
* @function
|
||||
* @name matchers#toBeFalse
|
||||
* @since 3.5.0
|
||||
* @example
|
||||
* expect(result).toBeFalse();
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeFalsy = function() {
|
||||
* {@link expect} the actual value to be falsy
|
||||
* @function
|
||||
* @name matchers#toBeFalsy
|
||||
* @since 2.0.0
|
||||
* @example
|
||||
* expect(result).toBeFalsy();
|
||||
*/
|
||||
@@ -10,7 +11,7 @@ getJasmineRequireObj().toBeFalsy = function() {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
return {
|
||||
pass: !!!actual
|
||||
pass: !actual
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeGreaterThan = function() {
|
||||
* {@link expect} the actual value to be greater than the expected value.
|
||||
* @function
|
||||
* @name matchers#toBeGreaterThan
|
||||
* @since 2.0.0
|
||||
* @param {Number} expected - The value to compare against.
|
||||
* @example
|
||||
* expect(result).toBeGreaterThan(3);
|
||||
@@ -19,4 +20,3 @@ getJasmineRequireObj().toBeGreaterThan = function() {
|
||||
|
||||
return toBeGreaterThan;
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeGreaterThanOrEqual = function() {
|
||||
* {@link expect} the actual value to be greater than or equal to the expected value.
|
||||
* @function
|
||||
* @name matchers#toBeGreaterThanOrEqual
|
||||
* @since 2.0.0
|
||||
* @param {Number} expected - The expected value to compare against.
|
||||
* @example
|
||||
* expect(result).toBeGreaterThanOrEqual(25);
|
||||
|
||||
64
src/core/matchers/toBeInstanceOf.js
Normal file
64
src/core/matchers/toBeInstanceOf.js
Normal file
@@ -0,0 +1,64 @@
|
||||
getJasmineRequireObj().toBeInstanceOf = function(j$) {
|
||||
var usageError = j$.formatErrorMsg(
|
||||
'<toBeInstanceOf>',
|
||||
'expect(value).toBeInstanceOf(<ConstructorFunction>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual to be an instance of the expected class
|
||||
* @function
|
||||
* @name matchers#toBeInstanceOf
|
||||
* @since 3.5.0
|
||||
* @param {Object} expected - The class or constructor function to check for
|
||||
* @example
|
||||
* expect('foo').toBeInstanceOf(String);
|
||||
* expect(3).toBeInstanceOf(Number);
|
||||
* expect(new Error()).toBeInstanceOf(Error);
|
||||
*/
|
||||
function toBeInstanceOf(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var actualType =
|
||||
actual && actual.constructor
|
||||
? j$.fnNameFor(actual.constructor)
|
||||
: matchersUtil.pp(actual),
|
||||
expectedType = expected
|
||||
? j$.fnNameFor(expected)
|
||||
: matchersUtil.pp(expected),
|
||||
expectedMatcher,
|
||||
pass;
|
||||
|
||||
try {
|
||||
expectedMatcher = new j$.Any(expected);
|
||||
pass = expectedMatcher.asymmetricMatch(actual);
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
usageError('Expected value is not a constructor function')
|
||||
);
|
||||
}
|
||||
|
||||
if (pass) {
|
||||
return {
|
||||
pass: true,
|
||||
message:
|
||||
'Expected instance of ' +
|
||||
actualType +
|
||||
' not to be an instance of ' +
|
||||
expectedType
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
pass: false,
|
||||
message:
|
||||
'Expected instance of ' +
|
||||
actualType +
|
||||
' to be an instance of ' +
|
||||
expectedType
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return toBeInstanceOf;
|
||||
};
|
||||
@@ -3,13 +3,13 @@ getJasmineRequireObj().toBeLessThan = function() {
|
||||
* {@link expect} the actual value to be less than the expected value.
|
||||
* @function
|
||||
* @name matchers#toBeLessThan
|
||||
* @since 2.0.0
|
||||
* @param {Number} expected - The expected value to compare against.
|
||||
* @example
|
||||
* expect(result).toBeLessThan(0);
|
||||
*/
|
||||
function toBeLessThan() {
|
||||
return {
|
||||
|
||||
compare: function(actual, expected) {
|
||||
return {
|
||||
pass: actual < expected
|
||||
|
||||
@@ -3,13 +3,13 @@ getJasmineRequireObj().toBeLessThanOrEqual = function() {
|
||||
* {@link expect} the actual value to be less than or equal to the expected value.
|
||||
* @function
|
||||
* @name matchers#toBeLessThanOrEqual
|
||||
* @since 2.0.0
|
||||
* @param {Number} expected - The expected value to compare against.
|
||||
* @example
|
||||
* expect(result).toBeLessThanOrEqual(123);
|
||||
*/
|
||||
function toBeLessThanOrEqual() {
|
||||
return {
|
||||
|
||||
compare: function(actual, expected) {
|
||||
return {
|
||||
pass: actual <= expected
|
||||
|
||||
@@ -3,20 +3,23 @@ getJasmineRequireObj().toBeNaN = function(j$) {
|
||||
* {@link expect} the actual value to be `NaN` (Not a Number).
|
||||
* @function
|
||||
* @name matchers#toBeNaN
|
||||
* @since 1.3.0
|
||||
* @example
|
||||
* expect(thing).toBeNaN();
|
||||
*/
|
||||
function toBeNaN() {
|
||||
function toBeNaN(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var result = {
|
||||
pass: (actual !== actual)
|
||||
pass: actual !== actual
|
||||
};
|
||||
|
||||
if (result.pass) {
|
||||
result.message = 'Expected actual not to be NaN.';
|
||||
} else {
|
||||
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be NaN.'; };
|
||||
result.message = function() {
|
||||
return 'Expected ' + matchersUtil.pp(actual) + ' to be NaN.';
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,20 +3,23 @@ getJasmineRequireObj().toBeNegativeInfinity = function(j$) {
|
||||
* {@link expect} the actual value to be `-Infinity` (-infinity).
|
||||
* @function
|
||||
* @name matchers#toBeNegativeInfinity
|
||||
* @since 2.6.0
|
||||
* @example
|
||||
* expect(thing).toBeNegativeInfinity();
|
||||
*/
|
||||
function toBeNegativeInfinity() {
|
||||
function toBeNegativeInfinity(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var result = {
|
||||
pass: (actual === Number.NEGATIVE_INFINITY)
|
||||
pass: actual === Number.NEGATIVE_INFINITY
|
||||
};
|
||||
|
||||
if (result.pass) {
|
||||
result.message = 'Expected actual not to be -Infinity.';
|
||||
} else {
|
||||
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be -Infinity.'; };
|
||||
result.message = function() {
|
||||
return 'Expected ' + matchersUtil.pp(actual) + ' to be -Infinity.';
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeNull = function() {
|
||||
* {@link expect} the actual value to be `null`.
|
||||
* @function
|
||||
* @name matchers#toBeNull
|
||||
* @since 1.3.0
|
||||
* @example
|
||||
* expect(result).toBeNull();
|
||||
*/
|
||||
|
||||
@@ -3,20 +3,23 @@ getJasmineRequireObj().toBePositiveInfinity = function(j$) {
|
||||
* {@link expect} the actual value to be `Infinity` (infinity).
|
||||
* @function
|
||||
* @name matchers#toBePositiveInfinity
|
||||
* @since 2.6.0
|
||||
* @example
|
||||
* expect(thing).toBePositiveInfinity();
|
||||
*/
|
||||
function toBePositiveInfinity() {
|
||||
function toBePositiveInfinity(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var result = {
|
||||
pass: (actual === Number.POSITIVE_INFINITY)
|
||||
pass: actual === Number.POSITIVE_INFINITY
|
||||
};
|
||||
|
||||
if (result.pass) {
|
||||
result.message = 'Expected actual not to be Infinity.';
|
||||
} else {
|
||||
result.message = function() { return 'Expected ' + j$.pp(actual) + ' to be Infinity.'; };
|
||||
result.message = function() {
|
||||
return 'Expected ' + matchersUtil.pp(actual) + ' to be Infinity.';
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeTrue = function() {
|
||||
* {@link expect} the actual value to be `true`.
|
||||
* @function
|
||||
* @name matchers#toBeTrue
|
||||
* @since 3.5.0
|
||||
* @example
|
||||
* expect(result).toBeTrue();
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeTruthy = function() {
|
||||
* {@link expect} the actual value to be truthy.
|
||||
* @function
|
||||
* @name matchers#toBeTruthy
|
||||
* @since 2.0.0
|
||||
* @example
|
||||
* expect(thing).toBeTruthy();
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,7 @@ getJasmineRequireObj().toBeUndefined = function() {
|
||||
* {@link expect} the actual value to be `undefined`.
|
||||
* @function
|
||||
* @name matchers#toBeUndefined
|
||||
* @since 1.3.0
|
||||
* @example
|
||||
* expect(result).toBeUndefined():
|
||||
*/
|
||||
|
||||
@@ -3,19 +3,17 @@ getJasmineRequireObj().toContain = function() {
|
||||
* {@link expect} the actual value to contain a specific value.
|
||||
* @function
|
||||
* @name matchers#toContain
|
||||
* @since 2.0.0
|
||||
* @param {Object} expected - The value to look for.
|
||||
* @example
|
||||
* expect(array).toContain(anElement);
|
||||
* expect(string).toContain(substring);
|
||||
*/
|
||||
function toContain(util, customEqualityTesters) {
|
||||
customEqualityTesters = customEqualityTesters || [];
|
||||
|
||||
function toContain(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
|
||||
return {
|
||||
pass: util.contains(actual, expected, customEqualityTesters)
|
||||
pass: matchersUtil.contains(actual, expected)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,21 +3,20 @@ getJasmineRequireObj().toEqual = function(j$) {
|
||||
* {@link expect} the actual value to be equal to the expected, using deep equality comparison.
|
||||
* @function
|
||||
* @name matchers#toEqual
|
||||
* @since 1.3.0
|
||||
* @param {Object} expected - Expected value
|
||||
* @example
|
||||
* expect(bigObject).toEqual({"foo": ['bar', 'baz']});
|
||||
*/
|
||||
function toEqual(util, customEqualityTesters) {
|
||||
customEqualityTesters = customEqualityTesters || [];
|
||||
|
||||
function toEqual(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = {
|
||||
pass: false
|
||||
},
|
||||
diffBuilder = j$.DiffBuilder();
|
||||
diffBuilder = j$.DiffBuilder({ prettyPrinter: matchersUtil.pp });
|
||||
|
||||
result.pass = util.equals(actual, expected, customEqualityTesters, diffBuilder);
|
||||
result.pass = matchersUtil.equals(actual, expected, diffBuilder);
|
||||
|
||||
// TODO: only set error message if test fails
|
||||
result.message = diffBuilder.getMessage();
|
||||
|
||||
@@ -1,33 +1,42 @@
|
||||
getJasmineRequireObj().toHaveBeenCalled = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalled>', 'expect(<spyObj>).toHaveBeenCalled()');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toHaveBeenCalled>',
|
||||
'expect(<spyObj>).toHaveBeenCalled()'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual (a {@link Spy}) to have been called.
|
||||
* @function
|
||||
* @name matchers#toHaveBeenCalled
|
||||
* @since 1.3.0
|
||||
* @example
|
||||
* expect(mySpy).toHaveBeenCalled();
|
||||
* expect(mySpy).not.toHaveBeenCalled();
|
||||
*/
|
||||
function toHaveBeenCalled() {
|
||||
function toHaveBeenCalled(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var result = {};
|
||||
|
||||
if (!j$.isSpy(actual)) {
|
||||
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (arguments.length > 1) {
|
||||
throw new Error(getErrorMsg('Does not take arguments, use toHaveBeenCalledWith'));
|
||||
throw new Error(
|
||||
getErrorMsg('Does not take arguments, use toHaveBeenCalledWith')
|
||||
);
|
||||
}
|
||||
|
||||
result.pass = actual.calls.any();
|
||||
|
||||
result.message = result.pass ?
|
||||
'Expected spy ' + actual.and.identity + ' not to have been called.' :
|
||||
'Expected spy ' + actual.and.identity + ' to have been called.';
|
||||
result.message = result.pass
|
||||
? 'Expected spy ' + actual.and.identity + ' not to have been called.'
|
||||
: 'Expected spy ' + actual.and.identity + ' to have been called.';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,46 @@
|
||||
getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledBefore>', 'expect(<spyObj>).toHaveBeenCalledBefore(<spyObj>)');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toHaveBeenCalledBefore>',
|
||||
'expect(<spyObj>).toHaveBeenCalledBefore(<spyObj>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual value (a {@link Spy}) to have been called before another {@link Spy}.
|
||||
* @function
|
||||
* @name matchers#toHaveBeenCalledBefore
|
||||
* @since 2.6.0
|
||||
* @param {Spy} expected - {@link Spy} that should have been called after the `actual` {@link Spy}.
|
||||
* @example
|
||||
* expect(mySpy).toHaveBeenCalledBefore(otherSpy);
|
||||
*/
|
||||
function toHaveBeenCalledBefore() {
|
||||
function toHaveBeenCalledBefore(matchersUtil) {
|
||||
return {
|
||||
compare: function(firstSpy, latterSpy) {
|
||||
if (!j$.isSpy(firstSpy)) {
|
||||
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(firstSpy) + '.'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Expected a spy, but got ' + matchersUtil.pp(firstSpy) + '.'
|
||||
)
|
||||
);
|
||||
}
|
||||
if (!j$.isSpy(latterSpy)) {
|
||||
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(latterSpy) + '.'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Expected a spy, but got ' + matchersUtil.pp(latterSpy) + '.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var result = { pass: false };
|
||||
|
||||
if (!firstSpy.calls.count()) {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to have been called.';
|
||||
result.message =
|
||||
'Expected spy ' + firstSpy.and.identity + ' to have been called.';
|
||||
return result;
|
||||
}
|
||||
if (!latterSpy.calls.count()) {
|
||||
result.message = 'Expected spy ' + latterSpy.and.identity + ' to have been called.';
|
||||
result.message =
|
||||
'Expected spy ' + latterSpy.and.identity + ' to have been called.';
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -37,17 +50,36 @@ getJasmineRequireObj().toHaveBeenCalledBefore = function(j$) {
|
||||
result.pass = latest1stSpyCall < first2ndSpyCall;
|
||||
|
||||
if (result.pass) {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to not have been called before spy ' + latterSpy.and.identity + ', but it was';
|
||||
result.message =
|
||||
'Expected spy ' +
|
||||
firstSpy.and.identity +
|
||||
' to not have been called before spy ' +
|
||||
latterSpy.and.identity +
|
||||
', but it was';
|
||||
} else {
|
||||
var first1stSpyCall = firstSpy.calls.first().invocationOrder;
|
||||
var latest2ndSpyCall = latterSpy.calls.mostRecent().invocationOrder;
|
||||
|
||||
if(first1stSpyCall < first2ndSpyCall) {
|
||||
result.message = 'Expected latest call to spy ' + firstSpy.and.identity + ' to have been called before first call to spy ' + latterSpy.and.identity + ' (no interleaved calls)';
|
||||
if (first1stSpyCall < first2ndSpyCall) {
|
||||
result.message =
|
||||
'Expected latest call to spy ' +
|
||||
firstSpy.and.identity +
|
||||
' to have been called before first call to spy ' +
|
||||
latterSpy.and.identity +
|
||||
' (no interleaved calls)';
|
||||
} else if (latest2ndSpyCall > latest1stSpyCall) {
|
||||
result.message = 'Expected first call to spy ' + latterSpy.and.identity + ' to have been called after latest call to spy ' + firstSpy.and.identity + ' (no interleaved calls)';
|
||||
result.message =
|
||||
'Expected first call to spy ' +
|
||||
latterSpy.and.identity +
|
||||
' to have been called after latest call to spy ' +
|
||||
firstSpy.and.identity +
|
||||
' (no interleaved calls)';
|
||||
} else {
|
||||
result.message = 'Expected spy ' + firstSpy.and.identity + ' to have been called before spy ' + latterSpy.and.identity;
|
||||
result.message =
|
||||
'Expected spy ' +
|
||||
firstSpy.and.identity +
|
||||
' to have been called before spy ' +
|
||||
latterSpy.and.identity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
99
src/core/matchers/toHaveBeenCalledOnceWith.js
Normal file
99
src/core/matchers/toHaveBeenCalledOnceWith.js
Normal file
@@ -0,0 +1,99 @@
|
||||
getJasmineRequireObj().toHaveBeenCalledOnceWith = function(j$) {
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toHaveBeenCalledOnceWith>',
|
||||
'expect(<spyObj>).toHaveBeenCalledOnceWith(...arguments)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual (a {@link Spy}) to have been called exactly once, and exactly with the particular arguments.
|
||||
* @function
|
||||
* @name matchers#toHaveBeenCalledOnceWith
|
||||
* @since 3.6.0
|
||||
* @param {...Object} - The arguments to look for
|
||||
* @example
|
||||
* expect(mySpy).toHaveBeenCalledOnceWith('foo', 'bar', 2);
|
||||
*/
|
||||
function toHaveBeenCalledOnceWith(util) {
|
||||
return {
|
||||
compare: function() {
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
actual = args[0],
|
||||
expectedArgs = args.slice(1);
|
||||
|
||||
if (!j$.isSpy(actual)) {
|
||||
throw new Error(
|
||||
getErrorMsg('Expected a spy, but got ' + util.pp(actual) + '.')
|
||||
);
|
||||
}
|
||||
|
||||
var prettyPrintedCalls = actual.calls
|
||||
.allArgs()
|
||||
.map(function(argsForCall) {
|
||||
return ' ' + util.pp(argsForCall);
|
||||
});
|
||||
|
||||
if (
|
||||
actual.calls.count() === 1 &&
|
||||
util.contains(actual.calls.allArgs(), expectedArgs)
|
||||
) {
|
||||
return {
|
||||
pass: true,
|
||||
message:
|
||||
'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' to have been called 0 times, multiple times, or once, but with arguments different from:\n' +
|
||||
' ' +
|
||||
util.pp(expectedArgs) +
|
||||
'\n' +
|
||||
'But the actual call was:\n' +
|
||||
prettyPrintedCalls.join(',\n') +
|
||||
'.\n\n'
|
||||
};
|
||||
}
|
||||
|
||||
function getDiffs() {
|
||||
return actual.calls.allArgs().map(function(argsForCall, callIx) {
|
||||
var diffBuilder = new j$.DiffBuilder();
|
||||
util.equals(argsForCall, expectedArgs, diffBuilder);
|
||||
return diffBuilder.getMessage();
|
||||
});
|
||||
}
|
||||
|
||||
function butString() {
|
||||
switch (actual.calls.count()) {
|
||||
case 0:
|
||||
return 'But it was never called.\n\n';
|
||||
case 1:
|
||||
return (
|
||||
'But the actual call was:\n' +
|
||||
prettyPrintedCalls.join(',\n') +
|
||||
'.\n' +
|
||||
getDiffs().join('\n') +
|
||||
'\n\n'
|
||||
);
|
||||
default:
|
||||
return (
|
||||
'But the actual calls were:\n' +
|
||||
prettyPrintedCalls.join(',\n') +
|
||||
'.\n\n'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pass: false,
|
||||
message:
|
||||
'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' to have been called only once, and with given args:\n' +
|
||||
' ' +
|
||||
util.pp(expectedArgs) +
|
||||
'\n' +
|
||||
butString()
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return toHaveBeenCalledOnceWith;
|
||||
};
|
||||
@@ -1,36 +1,59 @@
|
||||
getJasmineRequireObj().toHaveBeenCalledTimes = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledTimes>', 'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toHaveBeenCalledTimes>',
|
||||
'expect(<spyObj>).toHaveBeenCalledTimes(<Number>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual (a {@link Spy}) to have been called the specified number of times.
|
||||
* @function
|
||||
* @name matchers#toHaveBeenCalledTimes
|
||||
* @since 2.4.0
|
||||
* @param {Number} expected - The number of invocations to look for.
|
||||
* @example
|
||||
* expect(mySpy).toHaveBeenCalledTimes(3);
|
||||
*/
|
||||
function toHaveBeenCalledTimes() {
|
||||
function toHaveBeenCalledTimes(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
if (!j$.isSpy(actual)) {
|
||||
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
result = { pass: false };
|
||||
|
||||
if (!j$.isNumber_(expected)){
|
||||
throw new Error(getErrorMsg('The expected times failed is a required argument and must be a number.'));
|
||||
if (!j$.isNumber_(expected)) {
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'The expected times failed is a required argument and must be a number.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
actual = args[0];
|
||||
var calls = actual.calls.count();
|
||||
var timesMessage = expected === 1 ? 'once' : expected + ' times';
|
||||
result.pass = calls === expected;
|
||||
result.message = result.pass ?
|
||||
'Expected spy ' + actual.and.identity + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
|
||||
'Expected spy ' + actual.and.identity + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.';
|
||||
result.message = result.pass
|
||||
? 'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' not to have been called ' +
|
||||
timesMessage +
|
||||
'. It was called ' +
|
||||
calls +
|
||||
' times.'
|
||||
: 'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' to have been called ' +
|
||||
timesMessage +
|
||||
'. It was called ' +
|
||||
calls +
|
||||
' times.';
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toHaveBeenCalledWith>', 'expect(<spyObj>).toHaveBeenCalledWith(...arguments)');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toHaveBeenCalledWith>',
|
||||
'expect(<spyObj>).toHaveBeenCalledWith(...arguments)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual (a {@link Spy}) to have been called with particular arguments at least once.
|
||||
* @function
|
||||
* @name matchers#toHaveBeenCalledWith
|
||||
* @since 1.3.0
|
||||
* @param {...Object} - The arguments to look for
|
||||
* @example
|
||||
* expect(mySpy).toHaveBeenCalledWith('foo', 'bar', 2);
|
||||
*/
|
||||
function toHaveBeenCalledWith(util, customEqualityTesters) {
|
||||
function toHaveBeenCalledWith(matchersUtil) {
|
||||
return {
|
||||
compare: function() {
|
||||
var args = Array.prototype.slice.call(arguments, 0),
|
||||
@@ -19,19 +22,74 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
|
||||
result = { pass: false };
|
||||
|
||||
if (!j$.isSpy(actual)) {
|
||||
throw new Error(getErrorMsg('Expected a spy, but got ' + j$.pp(actual) + '.'));
|
||||
throw new Error(
|
||||
getErrorMsg(
|
||||
'Expected a spy, but got ' + matchersUtil.pp(actual) + '.'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!actual.calls.any()) {
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' to have been called with ' + j$.pp(expectedArgs) + ' but it was never called.'; };
|
||||
result.message = function() {
|
||||
return (
|
||||
'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' to have been called with:\n' +
|
||||
' ' +
|
||||
matchersUtil.pp(expectedArgs) +
|
||||
'\nbut it was never called.'
|
||||
);
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
if (util.contains(actual.calls.allArgs(), expectedArgs, customEqualityTesters)) {
|
||||
if (matchersUtil.contains(actual.calls.allArgs(), expectedArgs)) {
|
||||
result.pass = true;
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' not to have been called with ' + j$.pp(expectedArgs) + ' but it was.'; };
|
||||
result.message = function() {
|
||||
return (
|
||||
'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' not to have been called with:\n' +
|
||||
' ' +
|
||||
matchersUtil.pp(expectedArgs) +
|
||||
'\nbut it was.'
|
||||
);
|
||||
};
|
||||
} else {
|
||||
result.message = function() { return 'Expected spy ' + actual.and.identity + ' to have been called with ' + j$.pp(expectedArgs) + ' but actual calls were ' + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + '.'; };
|
||||
result.message = function() {
|
||||
var prettyPrintedCalls = actual.calls
|
||||
.allArgs()
|
||||
.map(function(argsForCall) {
|
||||
return ' ' + matchersUtil.pp(argsForCall);
|
||||
});
|
||||
|
||||
var diffs = actual.calls
|
||||
.allArgs()
|
||||
.map(function(argsForCall, callIx) {
|
||||
var diffBuilder = new j$.DiffBuilder();
|
||||
matchersUtil.equals(argsForCall, expectedArgs, diffBuilder);
|
||||
return (
|
||||
'Call ' +
|
||||
callIx +
|
||||
':\n' +
|
||||
diffBuilder.getMessage().replace(/^/gm, ' ')
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
'Expected spy ' +
|
||||
actual.and.identity +
|
||||
' to have been called with:\n' +
|
||||
' ' +
|
||||
matchersUtil.pp(expectedArgs) +
|
||||
'\n' +
|
||||
'' +
|
||||
'but actual calls were:\n' +
|
||||
prettyPrintedCalls.join(',\n') +
|
||||
'.\n\n' +
|
||||
diffs.join('\n')
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -3,17 +3,18 @@ getJasmineRequireObj().toHaveClass = function(j$) {
|
||||
* {@link expect} the actual value to be a DOM element that has the expected class
|
||||
* @function
|
||||
* @name matchers#toHaveClass
|
||||
* @since 3.0.0
|
||||
* @param {Object} expected - The class name to test for
|
||||
* @example
|
||||
* var el = document.createElement('div');
|
||||
* el.className = 'foo bar baz';
|
||||
* expect(el).toHaveClass('bar');
|
||||
*/
|
||||
function toHaveClass(util, customEqualityTesters) {
|
||||
function toHaveClass(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
if (!isElement(actual)) {
|
||||
throw new Error(j$.pp(actual) + ' is not a DOM element');
|
||||
throw new Error(matchersUtil.pp(actual) + ' is not a DOM element');
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -24,9 +25,9 @@ getJasmineRequireObj().toHaveClass = function(j$) {
|
||||
}
|
||||
|
||||
function isElement(maybeEl) {
|
||||
return maybeEl &&
|
||||
maybeEl.classList &&
|
||||
j$.isFunction_(maybeEl.classList.contains);
|
||||
return (
|
||||
maybeEl && maybeEl.classList && j$.isFunction_(maybeEl.classList.contains)
|
||||
);
|
||||
}
|
||||
|
||||
return toHaveClass;
|
||||
|
||||
51
src/core/matchers/toHaveSize.js
Normal file
51
src/core/matchers/toHaveSize.js
Normal file
@@ -0,0 +1,51 @@
|
||||
getJasmineRequireObj().toHaveSize = function(j$) {
|
||||
/**
|
||||
* {@link expect} the actual size to be equal to the expected, using array-like length or object keys size.
|
||||
* @function
|
||||
* @name matchers#toHaveSize
|
||||
* @since 3.6.0
|
||||
* @param {Object} expected - Expected size
|
||||
* @example
|
||||
* array = [1,2];
|
||||
* expect(array).toHaveSize(2);
|
||||
*/
|
||||
function toHaveSize() {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = {
|
||||
pass: false
|
||||
};
|
||||
|
||||
if (
|
||||
j$.isA_('WeakSet', actual) ||
|
||||
j$.isWeakMap(actual) ||
|
||||
j$.isDataView(actual)
|
||||
) {
|
||||
throw new Error('Cannot get size of ' + actual + '.');
|
||||
}
|
||||
|
||||
if (j$.isSet(actual) || j$.isMap(actual)) {
|
||||
result.pass = actual.size === expected;
|
||||
} else if (isLength(actual.length)) {
|
||||
result.pass = actual.length === expected;
|
||||
} else {
|
||||
result.pass = Object.keys(actual).length === expected;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // eslint-disable-line compat/compat
|
||||
function isLength(value) {
|
||||
return (
|
||||
typeof value == 'number' &&
|
||||
value > -1 &&
|
||||
value % 1 === 0 &&
|
||||
value <= MAX_SAFE_INTEGER
|
||||
);
|
||||
}
|
||||
|
||||
return toHaveSize;
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
getJasmineRequireObj().toMatch = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toMatch>', 'expect(<expectation>).toMatch(<string> || <regexp>)');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toMatch>',
|
||||
'expect(<expectation>).toMatch(<string> || <regexp>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} the actual value to match a regular expression
|
||||
* @function
|
||||
* @name matchers#toMatch
|
||||
* @since 1.3.0
|
||||
* @param {RegExp|String} expected - Value to look for in the string.
|
||||
* @example
|
||||
* expect("my string").toMatch(/string$/);
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
getJasmineRequireObj().toThrow = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toThrow>', 'expect(function() {<expectation>}).toThrow()');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toThrow>',
|
||||
'expect(function() {<expectation>}).toThrow()'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} a function to `throw` something.
|
||||
* @function
|
||||
* @name matchers#toThrow
|
||||
* @since 2.0.0
|
||||
* @param {Object} [expected] - Value that should be thrown. If not provided, simply the fact that something was thrown will be checked.
|
||||
* @example
|
||||
* expect(function() { return 'things'; }).toThrow('foo');
|
||||
* expect(function() { return 'stuff'; }).toThrow();
|
||||
*/
|
||||
function toThrow(util) {
|
||||
function toThrow(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
var result = { pass: false },
|
||||
@@ -36,16 +39,36 @@ getJasmineRequireObj().toThrow = function(j$) {
|
||||
|
||||
if (arguments.length == 1) {
|
||||
result.pass = true;
|
||||
result.message = function() { return 'Expected function not to throw, but it threw ' + j$.pp(thrown) + '.'; };
|
||||
result.message = function() {
|
||||
return (
|
||||
'Expected function not to throw, but it threw ' +
|
||||
matchersUtil.pp(thrown) +
|
||||
'.'
|
||||
);
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
if (util.equals(thrown, expected)) {
|
||||
if (matchersUtil.equals(thrown, expected)) {
|
||||
result.pass = true;
|
||||
result.message = function() { return 'Expected function not to throw ' + j$.pp(expected) + '.'; };
|
||||
result.message = function() {
|
||||
return (
|
||||
'Expected function not to throw ' +
|
||||
matchersUtil.pp(expected) +
|
||||
'.'
|
||||
);
|
||||
};
|
||||
} else {
|
||||
result.message = function() { return 'Expected function to throw ' + j$.pp(expected) + ', but it threw ' + j$.pp(thrown) + '.'; };
|
||||
result.message = function() {
|
||||
return (
|
||||
'Expected function to throw ' +
|
||||
matchersUtil.pp(expected) +
|
||||
', but it threw ' +
|
||||
matchersUtil.pp(thrown) +
|
||||
'.'
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
getJasmineRequireObj().toThrowError = function(j$) {
|
||||
|
||||
var getErrorMsg = j$.formatErrorMsg('<toThrowError>', 'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)');
|
||||
var getErrorMsg = j$.formatErrorMsg(
|
||||
'<toThrowError>',
|
||||
'expect(function() {<expectation>}).toThrowError(<ErrorConstructor>, <message>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} a function to `throw` an `Error`.
|
||||
* @function
|
||||
* @name matchers#toThrowError
|
||||
* @since 2.0.0
|
||||
* @param {Error} [expected] - `Error` constructor the object that was thrown needs to be an instance of. If not provided, `Error` will be used.
|
||||
* @param {RegExp|String} [message] - The message that should be set on the thrown `Error`
|
||||
* @example
|
||||
@@ -15,7 +18,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
* expect(function() { return 'other'; }).toThrowError(/foo/);
|
||||
* expect(function() { return 'other'; }).toThrowError();
|
||||
*/
|
||||
function toThrowError () {
|
||||
function toThrowError(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual) {
|
||||
var errorMatcher = getMatcher.apply(null, arguments),
|
||||
@@ -33,7 +36,13 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
|
||||
if (!j$.isError_(thrown)) {
|
||||
return fail(function() { return 'Expected function to throw an Error, but it threw ' + j$.pp(thrown) + '.'; });
|
||||
return fail(function() {
|
||||
return (
|
||||
'Expected function to throw an Error, but it threw ' +
|
||||
matchersUtil.pp(thrown) +
|
||||
'.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return errorMatcher.match(thrown);
|
||||
@@ -67,7 +76,11 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
function anyMatcher() {
|
||||
return {
|
||||
match: function(error) {
|
||||
return pass('Expected function not to throw an Error, but it threw ' + j$.fnNameFor(error) + '.');
|
||||
return pass(
|
||||
'Expected function not to throw an Error, but it threw ' +
|
||||
j$.fnNameFor(error) +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -75,9 +88,13 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
function exactMatcher(expected, errorType) {
|
||||
if (expected && !isStringOrRegExp(expected)) {
|
||||
if (errorType) {
|
||||
throw new Error(getErrorMsg('Expected error message is not a string or RegExp.'));
|
||||
throw new Error(
|
||||
getErrorMsg('Expected error message is not a string or RegExp.')
|
||||
);
|
||||
} else {
|
||||
throw new Error(getErrorMsg('Expected is not an Error, string, or RegExp.'));
|
||||
throw new Error(
|
||||
getErrorMsg('Expected is not an Error, string, or RegExp.')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,14 +106,18 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
var errorTypeDescription = errorType ? j$.fnNameFor(errorType) : 'an exception';
|
||||
var errorTypeDescription = errorType
|
||||
? j$.fnNameFor(errorType)
|
||||
: 'an exception';
|
||||
|
||||
function thrownDescription(thrown) {
|
||||
var thrownName = errorType ? j$.fnNameFor(thrown.constructor) : 'an exception',
|
||||
thrownMessage = '';
|
||||
var thrownName = errorType
|
||||
? j$.fnNameFor(thrown.constructor)
|
||||
: 'an exception',
|
||||
thrownMessage = '';
|
||||
|
||||
if (expected) {
|
||||
thrownMessage = ' with message ' + j$.pp(thrown.message);
|
||||
thrownMessage = ' with message ' + matchersUtil.pp(thrown.message);
|
||||
}
|
||||
|
||||
return thrownName + thrownMessage;
|
||||
@@ -106,27 +127,40 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
if (expected === null) {
|
||||
return '';
|
||||
} else if (expected instanceof RegExp) {
|
||||
return ' with a message matching ' + j$.pp(expected);
|
||||
return ' with a message matching ' + matchersUtil.pp(expected);
|
||||
} else {
|
||||
return ' with message ' + j$.pp(expected);
|
||||
return ' with message ' + matchersUtil.pp(expected);
|
||||
}
|
||||
}
|
||||
|
||||
function matches(error) {
|
||||
return (errorType === null || error instanceof errorType) &&
|
||||
(expected === null || messageMatch(error.message));
|
||||
return (
|
||||
(errorType === null || error instanceof errorType) &&
|
||||
(expected === null || messageMatch(error.message))
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
match: function(thrown) {
|
||||
if (matches(thrown)) {
|
||||
return pass(function() {
|
||||
return 'Expected function not to throw ' + errorTypeDescription + messageDescription() + '.';
|
||||
return (
|
||||
'Expected function not to throw ' +
|
||||
errorTypeDescription +
|
||||
messageDescription() +
|
||||
'.'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
return fail(function() {
|
||||
return 'Expected function to throw ' + errorTypeDescription + messageDescription() +
|
||||
', but it threw ' + thrownDescription(thrown) + '.';
|
||||
return (
|
||||
'Expected function to throw ' +
|
||||
errorTypeDescription +
|
||||
messageDescription() +
|
||||
', but it threw ' +
|
||||
thrownDescription(thrown) +
|
||||
'.'
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -134,7 +168,7 @@ getJasmineRequireObj().toThrowError = function(j$) {
|
||||
}
|
||||
|
||||
function isStringOrRegExp(potential) {
|
||||
return potential instanceof RegExp || (typeof potential == 'string');
|
||||
return potential instanceof RegExp || typeof potential == 'string';
|
||||
}
|
||||
|
||||
function isAnErrorType(type) {
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
getJasmineRequireObj().toThrowMatching = function(j$) {
|
||||
var usageError = j$.formatErrorMsg('<toThrowMatching>', 'expect(function() {<expectation>}).toThrowMatching(<Predicate>)');
|
||||
var usageError = j$.formatErrorMsg(
|
||||
'<toThrowMatching>',
|
||||
'expect(function() {<expectation>}).toThrowMatching(<Predicate>)'
|
||||
);
|
||||
|
||||
/**
|
||||
* {@link expect} a function to `throw` something matching a predicate.
|
||||
* @function
|
||||
* @name matchers#toThrowMatching
|
||||
* @since 3.0.0
|
||||
* @param {Function} predicate - A function that takes the thrown exception as its parameter and returns true if it matches.
|
||||
* @example
|
||||
* expect(function() { throw new Error('nope'); }).toThrowMatching(function(thrown) { return thrown.message === 'nope'; });
|
||||
*/
|
||||
function toThrowMatching() {
|
||||
function toThrowMatching(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, predicate) {
|
||||
var thrown;
|
||||
@@ -30,23 +34,32 @@ getJasmineRequireObj().toThrowMatching = function(j$) {
|
||||
}
|
||||
|
||||
if (predicate(thrown)) {
|
||||
return pass('Expected function not to throw an exception matching a predicate.');
|
||||
return pass(
|
||||
'Expected function not to throw an exception matching a predicate.'
|
||||
);
|
||||
} else {
|
||||
return fail(function() {
|
||||
return 'Expected function to throw an exception matching a predicate, ' +
|
||||
'but it threw ' + thrownDescription(thrown) + '.';
|
||||
});
|
||||
return fail(function() {
|
||||
return (
|
||||
'Expected function to throw an exception matching a predicate, ' +
|
||||
'but it threw ' +
|
||||
thrownDescription(thrown) +
|
||||
'.'
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function thrownDescription(thrown) {
|
||||
if (thrown && thrown.constructor) {
|
||||
return j$.fnNameFor(thrown.constructor) + ' with message ' +
|
||||
j$.pp(thrown.message);
|
||||
} else {
|
||||
return j$.pp(thrown);
|
||||
function thrownDescription(thrown) {
|
||||
if (thrown && thrown.constructor) {
|
||||
return (
|
||||
j$.fnNameFor(thrown.constructor) +
|
||||
' with message ' +
|
||||
matchersUtil.pp(thrown.message)
|
||||
);
|
||||
} else {
|
||||
return matchersUtil.pp(thrown);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
/* globals exports, global, module, window */
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
var jasmineRequire;
|
||||
|
||||
if (typeof module !== 'undefined' && module.exports && typeof exports !== 'undefined') {
|
||||
if (
|
||||
typeof module !== 'undefined' &&
|
||||
module.exports &&
|
||||
typeof exports !== 'undefined'
|
||||
) {
|
||||
if (typeof global !== 'undefined') {
|
||||
jasmineGlobal = global;
|
||||
} else {
|
||||
@@ -10,7 +14,11 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
}
|
||||
jasmineRequire = exports;
|
||||
} else {
|
||||
if (typeof window !== 'undefined' && typeof window.toString === 'function' && window.toString() === '[object GjsGlobal]') {
|
||||
if (
|
||||
typeof window !== 'undefined' &&
|
||||
typeof window.toString === 'function' &&
|
||||
window.toString() === '[object GjsGlobal]'
|
||||
) {
|
||||
jasmineGlobal = window;
|
||||
}
|
||||
jasmineRequire = jasmineGlobal.jasmineRequire = {};
|
||||
@@ -40,14 +48,24 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();
|
||||
j$.Expector = jRequire.Expector(j$);
|
||||
j$.Expectation = jRequire.Expectation(j$);
|
||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||
j$.noopTimer = jRequire.noopTimer();
|
||||
j$.buildExpectationResult = jRequire.buildExpectationResult(j$);
|
||||
j$.JsApiReporter = jRequire.JsApiReporter(j$);
|
||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||
j$.asymmetricEqualityTesterArgCompatShim = jRequire.asymmetricEqualityTesterArgCompatShim(
|
||||
j$
|
||||
);
|
||||
j$.makePrettyPrinter = jRequire.makePrettyPrinter(j$);
|
||||
j$.pp = j$.makePrettyPrinter();
|
||||
j$.MatchersUtil = jRequire.MatchersUtil(j$);
|
||||
j$.matchersUtil = new j$.MatchersUtil({
|
||||
customTesters: [],
|
||||
pp: j$.pp
|
||||
});
|
||||
|
||||
j$.ObjectContaining = jRequire.ObjectContaining(j$);
|
||||
j$.ArrayContaining = jRequire.ArrayContaining(j$);
|
||||
j$.ArrayWithExactContents = jRequire.ArrayWithExactContents(j$);
|
||||
j$.pp = jRequire.pp(j$);
|
||||
j$.MapContaining = jRequire.MapContaining(j$);
|
||||
j$.SetContaining = jRequire.SetContaining(j$);
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
@@ -65,6 +83,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.DiffBuilder = jRequire.DiffBuilder(j$);
|
||||
j$.NullDiffBuilder = jRequire.NullDiffBuilder(j$);
|
||||
j$.ObjectPath = jRequire.ObjectPath(j$);
|
||||
j$.MismatchTree = jRequire.MismatchTree(j$);
|
||||
j$.GlobalErrors = jRequire.GlobalErrors(j$);
|
||||
|
||||
j$.Truthy = jRequire.Truthy(j$);
|
||||
|
||||
@@ -15,6 +15,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* Calls to `describe` can be nested within other calls to compose your suite as a tree.
|
||||
* @name describe
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of the group
|
||||
@@ -29,6 +30,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* Specs within an `xdescribe` will be marked pending and not executed
|
||||
* @name xdescribe
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of the group
|
||||
@@ -44,6 +46,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
* If suites or specs are focused, only those that are focused will be executed
|
||||
* @see fit
|
||||
* @name fdescribe
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of the group
|
||||
@@ -57,7 +60,11 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
* Define a single spec. A spec should contain one or more {@link expect|expectations} that test the state of the code.
|
||||
*
|
||||
* A spec whose expectations all succeed will be passing and a spec with any failures will fail.
|
||||
* The name `it` is a pronoun for the test target, not an abbreviation of anything. It makes the
|
||||
* spec more readable by connecting the function name `it` and the argument `description` as a
|
||||
* complete sentence.
|
||||
* @name it
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of what this spec is checking
|
||||
@@ -74,6 +81,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* The spec will report as `pending` and will not be executed.
|
||||
* @name xit
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of what this spec is checking.
|
||||
@@ -88,6 +96,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* If suites or specs are focused, only those that are focused will be executed.
|
||||
* @name fit
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} description Textual description of what this spec is checking.
|
||||
@@ -102,6 +111,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Run some shared setup before each of the specs in the {@link describe} in which it is called.
|
||||
* @name beforeEach
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
|
||||
@@ -115,6 +125,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Run some shared teardown after each of the specs in the {@link describe} in which it is called.
|
||||
* @name afterEach
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
|
||||
@@ -130,6 +141,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* _Note:_ Be careful, sharing the setup from a beforeAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.
|
||||
* @name beforeAll
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {implementationCallback} [function] Function that contains the code to setup your specs.
|
||||
@@ -145,6 +157,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* _Note:_ Be careful, sharing the teardown from a afterAll makes it easy to accidentally leak state between your specs so that they erroneously pass or fail.
|
||||
* @name afterAll
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {implementationCallback} [function] Function that contains the code to teardown your specs.
|
||||
@@ -155,9 +168,34 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.afterAll.apply(env, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SpecResult}
|
||||
* @name setSpecProperty
|
||||
* @since 3.6.0
|
||||
* @function
|
||||
* @param {String} key The name of the property
|
||||
* @param {*} value The value of the property
|
||||
*/
|
||||
setSpecProperty: function(key, value) {
|
||||
return env.setSpecProperty(key, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a user-defined property that will be provided to reporters as part of the properties field of {@link SuiteResult}
|
||||
* @name setSuiteProperty
|
||||
* @since 3.6.0
|
||||
* @function
|
||||
* @param {String} key The name of the property
|
||||
* @param {*} value The value of the property
|
||||
*/
|
||||
setSuiteProperty: function(key, value) {
|
||||
return env.setSuiteProperty(key, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an expectation for a spec.
|
||||
* @name expect
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {Object} actual - Actual computed value to test expectations against.
|
||||
@@ -173,6 +211,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
* which must be either returned from the spec or waited for using `await`
|
||||
* in order for Jasmine to associate them with the correct spec.
|
||||
* @name expectAsync
|
||||
* @since 3.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {Object} actual - Actual computed value to test expectations against.
|
||||
@@ -189,6 +228,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Mark a spec as pending, expectation results will be ignored.
|
||||
* @name pending
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String} [message] - Reason the spec is pending.
|
||||
@@ -200,10 +240,11 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Explicitly mark a spec as failed.
|
||||
* @name fail
|
||||
* @since 2.1.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {String|Error} [error] - Reason for the failure.
|
||||
*/
|
||||
*/
|
||||
fail: function() {
|
||||
return env.fail.apply(env, arguments);
|
||||
},
|
||||
@@ -211,6 +252,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Install a spy onto an existing object.
|
||||
* @name spyOn
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {Object} obj - The object upon which to install the {@link Spy}.
|
||||
@@ -224,6 +266,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Install a spy on a property installed with `Object.defineProperty` onto an existing object.
|
||||
* @name spyOnProperty
|
||||
* @since 2.6.0
|
||||
* @function
|
||||
* @global
|
||||
* @param {Object} obj - The object upon which to install the {@link Spy}
|
||||
@@ -238,6 +281,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Installs spies on all writable and configurable properties of an object.
|
||||
* @name spyOnAllFunctions
|
||||
* @since 3.2.1
|
||||
* @function
|
||||
* @global
|
||||
* @param {Object} obj - The object upon which to install the {@link Spy}s
|
||||
@@ -262,6 +306,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addCustomEqualityTester
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Function} tester - A function which takes two arguments to compare and returns a `true` or `false` comparison result if it knows how to compare them, and `undefined` otherwise.
|
||||
* @see custom_equality
|
||||
@@ -275,6 +320,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addMatchers
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @param {Object} matchers - Keys from this object will be the new matcher names.
|
||||
* @see custom_matcher
|
||||
@@ -283,9 +329,38 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add custom async matchers for the current scope of specs.
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addAsyncMatchers
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {Object} matchers - Keys from this object will be the new async matcher names.
|
||||
* @see custom_matcher
|
||||
*/
|
||||
jasmine.addAsyncMatchers = function(matchers) {
|
||||
return env.addAsyncMatchers(matchers);
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a custom object formatter for the current scope of specs.
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addCustomObjectFormatter
|
||||
* @since 3.6.0
|
||||
* @function
|
||||
* @param {Function} formatter - A function which takes a value to format and returns a string if it knows how to format it, and `undefined` otherwise.
|
||||
* @see custom_object_formatters
|
||||
*/
|
||||
jasmine.addCustomObjectFormatter = function(formatter) {
|
||||
return env.addCustomObjectFormatter(formatter);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the currently booted mock {Clock} for this Jasmine environment.
|
||||
* @name jasmine.clock
|
||||
* @since 2.0.0
|
||||
* @function
|
||||
* @returns {Clock}
|
||||
*/
|
||||
@@ -296,6 +371,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Create a bare {@link Spy} object. This won't be installed anywhere and will not have any implementation behind it.
|
||||
* @name jasmine.createSpy
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @param {String} [name] - Name to give the spy. This will be displayed in failure messages.
|
||||
* @param {Function} [originalFn] - Function to act as the real implementation.
|
||||
@@ -308,13 +384,15 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
/**
|
||||
* Create an object with multiple {@link Spy}s as its members.
|
||||
* @name jasmine.createSpyObj
|
||||
* @since 1.3.0
|
||||
* @function
|
||||
* @param {String} [baseName] - Base name for the spies in the object.
|
||||
* @param {String[]|Object} methodNames - Array of method names to create spies for, or Object whose keys will be method names and values the {@link Spy#and#returnValue|returnValue}.
|
||||
* @param {String[]|Object} [propertyNames] - Array of property names to create spies for, or Object whose keys will be propertynames and values the {@link Spy#and#returnValue|returnValue}.
|
||||
* @return {Object}
|
||||
*/
|
||||
jasmine.createSpyObj = function(baseName, methodNames) {
|
||||
return env.createSpyObj(baseName, methodNames);
|
||||
jasmine.createSpyObj = function(baseName, methodNames, propertyNames) {
|
||||
return env.createSpyObj(baseName, methodNames, propertyNames);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -322,6 +400,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.addSpyStrategy
|
||||
* @since 3.5.0
|
||||
* @function
|
||||
* @param {String} name - The name of the strategy (i.e. what you call from `and`)
|
||||
* @param {Function} factory - Factory function that returns the plan to be executed.
|
||||
@@ -330,5 +409,21 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.addSpyStrategy(name, factory);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the default spy strategy for the current scope of specs.
|
||||
*
|
||||
* _Note:_ This is only callable from within a {@link beforeEach}, {@link it}, or {@link beforeAll}.
|
||||
* @name jasmine.setDefaultSpyStrategy
|
||||
* @function
|
||||
* @param {Function} defaultStrategyFn - a function that assigns a strategy
|
||||
* @example
|
||||
* beforeEach(function() {
|
||||
* jasmine.setDefaultSpyStrategy(and => and.returnValue(true));
|
||||
* });
|
||||
*/
|
||||
jasmine.setDefaultSpyStrategy = function(defaultStrategyFn) {
|
||||
return env.setDefaultSpyStrategy(defaultStrategyFn);
|
||||
};
|
||||
|
||||
return jasmineInterface;
|
||||
};
|
||||
|
||||
@@ -1,23 +1,12 @@
|
||||
getJasmineRequireObj().util = function(j$) {
|
||||
|
||||
var util = {};
|
||||
|
||||
util.inherit = function(childClass, parentClass) {
|
||||
var Subclass = function() {
|
||||
};
|
||||
var Subclass = function() {};
|
||||
Subclass.prototype = parentClass.prototype;
|
||||
childClass.prototype = new Subclass();
|
||||
};
|
||||
|
||||
util.htmlEscape = function(str) {
|
||||
if (!str) {
|
||||
return str;
|
||||
}
|
||||
return str.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
};
|
||||
|
||||
util.argsToArray = function(args) {
|
||||
var arrayOfArgs = [];
|
||||
for (var i = 0; i < args.length; i++) {
|
||||
@@ -58,7 +47,7 @@ getJasmineRequireObj().util = function(j$) {
|
||||
util.cloneArgs = function(args) {
|
||||
var clonedArgs = [];
|
||||
var argsAsArray = j$.util.argsToArray(args);
|
||||
for(var i = 0; i < argsAsArray.length; i++) {
|
||||
for (var i = 0; i < argsAsArray.length; i++) {
|
||||
var str = Object.prototype.toString.apply(argsAsArray[i]),
|
||||
primitives = /^\[object (Boolean|String|RegExp|Number)/;
|
||||
|
||||
@@ -100,19 +89,7 @@ getJasmineRequireObj().util = function(j$) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
};
|
||||
|
||||
function anyMatch(pattern, lines) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
if (lines[i].match(pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
util.errorWithStack = function errorWithStack () {
|
||||
util.errorWithStack = function errorWithStack() {
|
||||
// Don't throw and catch if we don't have to, because it makes it harder
|
||||
// for users to debug their code with exception breakpoints.
|
||||
var error = new Error();
|
||||
@@ -138,15 +115,32 @@ getJasmineRequireObj().util = function(j$) {
|
||||
var result;
|
||||
|
||||
return function() {
|
||||
var trace;
|
||||
|
||||
if (!result) {
|
||||
result = callerFile();
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}());
|
||||
})();
|
||||
|
||||
function StopIteration() {}
|
||||
StopIteration.prototype = Object.create(Error.prototype);
|
||||
StopIteration.prototype.constructor = StopIteration;
|
||||
|
||||
// useful for maps and sets since `forEach` is the only IE11-compatible way to iterate them
|
||||
util.forEachBreakable = function(iterable, iteratee) {
|
||||
function breakLoop() {
|
||||
throw new StopIteration();
|
||||
}
|
||||
|
||||
try {
|
||||
iterable.forEach(function(value, key) {
|
||||
iteratee(breakLoop, value, key, iterable);
|
||||
});
|
||||
} catch (error) {
|
||||
if (!(error instanceof StopIteration)) throw error;
|
||||
}
|
||||
};
|
||||
|
||||
return util;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user