From 00f6708e1f5f26a7ed3201160a9d209add56d67f Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Sat, 18 Sep 2021 09:43:02 -0700 Subject: [PATCH 1/4] Removed unused submodule --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index d88c3948..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "pages"] - path = pages - url = https://github.com/pivotal/jasmine.git From e3c9a59c6c29bac357dd22116dd8fcb491f9d468 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Wed, 22 Sep 2021 11:19:59 -0700 Subject: [PATCH 2/4] Added a stringContaining asymmetric equality tester * Fixes #1923. --- lib/jasmine-core/jasmine.js | 37 +++++++++++++++++++ .../StringContainingSpec.js | 27 ++++++++++++++ .../AsymmetricEqualityTestersSpec.js | 10 +++++ .../asymmetric_equality/StringContaining.js | 24 ++++++++++++ src/core/base.js | 11 ++++++ src/core/requireCore.js | 1 + 6 files changed, 110 insertions(+) create mode 100644 spec/core/asymmetric_equality/StringContainingSpec.js create mode 100644 src/core/asymmetric_equality/StringContaining.js diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 67ae3805..a4390730 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -96,6 +96,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.SpyRegistry = jRequire.SpyRegistry(j$); j$.SpyStrategy = jRequire.SpyStrategy(j$); j$.StringMatching = jRequire.StringMatching(j$); + j$.StringContaining = jRequire.StringContaining(j$); j$.UserContext = jRequire.UserContext(j$); j$.Suite = jRequire.Suite(j$); j$.Timer = jRequire.Timer(); @@ -487,6 +488,17 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return new j$.StringMatching(expected); }; + /** + * 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 contains the specified `String`. + * @name jasmine.stringContaining + * @function + * @param {String} expected + */ + j$.stringContaining = function(expected) { + return new j$.StringContaining(expected); + }; + /** * 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. @@ -2926,6 +2938,31 @@ getJasmineRequireObj().SetContaining = function(j$) { return SetContaining; }; +getJasmineRequireObj().StringContaining = function(j$) { + function StringContaining(expected) { + if (!j$.isString_(expected)) { + throw new Error('Expected is not a String'); + } + + this.expected = expected; + } + + StringContaining.prototype.asymmetricMatch = function(other) { + if (!j$.isString_(other)) { + // Arrays, etc. don't match no matter what their indexOf returns. + return false; + } + + return other.indexOf(this.expected) !== -1; + }; + + StringContaining.prototype.jasmineToString = function() { + return ''; + }; + + return StringContaining; +}; + getJasmineRequireObj().StringMatching = function(j$) { function StringMatching(expected) { if (!j$.isString_(expected) && !j$.isA_('RegExp', expected)) { diff --git a/spec/core/asymmetric_equality/StringContainingSpec.js b/spec/core/asymmetric_equality/StringContainingSpec.js new file mode 100644 index 00000000..aef1f48e --- /dev/null +++ b/spec/core/asymmetric_equality/StringContainingSpec.js @@ -0,0 +1,27 @@ +describe('StringContaining', function() { + it('searches for a provided substring when the expected is a String', function() { + var matcher = new jasmineUnderTest.StringContaining('foo'); + + expect(matcher.asymmetricMatch('barfoobaz')).toBe(true); + expect(matcher.asymmetricMatch('barbaz')).toBe(false); + }); + + it('raises an Error when the expected is not a String', function() { + expect(function() { + new jasmineUnderTest.StringContaining(/foo/); + }).toThrowError(/not a String/); + }); + + it('fails when the actual is not a String', function() { + var matcher = new jasmineUnderTest.StringContaining('x'); + expect(matcher.asymmetricMatch(['x'])).toBe(false); + }); + + it("jasmineToString's itself", function() { + var matching = new jasmineUnderTest.StringContaining('foo'); + + expect(matching.jasmineToString()).toEqual( + '' + ); + }); +}); diff --git a/spec/core/integration/AsymmetricEqualityTestersSpec.js b/spec/core/integration/AsymmetricEqualityTestersSpec.js index 3d12f15d..7ab1c77f 100644 --- a/spec/core/integration/AsymmetricEqualityTestersSpec.js +++ b/spec/core/integration/AsymmetricEqualityTestersSpec.js @@ -231,6 +231,16 @@ describe('Asymmetric equality testers (Integration)', function() { }); }); + describe('stringContaining', function() { + verifyPasses(function(env) { + env.expect('foo').toEqual(jasmineUnderTest.stringContaining('o')); + }); + + verifyFails(function(env) { + env.expect('bar').toEqual(jasmineUnderTest.stringContaining('o')); + }); + }); + describe('truthy', function() { verifyPasses(function(env) { env.expect(true).toEqual(jasmineUnderTest.truthy()); diff --git a/src/core/asymmetric_equality/StringContaining.js b/src/core/asymmetric_equality/StringContaining.js new file mode 100644 index 00000000..16f0c4e6 --- /dev/null +++ b/src/core/asymmetric_equality/StringContaining.js @@ -0,0 +1,24 @@ +getJasmineRequireObj().StringContaining = function(j$) { + function StringContaining(expected) { + if (!j$.isString_(expected)) { + throw new Error('Expected is not a String'); + } + + this.expected = expected; + } + + StringContaining.prototype.asymmetricMatch = function(other) { + if (!j$.isString_(other)) { + // Arrays, etc. don't match no matter what their indexOf returns. + return false; + } + + return other.indexOf(this.expected) !== -1; + }; + + StringContaining.prototype.jasmineToString = function() { + return ''; + }; + + return StringContaining; +}; diff --git a/src/core/base.js b/src/core/base.js index 89cd2b6e..fefa0479 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -319,6 +319,17 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return new j$.StringMatching(expected); }; + /** + * 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 contains the specified `String`. + * @name jasmine.stringContaining + * @function + * @param {String} expected + */ + j$.stringContaining = function(expected) { + return new j$.StringContaining(expected); + }; + /** * 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. diff --git a/src/core/requireCore.js b/src/core/requireCore.js index df7f2571..c4c41859 100644 --- a/src/core/requireCore.js +++ b/src/core/requireCore.js @@ -74,6 +74,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) { j$.SpyRegistry = jRequire.SpyRegistry(j$); j$.SpyStrategy = jRequire.SpyStrategy(j$); j$.StringMatching = jRequire.StringMatching(j$); + j$.StringContaining = jRequire.StringContaining(j$); j$.UserContext = jRequire.UserContext(j$); j$.Suite = jRequire.Suite(j$); j$.Timer = jRequire.Timer(); From be29aa95eb15b082eefd759e446846c9acbb87cd Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Thu, 23 Sep 2021 11:59:20 -0700 Subject: [PATCH 3/4] Improved jsdocs for asymmetric equality testers --- lib/jasmine-core/jasmine.js | 56 ++++++++++++++++++++++--------- src/core/base.js | 26 +++++++------- src/core/matchers/matchersUtil.js | 30 +++++++++++++++-- 3 files changed, 80 insertions(+), 32 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index a4390730..7183fa02 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -398,7 +398,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -410,7 +410,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -421,7 +421,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -432,7 +432,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -443,7 +443,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -454,7 +454,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -465,7 +465,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -477,7 +477,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -489,7 +489,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}), + * Get an {@link AsymmetricEqualityTester}, 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 contains the specified `String`. * @name jasmine.stringContaining * @function @@ -500,7 +500,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -512,7 +512,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -524,7 +524,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -537,7 +537,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -5608,9 +5608,33 @@ getJasmineRequireObj().MatchersUtil = function(j$) { /** * @interface AsymmetricEqualityTester * @classdesc An asymmetric equality tester is an object that can match multiple - * objects. Examples include jasmine.any() and jasmine.stringMatching(). - * User-defined asymmetric equality testers can also be defined and used in - * expectations. + * objects. Examples include jasmine.any() and jasmine.stringMatching(). Jasmine + * includes a number of built-in asymmetric equality testers, such as + * {@link jasmine.objectContaining}. User-defined asymmetric equality testers are + * also supported. + * + * Asymmetric equality testers work with any matcher, including user-defined + * custom matchers, that uses {@link MatchersUtil#equals} or + * {@link MatchersUtil#contains}. + * + * @example + * function numberDivisibleBy(divisor) { + * return { + * asymmetricMatch: function(n) { + * return typeof n === 'number' && n % divisor === 0; + * }, + * jasmineToString: function() { + * return ``; + * } + * }; + * } + * + * var actual = { + * n: 2, + * otherFields: "don't care" + * }; + * + * expect(actual).toEqual(jasmine.objectContaining({n: numberDivisibleBy(2)})); * @see custom_asymmetric_equality_testers * @since 2.0.0 */ diff --git a/src/core/base.js b/src/core/base.js index fefa0479..ddc3a73c 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -229,7 +229,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -241,7 +241,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -252,7 +252,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -263,7 +263,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -274,7 +274,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -285,7 +285,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -296,7 +296,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -308,7 +308,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -320,7 +320,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}), + * Get an {@link AsymmetricEqualityTester}, 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 contains the specified `String`. * @name jasmine.stringContaining * @function @@ -331,7 +331,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -343,7 +343,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -355,7 +355,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}), + * Get an {@link AsymmetricEqualityTester}, 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 @@ -368,7 +368,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}), + * Get an {@link AsymmetricEqualityTester}, 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 diff --git a/src/core/matchers/matchersUtil.js b/src/core/matchers/matchersUtil.js index 8d77cb3f..d2f848d8 100644 --- a/src/core/matchers/matchersUtil.js +++ b/src/core/matchers/matchersUtil.js @@ -659,9 +659,33 @@ getJasmineRequireObj().MatchersUtil = function(j$) { /** * @interface AsymmetricEqualityTester * @classdesc An asymmetric equality tester is an object that can match multiple - * objects. Examples include jasmine.any() and jasmine.stringMatching(). - * User-defined asymmetric equality testers can also be defined and used in - * expectations. + * objects. Examples include jasmine.any() and jasmine.stringMatching(). Jasmine + * includes a number of built-in asymmetric equality testers, such as + * {@link jasmine.objectContaining}. User-defined asymmetric equality testers are + * also supported. + * + * Asymmetric equality testers work with any matcher, including user-defined + * custom matchers, that uses {@link MatchersUtil#equals} or + * {@link MatchersUtil#contains}. + * + * @example + * function numberDivisibleBy(divisor) { + * return { + * asymmetricMatch: function(n) { + * return typeof n === 'number' && n % divisor === 0; + * }, + * jasmineToString: function() { + * return ``; + * } + * }; + * } + * + * var actual = { + * n: 2, + * otherFields: "don't care" + * }; + * + * expect(actual).toEqual(jasmine.objectContaining({n: numberDivisibleBy(2)})); * @see custom_asymmetric_equality_testers * @since 2.0.0 */ From 1f318c3c93558797f3181f390e9081a79995cdb1 Mon Sep 17 00:00:00 2001 From: Steve Gravrock Date: Thu, 23 Sep 2021 13:38:52 -0700 Subject: [PATCH 4/4] Added missing @since annotations --- lib/jasmine-core/jasmine.js | 20 +++++++++++++++++++- src/core/CallTracker.js | 1 + src/core/Clock.js | 1 + src/core/Env.js | 3 +++ src/core/Expectation.js | 1 + src/core/Spec.js | 7 ++++++- src/core/Suite.js | 6 ++++++ src/core/base.js | 1 + 8 files changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 7183fa02..6c05f9c1 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -492,6 +492,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { * Get an {@link AsymmetricEqualityTester}, 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 contains the specified `String`. * @name jasmine.stringContaining + * @since 3.10.0 * @function * @param {String} expected */ @@ -719,6 +720,7 @@ getJasmineRequireObj().Spec = function(j$) { /** * @interface Spec * @see Configuration#specFilter + * @since 2.0.0 */ function Spec(attrs) { this.expectationFactory = attrs.expectationFactory; @@ -729,6 +731,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#id * @readonly * @type {string} + * @since 2.0.0 */ this.id = attrs.id; /** @@ -736,6 +739,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#description * @readonly * @type {string} + * @since 2.0.0 */ this.description = attrs.description || ''; this.queueableFn = attrs.queueableFn; @@ -782,7 +786,8 @@ getJasmineRequireObj().Spec = function(j$) { * @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} - */ + * @since 2.0.0 +x */ this.result = { id: this.id, description: this.description, @@ -933,6 +938,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#getFullName * @function * @returns {string} + * @since 2.0.0 */ Spec.prototype.getFullName = function() { return this.getSpecName(this); @@ -1734,6 +1740,7 @@ getJasmineRequireObj().Env = function(j$) { * @function * @name Env#topSuite * @return {Suite} the root suite + * @since 2.0.0 */ this.topSuite = function() { return topSuite; @@ -1925,6 +1932,7 @@ getJasmineRequireObj().Env = function(j$) { * @typedef JasmineStartedInfo * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. + * @since 2.0.0 */ reporter.jasmineStarted( { @@ -1963,6 +1971,7 @@ getJasmineRequireObj().Env = function(j$) { * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level. * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level. + * @since 2.4.0 */ reporter.jasmineDone( { @@ -3159,6 +3168,7 @@ getJasmineRequireObj().CallTracker = function(j$) { /** * Get the "this" object that was passed to a specific invocation of this spy. * @name Spy#calls#thisFor + * @since 3.8.0 * @function * @param {Integer} index The 0-based invocation index. * @return {Object?} @@ -3320,6 +3330,7 @@ getJasmineRequireObj().Clock = function() { /** * @class Clock + * @since 1.3.0 * @classdesc Jasmine's mock clock is used when testing time dependent code.
* _Note:_ Do not construct this directly. You can get the current clock with * {@link jasmine.clock}. @@ -3962,6 +3973,7 @@ getJasmineRequireObj().Expectation = function(j$) { * Otherwise evaluate the matcher. * @member * @name async-matchers#already + * @since 3.8.0 * @type {async-matchers} * @example * await expectAsync(myPromise).already.toBeResolved(); @@ -9403,6 +9415,7 @@ getJasmineRequireObj().Suite = function(j$) { /** * @interface Suite * @see Env#topSuite + * @since 2.0.0 */ function Suite(attrs) { this.env = attrs.env; @@ -9411,6 +9424,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#id * @readonly * @type {string} + * @since 2.0.0 */ this.id = attrs.id; /** @@ -9425,6 +9439,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#description * @readonly * @type {string} + * @since 2.0.0 */ this.description = attrs.description; this.expectationFactory = attrs.expectationFactory; @@ -9443,6 +9458,7 @@ getJasmineRequireObj().Suite = function(j$) { * The suite's children. * @name Suite#children * @type {Array.<(Spec|Suite)>} + * @since 2.0.0 */ this.children = []; @@ -9456,6 +9472,7 @@ getJasmineRequireObj().Suite = function(j$) { * @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} + * @since 2.0.0 */ this.result = { id: this.id, @@ -9486,6 +9503,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#getFullName * @function * @returns {string} + * @since 2.0.0 */ Suite.prototype.getFullName = function() { var fullName = []; diff --git a/src/core/CallTracker.js b/src/core/CallTracker.js index 128790fe..fa9ebeaa 100644 --- a/src/core/CallTracker.js +++ b/src/core/CallTracker.js @@ -52,6 +52,7 @@ getJasmineRequireObj().CallTracker = function(j$) { /** * Get the "this" object that was passed to a specific invocation of this spy. * @name Spy#calls#thisFor + * @since 3.8.0 * @function * @param {Integer} index The 0-based invocation index. * @return {Object?} diff --git a/src/core/Clock.js b/src/core/Clock.js index 30c1ca7a..1bb593e1 100644 --- a/src/core/Clock.js +++ b/src/core/Clock.js @@ -7,6 +7,7 @@ getJasmineRequireObj().Clock = function() { /** * @class Clock + * @since 1.3.0 * @classdesc Jasmine's mock clock is used when testing time dependent code.
* _Note:_ Do not construct this directly. You can get the current clock with * {@link jasmine.clock}. diff --git a/src/core/Env.js b/src/core/Env.js index 063c4607..a5d19f3d 100644 --- a/src/core/Env.js +++ b/src/core/Env.js @@ -712,6 +712,7 @@ getJasmineRequireObj().Env = function(j$) { * @function * @name Env#topSuite * @return {Suite} the root suite + * @since 2.0.0 */ this.topSuite = function() { return topSuite; @@ -903,6 +904,7 @@ getJasmineRequireObj().Env = function(j$) { * @typedef JasmineStartedInfo * @property {Int} totalSpecsDefined - The total number of specs defined in this suite. * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. + * @since 2.0.0 */ reporter.jasmineStarted( { @@ -941,6 +943,7 @@ getJasmineRequireObj().Env = function(j$) { * @property {Order} order - Information about the ordering (random or not) of this execution of the suite. * @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level. * @property {Expectation[]} deprecationWarnings - List of deprecation warnings that occurred at the global level. + * @since 2.4.0 */ reporter.jasmineDone( { diff --git a/src/core/Expectation.js b/src/core/Expectation.js index 0309ec34..5545e1b0 100644 --- a/src/core/Expectation.js +++ b/src/core/Expectation.js @@ -126,6 +126,7 @@ getJasmineRequireObj().Expectation = function(j$) { * Otherwise evaluate the matcher. * @member * @name async-matchers#already + * @since 3.8.0 * @type {async-matchers} * @example * await expectAsync(myPromise).already.toBeResolved(); diff --git a/src/core/Spec.js b/src/core/Spec.js index 826f7157..2691ce04 100644 --- a/src/core/Spec.js +++ b/src/core/Spec.js @@ -2,6 +2,7 @@ getJasmineRequireObj().Spec = function(j$) { /** * @interface Spec * @see Configuration#specFilter + * @since 2.0.0 */ function Spec(attrs) { this.expectationFactory = attrs.expectationFactory; @@ -12,6 +13,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#id * @readonly * @type {string} + * @since 2.0.0 */ this.id = attrs.id; /** @@ -19,6 +21,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#description * @readonly * @type {string} + * @since 2.0.0 */ this.description = attrs.description || ''; this.queueableFn = attrs.queueableFn; @@ -65,7 +68,8 @@ getJasmineRequireObj().Spec = function(j$) { * @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} - */ + * @since 2.0.0 +x */ this.result = { id: this.id, description: this.description, @@ -216,6 +220,7 @@ getJasmineRequireObj().Spec = function(j$) { * @name Spec#getFullName * @function * @returns {string} + * @since 2.0.0 */ Spec.prototype.getFullName = function() { return this.getSpecName(this); diff --git a/src/core/Suite.js b/src/core/Suite.js index c3e475bd..40f3e6d3 100644 --- a/src/core/Suite.js +++ b/src/core/Suite.js @@ -2,6 +2,7 @@ getJasmineRequireObj().Suite = function(j$) { /** * @interface Suite * @see Env#topSuite + * @since 2.0.0 */ function Suite(attrs) { this.env = attrs.env; @@ -10,6 +11,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#id * @readonly * @type {string} + * @since 2.0.0 */ this.id = attrs.id; /** @@ -24,6 +26,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#description * @readonly * @type {string} + * @since 2.0.0 */ this.description = attrs.description; this.expectationFactory = attrs.expectationFactory; @@ -42,6 +45,7 @@ getJasmineRequireObj().Suite = function(j$) { * The suite's children. * @name Suite#children * @type {Array.<(Spec|Suite)>} + * @since 2.0.0 */ this.children = []; @@ -55,6 +59,7 @@ getJasmineRequireObj().Suite = function(j$) { * @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} + * @since 2.0.0 */ this.result = { id: this.id, @@ -85,6 +90,7 @@ getJasmineRequireObj().Suite = function(j$) { * @name Suite#getFullName * @function * @returns {string} + * @since 2.0.0 */ Suite.prototype.getFullName = function() { var fullName = []; diff --git a/src/core/base.js b/src/core/base.js index ddc3a73c..ec5a6383 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -323,6 +323,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { * Get an {@link AsymmetricEqualityTester}, 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 contains the specified `String`. * @name jasmine.stringContaining + * @since 3.10.0 * @function * @param {String} expected */