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();