@@ -60,6 +60,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
|||||||
j$.StackTrace = jRequire.StackTrace(j$);
|
j$.StackTrace = jRequire.StackTrace(j$);
|
||||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
||||||
j$.Expectation = jRequire.Expectation();
|
j$.Expectation = jRequire.Expectation();
|
||||||
|
j$.AsyncExpectation = jRequire.AsyncExpectation(j$);
|
||||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||||
@@ -260,7 +261,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
j$.isPromise = function(obj) {
|
j$.isPromise = function(obj) {
|
||||||
return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise;
|
return typeof jasmineGlobal.Promise !== 'undefined' && obj && obj.constructor === jasmineGlobal.Promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
j$.fnNameFor = function(func) {
|
j$.fnNameFor = function(func) {
|
||||||
@@ -536,6 +537,7 @@ getJasmineRequireObj().util = function(j$) {
|
|||||||
getJasmineRequireObj().Spec = function(j$) {
|
getJasmineRequireObj().Spec = function(j$) {
|
||||||
function Spec(attrs) {
|
function Spec(attrs) {
|
||||||
this.expectationFactory = attrs.expectationFactory;
|
this.expectationFactory = attrs.expectationFactory;
|
||||||
|
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||||
this.resultCallback = attrs.resultCallback || function() {};
|
this.resultCallback = attrs.resultCallback || function() {};
|
||||||
this.id = attrs.id;
|
this.id = attrs.id;
|
||||||
this.description = attrs.description || '';
|
this.description = attrs.description || '';
|
||||||
@@ -592,6 +594,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
|||||||
return this.expectationFactory(actual, this);
|
return this.expectationFactory(actual, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Spec.prototype.expectAsync = function(actual) {
|
||||||
|
return this.asyncExpectationFactory(actual, this);
|
||||||
|
};
|
||||||
|
|
||||||
Spec.prototype.execute = function(onComplete, excluded) {
|
Spec.prototype.execute = function(onComplete, excluded) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@@ -882,6 +888,19 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var asyncExpectationFactory = function(actual, spec) {
|
||||||
|
return j$.AsyncExpectation.factory({
|
||||||
|
util: j$.matchersUtil,
|
||||||
|
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
function addExpectationResult(passed, result) {
|
||||||
|
return spec.addExpectationResult(passed, result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}, customSpyStrategies: {}};
|
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}, customSpyStrategies: {}};
|
||||||
|
|
||||||
@@ -1012,6 +1031,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
id: getNextSuiteId(),
|
id: getNextSuiteId(),
|
||||||
description: 'Jasmine__TopLevel__Suite',
|
description: 'Jasmine__TopLevel__Suite',
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
expectationResultFactory: expectationResultFactory
|
expectationResultFactory: expectationResultFactory
|
||||||
});
|
});
|
||||||
defaultResourcesForRunnable(topSuite.id);
|
defaultResourcesForRunnable(topSuite.id);
|
||||||
@@ -1286,6 +1306,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
description: description,
|
description: description,
|
||||||
parentSuite: currentDeclarationSuite,
|
parentSuite: currentDeclarationSuite,
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
expectationResultFactory: expectationResultFactory,
|
expectationResultFactory: expectationResultFactory,
|
||||||
throwOnExpectationFailure: throwOnExpectationFailure
|
throwOnExpectationFailure: throwOnExpectationFailure
|
||||||
});
|
});
|
||||||
@@ -1379,6 +1400,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
id: getNextSpecId(),
|
id: getNextSpecId(),
|
||||||
beforeAndAfterFns: beforeAndAfterFns(suite),
|
beforeAndAfterFns: beforeAndAfterFns(suite),
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
resultCallback: specResultCallback,
|
resultCallback: specResultCallback,
|
||||||
getSpecName: function(spec) {
|
getSpecName: function(spec) {
|
||||||
return getSpecName(spec, suite);
|
return getSpecName(spec, suite);
|
||||||
@@ -1460,6 +1482,14 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
return currentRunnable().expect(actual);
|
return currentRunnable().expect(actual);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.expectAsync = function(actual) {
|
||||||
|
if (!currentRunnable()) {
|
||||||
|
throw new Error('\'expectAsync\' was used when there was no current spec, this could be because an asynchronous test timed out');
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRunnable().expectAsync(actual);
|
||||||
|
};
|
||||||
|
|
||||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||||
ensureIsNotNested('beforeEach');
|
ensureIsNotNested('beforeEach');
|
||||||
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
||||||
@@ -1950,6 +1980,160 @@ getJasmineRequireObj().Truthy = function(j$) {
|
|||||||
return Truthy;
|
return Truthy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getJasmineRequireObj().AsyncExpectation = function(j$) {
|
||||||
|
var promiseForMessage = {
|
||||||
|
jasmineToString: function() { return 'a promise'; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronous matchers.
|
||||||
|
* @namespace async-matchers
|
||||||
|
*/
|
||||||
|
function AsyncExpectation(options) {
|
||||||
|
var global = options.global || j$.getGlobal();
|
||||||
|
this.util = options.util || { buildFailureMessage: function() {} };
|
||||||
|
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||||
|
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||||
|
this.actual = options.actual;
|
||||||
|
this.isNot = options.isNot;
|
||||||
|
|
||||||
|
if (!global.Promise) {
|
||||||
|
throw new Error('expectAsync is unavailable because the environment does not support promises.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!j$.isPromise(this.actual)) {
|
||||||
|
throw new Error('Expected expectAsync to be called with a promise.');
|
||||||
|
}
|
||||||
|
|
||||||
|
['toBeResolved', 'toBeRejected', 'toBeResolvedTo'].forEach(wrapCompare.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapCompare(name) {
|
||||||
|
var compare = this[name];
|
||||||
|
this[name] = function() {
|
||||||
|
var self = this;
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
args.unshift(this.actual);
|
||||||
|
|
||||||
|
// Capture the call stack here, before we go async, so that it will
|
||||||
|
// contain frames that are relevant to the user instead of just parts
|
||||||
|
// of Jasmine.
|
||||||
|
var errorForStack = j$.util.errorWithStack();
|
||||||
|
|
||||||
|
return compare.apply(self, args).then(function(result) {
|
||||||
|
var message;
|
||||||
|
|
||||||
|
if (self.isNot) {
|
||||||
|
result.pass = !result.pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
args[0] = promiseForMessage;
|
||||||
|
message = j$.Expectation.finalizeMessage(self.util, name, self.isNot, args, result);
|
||||||
|
|
||||||
|
self.addExpectationResult(result.pass, {
|
||||||
|
matcherName: name,
|
||||||
|
passed: result.pass,
|
||||||
|
message: message,
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: errorForStack,
|
||||||
|
actual: self.actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be resolved.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeResolved
|
||||||
|
* @example
|
||||||
|
* await expectAsync(aPromise).toBeResolved();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(aPromise).toBeResolved();
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeResolved = function(actual) {
|
||||||
|
return actual.then(
|
||||||
|
function() { return {pass: true}; },
|
||||||
|
function() { return {pass: false}; }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be rejected.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeRejected
|
||||||
|
* @example
|
||||||
|
* await expectAsync(aPromise).toBeRejected();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(aPromise).toBeRejected();
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeRejected = function(actual) {
|
||||||
|
return actual.then(
|
||||||
|
function() { return {pass: false}; },
|
||||||
|
function() { return {pass: true}; }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be resolved to a value equal to the expected, using deep equality comparison.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeResolvedTo
|
||||||
|
* @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'});
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeResolvedTo = function(actualPromise, expectedValue) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
function prefix(passed) {
|
||||||
|
return 'Expected a promise ' +
|
||||||
|
(passed ? 'not ' : '') +
|
||||||
|
'to be resolved to ' + j$.pp(expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualPromise.then(
|
||||||
|
function(actualValue) {
|
||||||
|
if (self.util.equals(actualValue, expectedValue, self.customEqualityTesters)) {
|
||||||
|
return {
|
||||||
|
pass: true,
|
||||||
|
message: prefix(true) + '.'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: prefix(false) + ' but it was resolved to ' + j$.pp(actualValue) + '.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: prefix(false) + ' but it was rejected.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
AsyncExpectation.factory = function(options) {
|
||||||
|
var expect = new AsyncExpectation(options);
|
||||||
|
|
||||||
|
options = j$.util.clone(options);
|
||||||
|
options.isNot = true;
|
||||||
|
expect.not = new AsyncExpectation(options);
|
||||||
|
|
||||||
|
return expect;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return AsyncExpectation;
|
||||||
|
};
|
||||||
|
|
||||||
getJasmineRequireObj().CallTracker = function(j$) {
|
getJasmineRequireObj().CallTracker = function(j$) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2608,7 +2792,7 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
return function() {
|
return function() {
|
||||||
var args = Array.prototype.slice.call(arguments, 0),
|
var args = Array.prototype.slice.call(arguments, 0),
|
||||||
expected = args.slice(0),
|
expected = args.slice(0),
|
||||||
message = '';
|
message;
|
||||||
|
|
||||||
args.unshift(this.actual);
|
args.unshift(this.actual);
|
||||||
|
|
||||||
@@ -2626,20 +2810,7 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result = matcherCompare.apply(null, args);
|
var result = matcherCompare.apply(null, args);
|
||||||
|
message = Expectation.finalizeMessage(this.util, name, this.isNot, args, result);
|
||||||
if (!result.pass) {
|
|
||||||
if (!result.message) {
|
|
||||||
args.unshift(this.isNot);
|
|
||||||
args.unshift(name);
|
|
||||||
message = this.util.buildFailureMessage.apply(null, args);
|
|
||||||
} else {
|
|
||||||
if (Object.prototype.toString.apply(result.message) === '[object Function]') {
|
|
||||||
message = result.message();
|
|
||||||
} else {
|
|
||||||
message = result.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expected.length == 1) {
|
if (expected.length == 1) {
|
||||||
expected = expected[0];
|
expected = expected[0];
|
||||||
@@ -2660,6 +2831,23 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Expectation.finalizeMessage = function(util, name, isNot, args, result) {
|
||||||
|
if (result.pass) {
|
||||||
|
return '';
|
||||||
|
} else if (result.message) {
|
||||||
|
if (Object.prototype.toString.apply(result.message) === '[object Function]') {
|
||||||
|
return result.message();
|
||||||
|
} else {
|
||||||
|
return result.message;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args = args.slice();
|
||||||
|
args.unshift(isNot);
|
||||||
|
args.unshift(name);
|
||||||
|
return util.buildFailureMessage.apply(null, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Expectation.addCoreMatchers = function(matchers) {
|
Expectation.addCoreMatchers = function(matchers) {
|
||||||
var prototype = Expectation.prototype;
|
var prototype = Expectation.prototype;
|
||||||
for (var matcherName in matchers) {
|
for (var matcherName in matchers) {
|
||||||
@@ -2731,7 +2919,9 @@ getJasmineRequireObj().buildExpectationResult = function() {
|
|||||||
|
|
||||||
var error = options.error;
|
var error = options.error;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (options.stack) {
|
if (options.errorForStack) {
|
||||||
|
error = options.errorForStack;
|
||||||
|
} else if (options.stack) {
|
||||||
error = options;
|
error = options;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@@ -5177,6 +5367,25 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
|||||||
return env.expect(actual);
|
return env.expect(actual);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an asynchronous expectation for a spec. Note that the matchers
|
||||||
|
* that are provided by an asynchronous expectation all return promises
|
||||||
|
* 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
|
||||||
|
* @function
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {async-matchers}
|
||||||
|
* @example
|
||||||
|
* await expectAsync(somePromise).toBeResolved();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(somePromise).toBeResolved();
|
||||||
|
*/
|
||||||
|
expectAsync: function(actual) {
|
||||||
|
return env.expectAsync(actual);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a spec as pending, expectation results will be ignored.
|
* Mark a spec as pending, expectation results will be ignored.
|
||||||
* @name pending
|
* @name pending
|
||||||
@@ -5904,6 +6113,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
this.parentSuite = attrs.parentSuite;
|
this.parentSuite = attrs.parentSuite;
|
||||||
this.description = attrs.description;
|
this.description = attrs.description;
|
||||||
this.expectationFactory = attrs.expectationFactory;
|
this.expectationFactory = attrs.expectationFactory;
|
||||||
|
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||||
|
|
||||||
@@ -5936,6 +6146,10 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
return this.expectationFactory(actual, this);
|
return this.expectationFactory(actual, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Suite.prototype.expectAsync = function(actual) {
|
||||||
|
return this.asyncExpectationFactory(actual, this);
|
||||||
|
};
|
||||||
|
|
||||||
Suite.prototype.getFullName = function() {
|
Suite.prototype.getFullName = function() {
|
||||||
var fullName = [];
|
var fullName = [];
|
||||||
for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
|
for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
|
||||||
|
|||||||
288
spec/core/AsyncExpectationSpec.js
Normal file
288
spec/core/AsyncExpectationSpec.js
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
describe('AsyncExpectation', function() {
|
||||||
|
describe('Factory', function() {
|
||||||
|
it('throws an Error if promises are not available', function() {
|
||||||
|
var thenable = {then: function() {}},
|
||||||
|
options = {global: {}, actual: thenable}
|
||||||
|
function f() { jasmineUnderTest.AsyncExpectation.factory(options); }
|
||||||
|
expect(f).toThrowError('expectAsync is unavailable because the environment does not support promises.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws an Error if the argument is not a promise', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
function f() {
|
||||||
|
jasmineUnderTest.AsyncExpectation.factory({actual: 'not a promise'});
|
||||||
|
}
|
||||||
|
expect(f).toThrowError('Expected expectAsync to be called with a promise.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toBeResolved', function() {
|
||||||
|
it('passes if the actual is resolved', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.resolve(),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolved().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||||
|
matcherName: 'toBeResolved',
|
||||||
|
passed: true,
|
||||||
|
message: '',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails if the actual is rejected', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.reject('AsyncExpectationSpec rejection'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolved().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||||
|
matcherName: 'toBeResolved',
|
||||||
|
passed: false,
|
||||||
|
message: 'Expected a promise to be resolved.',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toBeRejected', function() {
|
||||||
|
it('passes if the actual is rejected', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.reject('AsyncExpectationSpec rejection'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeRejected().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||||
|
matcherName: 'toBeRejected',
|
||||||
|
passed: true,
|
||||||
|
message: '',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails if the actual is resolved', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.resolve(),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeRejected().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||||
|
matcherName: 'toBeRejected',
|
||||||
|
passed: false,
|
||||||
|
message: 'Expected a promise to be rejected.',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#toBeResolvedTo', function() {
|
||||||
|
it('passes if the promise is resolved to the expected value', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var actual = Promise.resolve({foo: 42});
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolvedTo({foo: 42}).then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(true, {
|
||||||
|
matcherName: 'toBeResolvedTo',
|
||||||
|
passed: true,
|
||||||
|
message: '',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails if the promise is rejected', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var actual = Promise.reject('AsyncExpectationSpec error');
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolvedTo('').then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||||
|
matcherName: 'toBeResolvedTo',
|
||||||
|
passed: false,
|
||||||
|
message: "Expected a promise to be resolved to '' but it was rejected.",
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails if the promise is resolved to a different value', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var actual = Promise.resolve({foo: 17});
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolvedTo({foo: 42}).then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false, {
|
||||||
|
matcherName: 'toBeResolvedTo',
|
||||||
|
passed: false,
|
||||||
|
message: 'Expected a promise to be resolved to Object({ foo: 42 }) but it was resolved to Object({ foo: 17 }).',
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: jasmine.any(Error),
|
||||||
|
actual: actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('builds its message correctly when negated', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
expectation = jasmineUnderTest.AsyncExpectation.factory({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: Promise.resolve(true),
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.not.toBeResolvedTo(true).then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false,
|
||||||
|
jasmine.objectContaining({
|
||||||
|
passed: false,
|
||||||
|
message: 'Expected a promise not to be resolved to true.'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('supports custom equality testers', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
customEqualityTesters: [function() { return true; }],
|
||||||
|
actual: Promise.resolve('actual'),
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolvedTo('expected').then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(true,
|
||||||
|
jasmine.objectContaining({passed: true}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('#not', function() {
|
||||||
|
it('converts a pass to a fail', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.resolve(),
|
||||||
|
expectation = jasmineUnderTest.AsyncExpectation.factory({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.not.toBeResolved().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(false,
|
||||||
|
jasmine.objectContaining({
|
||||||
|
passed: false,
|
||||||
|
message: 'Expected a promise not to be resolved.'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts a fail to a pass', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = Promise.reject(),
|
||||||
|
expectation = jasmineUnderTest.AsyncExpectation.factory({
|
||||||
|
util: jasmineUnderTest.matchersUtil,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.not.toBeResolved().then(function() {
|
||||||
|
expect(addExpectationResult).toHaveBeenCalledWith(true,
|
||||||
|
jasmine.objectContaining({
|
||||||
|
passed: true,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('propagates rejections from the comparison function', function() {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
var error = new Error('AsyncExpectationSpec failure');
|
||||||
|
|
||||||
|
spyOn(jasmineUnderTest.AsyncExpectation.prototype, 'toBeResolved')
|
||||||
|
.and.returnValue(Promise.reject(error));
|
||||||
|
|
||||||
|
var addExpectationResult = jasmine.createSpy('addExpectationResult'),
|
||||||
|
actual = dummyPromise(),
|
||||||
|
expectation = new jasmineUnderTest.AsyncExpectation({
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
return expectation.toBeResolved()
|
||||||
|
.then(
|
||||||
|
function() { fail('Expected a rejection'); },
|
||||||
|
function(e) { expect(e).toBe(error); }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
function dummyPromise() {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -44,6 +44,21 @@ describe("buildExpectationResult", function() {
|
|||||||
expect(result.stack).toEqual('foo');
|
expect(result.stack).toEqual('foo');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("delegates stack formatting to the provided formatter if there was a provided errorForStack", function() {
|
||||||
|
var fakeError = {stack: 'foo'},
|
||||||
|
stackFormatter = jasmine.createSpy("stack formatter").and.returnValue(fakeError.stack);
|
||||||
|
|
||||||
|
var result = jasmineUnderTest.buildExpectationResult(
|
||||||
|
{
|
||||||
|
passed: false,
|
||||||
|
errorForStack: fakeError,
|
||||||
|
stackFormatter: stackFormatter
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(stackFormatter).toHaveBeenCalledWith(fakeError);
|
||||||
|
expect(result.stack).toEqual('foo');
|
||||||
|
});
|
||||||
|
|
||||||
it("matcherName returns passed matcherName", function() {
|
it("matcherName returns passed matcherName", function() {
|
||||||
var result = jasmineUnderTest.buildExpectationResult({matcherName: 'some-value'});
|
var result = jasmineUnderTest.buildExpectationResult({matcherName: 'some-value'});
|
||||||
expect(result.matcherName).toBe('some-value');
|
expect(result.matcherName).toBe('some-value');
|
||||||
|
|||||||
@@ -2415,4 +2415,106 @@ describe("Env integration", function() {
|
|||||||
|
|
||||||
env.execute();
|
env.execute();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('supports async matchers', function(done) {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var env = new jasmineUnderTest.Env(),
|
||||||
|
specDone = jasmine.createSpy('specDone'),
|
||||||
|
suiteDone = jasmine.createSpy('suiteDone');
|
||||||
|
|
||||||
|
env.addReporter({
|
||||||
|
specDone: specDone,
|
||||||
|
suiteDone: suiteDone,
|
||||||
|
jasmineDone: function(result) {
|
||||||
|
expect(result.failedExpectations).toEqual([jasmine.objectContaining({
|
||||||
|
message: 'Expected a promise to be rejected.'
|
||||||
|
})]);
|
||||||
|
|
||||||
|
expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||||
|
description: 'has an async failure',
|
||||||
|
failedExpectations: [jasmine.objectContaining({
|
||||||
|
message: 'Expected a promise to be rejected.'
|
||||||
|
})]
|
||||||
|
}));
|
||||||
|
|
||||||
|
expect(suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||||
|
description: 'a suite',
|
||||||
|
failedExpectations: [jasmine.objectContaining({
|
||||||
|
message: 'Expected a promise to be rejected.'
|
||||||
|
})]
|
||||||
|
}));
|
||||||
|
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function fail(innerDone) {
|
||||||
|
var resolve;
|
||||||
|
var p = new Promise(function(res, rej) { resolve = res });
|
||||||
|
env.expectAsync(p).toBeRejected().then(innerDone);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
env.afterAll(fail);
|
||||||
|
env.describe('a suite', function() {
|
||||||
|
env.afterAll(fail);
|
||||||
|
env.it('has an async failure', fail);
|
||||||
|
});
|
||||||
|
|
||||||
|
env.execute();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('provides custom equality testers to async matchers', function(done) {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var env = new jasmineUnderTest.Env(),
|
||||||
|
specDone = jasmine.createSpy('specDone');
|
||||||
|
|
||||||
|
env.addReporter({
|
||||||
|
specDone: specDone,
|
||||||
|
jasmineDone: function() {
|
||||||
|
expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||||
|
description: 'has an async failure',
|
||||||
|
failedExpectations: []
|
||||||
|
}));
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
env.it('has an async failure', function() {
|
||||||
|
env.addCustomEqualityTester(function() { return true; });
|
||||||
|
var p = Promise.resolve('something');
|
||||||
|
return env.expectAsync(p).toBeResolvedTo('something else');
|
||||||
|
});
|
||||||
|
|
||||||
|
env.execute();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('includes useful stack frames in async matcher failures', function(done) {
|
||||||
|
jasmine.getEnv().requirePromises();
|
||||||
|
|
||||||
|
var env = new jasmineUnderTest.Env(),
|
||||||
|
specDone = jasmine.createSpy('specDone');
|
||||||
|
|
||||||
|
env.addReporter({
|
||||||
|
specDone: specDone,
|
||||||
|
jasmineDone: function() {
|
||||||
|
expect(specDone).toHaveBeenCalledWith(jasmine.objectContaining({
|
||||||
|
failedExpectations: [jasmine.objectContaining({
|
||||||
|
stack: jasmine.stringMatching('EnvSpec.js')
|
||||||
|
})]
|
||||||
|
}));
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
env.it('has an async failure', function() {
|
||||||
|
env.addCustomEqualityTester(function() { return true; });
|
||||||
|
var p = Promise.resolve();
|
||||||
|
return env.expectAsync(p).toBeRejected();
|
||||||
|
});
|
||||||
|
|
||||||
|
env.execute();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
8
spec/helpers/promises.js
Normal file
8
spec/helpers/promises.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
(function(env) {
|
||||||
|
env.requirePromises = function() {
|
||||||
|
if (typeof Promise !== 'function') {
|
||||||
|
env.pending("Environment does not support promises");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(jasmine.getEnv());
|
||||||
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"helpers/checkForSymbol.js",
|
"helpers/checkForSymbol.js",
|
||||||
"helpers/checkForTypedArrays.js",
|
"helpers/checkForTypedArrays.js",
|
||||||
"helpers/integrationMatchers.js",
|
"helpers/integrationMatchers.js",
|
||||||
|
"helpers/promises.js",
|
||||||
"helpers/nodeDefineJasmineUnderTest.js"
|
"helpers/nodeDefineJasmineUnderTest.js"
|
||||||
],
|
],
|
||||||
"random": true
|
"random": true
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ helpers:
|
|||||||
- 'helpers/checkForSymbol.js'
|
- 'helpers/checkForSymbol.js'
|
||||||
- 'helpers/checkForTypedArrays.js'
|
- 'helpers/checkForTypedArrays.js'
|
||||||
- 'helpers/integrationMatchers.js'
|
- 'helpers/integrationMatchers.js'
|
||||||
|
- 'helpers/promises.js'
|
||||||
- 'helpers/defineJasmineUnderTest.js'
|
- 'helpers/defineJasmineUnderTest.js'
|
||||||
spec_files:
|
spec_files:
|
||||||
- '**/*[Ss]pec.js'
|
- '**/*[Ss]pec.js'
|
||||||
|
|||||||
153
src/core/AsyncExpectation.js
Normal file
153
src/core/AsyncExpectation.js
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
getJasmineRequireObj().AsyncExpectation = function(j$) {
|
||||||
|
var promiseForMessage = {
|
||||||
|
jasmineToString: function() { return 'a promise'; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronous matchers.
|
||||||
|
* @namespace async-matchers
|
||||||
|
*/
|
||||||
|
function AsyncExpectation(options) {
|
||||||
|
var global = options.global || j$.getGlobal();
|
||||||
|
this.util = options.util || { buildFailureMessage: function() {} };
|
||||||
|
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||||
|
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||||
|
this.actual = options.actual;
|
||||||
|
this.isNot = options.isNot;
|
||||||
|
|
||||||
|
if (!global.Promise) {
|
||||||
|
throw new Error('expectAsync is unavailable because the environment does not support promises.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!j$.isPromise(this.actual)) {
|
||||||
|
throw new Error('Expected expectAsync to be called with a promise.');
|
||||||
|
}
|
||||||
|
|
||||||
|
['toBeResolved', 'toBeRejected', 'toBeResolvedTo'].forEach(wrapCompare.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrapCompare(name) {
|
||||||
|
var compare = this[name];
|
||||||
|
this[name] = function() {
|
||||||
|
var self = this;
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
args.unshift(this.actual);
|
||||||
|
|
||||||
|
// Capture the call stack here, before we go async, so that it will
|
||||||
|
// contain frames that are relevant to the user instead of just parts
|
||||||
|
// of Jasmine.
|
||||||
|
var errorForStack = j$.util.errorWithStack();
|
||||||
|
|
||||||
|
return compare.apply(self, args).then(function(result) {
|
||||||
|
var message;
|
||||||
|
|
||||||
|
if (self.isNot) {
|
||||||
|
result.pass = !result.pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
args[0] = promiseForMessage;
|
||||||
|
message = j$.Expectation.finalizeMessage(self.util, name, self.isNot, args, result);
|
||||||
|
|
||||||
|
self.addExpectationResult(result.pass, {
|
||||||
|
matcherName: name,
|
||||||
|
passed: result.pass,
|
||||||
|
message: message,
|
||||||
|
error: undefined,
|
||||||
|
errorForStack: errorForStack,
|
||||||
|
actual: self.actual
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be resolved.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeResolved
|
||||||
|
* @example
|
||||||
|
* await expectAsync(aPromise).toBeResolved();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(aPromise).toBeResolved();
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeResolved = function(actual) {
|
||||||
|
return actual.then(
|
||||||
|
function() { return {pass: true}; },
|
||||||
|
function() { return {pass: false}; }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be rejected.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeRejected
|
||||||
|
* @example
|
||||||
|
* await expectAsync(aPromise).toBeRejected();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(aPromise).toBeRejected();
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeRejected = function(actual) {
|
||||||
|
return actual.then(
|
||||||
|
function() { return {pass: false}; },
|
||||||
|
function() { return {pass: true}; }
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expect a promise to be resolved to a value equal to the expected, using deep equality comparison.
|
||||||
|
* @function
|
||||||
|
* @async
|
||||||
|
* @name async-matchers#toBeResolvedTo
|
||||||
|
* @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'});
|
||||||
|
*/
|
||||||
|
AsyncExpectation.prototype.toBeResolvedTo = function(actualPromise, expectedValue) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
function prefix(passed) {
|
||||||
|
return 'Expected a promise ' +
|
||||||
|
(passed ? 'not ' : '') +
|
||||||
|
'to be resolved to ' + j$.pp(expectedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return actualPromise.then(
|
||||||
|
function(actualValue) {
|
||||||
|
if (self.util.equals(actualValue, expectedValue, self.customEqualityTesters)) {
|
||||||
|
return {
|
||||||
|
pass: true,
|
||||||
|
message: prefix(true) + '.'
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: prefix(false) + ' but it was resolved to ' + j$.pp(actualValue) + '.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
return {
|
||||||
|
pass: false,
|
||||||
|
message: prefix(false) + ' but it was rejected.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
AsyncExpectation.factory = function(options) {
|
||||||
|
var expect = new AsyncExpectation(options);
|
||||||
|
|
||||||
|
options = j$.util.clone(options);
|
||||||
|
options.isNot = true;
|
||||||
|
expect.not = new AsyncExpectation(options);
|
||||||
|
|
||||||
|
return expect;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return AsyncExpectation;
|
||||||
|
};
|
||||||
@@ -117,6 +117,19 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var asyncExpectationFactory = function(actual, spec) {
|
||||||
|
return j$.AsyncExpectation.factory({
|
||||||
|
util: j$.matchersUtil,
|
||||||
|
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: addExpectationResult
|
||||||
|
});
|
||||||
|
|
||||||
|
function addExpectationResult(passed, result) {
|
||||||
|
return spec.addExpectationResult(passed, result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}, customSpyStrategies: {}};
|
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}, customSpyStrategies: {}};
|
||||||
|
|
||||||
@@ -247,6 +260,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
id: getNextSuiteId(),
|
id: getNextSuiteId(),
|
||||||
description: 'Jasmine__TopLevel__Suite',
|
description: 'Jasmine__TopLevel__Suite',
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
expectationResultFactory: expectationResultFactory
|
expectationResultFactory: expectationResultFactory
|
||||||
});
|
});
|
||||||
defaultResourcesForRunnable(topSuite.id);
|
defaultResourcesForRunnable(topSuite.id);
|
||||||
@@ -521,6 +535,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
description: description,
|
description: description,
|
||||||
parentSuite: currentDeclarationSuite,
|
parentSuite: currentDeclarationSuite,
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
expectationResultFactory: expectationResultFactory,
|
expectationResultFactory: expectationResultFactory,
|
||||||
throwOnExpectationFailure: throwOnExpectationFailure
|
throwOnExpectationFailure: throwOnExpectationFailure
|
||||||
});
|
});
|
||||||
@@ -614,6 +629,7 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
id: getNextSpecId(),
|
id: getNextSpecId(),
|
||||||
beforeAndAfterFns: beforeAndAfterFns(suite),
|
beforeAndAfterFns: beforeAndAfterFns(suite),
|
||||||
expectationFactory: expectationFactory,
|
expectationFactory: expectationFactory,
|
||||||
|
asyncExpectationFactory: asyncExpectationFactory,
|
||||||
resultCallback: specResultCallback,
|
resultCallback: specResultCallback,
|
||||||
getSpecName: function(spec) {
|
getSpecName: function(spec) {
|
||||||
return getSpecName(spec, suite);
|
return getSpecName(spec, suite);
|
||||||
@@ -695,6 +711,14 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
return currentRunnable().expect(actual);
|
return currentRunnable().expect(actual);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.expectAsync = function(actual) {
|
||||||
|
if (!currentRunnable()) {
|
||||||
|
throw new Error('\'expectAsync\' was used when there was no current spec, this could be because an asynchronous test timed out');
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentRunnable().expectAsync(actual);
|
||||||
|
};
|
||||||
|
|
||||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||||
ensureIsNotNested('beforeEach');
|
ensureIsNotNested('beforeEach');
|
||||||
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
ensureIsFunctionOrAsync(beforeEachFunction, 'beforeEach');
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
return function() {
|
return function() {
|
||||||
var args = Array.prototype.slice.call(arguments, 0),
|
var args = Array.prototype.slice.call(arguments, 0),
|
||||||
expected = args.slice(0),
|
expected = args.slice(0),
|
||||||
message = '';
|
message;
|
||||||
|
|
||||||
args.unshift(this.actual);
|
args.unshift(this.actual);
|
||||||
|
|
||||||
@@ -39,20 +39,7 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result = matcherCompare.apply(null, args);
|
var result = matcherCompare.apply(null, args);
|
||||||
|
message = Expectation.finalizeMessage(this.util, name, this.isNot, args, result);
|
||||||
if (!result.pass) {
|
|
||||||
if (!result.message) {
|
|
||||||
args.unshift(this.isNot);
|
|
||||||
args.unshift(name);
|
|
||||||
message = this.util.buildFailureMessage.apply(null, args);
|
|
||||||
} else {
|
|
||||||
if (Object.prototype.toString.apply(result.message) === '[object Function]') {
|
|
||||||
message = result.message();
|
|
||||||
} else {
|
|
||||||
message = result.message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expected.length == 1) {
|
if (expected.length == 1) {
|
||||||
expected = expected[0];
|
expected = expected[0];
|
||||||
@@ -73,6 +60,23 @@ getJasmineRequireObj().Expectation = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Expectation.finalizeMessage = function(util, name, isNot, args, result) {
|
||||||
|
if (result.pass) {
|
||||||
|
return '';
|
||||||
|
} else if (result.message) {
|
||||||
|
if (Object.prototype.toString.apply(result.message) === '[object Function]') {
|
||||||
|
return result.message();
|
||||||
|
} else {
|
||||||
|
return result.message;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
args = args.slice();
|
||||||
|
args.unshift(isNot);
|
||||||
|
args.unshift(name);
|
||||||
|
return util.buildFailureMessage.apply(null, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Expectation.addCoreMatchers = function(matchers) {
|
Expectation.addCoreMatchers = function(matchers) {
|
||||||
var prototype = Expectation.prototype;
|
var prototype = Expectation.prototype;
|
||||||
for (var matcherName in matchers) {
|
for (var matcherName in matchers) {
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ getJasmineRequireObj().buildExpectationResult = function() {
|
|||||||
|
|
||||||
var error = options.error;
|
var error = options.error;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
if (options.stack) {
|
if (options.errorForStack) {
|
||||||
|
error = options.errorForStack;
|
||||||
|
} else if (options.stack) {
|
||||||
error = options;
|
error = options;
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
getJasmineRequireObj().Spec = function(j$) {
|
getJasmineRequireObj().Spec = function(j$) {
|
||||||
function Spec(attrs) {
|
function Spec(attrs) {
|
||||||
this.expectationFactory = attrs.expectationFactory;
|
this.expectationFactory = attrs.expectationFactory;
|
||||||
|
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||||
this.resultCallback = attrs.resultCallback || function() {};
|
this.resultCallback = attrs.resultCallback || function() {};
|
||||||
this.id = attrs.id;
|
this.id = attrs.id;
|
||||||
this.description = attrs.description || '';
|
this.description = attrs.description || '';
|
||||||
@@ -57,6 +58,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
|||||||
return this.expectationFactory(actual, this);
|
return this.expectationFactory(actual, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Spec.prototype.expectAsync = function(actual) {
|
||||||
|
return this.asyncExpectationFactory(actual, this);
|
||||||
|
};
|
||||||
|
|
||||||
Spec.prototype.execute = function(onComplete, excluded) {
|
Spec.prototype.execute = function(onComplete, excluded) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
this.parentSuite = attrs.parentSuite;
|
this.parentSuite = attrs.parentSuite;
|
||||||
this.description = attrs.description;
|
this.description = attrs.description;
|
||||||
this.expectationFactory = attrs.expectationFactory;
|
this.expectationFactory = attrs.expectationFactory;
|
||||||
|
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||||
|
|
||||||
@@ -37,6 +38,10 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
return this.expectationFactory(actual, this);
|
return this.expectationFactory(actual, this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Suite.prototype.expectAsync = function(actual) {
|
||||||
|
return this.asyncExpectationFactory(actual, this);
|
||||||
|
};
|
||||||
|
|
||||||
Suite.prototype.getFullName = function() {
|
Suite.prototype.getFullName = function() {
|
||||||
var fullName = [];
|
var fullName = [];
|
||||||
for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
|
for (var parentSuite = this; parentSuite; parentSuite = parentSuite.parentSuite) {
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
j$.isPromise = function(obj) {
|
j$.isPromise = function(obj) {
|
||||||
return typeof jasmineGlobal.Promise !== 'undefined' && obj.constructor === jasmineGlobal.Promise;
|
return typeof jasmineGlobal.Promise !== 'undefined' && obj && obj.constructor === jasmineGlobal.Promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
j$.fnNameFor = function(func) {
|
j$.fnNameFor = function(func) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
|||||||
j$.StackTrace = jRequire.StackTrace(j$);
|
j$.StackTrace = jRequire.StackTrace(j$);
|
||||||
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
|
||||||
j$.Expectation = jRequire.Expectation();
|
j$.Expectation = jRequire.Expectation();
|
||||||
|
j$.AsyncExpectation = jRequire.AsyncExpectation(j$);
|
||||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||||
|
|||||||
@@ -167,6 +167,25 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
|||||||
return env.expect(actual);
|
return env.expect(actual);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an asynchronous expectation for a spec. Note that the matchers
|
||||||
|
* that are provided by an asynchronous expectation all return promises
|
||||||
|
* 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
|
||||||
|
* @function
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {async-matchers}
|
||||||
|
* @example
|
||||||
|
* await expectAsync(somePromise).toBeResolved();
|
||||||
|
* @example
|
||||||
|
* return expectAsync(somePromise).toBeResolved();
|
||||||
|
*/
|
||||||
|
expectAsync: function(actual) {
|
||||||
|
return env.expectAsync(actual);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a spec as pending, expectation results will be ignored.
|
* Mark a spec as pending, expectation results will be ignored.
|
||||||
* @name pending
|
* @name pending
|
||||||
|
|||||||
Reference in New Issue
Block a user