Merge branch 'master' into feat/to-have-been-called-once-with

This commit is contained in:
Maksym Kobieliev
2020-04-14 22:08:13 +03:00
106 changed files with 3739 additions and 1146 deletions

View File

@@ -115,4 +115,36 @@ describe('Custom Async Matchers (Integration)', function() {
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
it("provides custom equality testers to the matcher factory via matchersUtil", function(done) {
jasmine.getEnv().requirePromises();
var matcherFactory = function (matchersUtil) {
return {
compare: function (actual, expected) {
return Promise.resolve({pass: matchersUtil.equals(actual[0], expected)});
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function() {
env.addCustomEqualityTester(customEqualityFn);
env.addAsyncMatchers({
toBeArrayWithFirstElement: matcherFactory
});
return env.expectAsync([1, 2]).toBeArrayWithFirstElement("1");
});
var specExpectations = function(result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
});

View File

@@ -1,8 +1,8 @@
describe("Custom Matchers (Integration)", function() {
describe("Custom Matchers (Integration)", function () {
var env;
var fakeTimer;
beforeEach(function() {
beforeEach(function () {
env = new jasmineUnderTest.Env();
env.configure({random: false});
});
@@ -11,13 +11,13 @@ describe("Custom Matchers (Integration)", function() {
env.cleanup_();
});
it("allows adding more matchers local to a spec", function(done) {
env.it('spec defining a custom matcher', function() {
it("allows adding more matchers local to a spec", function (done) {
env.it('spec defining a custom matcher', function () {
env.addMatchers({
matcherForSpec: function() {
matcherForSpec: function () {
return {
compare: function(actual, expected) {
return { pass: false, message: "matcherForSpec: actual: " + actual + "; expected: " + expected };
compare: function (actual, expected) {
return {pass: false, message: "matcherForSpec: actual: " + actual + "; expected: " + expected};
}
}
}
@@ -87,6 +87,8 @@ describe("Custom Matchers (Integration)", function() {
it("supports asymmetric equality testers that take a list of custom equality testers", function(done) {
// TODO: remove this in the next major release.
spyOn(jasmineUnderTest, 'getEnv').and.returnValue(env);
env.it("spec using custom asymmetric equality tester", function() {
var customEqualityFn = function(a, b) {
if (a === 2 && b === "two") {
@@ -233,4 +235,34 @@ describe("Custom Matchers (Integration)", function() {
env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute();
});
it("provides custom equality testers to the matcher factory via matchersUtil", function (done) {
var matcherFactory = function (matchersUtil) {
return {
compare: function (actual, expected) {
return {pass: matchersUtil.equals(actual[0], expected)};
}
};
},
customEqualityFn = jasmine.createSpy("customEqualityFn").and.callFake(function (a, b) {
return a.toString() === b;
});
env.it("spec with expectation", function () {
env.addCustomEqualityTester(customEqualityFn);
env.addMatchers({
toBeArrayWithFirstElement: matcherFactory
});
env.expect([1, 2]).toBeArrayWithFirstElement("1");
});
var specExpectations = function (result) {
expect(customEqualityFn).toHaveBeenCalledWith(1, "1");
expect(result.failedExpectations).toEqual([]);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
});

View File

@@ -0,0 +1,67 @@
describe("Custom object formatters", function() {
var env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
env.configure({random: false});
});
it("scopes custom object formatters to a spec", function(done) {
env.it('a spec with custom pretty-printer', function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
env.expect(42).toBeUndefined();
});
env.it('a spec without custom pretty-printer', function() {
env.expect(42).toBeUndefined();
});
var specResults = [];
var specDone = function(result) {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.execute();
});
it("scopes custom object formatters to a suite", function(done) {
env.it('a spec without custom pretty-printer', function() {
env.expect(42).toBeUndefined();
});
env.describe('with custom pretty-printer', function() {
env.beforeEach(function() {
env.addCustomObjectFormatter(function(obj) { return 'custom(' + obj + ')'; });
});
env.it('a spec', function() {
env.expect(42).toBeUndefined();
});
});
var specResults = [];
var specDone = function(result) {
specResults.push(result);
};
var expectations = function() {
expect(specResults[0].failedExpectations[0].message).toEqual("Expected 42 to be undefined.");
expect(specResults[1].failedExpectations[0].message).toEqual("Expected custom(42) to be undefined.");
done();
};
env.addReporter({ specDone:specDone, jasmineDone: expectations});
env.execute();
});
it("throws an exception if you try to add a custom object formatter outside a runable", function() {
expect(function() {
env.addCustomObjectFormatter(function() {});
}).toThrowError('Custom object formatters must be added in a before function or a spec')
});
});

View File

@@ -616,6 +616,58 @@ describe("Env integration", function() {
env.execute();
});
it('reports the duration of the suite', function(done) {
var duration;
env.addReporter({
suiteDone: function(result) {
expect(duration).toBeUndefined();
duration = result.duration;
},
jasmineDone: function() {
expect(duration).toBeGreaterThanOrEqual(10);
done();
}
});
env.describe('my suite', function() {
env.it('takes time', function(done) {
// We can't just use the mock clock here because the timer is designed
// to record real time even when the mock clock is installed.
setTimeout(done, 10);
})
});
env.execute();
});
});
describe('specDone reporting', function() {
it('reports the duration of the spec', function(done) {
var duration;
env.addReporter({
specDone: function(result) {
expect(duration).toBeUndefined();
duration = result.duration;
},
jasmineDone: function() {
expect(duration).toBeGreaterThanOrEqual(10);
done();
}
});
env.describe('my suite', function() {
env.it('takes time', function(done) {
// We can't just use the mock clock here because the timer is designed
// to record real time even when the mock clock is installed.
setTimeout(done, 10);
})
});
env.execute();
});
});
it('reports expectation failures in global beforeAll', function(done) {
@@ -808,6 +860,31 @@ describe("Env integration", function() {
expect(originalFunctionWasCalled).toEqual(true);
});
env.it("works with constructors when using callThrough spy strategy", function() {
function MyClass(foo) {
if (!(this instanceof MyClass)) throw new Error('You must use the new keyword.');
this.foo = foo;
}
var subject = { MyClass: MyClass };
var spy = env.spyOn(subject, 'MyClass').and.callThrough();
expect(function() {
var result = new spy('hello world');
expect(result instanceof MyClass).toBeTruthy();
expect(result.foo).toEqual('hello world');
}).not.toThrow();
expect(function() {
var result = new spy('passing', 'extra', 'arguments', 'to', 'constructor');
expect(result instanceof MyClass).toBeTruthy();
expect(result.foo).toEqual('passing');
}).not.toThrow();
expect(function() {
spy('hello world');
}).toThrowError('You must use the new keyword.');
});
env.execute();
});
@@ -821,8 +898,8 @@ describe("Env integration", function() {
env.allowRespy(true);
env.addReporter({ jasmineDone: done });
env.describe('test suite', function(){
env.it('spec 0', function(){
env.describe('test suite', function() {
env.it('spec 0', function() {
env.spyOn(foo,'bar');
var error = null;
@@ -2584,4 +2661,33 @@ describe("Env integration", function() {
env.execute();
});
it("supports asymmetric equality testers that take a matchersUtil", function(done) {
var env = new jasmineUnderTest.Env();
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, matchersUtil) {
return matchersUtil.equals(sample, actual[0]);
}
};
};
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();
});
});

View File

@@ -47,6 +47,9 @@ describe('Matchers (Integration)', function() {
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown error rather than a matcher failure')
.not.toMatch(/^Error: /);
expect(result.failedExpectations[0].message)
.withContext('Failed with a thrown type error rather than a matcher failure')
.not.toMatch(/^TypeError: /);
expect(result.failedExpectations[0].matcherName).withContext('Matcher name')
.not.toEqual('');
};
@@ -56,6 +59,27 @@ describe('Matchers (Integration)', function() {
});
}
function verifyFailsWithCustomObjectFormatters(config) {
it('uses custom object formatters', function(done) {
env.it('a spec', function () {
env.addCustomObjectFormatter(config.formatter);
config.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)
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
}
function verifyPassesAsync(expectations) {
it('passes', function(done) {
jasmine.getEnv().requirePromises();
@@ -107,6 +131,30 @@ describe('Matchers (Integration)', function() {
});
}
function verifyFailsWithCustomObjectFormattersAsync(config) {
it('uses custom object formatters', function(done) {
var env = new jasmineUnderTest.Env();
jasmine.getEnv().requirePromises();
env.it('a spec', function () {
env.addCustomObjectFormatter(config.formatter);
return config.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)
.toEqual(config.expectedMessage);
};
env.addReporter({specDone: specExpectations, jasmineDone: done});
env.execute();
});
}
describe('nothing', function() {
verifyPasses(function(env) {
env.expect().nothing();
@@ -223,6 +271,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect(2).toBeNaN();
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBeNaN();
},
expectedMessage: 'Expected |1| to be NaN.'
});
});
describe('toBeNegativeInfinity', function() {
@@ -233,6 +291,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect(2).toBeNegativeInfinity();
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBeNegativeInfinity();
},
expectedMessage: 'Expected |1| to be -Infinity.'
});
});
describe('toBeNull', function() {
@@ -253,6 +321,16 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect(2).toBePositiveInfinity();
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
env.expect(1).toBePositiveInfinity();
},
expectedMessage: 'Expected |1| to be Infinity.'
})
});
describe('toBeResolved', function() {
@@ -276,6 +354,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve('foo')).toBeResolvedTo('bar');
});
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.resolve('x')).toBeResolvedTo('y');
},
expectedMessage: 'Expected a promise to be resolved to |y| ' +
'but it was resolved to |x|.'
});
});
describe('toBeRejected', function() {
@@ -299,6 +388,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWith('nope');
});
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('x')).toBeRejectedWith('y');
},
expectedMessage: 'Expected a promise to be rejected with |y| ' +
'but it was rejected with |x|.'
});
});
describe('toBeRejectedWithError', function() {
@@ -309,6 +409,17 @@ describe('Matchers (Integration)', function() {
verifyFailsAsync(function(env) {
return env.expectAsync(Promise.resolve()).toBeRejectedWithError(Error);
});
verifyFailsWithCustomObjectFormattersAsync({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
return env.expectAsync(Promise.reject('foo')).toBeRejectedWithError('foo');
},
expectedMessage: 'Expected a promise to be rejected with Error: |foo| ' +
'but it was rejected with |foo|.'
});
});
describe('toBeTrue', function() {
@@ -365,6 +476,30 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect('a').toEqual('b');
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
if (val === 5) {
return 'five';
} else if (val === 4) {
return 'four';
}
},
expectations: function(env) {
env.expect([{foo: 4}]).toEqual([{foo: 5}]);
},
expectedMessage: 'Expected $[0].foo = four to equal five.'
});
});
describe('toHaveSize', function() {
verifyPasses(function(env) {
env.expect(['a','b']).toHaveSize(2);
});
verifyFails(function(env) {
env.expect(['a','b']).toHaveSize(1);
});
});
describe('toHaveBeenCalled', function() {
@@ -423,6 +558,19 @@ describe('Matchers (Integration)', function() {
var spy = env.createSpy();
env.expect(spy).toHaveBeenCalledWith('foo');
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(spy).toHaveBeenCalledWith('x');
},
expectedMessage: 'Expected spy foo to have been called with:\n' +
' |x|\n' +
'but it was never called.'
});
});
describe('toHaveBeenCalledOnceWith', function() {
@@ -471,12 +619,28 @@ describe('Matchers (Integration)', function() {
describe('toThrow', function() {
verifyPasses(function(env) {
env.expect(function() { throw new Error(); }).toThrow();
env.addCustomEqualityTester(function(a, b) {
return a.toString() === b.toString();
});
env.expect(function() { throw '5'; }).toThrow(5);
});
verifyFails(function(env) {
env.expect(function() {}).toThrow();
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).not.toThrow();
},
expectedMessage: 'Expected function not to throw, but it threw |x|.'
});
});
describe('toThrowError', function() {
@@ -487,6 +651,19 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect(function() { }).toThrowError();
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw 'x'
}).toThrowError();
},
expectedMessage: 'Expected function to throw an Error, but it threw |x|.'
});
});
describe('toThrowMatching', function() {
@@ -501,5 +678,21 @@ describe('Matchers (Integration)', function() {
verifyFails(function(env) {
env.expect(throws).toThrowMatching(function() { return false; });
});
verifyFailsWithCustomObjectFormatters({
formatter: function(val) {
return '|' + val + '|';
},
expectations: function(env) {
var spy = env.createSpy('foo');
env.expect(function() {
throw new Error('nope')
}).toThrowMatching(function() {
return false;
});
},
expectedMessage: 'Expected function to throw an exception matching ' +
'a predicate, but it threw Error with message |nope|.'
});
});
});