From 3aa0115ae4334819c8a37ab18cbcd175c571c2fc Mon Sep 17 00:00:00 2001 From: Cody Mikol Date: Fri, 19 Oct 2018 23:23:42 -0400 Subject: [PATCH 1/2] feat(toBeRejectedTo): implement toBeRejectedTo functionality add functionality to determine whether a promise has been rejected to a specific value via expectAsync Fixes: #1595 --- spec/core/AsyncExpectationSpec.js | 109 ++++++++++++++++++++++++++++++ src/core/AsyncExpectation.js | 45 +++++++++++- 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/spec/core/AsyncExpectationSpec.js b/spec/core/AsyncExpectationSpec.js index b42901b2..010bf204 100644 --- a/spec/core/AsyncExpectationSpec.js +++ b/spec/core/AsyncExpectationSpec.js @@ -108,6 +108,115 @@ describe('AsyncExpectation', function() { }); }); + describe('#toBeRejectedTo', function () { + it('should return true if the promise is rejected to the expected value', function () { + jasmine.getEnv().requirePromises(); + + var actual = Promise.reject({error: 'PEBCAK'}); + var addExpectationResult = jasmine.createSpy('addExpectationResult'), + expectation = new jasmineUnderTest.AsyncExpectation({ + util: jasmineUnderTest.matchersUtil, + actual: actual, + addExpectationResult: addExpectationResult + }); + + return expectation.toBeRejectedTo({error: 'PEBCAK'}).then(function () { + expect(addExpectationResult).toHaveBeenCalledWith(true, { + matcherName: 'toBeRejectedTo', + passed: true, + message: '', + error: undefined, + errorForStack: jasmine.any(Error), + actual: actual + }); + }); + + }); + + it('should fail if the promise resolves', function () { + jasmine.getEnv().requirePromises(); + + var actual = Promise.resolve('AsyncExpectation error'); + var addExpectationResult = jasmine.createSpy('addExpectationResult'), + expectation = new jasmineUnderTest.AsyncExpectation({ + util: jasmineUnderTest.matchersUtil, + actual: actual, + addExpectationResult: addExpectationResult + }); + + return expectation.toBeRejectedTo('').then(function () { + expect(addExpectationResult).toHaveBeenCalledWith(false, { + matcherName: 'toBeRejectedTo', + passed: false, + message: "Expected a promise to be rejected to '' but it was resolved.", + error: undefined, + errorForStack: jasmine.any(Error), + actual: actual + }); + }); + }); + + it('should fail if the promise is rejected to a different value', function () { + jasmine.getEnv().requirePromises(); + + var actual = Promise.reject('A Bad Apple'); + var addExpectationResult = jasmine.createSpy('addExpectationResult'), + expectation = new jasmineUnderTest.AsyncExpectation({ + util: jasmineUnderTest.matchersUtil, + actual: actual, + addExpectationResult: addExpectationResult + }); + + return expectation.toBeRejectedTo('Some Cool Thing').then(function () { + expect(addExpectationResult).toHaveBeenCalledWith(false, { + matcherName: 'toBeRejectedTo', + passed: false, + message: "Expected a promise to be rejected to 'Some Cool Thing' but it was rejected to 'A Bad Apple'.", + error: undefined, + errorForStack: jasmine.any(Error), + actual: actual + }); + }); + }); + + it('should build its error correctly when negated', function () { + jasmine.getEnv().requirePromises(); + + var addExpectationResult = jasmine.createSpy('addExpectationResult'), + expectation = jasmineUnderTest.AsyncExpectation.factory({ + util: jasmineUnderTest.matchersUtil, + actual: Promise.reject(true), + addExpectationResult: addExpectationResult + }); + + return expectation.not.toBeRejectedTo(true).then(function () { + expect(addExpectationResult).toHaveBeenCalledWith(false, + jasmine.objectContaining({ + passed: false, + message: 'Expected a promise not to be rejected to true.' + }) + ); + }); + }); + + it('should support 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.reject('actual'), + addExpectationResult: addExpectationResult + }); + + return expectation.toBeRejectedTo('expected').then(function() { + expect(addExpectationResult).toHaveBeenCalledWith(true, + jasmine.objectContaining({passed: true})); + }); + }); + }); + describe('#toBeResolvedTo', function() { it('passes if the promise is resolved to the expected value', function() { jasmine.getEnv().requirePromises(); diff --git a/src/core/AsyncExpectation.js b/src/core/AsyncExpectation.js index 60a01837..78317022 100644 --- a/src/core/AsyncExpectation.js +++ b/src/core/AsyncExpectation.js @@ -23,7 +23,7 @@ getJasmineRequireObj().AsyncExpectation = function(j$) { throw new Error('Expected expectAsync to be called with a promise.'); } - ['toBeResolved', 'toBeRejected', 'toBeResolvedTo'].forEach(wrapCompare.bind(this)); + ['toBeResolved', 'toBeRejected', 'toBeResolvedTo', 'toBeRejectedTo'].forEach(wrapCompare.bind(this)); } function wrapCompare(name) { @@ -137,6 +137,49 @@ getJasmineRequireObj().AsyncExpectation = function(j$) { ); }; + /** + * Expect a promise to be rejected to a value equal to the expected, using deep equality comparison. + * @function + * @async + * @name async-matchers#toBeRejectedTo + * @param {Object} expected - Value that the promise is expected to reject to + * @example + * await expectAsync(aPromise).toBeRejectedTo({prop: 'value'}); + * @example + * return expectAsync(aPromise).toBeRejectedTo({prop: 'value'}); + */ + AsyncExpectation.prototype.toBeRejectedTo = function(actualPromise, expectedValue) { + var self = this; + + function prefix(passed) { + return 'Expected a promise ' + + (passed ? 'not ' : '') + + 'to be rejected to ' + j$.pp(expectedValue); + } + + return actualPromise.then( + function() { + return { + pass: false, + message: prefix(false) + ' but it was resolved.' + }; + }, + 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 rejected to ' + j$.pp(actualValue) + '.' + }; + } + } + ); + }; + AsyncExpectation.factory = function(options) { var expect = new AsyncExpectation(options); From fe042fdf825b4d2841640dc274fde3d534d46303 Mon Sep 17 00:00:00 2001 From: Gregg Van Hove Date: Mon, 22 Oct 2018 11:18:56 -0700 Subject: [PATCH 2/2] Use toBeRejectedWith instead of toBeRejectedTo --- spec/core/AsyncExpectationSpec.js | 24 ++++++++++++------------ src/core/AsyncExpectation.js | 10 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/spec/core/AsyncExpectationSpec.js b/spec/core/AsyncExpectationSpec.js index 010bf204..d53930a6 100644 --- a/spec/core/AsyncExpectationSpec.js +++ b/spec/core/AsyncExpectationSpec.js @@ -108,7 +108,7 @@ describe('AsyncExpectation', function() { }); }); - describe('#toBeRejectedTo', function () { + describe('#toBeRejectedWith', function () { it('should return true if the promise is rejected to the expected value', function () { jasmine.getEnv().requirePromises(); @@ -120,9 +120,9 @@ describe('AsyncExpectation', function() { addExpectationResult: addExpectationResult }); - return expectation.toBeRejectedTo({error: 'PEBCAK'}).then(function () { + return expectation.toBeRejectedWith({error: 'PEBCAK'}).then(function () { expect(addExpectationResult).toHaveBeenCalledWith(true, { - matcherName: 'toBeRejectedTo', + matcherName: 'toBeRejectedWith', passed: true, message: '', error: undefined, @@ -144,9 +144,9 @@ describe('AsyncExpectation', function() { addExpectationResult: addExpectationResult }); - return expectation.toBeRejectedTo('').then(function () { + return expectation.toBeRejectedWith('').then(function () { expect(addExpectationResult).toHaveBeenCalledWith(false, { - matcherName: 'toBeRejectedTo', + matcherName: 'toBeRejectedWith', passed: false, message: "Expected a promise to be rejected to '' but it was resolved.", error: undefined, @@ -167,9 +167,9 @@ describe('AsyncExpectation', function() { addExpectationResult: addExpectationResult }); - return expectation.toBeRejectedTo('Some Cool Thing').then(function () { + return expectation.toBeRejectedWith('Some Cool Thing').then(function () { expect(addExpectationResult).toHaveBeenCalledWith(false, { - matcherName: 'toBeRejectedTo', + matcherName: 'toBeRejectedWith', passed: false, message: "Expected a promise to be rejected to 'Some Cool Thing' but it was rejected to 'A Bad Apple'.", error: undefined, @@ -189,7 +189,7 @@ describe('AsyncExpectation', function() { addExpectationResult: addExpectationResult }); - return expectation.not.toBeRejectedTo(true).then(function () { + return expectation.not.toBeRejectedWith(true).then(function () { expect(addExpectationResult).toHaveBeenCalledWith(false, jasmine.objectContaining({ passed: false, @@ -210,7 +210,7 @@ describe('AsyncExpectation', function() { addExpectationResult: addExpectationResult }); - return expectation.toBeRejectedTo('expected').then(function() { + return expectation.toBeRejectedWith('expected').then(function() { expect(addExpectationResult).toHaveBeenCalledWith(true, jasmine.objectContaining({passed: true})); }); @@ -324,7 +324,7 @@ describe('AsyncExpectation', function() { }); }); }); - + describe('#not', function() { it('converts a pass to a fail', function() { jasmine.getEnv().requirePromises(); @@ -338,7 +338,7 @@ describe('AsyncExpectation', function() { }); return expectation.not.toBeResolved().then(function() { - expect(addExpectationResult).toHaveBeenCalledWith(false, + expect(addExpectationResult).toHaveBeenCalledWith(false, jasmine.objectContaining({ passed: false, message: 'Expected a promise not to be resolved.' @@ -359,7 +359,7 @@ describe('AsyncExpectation', function() { }); return expectation.not.toBeResolved().then(function() { - expect(addExpectationResult).toHaveBeenCalledWith(true, + expect(addExpectationResult).toHaveBeenCalledWith(true, jasmine.objectContaining({ passed: true, message: '' diff --git a/src/core/AsyncExpectation.js b/src/core/AsyncExpectation.js index 78317022..31f5f430 100644 --- a/src/core/AsyncExpectation.js +++ b/src/core/AsyncExpectation.js @@ -23,7 +23,7 @@ getJasmineRequireObj().AsyncExpectation = function(j$) { throw new Error('Expected expectAsync to be called with a promise.'); } - ['toBeResolved', 'toBeRejected', 'toBeResolvedTo', 'toBeRejectedTo'].forEach(wrapCompare.bind(this)); + ['toBeResolved', 'toBeRejected', 'toBeResolvedTo', 'toBeRejectedWith'].forEach(wrapCompare.bind(this)); } function wrapCompare(name) { @@ -141,14 +141,14 @@ getJasmineRequireObj().AsyncExpectation = function(j$) { * Expect a promise to be rejected to a value equal to the expected, using deep equality comparison. * @function * @async - * @name async-matchers#toBeRejectedTo + * @name async-matchers#toBeRejectedWith * @param {Object} expected - Value that the promise is expected to reject to * @example - * await expectAsync(aPromise).toBeRejectedTo({prop: 'value'}); + * await expectAsync(aPromise).toBeRejectedWith({prop: 'value'}); * @example - * return expectAsync(aPromise).toBeRejectedTo({prop: 'value'}); + * return expectAsync(aPromise).toBeRejectedWith({prop: 'value'}); */ - AsyncExpectation.prototype.toBeRejectedTo = function(actualPromise, expectedValue) { + AsyncExpectation.prototype.toBeRejectedWith = function(actualPromise, expectedValue) { var self = this; function prefix(passed) {