diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index a22dce1b..90adb387 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -59,6 +59,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.util = jRequire.util(j$); j$.errors = jRequire.errors(); j$.formatErrorMsg = jRequire.formatErrorMsg(); + j$.AllOf = jRequire.AllOf(j$); j$.Any = jRequire.Any(j$); j$.Anything = jRequire.Anything(j$); j$.CallTracker = jRequire.CallTracker(j$); @@ -416,6 +417,19 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { ); }; + /** + * Get an {@link AsymmetricEqualityTester} that will succeed if the actual + * value being compared matches every provided equality tester. + * @name asymmetricEqualityTesters.allOf + * @emittedName jasmine.allOf + * @since 5.13.0 + * @function + * @param {...*} arguments - The asymmetric equality checkers to compare. + */ + j$.allOf = function() { + return new j$.AllOf(...arguments); + }; + /** * Get an {@link AsymmetricEqualityTester} that will succeed if the actual * value being compared is an instance of the specified class/constructor. @@ -2084,6 +2098,34 @@ getJasmineRequireObj().JsApiReporter = function(j$) { return JsApiReporter; }; +getJasmineRequireObj().AllOf = function(j$) { + function AllOf() { + const expectedValues = Array.from(arguments); + if (expectedValues.length === 0) { + throw new TypeError( + 'jasmine.allOf() expects at least one argument to be passed.' + ); + } + this.expectedValues = expectedValues; + } + + AllOf.prototype.asymmetricMatch = function(other, matchersUtil) { + for (const expectedValue of this.expectedValues) { + if (!matchersUtil.equals(other, expectedValue)) { + return false; + } + } + + return true; + }; + + AllOf.prototype.jasmineToString = function(pp) { + return ''; + }; + + return AllOf; +}; + getJasmineRequireObj().Any = function(j$) { function Any(expectedObject) { if (typeof expectedObject === 'undefined') { diff --git a/spec/core/asymmetric_equality/AllOfSpec.js b/spec/core/asymmetric_equality/AllOfSpec.js new file mode 100644 index 00000000..6442ede0 --- /dev/null +++ b/spec/core/asymmetric_equality/AllOfSpec.js @@ -0,0 +1,63 @@ +describe('AllOf', function() { + it('matches a single value', function() { + const matchersUtil = new jasmineUnderTest.MatchersUtil(); + const allOf = new jasmineUnderTest.AllOf('foo'); + + expect(allOf.asymmetricMatch('foo', matchersUtil)).toBeTrue(); + }); + + it('matches a single matcher', function() { + const matchersUtil = new jasmineUnderTest.MatchersUtil(); + const allOf = new jasmineUnderTest.AllOf( + new jasmineUnderTest.StringContaining('oo') + ); + + expect(allOf.asymmetricMatch('foo', matchersUtil)).toBeTrue(); + }); + + it('matches multiple matchers', function() { + const matchersUtil = new jasmineUnderTest.MatchersUtil(); + const allOf = new jasmineUnderTest.AllOf( + new jasmineUnderTest.StringContaining('o'), + new jasmineUnderTest.StringContaining('f') + ); + + expect(allOf.asymmetricMatch('foo', matchersUtil)).toBeTrue(); + }); + + it('does not match when value does not match', function() { + const matchersUtil = new jasmineUnderTest.MatchersUtil(); + const allOf = new jasmineUnderTest.AllOf('bar'); + + expect(allOf.asymmetricMatch('foo', matchersUtil)).toBeFalse(); + }); + + it('does not match when any matchers fail', function() { + const matchersUtil = new jasmineUnderTest.MatchersUtil(); + const allOf = new jasmineUnderTest.AllOf( + new jasmineUnderTest.StringContaining('o'), + new jasmineUnderTest.StringContaining('x') + ); + + expect(allOf.asymmetricMatch('foo', matchersUtil)).toBeFalse(); + }); + + it('jasmineToStrings itself', function() { + const matcher = new jasmineUnderTest.AllOf('o'); + const pp = jasmine.createSpy('pp').and.returnValue('sample'); + + expect(matcher.jasmineToString(pp)).toEqual(''); + expect(pp).toHaveBeenCalledWith(['o']); + }); + + describe('when called without an argument', function() { + it('tells the user to pass a constructor argument', function() { + expect(function() { + new jasmineUnderTest.AllOf(); + }).toThrowError( + TypeError, + 'jasmine.allOf() expects at least one argument to be passed.' + ); + }); + }); +}); diff --git a/src/core/asymmetric_equality/AllOf.js b/src/core/asymmetric_equality/AllOf.js new file mode 100644 index 00000000..db67a947 --- /dev/null +++ b/src/core/asymmetric_equality/AllOf.js @@ -0,0 +1,27 @@ +getJasmineRequireObj().AllOf = function(j$) { + function AllOf() { + const expectedValues = Array.from(arguments); + if (expectedValues.length === 0) { + throw new TypeError( + 'jasmine.allOf() expects at least one argument to be passed.' + ); + } + this.expectedValues = expectedValues; + } + + AllOf.prototype.asymmetricMatch = function(other, matchersUtil) { + for (const expectedValue of this.expectedValues) { + if (!matchersUtil.equals(other, expectedValue)) { + return false; + } + } + + return true; + }; + + AllOf.prototype.jasmineToString = function(pp) { + return ''; + }; + + return AllOf; +}; diff --git a/src/core/base.js b/src/core/base.js index 95ea4bba..608e83d7 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -221,6 +221,19 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { ); }; + /** + * Get an {@link AsymmetricEqualityTester} that will succeed if the actual + * value being compared matches every provided equality tester. + * @name asymmetricEqualityTesters.allOf + * @emittedName jasmine.allOf + * @since 5.13.0 + * @function + * @param {...*} arguments - The asymmetric equality checkers to compare. + */ + j$.allOf = function() { + return new j$.AllOf(...arguments); + }; + /** * Get an {@link AsymmetricEqualityTester} that will succeed if the actual * value being compared is an instance of the specified class/constructor. diff --git a/src/core/requireCore.js b/src/core/requireCore.js index 669bd244..49f7d729 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -35,6 +35,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.util = jRequire.util(j$); j$.errors = jRequire.errors(); j$.formatErrorMsg = jRequire.formatErrorMsg(); + j$.AllOf = jRequire.AllOf(j$); j$.Any = jRequire.Any(j$); j$.Anything = jRequire.Anything(j$); j$.CallTracker = jRequire.CallTracker(j$);