From 3aa0115ae4334819c8a37ab18cbcd175c571c2fc Mon Sep 17 00:00:00 2001 From: Cody Mikol Date: Fri, 19 Oct 2018 23:23:42 -0400 Subject: [PATCH] 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);