diff --git a/spec/core/integration/AsymmetricEqualityTestersSpec.js b/spec/core/integration/AsymmetricEqualityTestersSpec.js new file mode 100644 index 00000000..1ccf2801 --- /dev/null +++ b/spec/core/integration/AsymmetricEqualityTestersSpec.js @@ -0,0 +1,222 @@ +describe('Asymmetric equality testers (Integration)', function () { + function verifyPasses(expectations, setup) { + it('passes', function (done) { + var env = new jasmineUnderTest.Env(); + env.it('a spec', function () { + expectations(env); + }); + + var specExpectations = function (result) { + expect(result.status).toEqual('passed'); + expect(result.passedExpectations.length) + .withContext('Number of passed expectations') + .toEqual(1); + expect(result.failedExpectations.length) + .withContext('Number of failed expectations') + .toEqual(0); + expect(result.failedExpectations[0] && result.failedExpectations[0].message) + .withContext('Failure message') + .toBeUndefined(); + }; + + env.addReporter({specDone: specExpectations, jasmineDone: done}); + env.execute(); + }); + } + + function verifyFails(expectations) { + it('fails', function (done) { + var env = new jasmineUnderTest.Env(); + env.it('a spec', function () { + expectations(env); + }); + + var specExpectations = function (result) { + expect(result.status).toEqual('failed'); + expect(result.failedExpectations.length) + .withContext('Number of failed expectations') + .toEqual(1); + expect(result.failedExpectations[0].message) + .withContext('Failed with a thrown error rather than a matcher failure') + .not.toMatch(/^Error: /); + expect(result.failedExpectations[0].matcherName).withContext('Matcher name') + .not.toEqual(''); + }; + + env.addReporter({specDone: specExpectations, jasmineDone: done}); + env.execute(); + }); + } + + describe('any', function () { + verifyPasses(function (env) { + env.expect(5).toEqual(jasmineUnderTest.any(Number)); + }); + + verifyFails(function (env) { + env.expect("five").toEqual(jasmineUnderTest.any(Number)); + }); + }); + + describe('anything', function () { + verifyPasses(function (env) { + env.expect('').toEqual(jasmineUnderTest.anything()); + }); + + verifyFails(function (env) { + env.expect(null).toEqual(jasmineUnderTest.anything()); + }); + }); + + describe('arrayContaining', function () { + verifyPasses(function (env) { + env.addCustomEqualityTester(function (a, b) { + return a.toString() === b.toString(); + }); + env.expect([1, 2, 3]).toEqual(jasmineUnderTest.arrayContaining(["2"])); + }); + + verifyFails(function (env) { + env.expect(null).toEqual(jasmineUnderTest.arrayContaining([2])); + }); + }); + + describe('arrayWithExactContents', function () { + verifyPasses(function (env) { + env.addCustomEqualityTester(function (a, b) { + return a.toString() === b.toString(); + }); + env.expect([1, 2]).toEqual(jasmineUnderTest.arrayWithExactContents(["2", "1"])); + }); + + verifyFails(function (env) { + env.expect([]).toEqual(jasmineUnderTest.arrayWithExactContents([2])); + }); + }); + + describe('empty', function () { + verifyPasses(function (env) { + env.expect([]).toEqual(jasmineUnderTest.empty()); + }); + + verifyFails(function (env) { + env.expect([1]).toEqual(jasmineUnderTest.empty()); + }); + }); + + describe('falsy', function () { + verifyPasses(function (env) { + env.expect(false).toEqual(jasmineUnderTest.falsy()); + }); + + verifyFails(function (env) { + env.expect(true).toEqual(jasmineUnderTest.falsy()); + }); + }); + + describe('mapContaining', function () { + if (jasmine.getEnv().hasFunctioningMaps()) { + verifyPasses(function (env) { + var actual = new Map(); + actual.set('a', "2"); + var expected = new Map(); + expected.set('a', 2); + + env.addCustomEqualityTester(function (a, b) { + return a.toString() === b.toString(); + }); + + env.expect(actual).toEqual(jasmineUnderTest.mapContaining(expected)); + }); + } else { + it('passes', function() { + jasmine.getEnv().pending('Browser has incomplete or missing support for Maps'); + }); + } + + if (jasmine.getEnv().hasFunctioningMaps()) { + verifyFails(function (env) { + env.expect('something').toEqual(jasmineUnderTest.mapContaining(new Map())); + }); + } else { + it('fails', function() { + jasmine.getEnv().pending('Browser has incomplete or missing support for Maps'); + }); + } + }); + + describe('notEmpty', function () { + verifyPasses(function (env) { + env.expect([1]).toEqual(jasmineUnderTest.notEmpty()); + }); + + verifyFails(function (env) { + env.expect([]).toEqual(jasmineUnderTest.notEmpty()); + }); + }); + + describe('objectContaining', function () { + verifyPasses(function (env) { + env.addCustomEqualityTester(function (a, b) { + return a.toString() === b.toString(); + }); + + env.expect({a: 1, b: 2}).toEqual(jasmineUnderTest.objectContaining({a: "1"})); + }); + + verifyFails(function (env) { + env.expect({}).toEqual(jasmineUnderTest.objectContaining({a: "1"})); + }); + }); + + describe('setContaining', function () { + if (jasmine.getEnv().hasFunctioningSets()) { + verifyPasses(function (env) { + var actual = new Set(); + actual.add("1"); + var expected = new Set(); + actual.add(1); + + env.addCustomEqualityTester(function (a, b) { + return a.toString() === b.toString(); + }); + + env.expect(actual).toEqual(jasmineUnderTest.setContaining(expected)); + }); + } else { + it('pases', function() { + jasmine.getEnv().pending('Browser has incomplete or missing support for Sets'); + }); + } + + if (jasmine.getEnv().hasFunctioningSets()) { + verifyFails(function (env) { + env.expect('something').toEqual(jasmineUnderTest.setContaining(new Set())); + }); + } else { + it('fails', function() { + jasmine.getEnv().pending('Browser has incomplete or missing support for Sets'); + }); + } + }); + + describe('stringMatching', function () { + verifyPasses(function (env) { + env.expect('foo').toEqual(jasmineUnderTest.stringMatching(/o/)); + }); + + verifyFails(function (env) { + env.expect('bar').toEqual(jasmineUnderTest.stringMatching(/o/)); + }); + }); + + describe('truthy', function () { + verifyPasses(function (env) { + env.expect(true).toEqual(jasmineUnderTest.truthy()); + }); + + verifyFails(function (env) { + env.expect(false).toEqual(jasmineUnderTest.truthy()); + }); + }); +}); diff --git a/spec/core/integration/CustomAsyncMatchersSpec.js b/spec/core/integration/CustomAsyncMatchersSpec.js index a38ad472..9f0f4a16 100644 --- a/spec/core/integration/CustomAsyncMatchersSpec.js +++ b/spec/core/integration/CustomAsyncMatchersSpec.js @@ -79,4 +79,40 @@ describe('Custom Async Matchers (Integration)', function() { env.addReporter({ specDone: specExpectations, jasmineDone: done }); env.execute(); }); + + // TODO: remove this in the next major release. + it("passes the jasmine utility and current equality testers to the matcher factory", function(done) { + jasmine.getEnv().requirePromises(); + + var matcherFactory = function () { + return { + compare: function () { + return Promise.resolve({pass: true}); + } + }; + }, + matcherFactorySpy = jasmine.createSpy("matcherFactorySpy").and.callFake(matcherFactory), + customEqualityFn = function () { + return true; + }; + + env.it("spec with expectation", function() { + env.addCustomEqualityTester(customEqualityFn); + env.addAsyncMatchers({ + toBeReal: matcherFactorySpy + }); + + return env.expectAsync(true).toBeReal(); + }); + + var specExpectations = function() { + expect(matcherFactorySpy).toHaveBeenCalledWith( + jasmine.any(jasmineUnderTest.MatchersUtil), + [customEqualityFn] + ); + }; + + env.addReporter({ specDone: specExpectations, jasmineDone: done }); + env.execute(); + }); }); diff --git a/spec/core/integration/CustomMatchersSpec.js b/spec/core/integration/CustomMatchersSpec.js index 184c89be..af8f4cbc 100644 --- a/spec/core/integration/CustomMatchersSpec.js +++ b/spec/core/integration/CustomMatchersSpec.js @@ -85,6 +85,34 @@ describe("Custom Matchers (Integration)", function() { env.execute(); }); + it("supports asymmetric equality testers that take a list of custom equality testers", function(done) { + // TODO: remove this in the next major release. + env.it("spec using custom asymmetric equality tester", function() { + var customEqualityFn = function(a, b) { + if (a === 2 && b === "two") { + return true; + } + }; + var arrayWithFirstElement = function(sample) { + return { + asymmetricMatch: function (actual, customEqualityTesters) { + return jasmineUnderTest.matchersUtil.equals(sample, actual[0], customEqualityTesters); + } + }; + }; + + env.addCustomEqualityTester(customEqualityFn); + env.expect(["two"]).toEqual(arrayWithFirstElement(2)); + }); + + var specExpectations = function(result) { + expect(result.status).toEqual('passed'); + }; + + env.addReporter({ specDone: specExpectations, jasmineDone: done }); + env.execute(); + }); + it("displays an appropriate failure message if a custom equality matcher fails", function(done) { env.it("spec using custom equality matcher", function() { var customEqualityFn = function(a, b) { @@ -179,23 +207,27 @@ describe("Custom Matchers (Integration)", function() { env.execute(); }); - it("passes the jasmine utility and current equality matchers to the expectation factory", function(done) { + // TODO: remove this in the next major release. + it("passes the jasmine utility and current equality testers to the matcher factory", function(done) { var matcherFactory = function() { return { compare: function() { return {pass: true}; }}; }, - argumentSpy = jasmine.createSpy("argument spy").and.returnValue(matcherFactory), + matcherFactorySpy = jasmine.createSpy("matcherFactorySpy").and.callFake(matcherFactory), customEqualityFn = function() { return true; }; env.it("spec with expectation", function() { env.addCustomEqualityTester(customEqualityFn); env.addMatchers({ - toBeReal: argumentSpy + toBeReal: matcherFactorySpy }); env.expect(true).toBeReal(); }); var specExpectations = function() { - expect(argumentSpy).toHaveBeenCalledWith(jasmineUnderTest.matchersUtil, [customEqualityFn]); + expect(matcherFactorySpy).toHaveBeenCalledWith( + jasmine.any(jasmineUnderTest.MatchersUtil), + [customEqualityFn] + ); }; env.addReporter({ specDone: specExpectations, jasmineDone: done }); diff --git a/spec/core/integration/MatchersSpec.js b/spec/core/integration/MatchersSpec.js index 95eaf041..25af3217 100644 --- a/spec/core/integration/MatchersSpec.js +++ b/spec/core/integration/MatchersSpec.js @@ -267,7 +267,10 @@ describe('Matchers (Integration)', function() { describe('toBeResolvedTo', function() { verifyPassesAsync(function(env) { - return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('foo'); + env.addCustomEqualityTester(function(a, b) { + return a.toString() === b.toString(); + }); + return env.expectAsync(Promise.resolve('5')).toBeResolvedTo(5); }); verifyFailsAsync(function(env) { @@ -287,7 +290,10 @@ describe('Matchers (Integration)', function() { describe('toBeRejectedWith', function() { verifyPassesAsync(function(env) { - return env.expectAsync(Promise.reject('nope')).toBeRejectedWith('nope'); + env.addCustomEqualityTester(function(a, b) { + return a.toString() === b.toString(); + }); + return env.expectAsync(Promise.reject('5')).toBeRejectedWith(5); }); verifyFailsAsync(function(env) { @@ -337,7 +343,10 @@ describe('Matchers (Integration)', function() { describe('toContain', function() { verifyPasses(function(env) { - env.expect('foobar').toContain('oo'); + env.addCustomEqualityTester(function(a, b) { + return a.toString() === b.toString(); + }); + env.expect(['1', '2', '3']).toContain(2); }); verifyFails(function(env) { @@ -347,7 +356,10 @@ describe('Matchers (Integration)', function() { describe('toEqual', function() { verifyPasses(function(env) { - env.expect('a').toEqual('a'); + env.addCustomEqualityTester(function(a, b) { + return a.toString() === b.toString(); + }); + env.expect(5).toEqual('5'); }); verifyFails(function(env) { @@ -400,8 +412,11 @@ describe('Matchers (Integration)', function() { describe('toHaveBeenCalledWith', function() { verifyPasses(function(env) { var spy = env.createSpy(); - spy('foo'); - env.expect(spy).toHaveBeenCalledWith('foo'); + spy('5'); + env.addCustomEqualityTester(function(a, b) { + return a.toString() === b.toString(); + }); + env.expect(spy).toHaveBeenCalledWith(5); }); verifyFails(function(env) { diff --git a/spec/core/matchers/matchersUtilSpec.js b/spec/core/matchers/matchersUtilSpec.js index d5d88ab3..038d101a 100644 --- a/spec/core/matchers/matchersUtilSpec.js +++ b/spec/core/matchers/matchersUtilSpec.js @@ -725,7 +725,7 @@ describe("matchersUtil", function() { it("uses custom equality testers if passed in and actual is an Array", function() { var customTester = function(a, b) {return true;}; - expect(jasmineUnderTest.matchersUtil.contains([1, 2], 2, [customTester])).toBe(true); + expect(jasmineUnderTest.matchersUtil.contains([1, 2], 3, [customTester])).toBe(true); }); it("fails when actual is undefined", function() { diff --git a/spec/helpers/checkForMap.js b/spec/helpers/checkForMap.js index 64e32cdc..46e346a8 100644 --- a/spec/helpers/checkForMap.js +++ b/spec/helpers/checkForMap.js @@ -1,5 +1,5 @@ (function(env) { - function hasFunctioningMaps() { + env.hasFunctioningMaps = function() { if (typeof Map === 'undefined') { return false; } @@ -36,10 +36,10 @@ } catch (e) { return false; } - } + }; env.requireFunctioningMaps = function() { - if (!hasFunctioningMaps()) { + if (!env.hasFunctioningMaps()) { env.pending('Browser has incomplete or missing support for Maps'); } }; diff --git a/spec/helpers/checkForSet.js b/spec/helpers/checkForSet.js index 1be8de45..dacb06aa 100644 --- a/spec/helpers/checkForSet.js +++ b/spec/helpers/checkForSet.js @@ -1,5 +1,5 @@ (function(env) { - function hasFunctioningSets() { + env.hasFunctioningSets = function() { if (typeof Set === 'undefined') { return false; } @@ -40,10 +40,10 @@ } catch (e) { return false; } - } + }; env.requireFunctioningSets = function() { - if (!hasFunctioningSets()) { + if (!env.hasFunctioningSets()) { env.pending('Browser has incomplete or missing support for Sets'); } };