Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5e0e6481d | ||
|
|
bcf69b86b4 | ||
|
|
a5f79fac81 | ||
|
|
18a00822c5 | ||
|
|
4cc8437f79 | ||
|
|
8e58305b0a | ||
|
|
bd368aceee | ||
|
|
8f16021887 | ||
|
|
bbb1b69b2e | ||
|
|
9ea8a2096f | ||
|
|
66340e2b19 | ||
|
|
fe29dfa89c | ||
|
|
41f7fabe2f | ||
|
|
856a040a2d | ||
|
|
f7eaa5ec29 | ||
|
|
0c87d47318 | ||
|
|
c24b2f5a73 | ||
|
|
774c83a36e | ||
|
|
751cf6ab5b | ||
|
|
2fd76c954c | ||
|
|
bb4d18f959 |
@@ -36,9 +36,10 @@ When ready to release - specs are all green and the stories are done:
|
||||
### Commit and push core changes
|
||||
|
||||
1. Run the browser tests using `scripts/run-all-browsers`.
|
||||
1. Commit release notes and version changes (jasmine.js, package.json)
|
||||
1. Push
|
||||
1. Wait for Circle CI to go green
|
||||
2. Commit release notes and version changes (jasmine.js, package.json)
|
||||
3. Push
|
||||
4. Tag the release and push the tag.
|
||||
5. Wait for Circle CI to go green
|
||||
|
||||
### Build standalone distribution
|
||||
|
||||
@@ -47,7 +48,6 @@ When ready to release - specs are all green and the stories are done:
|
||||
|
||||
### Release the core NPM module
|
||||
|
||||
1. Run the tests on Windows. (CI only tests on Linux.)
|
||||
1. `npm adduser` to save your credentials locally
|
||||
1. `npm publish .` to publish what's in `package.json`
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "4.1.1",
|
||||
"version": "4.2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
@@ -43,8 +43,8 @@
|
||||
"grunt-contrib-concat": "^2.0.0",
|
||||
"grunt-css-url-embed": "^1.11.1",
|
||||
"grunt-sass": "^3.0.2",
|
||||
"jasmine": "github:jasmine/jasmine-npm#main",
|
||||
"jasmine-browser-runner": "github:jasmine/jasmine-browser#main",
|
||||
"jasmine": "^4.1.0",
|
||||
"jasmine-browser-runner": "^1.0.0",
|
||||
"jsdom": "^19.0.0",
|
||||
"load-grunt-tasks": "^5.1.0",
|
||||
"prettier": "1.17.1",
|
||||
@@ -95,14 +95,15 @@
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"space-before-blocks": "error"
|
||||
"space-before-blocks": "error",
|
||||
"no-eval": "error"
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"Safari >= 13",
|
||||
"Safari >= 14",
|
||||
"last 2 Chrome versions",
|
||||
"last 2 Firefox versions",
|
||||
"Firefox >= 68",
|
||||
"Firefox >= 91",
|
||||
"last 2 Edge versions"
|
||||
]
|
||||
}
|
||||
|
||||
29
release_notes/4.2.0.md
Normal file
29
release_notes/4.2.0.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Jasmine 4.2.0 Release Notes
|
||||
|
||||
## New Features
|
||||
|
||||
* Added a jasmine.is asymmetric equality tester
|
||||
* Allows the use of === comparisons for specific fields of an object that
|
||||
should otherwise be compared with the default deep value equality logic.
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* More reliably report errors that occur late in the suite/spec lifecycle
|
||||
* Previously, an error that occurred after Jasmine started to report the
|
||||
suiteDone or specDone event for the current runable would not be reliably
|
||||
reported. Now such an error is reported on the nearest ancestor suite whose
|
||||
suiteDone event has not yet been reported.
|
||||
|
||||
* Don't report a deprecation when a runnable uses two forms of async
|
||||
* This was made into an error in 4.0, so the deprecation is redundant.
|
||||
|
||||
* Include property getter values in pretty-printed objects
|
||||
|
||||
## Documentation Updates
|
||||
|
||||
* Removed duplicate Suite and Spec jsdocs
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
@@ -323,16 +323,16 @@ describe('PrettyPrinter', function() {
|
||||
);
|
||||
});
|
||||
|
||||
it('should indicate getters on objects as such', function() {
|
||||
it('should use the return value of getters', function() {
|
||||
const pp = jasmineUnderTest.makePrettyPrinter();
|
||||
const sampleValue = {
|
||||
id: 1,
|
||||
get calculatedValue() {
|
||||
throw new Error("don't call me!");
|
||||
return 'the getter return value';
|
||||
}
|
||||
};
|
||||
expect(pp(sampleValue)).toEqual(
|
||||
'Object({ id: 1, calculatedValue: <getter> })'
|
||||
"Object({ id: 1, calculatedValue: 'the getter return value' })"
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -632,7 +632,8 @@ describe('QueueRunner', function() {
|
||||
});
|
||||
|
||||
it('issues a more specific error if the function is `async`', function() {
|
||||
eval('var fn = async function(done){};');
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async function fn(done) {}
|
||||
const onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new jasmineUnderTest.QueueRunner({
|
||||
queueableFns: [{ fn: fn }],
|
||||
|
||||
@@ -334,7 +334,7 @@ describe('Spec', function() {
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') }
|
||||
});
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(true, {});
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
@@ -342,8 +342,8 @@ describe('Spec', function() {
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') }
|
||||
});
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(false);
|
||||
spec.addExpectationResult(true, {});
|
||||
spec.addExpectationResult(false, {});
|
||||
expect(spec.status()).toBe('failed');
|
||||
});
|
||||
|
||||
@@ -352,14 +352,11 @@ describe('Spec', function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy('spec body') },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
spec.addExpectationResult(true, 'expectation1');
|
||||
spec.addExpectationResult(false, 'expectation2');
|
||||
spec.addExpectationResult(true, { message: 'expectation1' });
|
||||
spec.addExpectationResult(false, { message: 'expectation2' });
|
||||
|
||||
spec.execute();
|
||||
|
||||
@@ -367,10 +364,10 @@ describe('Spec', function() {
|
||||
fns[fns.length - 1].fn();
|
||||
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
|
||||
'expectation1'
|
||||
jasmine.objectContaining({ message: 'expectation1' })
|
||||
]);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
'expectation2'
|
||||
jasmine.objectContaining({ message: 'expectation2' })
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -379,17 +376,14 @@ describe('Spec', function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback,
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.addExpectationResult(true, 'passed');
|
||||
spec.addExpectationResult(true, { message: 'passed' });
|
||||
expect(function() {
|
||||
spec.addExpectationResult(false, 'failed');
|
||||
spec.addExpectationResult(false, { message: 'failed' });
|
||||
}).toThrowError(jasmineUnderTest.errors.ExpectationFailed);
|
||||
|
||||
spec.execute();
|
||||
@@ -397,20 +391,104 @@ describe('Spec', function() {
|
||||
const fns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
fns[fns.length - 1].fn();
|
||||
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
|
||||
'passed'
|
||||
jasmine.objectContaining({ message: 'passed' })
|
||||
]);
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
'failed'
|
||||
jasmine.objectContaining({ message: 'failed' })
|
||||
]);
|
||||
});
|
||||
|
||||
it('forwards late expectation failures to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
onLateError,
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
const data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: new Error('nope')
|
||||
};
|
||||
|
||||
spec.reportedDone = true;
|
||||
spec.addExpectationResult(false, data, true);
|
||||
|
||||
expect(onLateError).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^Error: nope/)
|
||||
})
|
||||
);
|
||||
expect(spec.result.failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not forward non-late expectation failures to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
onLateError,
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
const data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: new Error('nope')
|
||||
};
|
||||
|
||||
spec.addExpectationResult(false, data, true);
|
||||
|
||||
expect(onLateError).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('forwards late handleException calls to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
onLateError,
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
|
||||
spec.reportedDone = true;
|
||||
spec.handleException(new Error('oops'));
|
||||
|
||||
expect(onLateError).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^Error: oops/)
|
||||
})
|
||||
);
|
||||
expect(spec.result.failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not forward non-late handleException calls to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
onLateError,
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
const error = new Error('oops');
|
||||
|
||||
spec.handleException(error);
|
||||
|
||||
expect(onLateError).not.toHaveBeenCalled();
|
||||
expect(spec.result.failedExpectations.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('clears the reportedDone flag when reset', function() {
|
||||
const spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
spec.reportedDone = true;
|
||||
|
||||
spec.reset();
|
||||
|
||||
expect(spec.reportedDone).toBeFalse();
|
||||
});
|
||||
|
||||
it('does not throw an ExpectationFailed error when handling an error', function() {
|
||||
const resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
attrs.onComplete();
|
||||
},
|
||||
@@ -418,7 +496,7 @@ describe('Spec', function() {
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
spec.onException('failing exception');
|
||||
spec.handleException('failing exception');
|
||||
});
|
||||
|
||||
it('can return its full name', function() {
|
||||
@@ -483,25 +561,23 @@ describe('Spec', function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException('foo');
|
||||
spec.handleException('foo');
|
||||
spec.execute();
|
||||
|
||||
const args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
args.queueableFns[args.queueableFns.length - 1].fn();
|
||||
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
|
||||
{
|
||||
error: 'foo',
|
||||
message: 'foo thrown',
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: ''
|
||||
actual: '',
|
||||
stack: null
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -511,14 +587,11 @@ describe('Spec', function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: function() {} },
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
resultCallback: resultCallback
|
||||
});
|
||||
|
||||
spec.onException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
spec.handleException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
spec.execute();
|
||||
|
||||
const args = fakeQueueRunner.calls.mostRecent().args[0];
|
||||
@@ -636,7 +709,7 @@ describe('Spec', function() {
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: function(config) {
|
||||
spec.debugLog('msg');
|
||||
spec.onException(new Error('nope'));
|
||||
spec.handleException(new Error('nope'));
|
||||
for (const fn of config.queueableFns) {
|
||||
fn.fn();
|
||||
}
|
||||
|
||||
@@ -106,9 +106,9 @@ describe('SpyStrategy', function() {
|
||||
|
||||
it('allows a fake async function to be called instead', function(done) {
|
||||
const originalFn = jasmine.createSpy('original'),
|
||||
fakeFn = jasmine
|
||||
.createSpy('fake')
|
||||
.and.callFake(eval('async () => { return 67; }')),
|
||||
fakeFn = jasmine.createSpy('fake').and.callFake(async () => {
|
||||
return 67;
|
||||
}),
|
||||
spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: originalFn });
|
||||
|
||||
spyStrategy.callFake(fakeFn);
|
||||
|
||||
@@ -71,20 +71,9 @@ describe('Suite', function() {
|
||||
suite.beforeAll(outerBefore);
|
||||
suite.beforeAll(innerBefore);
|
||||
|
||||
function sameInstance(expected) {
|
||||
return {
|
||||
asymmetricMatch: function(actual) {
|
||||
return actual === expected;
|
||||
},
|
||||
jasmineToString: function() {
|
||||
return `<same instance as ${expected}>`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
expect(suite.beforeAllFns).toEqual([
|
||||
{ fn: outerBefore.fn, type: 'beforeAll', suite: sameInstance(suite) },
|
||||
{ fn: innerBefore.fn, type: 'beforeAll', suite: sameInstance(suite) }
|
||||
{ fn: outerBefore.fn, type: 'beforeAll', suite: jasmine.is(suite) },
|
||||
{ fn: innerBefore.fn, type: 'beforeAll', suite: jasmine.is(suite) }
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -123,13 +112,9 @@ describe('Suite', function() {
|
||||
});
|
||||
|
||||
it('has a status of failed if any expectations have failed', function() {
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function() {
|
||||
return 'hi';
|
||||
}
|
||||
});
|
||||
const suite = new jasmineUnderTest.Suite({});
|
||||
|
||||
suite.addExpectationResult(false);
|
||||
suite.addExpectationResult(false, {});
|
||||
expect(suite.status()).toBe('failed');
|
||||
});
|
||||
|
||||
@@ -148,28 +133,110 @@ describe('Suite', function() {
|
||||
|
||||
it('throws an ExpectationFailed when receiving a failed expectation when throwOnExpectationFailure is set', function() {
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function(data) {
|
||||
return data;
|
||||
},
|
||||
throwOnExpectationFailure: true
|
||||
});
|
||||
|
||||
expect(function() {
|
||||
suite.addExpectationResult(false, 'failed');
|
||||
suite.addExpectationResult(false, { message: 'failed' });
|
||||
}).toThrowError(jasmineUnderTest.errors.ExpectationFailed);
|
||||
|
||||
expect(suite.status()).toBe('failed');
|
||||
expect(suite.result.failedExpectations).toEqual(['failed']);
|
||||
expect(suite.result.failedExpectations).toEqual([
|
||||
jasmine.objectContaining({ message: 'failed' })
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not add an additional failure when an expectation fails', function() {
|
||||
const suite = new jasmineUnderTest.Suite({});
|
||||
|
||||
suite.onException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
suite.handleException(new jasmineUnderTest.errors.ExpectationFailed());
|
||||
|
||||
expect(suite.getResult().failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('forwards late expectation failures to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const suite = new jasmineUnderTest.Suite({ onLateError });
|
||||
const data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: new Error('nope')
|
||||
};
|
||||
|
||||
suite.reportedDone = true;
|
||||
suite.addExpectationResult(false, data, true);
|
||||
|
||||
expect(onLateError).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^Error: nope/)
|
||||
})
|
||||
);
|
||||
expect(suite.result.failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not forward non-late expectation failures to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
onLateError
|
||||
});
|
||||
const data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: new Error('nope')
|
||||
};
|
||||
|
||||
suite.addExpectationResult(false, data, true);
|
||||
|
||||
expect(onLateError).not.toHaveBeenCalled();
|
||||
expect(suite.result.failedExpectations.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('forwards late handleException calls to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
onLateError
|
||||
});
|
||||
const error = new Error('oops');
|
||||
|
||||
suite.reportedDone = true;
|
||||
suite.handleException(error);
|
||||
|
||||
expect(onLateError).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^Error: oops/)
|
||||
})
|
||||
);
|
||||
expect(suite.result.failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it('does not forward non-late handleException calls to onLateError', function() {
|
||||
const onLateError = jasmine.createSpy('onLateError');
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
onLateError
|
||||
});
|
||||
const error = new Error('oops');
|
||||
|
||||
suite.handleException(error);
|
||||
|
||||
expect(onLateError).not.toHaveBeenCalled();
|
||||
expect(suite.result.failedExpectations.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('clears the reportedDone flag when reset', function() {
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
queueableFn: { fn: function() {} }
|
||||
});
|
||||
suite.reportedDone = true;
|
||||
|
||||
suite.reset();
|
||||
|
||||
expect(suite.reportedDone).toBeFalse();
|
||||
});
|
||||
|
||||
it('calls timer to compute duration', function() {
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
env: env,
|
||||
@@ -261,12 +328,8 @@ describe('Suite', function() {
|
||||
});
|
||||
|
||||
it('should reset the failedExpectations', function() {
|
||||
const suite = new jasmineUnderTest.Suite({
|
||||
expectationResultFactory: function(error) {
|
||||
return error;
|
||||
}
|
||||
});
|
||||
suite.onException(new Error());
|
||||
const suite = new jasmineUnderTest.Suite({});
|
||||
suite.handleException(new Error());
|
||||
|
||||
suite.reset();
|
||||
|
||||
|
||||
30
spec/core/asymmetric_equality/IsSpec.js
Normal file
30
spec/core/asymmetric_equality/IsSpec.js
Normal file
@@ -0,0 +1,30 @@
|
||||
describe('Is', function() {
|
||||
it('passes for primitives that are ===', function() {
|
||||
const exactly = new jasmineUnderTest.Is(17);
|
||||
expect(exactly.asymmetricMatch(17)).toBeTrue();
|
||||
});
|
||||
|
||||
it('fails for primitives that are not ===', function() {
|
||||
const exactly = new jasmineUnderTest.Is(42);
|
||||
expect(exactly.asymmetricMatch('42')).toBeFalse();
|
||||
});
|
||||
|
||||
it('passes for the same object instance', function() {
|
||||
const obj = {};
|
||||
const exactly = new jasmineUnderTest.Is(obj);
|
||||
expect(exactly.asymmetricMatch(obj)).toBeTrue();
|
||||
});
|
||||
|
||||
it('fails for different object instances, even if they are deep value equal', function() {
|
||||
const exactly = new jasmineUnderTest.Is({});
|
||||
expect(exactly.asymmetricMatch({})).toBeFalse();
|
||||
});
|
||||
|
||||
it('describes itself for use in diffs and pretty printing', function() {
|
||||
const exactly = new jasmineUnderTest.Is({ foo: ['bar'] });
|
||||
const pp = jasmineUnderTest.basicPrettyPrinter_;
|
||||
expect(exactly.jasmineToString(pp)).toEqual(
|
||||
"<jasmine.is(Object({ foo: [ 'bar' ] }))>"
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -22,56 +22,38 @@ describe('buildExpectationResult', function() {
|
||||
expect(result.message).toBe('some-value');
|
||||
});
|
||||
|
||||
it('delegates message formatting to the provided formatter if there was an Error', function() {
|
||||
const fakeError = { message: 'foo' },
|
||||
messageFormatter = jasmine
|
||||
.createSpy('exception message formatter')
|
||||
.and.returnValue(fakeError.message);
|
||||
describe('When the error property is provided', function() {
|
||||
it('sets the message to the formatted error', function() {
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
error: { message: 'foo', fileName: 'somefile.js' }
|
||||
});
|
||||
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
messageFormatter: messageFormatter
|
||||
expect(result.message).toEqual('foo in somefile.js');
|
||||
});
|
||||
|
||||
expect(messageFormatter).toHaveBeenCalledWith(fakeError);
|
||||
expect(result.message).toEqual('foo');
|
||||
it('delegates stack formatting to the provided formatter', function() {
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
error: { stack: 'foo', extra: 'wombat' }
|
||||
});
|
||||
|
||||
expect(result.stack).toEqual(
|
||||
"error properties: Object({ extra: 'wombat' })\nfoo"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('delegates stack formatting to the provided formatter if there was an Error', function() {
|
||||
const fakeError = { stack: 'foo' },
|
||||
stackFormatter = jasmine
|
||||
.createSpy('stack formatter')
|
||||
.and.returnValue(fakeError.stack);
|
||||
describe('When the errorForStack property is provided', function() {
|
||||
it('builds the stack trace using errorForStack instead of Error', function() {
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
errorForStack: { stack: 'foo' },
|
||||
error: { stack: 'bar' }
|
||||
});
|
||||
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
error: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
expect(result.stack).toEqual('bar');
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError, {
|
||||
omitMessage: true
|
||||
});
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it('delegates stack formatting to the provided formatter if there was a provided errorForStack', function() {
|
||||
const fakeError = { stack: 'foo' },
|
||||
stackFormatter = jasmine
|
||||
.createSpy('stack formatter')
|
||||
.and.returnValue(fakeError.stack);
|
||||
|
||||
const result = jasmineUnderTest.buildExpectationResult({
|
||||
passed: false,
|
||||
errorForStack: fakeError,
|
||||
stackFormatter: stackFormatter
|
||||
});
|
||||
|
||||
expect(stackFormatter).toHaveBeenCalledWith(fakeError, {
|
||||
omitMessage: true
|
||||
});
|
||||
expect(result.stack).toEqual('foo');
|
||||
});
|
||||
|
||||
it('matcherName returns passed matcherName', function() {
|
||||
@@ -1,55 +1,57 @@
|
||||
describe('Asymmetric equality testers (Integration)', function() {
|
||||
function verifyPasses(expectations) {
|
||||
it('passes', function(done) {
|
||||
it('passes', async function() {
|
||||
const env = new jasmineUnderTest.Env();
|
||||
env.it('a spec', function() {
|
||||
expectations(env);
|
||||
});
|
||||
|
||||
const 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();
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
function verifyFails(expectations) {
|
||||
it('fails', function(done) {
|
||||
it('fails', async function() {
|
||||
const env = new jasmineUnderTest.Env();
|
||||
env.it('a spec', function() {
|
||||
expectations(env);
|
||||
});
|
||||
|
||||
const 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('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
|
||||
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('');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
it('allows adding more matchers local to a spec', function(done) {
|
||||
it('allows adding more matchers local to a spec', async function() {
|
||||
env.it('spec defining a custom matcher', function() {
|
||||
env.addMatchers({
|
||||
matcherForSpec: function() {
|
||||
@@ -37,20 +37,18 @@ describe('Custom Matchers (Integration)', function() {
|
||||
});
|
||||
|
||||
const specDoneSpy = jasmine.createSpy('specDoneSpy');
|
||||
const expectations = function() {
|
||||
const firstSpecResult = specDoneSpy.calls.first().args[0];
|
||||
expect(firstSpecResult.status).toEqual('failed');
|
||||
expect(firstSpecResult.failedExpectations[0].message).toEqual(
|
||||
'matcherForSpec: actual: zzz; expected: yyy'
|
||||
);
|
||||
done();
|
||||
};
|
||||
env.addReporter({ specDone: specDoneSpy });
|
||||
|
||||
env.execute(null, expectations);
|
||||
await env.execute();
|
||||
|
||||
const firstSpecResult = specDoneSpy.calls.first().args[0];
|
||||
expect(firstSpecResult.status).toEqual('failed');
|
||||
expect(firstSpecResult.failedExpectations[0].message).toEqual(
|
||||
'matcherForSpec: actual: zzz; expected: yyy'
|
||||
);
|
||||
});
|
||||
|
||||
it('passes the spec if the custom matcher passes', function(done) {
|
||||
it('passes the spec if the custom matcher passes', async function() {
|
||||
env.it('spec using custom matcher', function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
@@ -65,15 +63,16 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(result.status).toEqual('passed');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('passed');
|
||||
});
|
||||
|
||||
it('passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers', function(done) {
|
||||
it('passes the spec if the custom equality matcher passes for types nested inside asymmetric equality testers', async function() {
|
||||
env.it('spec using custom equality matcher', function() {
|
||||
const customEqualityFn = function(a, b) {
|
||||
// All "foo*" strings match each other.
|
||||
@@ -99,15 +98,16 @@ describe('Custom Matchers (Integration)', function() {
|
||||
.toEqual(jasmineUnderTest.arrayWithExactContents(['fooBar']));
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(result.status).toEqual('passed');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('passed');
|
||||
});
|
||||
|
||||
it('displays an appropriate failure message if a custom equality matcher fails', function(done) {
|
||||
it('displays an appropriate failure message if a custom equality matcher fails', async function() {
|
||||
env.it('spec using custom equality matcher', function() {
|
||||
const customEqualityFn = function(a, b) {
|
||||
// "foo" is not equal to anything
|
||||
@@ -120,18 +120,19 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect({ foo: 'foo' }).toEqual({ foo: 'foo' });
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
"Expected $.foo = 'foo' to equal 'foo'."
|
||||
);
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
"Expected $.foo = 'foo' to equal 'foo'."
|
||||
);
|
||||
});
|
||||
|
||||
it('uses the negative compare function for a negative comparison, if provided', function(done) {
|
||||
it('uses the negative compare function for a negative comparison, if provided', async function() {
|
||||
env.it('spec with custom negative comparison matcher', function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
@@ -149,15 +150,16 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect(true).not.toBeReal();
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(result.status).toEqual('passed');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('passed');
|
||||
});
|
||||
|
||||
it('generates messages with the same rules as built in matchers absent a custom message', function(done) {
|
||||
it('generates messages with the same rules as built in matchers absent a custom message', async function() {
|
||||
env.it('spec with an expectation', function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
@@ -172,17 +174,18 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect('a').toBeReal();
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
"Expected 'a' to be real."
|
||||
);
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
"Expected 'a' to be real."
|
||||
);
|
||||
});
|
||||
|
||||
it('passes the expected and actual arguments to the comparison function', function(done) {
|
||||
it('passes the expected and actual arguments to the comparison function', async function() {
|
||||
const argumentSpy = jasmine
|
||||
.createSpy('argument spy')
|
||||
.and.returnValue({ pass: true });
|
||||
@@ -199,17 +202,13 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect(true).toBeReal('arg1', 'arg2');
|
||||
});
|
||||
|
||||
const specExpectations = function() {
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true);
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg');
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg1', 'arg2');
|
||||
};
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
await env.execute();
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true);
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg');
|
||||
expect(argumentSpy).toHaveBeenCalledWith(true, 'arg1', 'arg2');
|
||||
});
|
||||
|
||||
it('passes the jasmine utility to the matcher factory', function(done) {
|
||||
it('passes the jasmine utility to the matcher factory', async function() {
|
||||
const matcherFactory = function() {
|
||||
return {
|
||||
compare: function() {
|
||||
@@ -229,17 +228,13 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
const specExpectations = function() {
|
||||
expect(matcherFactorySpy).toHaveBeenCalledWith(
|
||||
jasmine.any(jasmineUnderTest.MatchersUtil)
|
||||
);
|
||||
};
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
await env.execute();
|
||||
expect(matcherFactorySpy).toHaveBeenCalledWith(
|
||||
jasmine.any(jasmineUnderTest.MatchersUtil)
|
||||
);
|
||||
});
|
||||
|
||||
it('provides custom equality testers to the matcher factory via matchersUtil', function(done) {
|
||||
it('provides custom equality testers to the matcher factory via matchersUtil', async function() {
|
||||
const matcherFactory = function(matchersUtil) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
@@ -262,12 +257,13 @@ describe('Custom Matchers (Integration)', function() {
|
||||
env.expect([1, 2]).toBeArrayWithFirstElement('1');
|
||||
});
|
||||
|
||||
const specExpectations = function(result) {
|
||||
expect(customEqualityFn).toHaveBeenCalledWith(1, '1');
|
||||
expect(result.failedExpectations).toEqual([]);
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(customEqualityFn).toHaveBeenCalledWith(1, '1');
|
||||
expect(result.failedExpectations).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('Custom object formatters', function() {
|
||||
env.configure({ random: false });
|
||||
});
|
||||
|
||||
it('scopes custom object formatters to a spec', function(done) {
|
||||
it('scopes custom object formatters to a spec', async function() {
|
||||
env.it('a spec with custom pretty-printer', function() {
|
||||
env.addCustomObjectFormatter(function(obj) {
|
||||
return 'custom(' + obj + ')';
|
||||
@@ -22,21 +22,19 @@ describe('Custom object formatters', function() {
|
||||
const specDone = function(result) {
|
||||
specResults.push(result);
|
||||
};
|
||||
const 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 });
|
||||
|
||||
env.execute(null, expectations);
|
||||
await env.execute();
|
||||
|
||||
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.'
|
||||
);
|
||||
});
|
||||
|
||||
it('scopes custom object formatters to a suite', function(done) {
|
||||
it('scopes custom object formatters to a suite', async function() {
|
||||
env.it('a spec without custom pretty-printer', function() {
|
||||
env.expect(42).toBeUndefined();
|
||||
});
|
||||
@@ -57,18 +55,16 @@ describe('Custom object formatters', function() {
|
||||
const specDone = function(result) {
|
||||
specResults.push(result);
|
||||
};
|
||||
const 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 });
|
||||
|
||||
env.execute(null, expectations);
|
||||
await env.execute();
|
||||
|
||||
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.'
|
||||
);
|
||||
});
|
||||
|
||||
it('throws an exception if you try to add a custom object formatter outside a runable', function() {
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('Deprecation (integration)', function() {
|
||||
env.cleanup_();
|
||||
});
|
||||
|
||||
it('reports a deprecation on the top suite', function(done) {
|
||||
it('reports a deprecation on the top suite', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -20,24 +20,23 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
env.it('a spec', function() {});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
});
|
||||
|
||||
it('reports a deprecation on a descendent suite', function(done) {
|
||||
it('reports a deprecation on a descendent suite', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['suiteDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -49,26 +48,23 @@ describe('Deprecation (integration)', function() {
|
||||
env.it('a spec', function() {});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message \(in suite: a suite\)/)
|
||||
);
|
||||
});
|
||||
|
||||
it('reports a deprecation on a spec', function(done) {
|
||||
it('reports a deprecation on a spec', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -79,26 +75,25 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('omits the suite or spec context when ignoreRunnable is true', function(done) {
|
||||
it('omits the suite or spec context when ignoreRunnable is true', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -107,27 +102,26 @@ describe('Deprecation (integration)', function() {
|
||||
env.deprecated('the message', { ignoreRunnable: true });
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/the message/)
|
||||
);
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/a spec/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/the message/)
|
||||
);
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/a spec/)
|
||||
);
|
||||
});
|
||||
|
||||
it('includes the stack trace', function(done) {
|
||||
it('includes the stack trace', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -138,25 +132,24 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error.calls.argsFor(0)[0].replace(/\n/g, 'NL')).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)NL.*DeprecationSpec.js/
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error.calls.argsFor(0)[0].replace(/\n/g, 'NL')).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)NL.*DeprecationSpec.js/
|
||||
);
|
||||
});
|
||||
|
||||
it('excludes the stack trace when omitStackTrace is true', function(done) {
|
||||
it('excludes the stack trace when omitStackTrace is true', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -167,25 +160,24 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.falsy()
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
stack: jasmine.falsy()
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalled();
|
||||
expect(console.error).not.toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/DeprecationSpec.js/)
|
||||
);
|
||||
});
|
||||
|
||||
it('emits a given deprecation only once', function(done) {
|
||||
it('emits a given deprecation only once', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', [
|
||||
'specDone',
|
||||
'suiteDone'
|
||||
@@ -205,43 +197,40 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only the other one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^a different message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(2);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
)
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: a different message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
// only the other one
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^a different message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(2);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message \(in suite: a suite\)/)
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(
|
||||
/^DEPRECATION: a different message \(in spec: a suite a spec\)/
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('emits a given deprecation each time when config.verboseDeprecations is true', function(done) {
|
||||
it('emits a given deprecation each time when config.verboseDeprecations is true', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', [
|
||||
'specDone',
|
||||
'suiteDone'
|
||||
@@ -262,46 +251,45 @@ describe('Deprecation (integration)', function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
}),
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(3);
|
||||
expect(console.error.calls.argsFor(0)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(1)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
}),
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledTimes(3);
|
||||
expect(console.error.calls.argsFor(0)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(1)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in suite: a suite\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
expect(console.error.calls.argsFor(2)[0]).toMatch(
|
||||
/^DEPRECATION: the message \(in spec: a suite a spec\)/
|
||||
);
|
||||
});
|
||||
|
||||
it('handles deprecations that occur before execute() is called', function(done) {
|
||||
it('handles deprecations that occur before execute() is called', async function() {
|
||||
const reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
spyOn(console, 'error');
|
||||
@@ -309,20 +297,19 @@ describe('Deprecation (integration)', function() {
|
||||
env.deprecated('the message');
|
||||
env.it('a spec', function() {});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringMatching(/^the message/)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.stringMatching(/^DEPRECATION: the message/)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -454,55 +454,319 @@ describe('Env integration', function() {
|
||||
env.execute(null, assertions);
|
||||
});
|
||||
|
||||
it('copes with async failures after done has been called', function(done) {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn, delay) {
|
||||
clearTimeout(fn, delay);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'suiteDone'
|
||||
]);
|
||||
describe('Handling async errors', function() {
|
||||
it('routes async errors to a running spec', async function() {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn, delay) {
|
||||
clearTimeout(fn, delay);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'suiteDone'
|
||||
]);
|
||||
|
||||
const assertions = function() {
|
||||
expect(reporter.specDone).not.toHaveFailedExpectationsForRunnable(
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('A suite', function() {
|
||||
env.it('fails', function(specDone) {
|
||||
setTimeout(function() {
|
||||
global.onerror('fail');
|
||||
specDone();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.specDone).toHaveFailedExpectationsForRunnable(
|
||||
'A suite fails',
|
||||
['fail thrown']
|
||||
);
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable(
|
||||
'A suite',
|
||||
['fail thrown']
|
||||
);
|
||||
done();
|
||||
};
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
describe('When the running spec has reported specDone', function() {
|
||||
it('routes async errors to an ancestor suite', async function() {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn) {
|
||||
clearTimeout(fn);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
|
||||
env.fdescribe('A suite', function() {
|
||||
env.it('fails', function(specDone) {
|
||||
setTimeout(function() {
|
||||
specDone();
|
||||
const realClearStack = jasmineUnderTest.getClearStack(global);
|
||||
const clearStackCallbacks = {};
|
||||
let clearStackCallCount = 0;
|
||||
spyOn(jasmineUnderTest, 'getClearStack').and.returnValue(function(fn) {
|
||||
clearStackCallCount++;
|
||||
|
||||
if (clearStackCallbacks[clearStackCallCount]) {
|
||||
clearStackCallbacks[clearStackCallCount]();
|
||||
}
|
||||
|
||||
realClearStack(fn);
|
||||
});
|
||||
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
let suiteErrors = [];
|
||||
env.addReporter({
|
||||
suiteDone: function(result) {
|
||||
const messages = result.failedExpectations.map(e => e.message);
|
||||
suiteErrors = suiteErrors.concat(messages);
|
||||
},
|
||||
specDone: function() {
|
||||
clearStackCallbacks[clearStackCallCount + 1] = function() {
|
||||
global.onerror('fail at the end of the reporter queue');
|
||||
};
|
||||
clearStackCallbacks[clearStackCallCount + 2] = function() {
|
||||
global.onerror('fail at the end of the spec queue');
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
env.describe('A suite', function() {
|
||||
env.it('is finishing when the failure occurs', function() {});
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
|
||||
expect(suiteErrors).toEqual([
|
||||
'fail at the end of the reporter queue thrown',
|
||||
'fail at the end of the spec queue thrown'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('routes async errors to a running suite', function(done) {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn, delay) {
|
||||
clearTimeout(fn, delay);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'suiteDone'
|
||||
]);
|
||||
|
||||
const assertions = function() {
|
||||
expect(reporter.specDone).not.toHaveFailedExpectationsForRunnable(
|
||||
'A suite fails',
|
||||
['fail thrown']
|
||||
);
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable(
|
||||
'A suite',
|
||||
['fail thrown']
|
||||
);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.fdescribe('A suite', function() {
|
||||
env.it('fails', function(specDone) {
|
||||
setTimeout(function() {
|
||||
specDone();
|
||||
setTimeout(function() {
|
||||
global.onerror('fail');
|
||||
setTimeout(function() {
|
||||
global.onerror('fail');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('Ignored', function() {
|
||||
env.it('is not run', function() {});
|
||||
});
|
||||
|
||||
env.execute(null, assertions);
|
||||
});
|
||||
|
||||
env.describe('Ignored', function() {
|
||||
env.it('is not run', function() {});
|
||||
describe('When the running suite has reported suiteDone', function() {
|
||||
it('routes async errors to an ancestor suite', async function() {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn, delay) {
|
||||
clearTimeout(fn, delay);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
|
||||
const realClearStack = jasmineUnderTest.getClearStack(global);
|
||||
const clearStackCallbacks = {};
|
||||
let clearStackCallCount = 0;
|
||||
spyOn(jasmineUnderTest, 'getClearStack').and.returnValue(function(fn) {
|
||||
clearStackCallCount++;
|
||||
|
||||
if (clearStackCallbacks[clearStackCallCount]) {
|
||||
clearStackCallbacks[clearStackCallCount]();
|
||||
}
|
||||
|
||||
realClearStack(fn);
|
||||
});
|
||||
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
let suiteErrors = [];
|
||||
env.addReporter({
|
||||
suiteDone: function(result) {
|
||||
const messages = result.failedExpectations.map(e => e.message);
|
||||
suiteErrors = suiteErrors.concat(messages);
|
||||
|
||||
if (result.description === 'A nested suite') {
|
||||
clearStackCallbacks[clearStackCallCount + 1] = function() {
|
||||
global.onerror('fail at the end of the reporter queue');
|
||||
};
|
||||
clearStackCallbacks[clearStackCallCount + 2] = function() {
|
||||
global.onerror('fail at the end of the suite queue');
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
env.describe('A suite', function() {
|
||||
env.describe('A nested suite', function() {
|
||||
env.it('a spec', function() {});
|
||||
});
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
|
||||
expect(suiteErrors).toEqual([
|
||||
'fail at the end of the reporter queue thrown',
|
||||
'fail at the end of the suite queue thrown'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, assertions);
|
||||
describe('When the env has started reporting jasmineDone', function() {
|
||||
it('logs the error to the console', async function() {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn, delay) {
|
||||
clearTimeout(fn, delay);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
global.onerror('a very late error');
|
||||
}
|
||||
});
|
||||
|
||||
env.it('a spec', function() {});
|
||||
|
||||
await env.execute();
|
||||
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
'Jasmine received a result after the suite finished:'
|
||||
);
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
message: 'a very late error thrown',
|
||||
globalErrorType: 'afterAll'
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('routes all errors that occur during stack clearing somewhere', async function() {
|
||||
const global = {
|
||||
setTimeout: function(fn, delay) {
|
||||
return setTimeout(fn, delay);
|
||||
},
|
||||
clearTimeout: function(fn) {
|
||||
clearTimeout(fn);
|
||||
}
|
||||
};
|
||||
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
|
||||
|
||||
const realClearStack = jasmineUnderTest.getClearStack(global);
|
||||
let clearStackCallCount = 0;
|
||||
let jasmineDone = false;
|
||||
const expectedErrors = [];
|
||||
const expectedErrorsAfterJasmineDone = [];
|
||||
spyOn(jasmineUnderTest, 'getClearStack').and.returnValue(function(fn) {
|
||||
clearStackCallCount++;
|
||||
const msg = `Error in clearStack #${clearStackCallCount}`;
|
||||
|
||||
if (jasmineDone) {
|
||||
expectedErrorsAfterJasmineDone.push(`${msg} thrown`);
|
||||
} else {
|
||||
expectedErrors.push(`${msg} thrown`);
|
||||
}
|
||||
|
||||
global.onerror(msg);
|
||||
realClearStack(fn);
|
||||
});
|
||||
spyOn(console, 'error');
|
||||
|
||||
env.cleanup_();
|
||||
env = new jasmineUnderTest.Env();
|
||||
|
||||
const receivedErrors = [];
|
||||
function logErrors(event) {
|
||||
for (const failure of event.failedExpectations) {
|
||||
receivedErrors.push(failure.message);
|
||||
}
|
||||
}
|
||||
env.addReporter({
|
||||
specDone: logErrors,
|
||||
suiteDone: logErrors,
|
||||
jasmineDone: function(event) {
|
||||
jasmineDone = true;
|
||||
logErrors(event);
|
||||
}
|
||||
});
|
||||
|
||||
env.describe('A suite', function() {
|
||||
env.it('is finishing when the failure occurs', function() {});
|
||||
});
|
||||
|
||||
await env.execute();
|
||||
|
||||
expect(receivedErrors.length).toEqual(expectedErrors.length);
|
||||
|
||||
for (const e of expectedErrors) {
|
||||
expect(receivedErrors).toContain(e);
|
||||
}
|
||||
|
||||
for (const message of expectedErrorsAfterJasmineDone) {
|
||||
/* eslint-disable-next-line no-console */
|
||||
expect(console.error).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({ message })
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('reports multiple calls to done in the top suite as errors', function(done) {
|
||||
@@ -539,11 +803,18 @@ describe('Env integration', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('reports multiple calls to done in a non-top suite as errors', function(done) {
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
|
||||
it('reports multiple calls to done in a non-top suite as errors', async function() {
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'jasmineDone',
|
||||
'suiteDone'
|
||||
]);
|
||||
const message =
|
||||
"An asynchronous beforeAll or afterAll function called its 'done' " +
|
||||
'callback more than once.\n(in suite: a suite)';
|
||||
let lateDone;
|
||||
reporter.suiteDone.and.callFake(function() {
|
||||
lateDone();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
env.describe('a suite', function() {
|
||||
@@ -555,31 +826,50 @@ describe('Env integration', function() {
|
||||
env.afterAll(function(innerDone) {
|
||||
innerDone();
|
||||
innerDone();
|
||||
lateDone = innerDone;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(errors.length).toEqual(2);
|
||||
expect(errors[0].message)
|
||||
.withContext('suite beforeAll')
|
||||
.toContain(message);
|
||||
expect(errors[0].globalErrorType).toEqual('lateError');
|
||||
expect(errors[1].message)
|
||||
.withContext('suite afterAll')
|
||||
.toContain(message);
|
||||
expect(errors[1].globalErrorType).toEqual('lateError');
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.suiteDone).toHaveBeenCalled();
|
||||
const suiteErrors = reporter.suiteDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(suiteErrors.length).toEqual(2);
|
||||
expect(suiteErrors[0].message)
|
||||
.withContext('suite beforeAll')
|
||||
.toContain(message);
|
||||
expect(suiteErrors[1].message)
|
||||
.withContext('suite afterAll')
|
||||
.toContain(message);
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
const topErrors = reporter.jasmineDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(topErrors.length).toEqual(1);
|
||||
expect(topErrors[0].message)
|
||||
.withContext('late suite afterAll')
|
||||
.toContain(message);
|
||||
expect(topErrors[0].globalErrorType).toEqual('lateError');
|
||||
expect(topErrors[0].globalErrorType).toEqual('lateError');
|
||||
});
|
||||
|
||||
it('reports multiple calls to done in a spec as errors', function(done) {
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
|
||||
it('reports multiple calls to done in a spec as errors', async function() {
|
||||
const reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
'specDone',
|
||||
'suiteDone',
|
||||
'jasmineDone'
|
||||
]);
|
||||
const message =
|
||||
'An asynchronous spec, beforeEach, or afterEach function called its ' +
|
||||
"'done' callback more than once.\n(in spec: a suite a spec)";
|
||||
let lateDone;
|
||||
reporter.specDone.and.callFake(function() {
|
||||
lateDone();
|
||||
});
|
||||
reporter.suiteDone.and.callFake(function() {
|
||||
lateDone();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
env.describe('a suite', function() {
|
||||
@@ -594,28 +884,39 @@ describe('Env integration', function() {
|
||||
env.afterEach(function(innerDone) {
|
||||
innerDone();
|
||||
innerDone();
|
||||
lateDone = innerDone;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute(null, function() {
|
||||
expect(reporter.jasmineDone).toHaveBeenCalled();
|
||||
const errors = reporter.jasmineDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(errors.length).toEqual(3);
|
||||
expect(errors[0].message)
|
||||
.withContext('error caused by beforeEach')
|
||||
.toContain(message);
|
||||
expect(errors[0].globalErrorType).toEqual('lateError');
|
||||
expect(errors[1].message)
|
||||
.withContext('error caused by it')
|
||||
.toContain(message);
|
||||
expect(errors[1].globalErrorType).toEqual('lateError');
|
||||
expect(errors[2].message)
|
||||
.withContext('error caused by afterEach')
|
||||
.toContain(message);
|
||||
expect(errors[2].globalErrorType).toEqual('lateError');
|
||||
done();
|
||||
});
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.specDone).toHaveBeenCalled();
|
||||
const specErrors = reporter.specDone.calls.argsFor(0)[0].failedExpectations;
|
||||
expect(specErrors.length).toEqual(3);
|
||||
expect(specErrors[0].message)
|
||||
.withContext('error caused by beforeEach')
|
||||
.toContain(message);
|
||||
expect(specErrors[1].message)
|
||||
.withContext('error caused by it')
|
||||
.toContain(message);
|
||||
expect(specErrors[2].message)
|
||||
.withContext('error caused by afterEach')
|
||||
.toContain(message);
|
||||
|
||||
const suiteErrors = reporter.suiteDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(suiteErrors.length).toEqual(1);
|
||||
expect(suiteErrors[0].message)
|
||||
.withContext('late error caused by afterEach')
|
||||
.toContain(message);
|
||||
|
||||
const topErrors = reporter.jasmineDone.calls.argsFor(0)[0]
|
||||
.failedExpectations;
|
||||
expect(topErrors.length).toEqual(1);
|
||||
expect(topErrors[0].message)
|
||||
.withContext('really late error caused by afterEach')
|
||||
.toContain(message);
|
||||
expect(topErrors[0].globalErrorType).toEqual('lateError');
|
||||
});
|
||||
|
||||
it('reports multiple calls to done in reporters as errors', function(done) {
|
||||
@@ -1320,7 +1621,7 @@ describe('Env integration', function() {
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = 5;
|
||||
jasmineUnderTest.DEFAULT_TIMEOUT_INTERVAL = 500;
|
||||
|
||||
env.beforeAll(function() {
|
||||
clock.install();
|
||||
@@ -1331,7 +1632,7 @@ describe('Env integration', function() {
|
||||
});
|
||||
|
||||
env.it('spec that should not time out', function(innerDone) {
|
||||
clock.tick(6);
|
||||
clock.tick(1000);
|
||||
expect(true).toEqual(true);
|
||||
jasmine.debugLog('Calling realSetTimeout in spec');
|
||||
realSetTimeout(function() {
|
||||
|
||||
@@ -10,156 +10,158 @@ describe('Matchers (Integration)', function() {
|
||||
});
|
||||
|
||||
function verifyPasses(expectations) {
|
||||
it('passes', function(done) {
|
||||
it('passes', async function() {
|
||||
env.it('a spec', function() {
|
||||
expectations(env);
|
||||
});
|
||||
|
||||
const 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();
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
function verifyFails(expectations) {
|
||||
it('fails', function(done) {
|
||||
it('fails', async function() {
|
||||
env.it('a spec', function() {
|
||||
expectations(env);
|
||||
});
|
||||
|
||||
const 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].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('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
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].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('');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyFailsWithCustomObjectFormatters(config) {
|
||||
it('uses custom object formatters', function(done) {
|
||||
it('uses custom object formatters', async function() {
|
||||
env.it('a spec', function() {
|
||||
env.addCustomObjectFormatter(config.formatter);
|
||||
config.expectations(env);
|
||||
});
|
||||
|
||||
const 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
|
||||
);
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations.length)
|
||||
.withContext('Number of failed expectations')
|
||||
.toEqual(1);
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
config.expectedMessage
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function verifyPassesAsync(expectations) {
|
||||
it('passes', function(done) {
|
||||
it('passes', async function() {
|
||||
env.it('a spec', function() {
|
||||
return expectations(env);
|
||||
});
|
||||
|
||||
const 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();
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
function verifyFailsAsync(expectations) {
|
||||
it('fails', function(done) {
|
||||
it('fails', async function() {
|
||||
env.it('a spec', function() {
|
||||
return expectations(env);
|
||||
});
|
||||
|
||||
const 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('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
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('');
|
||||
});
|
||||
}
|
||||
|
||||
function verifyFailsWithCustomObjectFormattersAsync(config) {
|
||||
it('uses custom object formatters', function(done) {
|
||||
it('uses custom object formatters', async function() {
|
||||
const env = new jasmineUnderTest.Env();
|
||||
env.it('a spec', function() {
|
||||
env.addCustomObjectFormatter(config.formatter);
|
||||
return config.expectations(env);
|
||||
});
|
||||
|
||||
const 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
|
||||
);
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations.length)
|
||||
.withContext('Number of failed expectations')
|
||||
.toEqual(1);
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
config.expectedMessage
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -753,76 +755,79 @@ describe('Matchers (Integration)', function() {
|
||||
});
|
||||
|
||||
describe('When an async matcher is used with .already()', function() {
|
||||
it('propagates the matcher result when the promise is resolved', function(done) {
|
||||
it('propagates the matcher result when the promise is resolved', async function() {
|
||||
env.it('a spec', function() {
|
||||
return env.expectAsync(Promise.resolve()).already.toBeRejected();
|
||||
});
|
||||
|
||||
const 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(
|
||||
'Expected [object Promise] to be rejected.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations.length)
|
||||
.withContext('Number of failed expectations')
|
||||
.toEqual(1);
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
'Expected [object Promise] to be rejected.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
});
|
||||
|
||||
it('propagates the matcher result when the promise is rejected', function(done) {
|
||||
it('propagates the matcher result when the promise is rejected', async function() {
|
||||
env.it('a spec', function() {
|
||||
return env
|
||||
.expectAsync(Promise.reject(new Error('nope')))
|
||||
.already.toBeResolved();
|
||||
});
|
||||
|
||||
const 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(
|
||||
'Expected a promise to be resolved but it was ' +
|
||||
'rejected with Error: nope.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations.length)
|
||||
.withContext('Number of failed expectations')
|
||||
.toEqual(1);
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
'Expected a promise to be resolved but it was ' +
|
||||
'rejected with Error: nope.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
});
|
||||
|
||||
it('fails when the promise is pending', function(done) {
|
||||
it('fails when the promise is pending', async function() {
|
||||
const promise = new Promise(function() {});
|
||||
|
||||
env.it('a spec', function() {
|
||||
return env.expectAsync(promise).already.toBeResolved();
|
||||
});
|
||||
|
||||
const 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(
|
||||
'Expected a promise to be settled ' +
|
||||
'(via expectAsync(...).already) but it was pending.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
};
|
||||
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||
env.addReporter(reporter);
|
||||
await env.execute();
|
||||
|
||||
env.addReporter({ specDone: specExpectations });
|
||||
env.execute(null, done);
|
||||
expect(reporter.specDone).toHaveBeenCalledTimes(1);
|
||||
const result = reporter.specDone.calls.argsFor(0)[0];
|
||||
expect(result.status).toEqual('failed');
|
||||
expect(result.failedExpectations.length)
|
||||
.withContext('Number of failed expectations')
|
||||
.toEqual(1);
|
||||
expect(result.failedExpectations[0].message).toEqual(
|
||||
'Expected a promise to be settled ' +
|
||||
'(via expectAsync(...).already) but it was pending.'
|
||||
);
|
||||
expect(result.failedExpectations[0].matcherName)
|
||||
.withContext('Matcher name')
|
||||
.not.toEqual('');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('DiffBuilder', function() {
|
||||
it('records the actual and expected objects', function() {
|
||||
const diffBuilder = jasmineUnderTest.DiffBuilder();
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder();
|
||||
diffBuilder.setRoots({ x: 'actual' }, { x: 'expected' });
|
||||
diffBuilder.recordMismatch();
|
||||
|
||||
@@ -10,7 +10,7 @@ describe('DiffBuilder', function() {
|
||||
});
|
||||
|
||||
it('prints the path at which the difference was found', function() {
|
||||
const diffBuilder = jasmineUnderTest.DiffBuilder();
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder();
|
||||
diffBuilder.setRoots({ foo: { x: 'actual' } }, { foo: { x: 'expected' } });
|
||||
|
||||
diffBuilder.withPath('foo', function() {
|
||||
@@ -23,7 +23,7 @@ describe('DiffBuilder', function() {
|
||||
});
|
||||
|
||||
it('prints multiple messages, separated by newlines', function() {
|
||||
const diffBuilder = jasmineUnderTest.DiffBuilder();
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder();
|
||||
diffBuilder.setRoots({ foo: 1, bar: 3 }, { foo: 2, bar: 4 });
|
||||
|
||||
diffBuilder.withPath('foo', function() {
|
||||
@@ -40,7 +40,7 @@ describe('DiffBuilder', function() {
|
||||
});
|
||||
|
||||
it('allows customization of the message', function() {
|
||||
const diffBuilder = jasmineUnderTest.DiffBuilder();
|
||||
const diffBuilder = new jasmineUnderTest.DiffBuilder();
|
||||
diffBuilder.setRoots({ x: 'bar' }, { x: 'foo' });
|
||||
|
||||
function darthVaderFormatter(actual, expected, path) {
|
||||
@@ -68,7 +68,7 @@ describe('DiffBuilder', function() {
|
||||
const prettyPrinter = function(val) {
|
||||
return '|' + val + '|';
|
||||
},
|
||||
diffBuilder = jasmineUnderTest.DiffBuilder({
|
||||
diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
prettyPrinter: prettyPrinter
|
||||
});
|
||||
prettyPrinter.customFormat_ = function() {};
|
||||
@@ -86,7 +86,7 @@ describe('DiffBuilder', function() {
|
||||
it('passes the injected pretty-printer to the diff formatter', function() {
|
||||
const diffFormatter = jasmine.createSpy('diffFormatter'),
|
||||
prettyPrinter = function() {},
|
||||
diffBuilder = jasmineUnderTest.DiffBuilder({
|
||||
diffBuilder = new jasmineUnderTest.DiffBuilder({
|
||||
prettyPrinter: prettyPrinter
|
||||
});
|
||||
prettyPrinter.customFormat_ = function() {};
|
||||
|
||||
@@ -104,7 +104,9 @@ describe('toBeInstanceOf', function() {
|
||||
});
|
||||
|
||||
it('passes for an async function', function() {
|
||||
const fn = eval("(async function fn() { return 'foo'; })");
|
||||
async function fn() {
|
||||
return 'foo';
|
||||
}
|
||||
|
||||
const matcher = jasmineUnderTest.matchers.toBeInstanceOf();
|
||||
const result = matcher.compare(fn, Function);
|
||||
|
||||
@@ -24,11 +24,10 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
) {
|
||||
var f;
|
||||
if (typeof funcToCall === 'string') {
|
||||
/* jshint evil: true */
|
||||
f = function() {
|
||||
// eslint-disable-next-line no-eval
|
||||
return eval(funcToCall);
|
||||
};
|
||||
/* jshint evil: false */
|
||||
} else {
|
||||
f = funcToCall;
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
var expectationFactory = function(actual, spec) {
|
||||
const expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.factory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
@@ -342,16 +342,21 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: Unify recordLateError with recordLateExpectation? The extra
|
||||
// diagnostic info added by the latter is probably useful in most cases.
|
||||
function recordLateError(error) {
|
||||
const result = expectationResultFactory({
|
||||
error,
|
||||
passed: false,
|
||||
matcherName: '',
|
||||
expected: '',
|
||||
actual: ''
|
||||
});
|
||||
result.globalErrorType = 'lateError';
|
||||
topSuite.result.failedExpectations.push(result);
|
||||
const isExpectationResult =
|
||||
error.matcherName !== undefined && error.passed !== undefined;
|
||||
const result = isExpectationResult
|
||||
? error
|
||||
: j$.buildExpectationResult({
|
||||
error,
|
||||
passed: false,
|
||||
matcherName: '',
|
||||
expected: '',
|
||||
actual: ''
|
||||
});
|
||||
routeLateFailure(result);
|
||||
}
|
||||
|
||||
function recordLateExpectation(runable, runableType, result) {
|
||||
@@ -382,7 +387,27 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
topSuite.result.failedExpectations.push(delayedExpectationResult);
|
||||
}
|
||||
|
||||
var asyncExpectationFactory = function(actual, spec, runableType) {
|
||||
function routeLateFailure(expectationResult) {
|
||||
// Report the result on the nearest ancestor suite that hasn't already
|
||||
// been reported done.
|
||||
for (let r = currentRunnable(); r; r = r.parentSuite) {
|
||||
if (!r.reportedDone) {
|
||||
if (r === topSuite) {
|
||||
expectationResult.globalErrorType = 'lateError';
|
||||
}
|
||||
|
||||
r.result.failedExpectations.push(expectationResult);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, all results have been reported and there's nothing we
|
||||
// can do except log the result and hope the user sees it.
|
||||
console.error('Jasmine received a result after the suite finished:');
|
||||
console.error(expectationResult);
|
||||
}
|
||||
|
||||
const asyncExpectationFactory = function(actual, spec, runableType) {
|
||||
return j$.Expectation.asyncFactory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,
|
||||
@@ -397,11 +422,11 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spec.addExpectationResult(passed, result);
|
||||
}
|
||||
};
|
||||
var suiteAsyncExpectationFactory = function(actual, suite) {
|
||||
const suiteAsyncExpectationFactory = function(actual, suite) {
|
||||
return asyncExpectationFactory(actual, suite, 'Suite');
|
||||
};
|
||||
|
||||
var specAsyncExpectationFactory = function(actual, suite) {
|
||||
const specAsyncExpectationFactory = function(actual, suite) {
|
||||
return asyncExpectationFactory(actual, suite, 'Spec');
|
||||
};
|
||||
|
||||
@@ -474,16 +499,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return fullName.join(' ');
|
||||
};
|
||||
|
||||
// TODO: we may just be able to pass in the fn instead of wrapping here
|
||||
var buildExpectationResult = j$.buildExpectationResult,
|
||||
exceptionFormatter = new j$.ExceptionFormatter(),
|
||||
expectationResultFactory = function(attrs) {
|
||||
attrs.messageFormatter = exceptionFormatter.message;
|
||||
attrs.stackFormatter = exceptionFormatter.stack;
|
||||
|
||||
return buildExpectationResult(attrs);
|
||||
};
|
||||
|
||||
/**
|
||||
* Causes a deprecation warning to be logged to the console and reported to
|
||||
* reporters.
|
||||
@@ -537,7 +552,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
options.onException =
|
||||
options.onException ||
|
||||
function(e) {
|
||||
(currentRunnable() || topSuite).onException(e);
|
||||
(currentRunnable() || topSuite).handleException(e);
|
||||
};
|
||||
options.deprecated = self.deprecated;
|
||||
|
||||
@@ -549,7 +564,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
expectationFactory: expectationFactory,
|
||||
asyncExpectationFactory: suiteAsyncExpectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
autoCleanClosures: config.autoCleanClosures,
|
||||
onLateError: recordLateError
|
||||
});
|
||||
@@ -722,10 +736,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (suite.hadBeforeAllFailure) {
|
||||
reportChildrenOfBeforeAllFailure(suite).then(function() {
|
||||
reporter.suiteDone(result, next);
|
||||
reportSuiteDone(suite, result, next);
|
||||
});
|
||||
} else {
|
||||
reporter.suiteDone(result, next);
|
||||
reportSuiteDone(suite, result, next);
|
||||
}
|
||||
},
|
||||
orderChildren: function(node) {
|
||||
@@ -815,6 +829,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
failedExpectations: topSuite.result.failedExpectations,
|
||||
deprecationWarnings: topSuite.result.deprecationWarnings
|
||||
};
|
||||
topSuite.reportedDone = true;
|
||||
reporter.jasmineDone(jasmineDoneInfo, function() {
|
||||
done(jasmineDoneInfo);
|
||||
});
|
||||
@@ -859,7 +874,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
child.result.status = 'failed';
|
||||
|
||||
await new Promise(function(resolve) {
|
||||
reporter.specDone(child.result, resolve);
|
||||
reportSpecDone(child, child.result, resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1007,7 +1022,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
timer: new j$.Timer(),
|
||||
expectationFactory: expectationFactory,
|
||||
asyncExpectationFactory: suiteAsyncExpectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
throwOnExpectationFailure: config.stopSpecOnExpectationFailure,
|
||||
autoCleanClosures: config.autoCleanClosures,
|
||||
onLateError: recordLateError
|
||||
@@ -1073,7 +1087,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
suite.onException(declarationError);
|
||||
suite.handleException(declarationError);
|
||||
}
|
||||
|
||||
currentDeclarationSuite = parentSuite;
|
||||
@@ -1116,7 +1130,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
},
|
||||
onStart: specStarted,
|
||||
description: description,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
userContext: function() {
|
||||
return suite.clonedSharedUserContext();
|
||||
@@ -1139,7 +1152,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
hasFailures = true;
|
||||
}
|
||||
|
||||
reporter.specDone(result, next);
|
||||
reportSpecDone(spec, result, next);
|
||||
}
|
||||
|
||||
function specStarted(spec, next) {
|
||||
@@ -1149,6 +1162,16 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
function reportSpecDone(spec, result, next) {
|
||||
spec.reportedDone = true;
|
||||
reporter.specDone(result, next);
|
||||
}
|
||||
|
||||
function reportSuiteDone(suite, result, next) {
|
||||
suite.reportedDone = true;
|
||||
reporter.suiteDone(result, next);
|
||||
}
|
||||
|
||||
this.it_ = function(description, fn, timeout) {
|
||||
ensureIsNotNested('it');
|
||||
// it() sometimes doesn't have a fn argument, so only check the type if
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
var ignoredProperties = [
|
||||
const ignoredProperties = [
|
||||
'name',
|
||||
'message',
|
||||
'stack',
|
||||
@@ -13,9 +13,10 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
];
|
||||
|
||||
function ExceptionFormatter(options) {
|
||||
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
const jasmineFile =
|
||||
(options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
this.message = function(error) {
|
||||
var message = '';
|
||||
let message = '';
|
||||
|
||||
if (error.jasmineMessage) {
|
||||
message += error.jasmineMessage;
|
||||
@@ -43,9 +44,9 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var stackTrace = new j$.StackTrace(error);
|
||||
var lines = filterJasmine(stackTrace);
|
||||
var result = '';
|
||||
const stackTrace = new j$.StackTrace(error);
|
||||
const lines = filterJasmine(stackTrace);
|
||||
let result = '';
|
||||
|
||||
if (stackTrace.message && !omitMessage) {
|
||||
lines.unshift(stackTrace.message);
|
||||
@@ -58,9 +59,9 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
};
|
||||
|
||||
function filterJasmine(stackTrace) {
|
||||
var result = [],
|
||||
jasmineMarker =
|
||||
stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
|
||||
const result = [];
|
||||
const jasmineMarker =
|
||||
stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
|
||||
|
||||
stackTrace.frames.forEach(function(frame) {
|
||||
if (frame.file !== jasmineFile) {
|
||||
@@ -78,10 +79,10 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var result = {};
|
||||
var empty = true;
|
||||
const result = {};
|
||||
let empty = true;
|
||||
|
||||
for (var prop in error) {
|
||||
for (const prop in error) {
|
||||
if (j$.util.arrayContains(ignoredProperties, prop)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
function Expectation(options) {
|
||||
this.expector = new j$.Expector(options);
|
||||
|
||||
var customMatchers = options.customMatchers || {};
|
||||
for (var matcherName in customMatchers) {
|
||||
const customMatchers = options.customMatchers || {};
|
||||
for (const matcherName in customMatchers) {
|
||||
this[matcherName] = wrapSyncCompare(
|
||||
matcherName,
|
||||
customMatchers[matcherName]
|
||||
@@ -77,8 +77,8 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
function AsyncExpectation(options) {
|
||||
this.expector = new j$.Expector(options);
|
||||
|
||||
var customAsyncMatchers = options.customAsyncMatchers || {};
|
||||
for (var matcherName in customAsyncMatchers) {
|
||||
const customAsyncMatchers = options.customAsyncMatchers || {};
|
||||
for (const matcherName in customAsyncMatchers) {
|
||||
this[matcherName] = wrapAsyncCompare(
|
||||
matcherName,
|
||||
customAsyncMatchers[matcherName]
|
||||
@@ -134,36 +134,34 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
|
||||
function wrapSyncCompare(name, matcherFactory) {
|
||||
return function() {
|
||||
var result = this.expector.compare(name, matcherFactory, arguments);
|
||||
const result = this.expector.compare(name, matcherFactory, arguments);
|
||||
this.expector.processResult(result);
|
||||
};
|
||||
}
|
||||
|
||||
function wrapAsyncCompare(name, matcherFactory) {
|
||||
return function() {
|
||||
var self = this;
|
||||
|
||||
// Capture the call stack here, before we go async, so that it will contain
|
||||
// frames that are relevant to the user instead of just parts of Jasmine.
|
||||
var errorForStack = j$.util.errorWithStack();
|
||||
const errorForStack = j$.util.errorWithStack();
|
||||
|
||||
return this.expector
|
||||
.compare(name, matcherFactory, arguments)
|
||||
.then(function(result) {
|
||||
self.expector.processResult(result, errorForStack);
|
||||
.then(result => {
|
||||
this.expector.processResult(result, errorForStack);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function addCoreMatchers(prototype, matchers, wrapper) {
|
||||
for (var matcherName in matchers) {
|
||||
var matcher = matchers[matcherName];
|
||||
for (const matcherName in matchers) {
|
||||
const matcher = matchers[matcherName];
|
||||
prototype[matcherName] = wrapper(matcherName, matcher);
|
||||
}
|
||||
}
|
||||
|
||||
function addFilter(source, filter) {
|
||||
var result = Object.create(source);
|
||||
const result = Object.create(source);
|
||||
result.expector = source.expector.addFilter(filter);
|
||||
return result;
|
||||
}
|
||||
@@ -188,7 +186,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
return result;
|
||||
}
|
||||
|
||||
var syncNegatingFilter = {
|
||||
const syncNegatingFilter = {
|
||||
selectComparisonFunc: function(matcher) {
|
||||
function defaultNegativeCompare() {
|
||||
return negate(matcher.compare.apply(null, arguments));
|
||||
@@ -199,7 +197,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
buildFailureMessage: negatedFailureMessage
|
||||
};
|
||||
|
||||
var asyncNegatingFilter = {
|
||||
const asyncNegatingFilter = {
|
||||
selectComparisonFunc: function(matcher) {
|
||||
function defaultNegativeCompare() {
|
||||
return matcher.compare.apply(this, arguments).then(negate);
|
||||
@@ -210,10 +208,10 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
buildFailureMessage: negatedFailureMessage
|
||||
};
|
||||
|
||||
var expectSettledPromiseFilter = {
|
||||
const expectSettledPromiseFilter = {
|
||||
selectComparisonFunc: function(matcher) {
|
||||
return function(actual) {
|
||||
var matcherArgs = arguments;
|
||||
const matcherArgs = arguments;
|
||||
|
||||
return j$.isPending_(actual).then(function(isPending) {
|
||||
if (isPending) {
|
||||
@@ -236,9 +234,7 @@ getJasmineRequireObj().Expectation = function(j$) {
|
||||
}
|
||||
|
||||
ContextAddingFilter.prototype.modifyFailureMessage = function(msg) {
|
||||
var nl = msg.indexOf('\n');
|
||||
|
||||
if (nl === -1) {
|
||||
if (msg.indexOf('\n') === -1) {
|
||||
return this.message + ': ' + msg;
|
||||
} else {
|
||||
return this.message + ':\n' + indent(msg);
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/*jshint bitwise: false*/
|
||||
|
||||
getJasmineRequireObj().Order = function() {
|
||||
function Order(options) {
|
||||
this.random = 'random' in options ? options.random : true;
|
||||
|
||||
@@ -1,11 +1,298 @@
|
||||
getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
function SinglePrettyPrintRun(customObjectFormatters, pp) {
|
||||
this.customObjectFormatters_ = customObjectFormatters;
|
||||
this.ppNestLevel_ = 0;
|
||||
this.seen = [];
|
||||
this.length = 0;
|
||||
this.stringParts = [];
|
||||
this.pp_ = pp;
|
||||
class SinglePrettyPrintRun {
|
||||
constructor(customObjectFormatters, pp) {
|
||||
this.customObjectFormatters_ = customObjectFormatters;
|
||||
this.ppNestLevel_ = 0;
|
||||
this.seen = [];
|
||||
this.length = 0;
|
||||
this.stringParts = [];
|
||||
this.pp_ = pp;
|
||||
}
|
||||
|
||||
format(value) {
|
||||
this.ppNestLevel_++;
|
||||
try {
|
||||
const customFormatResult = this.applyCustomFormatters_(value);
|
||||
|
||||
if (customFormatResult) {
|
||||
this.emitScalar(customFormatResult);
|
||||
} else if (j$.util.isUndefined(value)) {
|
||||
this.emitScalar('undefined');
|
||||
} else if (value === null) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === 0 && 1 / value === -Infinity) {
|
||||
this.emitScalar('-0');
|
||||
} else if (value === j$.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString(this.pp_));
|
||||
} else if (j$.isString_(value)) {
|
||||
this.emitString(value);
|
||||
} else if (j$.isSpy(value)) {
|
||||
this.emitScalar('spy on ' + value.and.identity);
|
||||
} else if (j$.isSpy(value.toString)) {
|
||||
this.emitScalar('spy on ' + value.toString.and.identity);
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
} else if (j$.isDomNode(value)) {
|
||||
if (value.tagName) {
|
||||
this.emitDomElement(value);
|
||||
} else {
|
||||
this.emitScalar('HTMLNode');
|
||||
}
|
||||
} else if (value instanceof Date) {
|
||||
this.emitScalar('Date(' + value + ')');
|
||||
} else if (j$.isSet(value)) {
|
||||
this.emitSet(value);
|
||||
} else if (j$.isMap(value)) {
|
||||
this.emitMap(value);
|
||||
} else if (j$.isTypedArray_(value)) {
|
||||
this.emitTypedArray(value);
|
||||
} else if (
|
||||
value.toString &&
|
||||
typeof value === 'object' &&
|
||||
!j$.isArray_(value) &&
|
||||
hasCustomToString(value)
|
||||
) {
|
||||
try {
|
||||
this.emitScalar(value.toString());
|
||||
} catch (e) {
|
||||
this.emitScalar('has-invalid-toString-method');
|
||||
}
|
||||
} else if (j$.util.arrayContains(this.seen, value)) {
|
||||
this.emitScalar(
|
||||
'<circular reference: ' +
|
||||
(j$.isArray_(value) ? 'Array' : 'Object') +
|
||||
'>'
|
||||
);
|
||||
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
|
||||
this.seen.push(value);
|
||||
if (j$.isArray_(value)) {
|
||||
this.emitArray(value);
|
||||
} else {
|
||||
this.emitObject(value);
|
||||
}
|
||||
this.seen.pop();
|
||||
} else {
|
||||
this.emitScalar(value.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
this.ppNestLevel_--;
|
||||
}
|
||||
}
|
||||
|
||||
applyCustomFormatters_(value) {
|
||||
return customFormat(value, this.customObjectFormatters_);
|
||||
}
|
||||
|
||||
iterateObject(obj, fn) {
|
||||
const objKeys = j$.MatchersUtil.keys(obj, j$.isArray_(obj));
|
||||
const length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
fn(objKeys[i]);
|
||||
}
|
||||
|
||||
return objKeys.length > length;
|
||||
}
|
||||
|
||||
emitScalar(value) {
|
||||
this.append(value);
|
||||
}
|
||||
|
||||
emitString(value) {
|
||||
this.append("'" + value + "'");
|
||||
}
|
||||
|
||||
emitArray(array) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Array');
|
||||
return;
|
||||
}
|
||||
|
||||
const length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
this.append('[ ');
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(array[i]);
|
||||
}
|
||||
if (array.length > length) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
let first = array.length === 0;
|
||||
const wasTruncated = this.iterateObject(array, property => {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
this.append(', ');
|
||||
}
|
||||
|
||||
this.formatProperty(array, property);
|
||||
});
|
||||
|
||||
if (wasTruncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' ]');
|
||||
}
|
||||
|
||||
emitSet(set) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Set');
|
||||
return;
|
||||
}
|
||||
this.append('Set( ');
|
||||
const size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
let i = 0;
|
||||
set.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(value);
|
||||
|
||||
i++;
|
||||
}, this);
|
||||
if (set.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
}
|
||||
|
||||
emitMap(map) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Map');
|
||||
return;
|
||||
}
|
||||
this.append('Map( ');
|
||||
const size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
let i = 0;
|
||||
map.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format([key, value]);
|
||||
|
||||
i++;
|
||||
}, this);
|
||||
if (map.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
}
|
||||
|
||||
emitObject(obj) {
|
||||
const ctor = obj.constructor;
|
||||
const constructorName =
|
||||
typeof ctor === 'function' && obj instanceof ctor
|
||||
? j$.fnNameFor(obj.constructor)
|
||||
: 'null';
|
||||
|
||||
this.append(constructorName);
|
||||
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.append('({ ');
|
||||
let first = true;
|
||||
|
||||
const wasTruncated = this.iterateObject(obj, property => {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
this.append(', ');
|
||||
}
|
||||
|
||||
this.formatProperty(obj, property);
|
||||
});
|
||||
|
||||
if (wasTruncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' })');
|
||||
}
|
||||
|
||||
emitTypedArray(arr) {
|
||||
const constructorName = j$.fnNameFor(arr.constructor);
|
||||
const limitedArray = Array.prototype.slice.call(
|
||||
arr,
|
||||
0,
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
);
|
||||
let itemsString = Array.prototype.join.call(limitedArray, ', ');
|
||||
|
||||
if (limitedArray.length !== arr.length) {
|
||||
itemsString += ', ...';
|
||||
}
|
||||
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
}
|
||||
|
||||
emitDomElement(el) {
|
||||
const tagName = el.tagName.toLowerCase();
|
||||
let out = '<' + tagName;
|
||||
|
||||
for (const attr of el.attributes) {
|
||||
out += ' ' + attr.name;
|
||||
|
||||
if (attr.value !== '') {
|
||||
out += '="' + attr.value + '"';
|
||||
}
|
||||
}
|
||||
|
||||
out += '>';
|
||||
|
||||
if (el.childElementCount !== 0 || el.textContent !== '') {
|
||||
out += '...</' + tagName + '>';
|
||||
}
|
||||
|
||||
this.append(out);
|
||||
}
|
||||
|
||||
formatProperty(obj, property) {
|
||||
if (typeof property === 'symbol') {
|
||||
this.append(property.toString());
|
||||
} else {
|
||||
this.append(property);
|
||||
}
|
||||
|
||||
this.append(': ');
|
||||
this.format(obj[property]);
|
||||
}
|
||||
|
||||
append(value) {
|
||||
// This check protects us from the rare case where an object has overriden
|
||||
// `toString()` with an invalid implementation (returning a non-string).
|
||||
if (typeof value !== 'string') {
|
||||
value = Object.prototype.toString.call(value);
|
||||
}
|
||||
|
||||
const result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
|
||||
this.length += result.value.length;
|
||||
this.stringParts.push(result.value);
|
||||
|
||||
if (result.truncated) {
|
||||
throw new MaxCharsReachedError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hasCustomToString(value) {
|
||||
@@ -23,315 +310,6 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
SinglePrettyPrintRun.prototype.format = function(value) {
|
||||
this.ppNestLevel_++;
|
||||
try {
|
||||
var customFormatResult = this.applyCustomFormatters_(value);
|
||||
|
||||
if (customFormatResult) {
|
||||
this.emitScalar(customFormatResult);
|
||||
} else if (j$.util.isUndefined(value)) {
|
||||
this.emitScalar('undefined');
|
||||
} else if (value === null) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === 0 && 1 / value === -Infinity) {
|
||||
this.emitScalar('-0');
|
||||
} else if (value === j$.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString(this.pp_));
|
||||
} else if (j$.isString_(value)) {
|
||||
this.emitString(value);
|
||||
} else if (j$.isSpy(value)) {
|
||||
this.emitScalar('spy on ' + value.and.identity);
|
||||
} else if (j$.isSpy(value.toString)) {
|
||||
this.emitScalar('spy on ' + value.toString.and.identity);
|
||||
} else if (value instanceof RegExp) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
} else if (j$.isDomNode(value)) {
|
||||
if (value.tagName) {
|
||||
this.emitDomElement(value);
|
||||
} else {
|
||||
this.emitScalar('HTMLNode');
|
||||
}
|
||||
} else if (value instanceof Date) {
|
||||
this.emitScalar('Date(' + value + ')');
|
||||
} else if (j$.isSet(value)) {
|
||||
this.emitSet(value);
|
||||
} else if (j$.isMap(value)) {
|
||||
this.emitMap(value);
|
||||
} else if (j$.isTypedArray_(value)) {
|
||||
this.emitTypedArray(value);
|
||||
} else if (
|
||||
value.toString &&
|
||||
typeof value === 'object' &&
|
||||
!j$.isArray_(value) &&
|
||||
hasCustomToString(value)
|
||||
) {
|
||||
try {
|
||||
this.emitScalar(value.toString());
|
||||
} catch (e) {
|
||||
this.emitScalar('has-invalid-toString-method');
|
||||
}
|
||||
} else if (j$.util.arrayContains(this.seen, value)) {
|
||||
this.emitScalar(
|
||||
'<circular reference: ' +
|
||||
(j$.isArray_(value) ? 'Array' : 'Object') +
|
||||
'>'
|
||||
);
|
||||
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
|
||||
this.seen.push(value);
|
||||
if (j$.isArray_(value)) {
|
||||
this.emitArray(value);
|
||||
} else {
|
||||
this.emitObject(value);
|
||||
}
|
||||
this.seen.pop();
|
||||
} else {
|
||||
this.emitScalar(value.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
if (this.ppNestLevel_ > 1 || !(e instanceof MaxCharsReachedError)) {
|
||||
throw e;
|
||||
}
|
||||
} finally {
|
||||
this.ppNestLevel_--;
|
||||
}
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.applyCustomFormatters_ = function(value) {
|
||||
return customFormat(value, this.customObjectFormatters_);
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.iterateObject = function(obj, fn) {
|
||||
var objKeys = j$.MatchersUtil.keys(obj, j$.isArray_(obj));
|
||||
var isGetter = function isGetter(prop) {};
|
||||
|
||||
if (obj.__lookupGetter__) {
|
||||
isGetter = function isGetter(prop) {
|
||||
var getter = obj.__lookupGetter__(prop);
|
||||
return !j$.util.isUndefined(getter) && getter !== null;
|
||||
};
|
||||
}
|
||||
var length = Math.min(objKeys.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var property = objKeys[i];
|
||||
fn(property, isGetter(property));
|
||||
}
|
||||
|
||||
return objKeys.length > length;
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitScalar = function(value) {
|
||||
this.append(value);
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitString = function(value) {
|
||||
this.append("'" + value + "'");
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitArray = function(array) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Array');
|
||||
return;
|
||||
}
|
||||
var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
this.append('[ ');
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(array[i]);
|
||||
}
|
||||
if (array.length > length) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var first = array.length === 0;
|
||||
var truncated = this.iterateObject(array, function(property, isGetter) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
self.append(', ');
|
||||
}
|
||||
|
||||
self.formatProperty(array, property, isGetter);
|
||||
});
|
||||
|
||||
if (truncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' ]');
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitSet = function(set) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Set');
|
||||
return;
|
||||
}
|
||||
this.append('Set( ');
|
||||
var size = Math.min(set.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var i = 0;
|
||||
set.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format(value);
|
||||
|
||||
i++;
|
||||
}, this);
|
||||
if (set.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitMap = function(map) {
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append('Map');
|
||||
return;
|
||||
}
|
||||
this.append('Map( ');
|
||||
var size = Math.min(map.size, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
|
||||
var i = 0;
|
||||
map.forEach(function(value, key) {
|
||||
if (i >= size) {
|
||||
return;
|
||||
}
|
||||
if (i > 0) {
|
||||
this.append(', ');
|
||||
}
|
||||
this.format([key, value]);
|
||||
|
||||
i++;
|
||||
}, this);
|
||||
if (map.size > size) {
|
||||
this.append(', ...');
|
||||
}
|
||||
this.append(' )');
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitObject = function(obj) {
|
||||
var ctor = obj.constructor,
|
||||
constructorName;
|
||||
|
||||
constructorName =
|
||||
typeof ctor === 'function' && obj instanceof ctor
|
||||
? j$.fnNameFor(obj.constructor)
|
||||
: 'null';
|
||||
|
||||
this.append(constructorName);
|
||||
|
||||
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.append('({ ');
|
||||
var first = true;
|
||||
|
||||
var truncated = this.iterateObject(obj, function(property, isGetter) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
self.append(', ');
|
||||
}
|
||||
|
||||
self.formatProperty(obj, property, isGetter);
|
||||
});
|
||||
|
||||
if (truncated) {
|
||||
this.append(', ...');
|
||||
}
|
||||
|
||||
this.append(' })');
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitTypedArray = function(arr) {
|
||||
var constructorName = j$.fnNameFor(arr.constructor),
|
||||
limitedArray = Array.prototype.slice.call(
|
||||
arr,
|
||||
0,
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH
|
||||
),
|
||||
itemsString = Array.prototype.join.call(limitedArray, ', ');
|
||||
|
||||
if (limitedArray.length !== arr.length) {
|
||||
itemsString += ', ...';
|
||||
}
|
||||
|
||||
this.append(constructorName + ' [ ' + itemsString + ' ]');
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.emitDomElement = function(el) {
|
||||
var tagName = el.tagName.toLowerCase(),
|
||||
attrs = el.attributes,
|
||||
i,
|
||||
len = attrs.length,
|
||||
out = '<' + tagName,
|
||||
attr;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
attr = attrs[i];
|
||||
out += ' ' + attr.name;
|
||||
|
||||
if (attr.value !== '') {
|
||||
out += '="' + attr.value + '"';
|
||||
}
|
||||
}
|
||||
|
||||
out += '>';
|
||||
|
||||
if (el.childElementCount !== 0 || el.textContent !== '') {
|
||||
out += '...</' + tagName + '>';
|
||||
}
|
||||
|
||||
this.append(out);
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.formatProperty = function(
|
||||
obj,
|
||||
property,
|
||||
isGetter
|
||||
) {
|
||||
if (typeof property === 'symbol') {
|
||||
this.append(property.toString());
|
||||
} else {
|
||||
this.append(property);
|
||||
}
|
||||
|
||||
this.append(': ');
|
||||
|
||||
if (isGetter) {
|
||||
this.append('<getter>');
|
||||
} else {
|
||||
this.format(obj[property]);
|
||||
}
|
||||
};
|
||||
|
||||
SinglePrettyPrintRun.prototype.append = function(value) {
|
||||
// This check protects us from the rare case where an object has overriden
|
||||
// `toString()` with an invalid implementation (returning a non-string).
|
||||
if (typeof value !== 'string') {
|
||||
value = Object.prototype.toString.call(value);
|
||||
}
|
||||
|
||||
var result = truncate(value, j$.MAX_PRETTY_PRINT_CHARS - this.length);
|
||||
this.length += result.value.length;
|
||||
this.stringParts.push(result.value);
|
||||
|
||||
if (result.truncated) {
|
||||
throw new MaxCharsReachedError();
|
||||
}
|
||||
};
|
||||
|
||||
function truncate(s, maxlen) {
|
||||
if (s.length <= maxlen) {
|
||||
return { value: s, truncated: false };
|
||||
@@ -351,10 +329,8 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
MaxCharsReachedError.prototype = new Error();
|
||||
|
||||
function customFormat(value, customObjectFormatters) {
|
||||
var i, result;
|
||||
|
||||
for (i = 0; i < customObjectFormatters.length; i++) {
|
||||
result = customObjectFormatters[i](value);
|
||||
for (const formatter of customObjectFormatters) {
|
||||
const result = formatter(value);
|
||||
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
@@ -365,8 +341,11 @@ getJasmineRequireObj().makePrettyPrinter = function(j$) {
|
||||
return function(customObjectFormatters) {
|
||||
customObjectFormatters = customObjectFormatters || [];
|
||||
|
||||
var pp = function(value) {
|
||||
var prettyPrinter = new SinglePrettyPrintRun(customObjectFormatters, pp);
|
||||
const pp = function(value) {
|
||||
const prettyPrinter = new SinglePrettyPrintRun(
|
||||
customObjectFormatters,
|
||||
pp
|
||||
);
|
||||
prettyPrinter.format(value);
|
||||
return prettyPrinter.stringParts.join('');
|
||||
};
|
||||
|
||||
@@ -253,8 +253,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
};
|
||||
|
||||
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
|
||||
var msg;
|
||||
|
||||
if (retval && j$.isFunction_(retval.then)) {
|
||||
// Issue a warning that matches the user's code.
|
||||
// Omit the stack trace because there's almost certainly no user code
|
||||
@@ -274,8 +272,6 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
'function to not return a promise.'
|
||||
);
|
||||
}
|
||||
|
||||
this.deprecated(msg, { omitStackTrace: true });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
getJasmineRequireObj().Spec = function(j$) {
|
||||
/**
|
||||
* @interface Spec
|
||||
* @see Configuration#specFilter
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function Spec(attrs) {
|
||||
this.expectationFactory = attrs.expectationFactory;
|
||||
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
/**
|
||||
* The unique ID of this spec.
|
||||
* @name Spec#id
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.id = attrs.id;
|
||||
/**
|
||||
* The description passed to the {@link it} that created this spec.
|
||||
* @name Spec#description
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.description = attrs.description || '';
|
||||
this.queueableFn = attrs.queueableFn;
|
||||
this.beforeAndAfterFns =
|
||||
@@ -43,8 +24,6 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
function() {
|
||||
return '';
|
||||
};
|
||||
this.expectationResultFactory =
|
||||
attrs.expectationResultFactory || function() {};
|
||||
this.onLateError = attrs.onLateError || function() {};
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions =
|
||||
@@ -86,14 +65,20 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
properties: null,
|
||||
debugLogs: null
|
||||
};
|
||||
|
||||
this.reportedDone = false;
|
||||
}
|
||||
|
||||
Spec.prototype.addExpectationResult = function(passed, data, isError) {
|
||||
var expectationResult = this.expectationResultFactory(data);
|
||||
const expectationResult = j$.buildExpectationResult(data);
|
||||
if (passed) {
|
||||
this.result.passedExpectations.push(expectationResult);
|
||||
} else {
|
||||
this.result.failedExpectations.push(expectationResult);
|
||||
if (this.reportedDone) {
|
||||
this.onLateError(expectationResult);
|
||||
} else {
|
||||
this.result.failedExpectations.push(expectationResult);
|
||||
}
|
||||
|
||||
if (this.throwOnExpectationFailure && !isError) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
@@ -147,7 +132,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
isLeaf: true,
|
||||
queueableFns: [...fns.befores, this.queueableFn, ...fns.afters],
|
||||
onException: function() {
|
||||
self.onException.apply(self, arguments);
|
||||
self.handleException.apply(self, arguments);
|
||||
},
|
||||
onMultipleDone: function() {
|
||||
// Issue a deprecation. Include the context ourselves and pass
|
||||
@@ -197,9 +182,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
debugLogs: null
|
||||
};
|
||||
this.markedPending = this.markedExcluding;
|
||||
this.reportedDone = false;
|
||||
};
|
||||
|
||||
Spec.prototype.onException = function onException(e) {
|
||||
Spec.prototype.handleException = function handleException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
this.pend(extractCustomPendingMessage(e));
|
||||
return;
|
||||
@@ -273,13 +259,6 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return 'passed';
|
||||
};
|
||||
|
||||
/**
|
||||
* The full description including all ancestors of this spec.
|
||||
* @name Spec#getFullName
|
||||
* @function
|
||||
* @returns {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
Spec.prototype.getFullName = function() {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
@@ -289,7 +268,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
deprecation = { message: deprecation };
|
||||
}
|
||||
this.result.deprecationWarnings.push(
|
||||
this.expectationResultFactory(deprecation)
|
||||
j$.buildExpectationResult(deprecation)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -332,6 +311,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
/**
|
||||
* @interface Spec
|
||||
* @see Configuration#specFilter
|
||||
* @since 2.0.0
|
||||
*/
|
||||
Object.defineProperty(Spec.prototype, 'metadata', {
|
||||
get: function() {
|
||||
@@ -342,6 +322,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @name Spec#id
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
id: this.id,
|
||||
|
||||
@@ -350,6 +331,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @name Spec#description
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
description: this.description,
|
||||
|
||||
@@ -358,6 +340,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @name Spec#getFullName
|
||||
* @function
|
||||
* @returns {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
getFullName: this.getFullName.bind(this)
|
||||
};
|
||||
|
||||
@@ -1,48 +1,21 @@
|
||||
getJasmineRequireObj().Suite = function(j$) {
|
||||
/**
|
||||
* @interface Suite
|
||||
* @see Env#topSuite
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function Suite(attrs) {
|
||||
this.env = attrs.env;
|
||||
/**
|
||||
* The unique ID of this suite.
|
||||
* @name Suite#id
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.id = attrs.id;
|
||||
this.parentSuite = attrs.parentSuite;
|
||||
/**
|
||||
* The description passed to the {@link describe} that created this suite.
|
||||
* @name Suite#description
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.description = attrs.description;
|
||||
this.expectationFactory = attrs.expectationFactory;
|
||||
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
|
||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
this.autoCleanClosures =
|
||||
attrs.autoCleanClosures === undefined ? true : !!attrs.autoCleanClosures;
|
||||
this.onLateError = attrs.onLateError;
|
||||
this.onLateError = attrs.onLateError || function() {};
|
||||
|
||||
this.beforeFns = [];
|
||||
this.afterFns = [];
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
this.timer = attrs.timer || new j$.Timer();
|
||||
|
||||
/**
|
||||
* The suite's children.
|
||||
* @name Suite#children
|
||||
* @type {Array.<(Spec|Suite)>}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
this.reset();
|
||||
@@ -61,13 +34,6 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
return this.asyncExpectationFactory(actual, this);
|
||||
};
|
||||
|
||||
/**
|
||||
* The full description including all ancestors of this suite.
|
||||
* @name Suite#getFullName
|
||||
* @function
|
||||
* @returns {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
Suite.prototype.getFullName = function() {
|
||||
var fullName = [];
|
||||
for (
|
||||
@@ -163,6 +129,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.children.forEach(function(child) {
|
||||
child.reset();
|
||||
});
|
||||
this.reportedDone = false;
|
||||
};
|
||||
|
||||
Suite.prototype.addChild = function(child) {
|
||||
@@ -204,25 +171,29 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
return j$.UserContext.fromExisting(this.sharedUserContext());
|
||||
};
|
||||
|
||||
Suite.prototype.onException = function() {
|
||||
Suite.prototype.handleException = function() {
|
||||
if (arguments[0] instanceof j$.errors.ExpectationFailed) {
|
||||
return;
|
||||
}
|
||||
|
||||
var data = {
|
||||
const data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: arguments[0]
|
||||
};
|
||||
var failedExpectation = this.expectationResultFactory(data);
|
||||
const failedExpectation = j$.buildExpectationResult(data);
|
||||
|
||||
if (!this.parentSuite) {
|
||||
failedExpectation.globalErrorType = 'afterAll';
|
||||
}
|
||||
|
||||
this.result.failedExpectations.push(failedExpectation);
|
||||
if (this.reportedDone) {
|
||||
this.onLateError(failedExpectation);
|
||||
} else {
|
||||
this.result.failedExpectations.push(failedExpectation);
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.onMultipleDone = function() {
|
||||
@@ -249,8 +220,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
|
||||
Suite.prototype.addExpectationResult = function() {
|
||||
if (isFailure(arguments)) {
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
const data = arguments[1];
|
||||
const expectationResult = j$.buildExpectationResult(data);
|
||||
|
||||
if (this.reportedDone) {
|
||||
this.onLateError(expectationResult);
|
||||
} else {
|
||||
this.result.failedExpectations.push(expectationResult);
|
||||
}
|
||||
|
||||
if (this.throwOnExpectationFailure) {
|
||||
throw new j$.errors.ExpectationFailed();
|
||||
}
|
||||
@@ -262,7 +240,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
deprecation = { message: deprecation };
|
||||
}
|
||||
this.result.deprecationWarnings.push(
|
||||
this.expectationResultFactory(deprecation)
|
||||
j$.buildExpectationResult(deprecation)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -279,6 +257,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
/**
|
||||
* @interface Suite
|
||||
* @see Env#topSuite
|
||||
* @since 2.0.0
|
||||
*/
|
||||
function SuiteMetadata(suite) {
|
||||
this.suite_ = suite;
|
||||
@@ -287,6 +266,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @name Suite#id
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.id = suite.id;
|
||||
|
||||
@@ -303,6 +283,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @name Suite#description
|
||||
* @readonly
|
||||
* @type {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
this.description = suite.description;
|
||||
}
|
||||
@@ -312,6 +293,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @name Suite#getFullName
|
||||
* @function
|
||||
* @returns {string}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
SuiteMetadata.prototype.getFullName = function() {
|
||||
return this.suite_.getFullName();
|
||||
@@ -321,6 +303,7 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* The suite's children.
|
||||
* @name Suite#children
|
||||
* @type {Array.<(Spec|Suite)>}
|
||||
* @since 2.0.0
|
||||
*/
|
||||
Object.defineProperty(SuiteMetadata.prototype, 'children', {
|
||||
get: function() {
|
||||
|
||||
@@ -42,7 +42,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
queueableFns: childFns,
|
||||
userContext: tree.sharedUserContext(),
|
||||
onException: function() {
|
||||
tree.onException.apply(tree, arguments);
|
||||
tree.handleException.apply(tree, arguments);
|
||||
},
|
||||
onComplete: done,
|
||||
onMultipleDone: tree.onMultipleDone
|
||||
@@ -218,7 +218,7 @@ getJasmineRequireObj().TreeProcessor = function() {
|
||||
queueableFns: [onStart].concat(wrapChildren(node, segmentNumber)),
|
||||
userContext: node.sharedUserContext(),
|
||||
onException: function() {
|
||||
node.onException.apply(node, arguments);
|
||||
node.handleException.apply(node, arguments);
|
||||
},
|
||||
onMultipleDone: node.onMultipleDone
|
||||
? node.onMultipleDone.bind(node)
|
||||
|
||||
@@ -30,12 +30,9 @@ getJasmineRequireObj().Any = function(j$) {
|
||||
return typeof other == 'boolean';
|
||||
}
|
||||
|
||||
/* jshint -W122 */
|
||||
/* global Symbol */
|
||||
if (typeof Symbol != 'undefined' && this.expectedObject == Symbol) {
|
||||
return typeof other == 'symbol';
|
||||
}
|
||||
/* jshint +W122 */
|
||||
|
||||
return other instanceof this.expectedObject;
|
||||
};
|
||||
|
||||
17
src/core/asymmetric_equality/Is.js
Normal file
17
src/core/asymmetric_equality/Is.js
Normal file
@@ -0,0 +1,17 @@
|
||||
getJasmineRequireObj().Is = function(j$) {
|
||||
class Is {
|
||||
constructor(expected) {
|
||||
this.expected_ = expected;
|
||||
}
|
||||
|
||||
asymmetricMatch(actual) {
|
||||
return actual === this.expected_;
|
||||
}
|
||||
|
||||
jasmineToString(pp) {
|
||||
return `<jasmine.is(${pp(this.expected_)})>`;
|
||||
}
|
||||
}
|
||||
|
||||
return Is;
|
||||
};
|
||||
@@ -283,6 +283,18 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
return new j$.Empty();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an {@link AsymmetricEqualityTester}, usable in any {@link matchers|matcher}
|
||||
* that passes if the actual value is the same as the sample as determined
|
||||
* by the `===` operator.
|
||||
* @name jasmine.is
|
||||
* @function
|
||||
* @param {Object} sample - The value to compare the actual to.
|
||||
*/
|
||||
j$.is = function(sample) {
|
||||
return new j$.Is(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
//TODO: expectation result may make more sense as a presentation of an expectation.
|
||||
getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
function buildExpectationResult(options) {
|
||||
var messageFormatter = options.messageFormatter || function() {},
|
||||
stackFormatter = options.stackFormatter || function() {};
|
||||
const exceptionFormatter = new j$.ExceptionFormatter();
|
||||
|
||||
/**
|
||||
* @typedef Expectation
|
||||
@@ -16,7 +15,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
* is reported on the top suite. Valid values are undefined, "afterAll",
|
||||
* "load", "lateExpectation", and "lateError".
|
||||
*/
|
||||
var result = {
|
||||
const result = {
|
||||
matcherName: options.matcherName,
|
||||
message: message(),
|
||||
stack: options.omitStackTrace ? '' : stack(),
|
||||
@@ -52,7 +51,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
} else if (options.message) {
|
||||
return options.message;
|
||||
} else if (options.error) {
|
||||
return messageFormatter(options.error);
|
||||
return exceptionFormatter.message(options.error);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
@@ -62,7 +61,8 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var error = options.error;
|
||||
let error = options.error;
|
||||
|
||||
if (!error) {
|
||||
if (options.errorForStack) {
|
||||
error = options.errorForStack;
|
||||
@@ -78,7 +78,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
|
||||
}
|
||||
// Omit the message from the stack trace because it will be
|
||||
// included elsewhere.
|
||||
return stackFormatter(error, { omitMessage: true });
|
||||
return exceptionFormatter.stack(error, { omitMessage: true });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,118 +1,112 @@
|
||||
getJasmineRequireObj().DiffBuilder = function(j$) {
|
||||
return function DiffBuilder(config) {
|
||||
var prettyPrinter = (config || {}).prettyPrinter || j$.makePrettyPrinter(),
|
||||
mismatches = new j$.MismatchTree(),
|
||||
path = new j$.ObjectPath(),
|
||||
actualRoot = undefined,
|
||||
expectedRoot = undefined;
|
||||
class DiffBuilder {
|
||||
constructor(config) {
|
||||
this.prettyPrinter_ =
|
||||
(config || {}).prettyPrinter || j$.makePrettyPrinter();
|
||||
this.mismatches_ = new j$.MismatchTree();
|
||||
this.path_ = new j$.ObjectPath();
|
||||
this.actualRoot_ = undefined;
|
||||
this.expectedRoot_ = undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
setRoots: function(actual, expected) {
|
||||
actualRoot = actual;
|
||||
expectedRoot = expected;
|
||||
},
|
||||
setRoots(actual, expected) {
|
||||
this.actualRoot_ = actual;
|
||||
this.expectedRoot_ = expected;
|
||||
}
|
||||
|
||||
recordMismatch: function(formatter) {
|
||||
mismatches.add(path, formatter);
|
||||
},
|
||||
recordMismatch(formatter) {
|
||||
this.mismatches_.add(this.path_, formatter);
|
||||
}
|
||||
|
||||
getMessage: function() {
|
||||
var messages = [];
|
||||
getMessage() {
|
||||
const messages = [];
|
||||
|
||||
mismatches.traverse(function(path, isLeaf, formatter) {
|
||||
var actualCustom,
|
||||
expectedCustom,
|
||||
useCustom,
|
||||
derefResult = dereferencePath(
|
||||
path,
|
||||
actualRoot,
|
||||
expectedRoot,
|
||||
prettyPrinter
|
||||
),
|
||||
actual = derefResult.actual,
|
||||
expected = derefResult.expected;
|
||||
|
||||
if (formatter) {
|
||||
messages.push(formatter(actual, expected, path, prettyPrinter));
|
||||
return true;
|
||||
}
|
||||
|
||||
actualCustom = prettyPrinter.customFormat_(actual);
|
||||
expectedCustom = prettyPrinter.customFormat_(expected);
|
||||
useCustom = !(
|
||||
j$.util.isUndefined(actualCustom) &&
|
||||
j$.util.isUndefined(expectedCustom)
|
||||
);
|
||||
|
||||
if (useCustom) {
|
||||
messages.push(
|
||||
wrapPrettyPrinted(actualCustom, expectedCustom, path)
|
||||
);
|
||||
return false; // don't recurse further
|
||||
}
|
||||
|
||||
if (isLeaf) {
|
||||
messages.push(
|
||||
defaultFormatter(actual, expected, path, prettyPrinter)
|
||||
);
|
||||
}
|
||||
this.mismatches_.traverse((path, isLeaf, formatter) => {
|
||||
const { actual, expected } = this.dereferencePath_(path);
|
||||
|
||||
if (formatter) {
|
||||
messages.push(formatter(actual, expected, path, this.prettyPrinter_));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return messages.join('\n');
|
||||
},
|
||||
const actualCustom = this.prettyPrinter_.customFormat_(actual);
|
||||
const expectedCustom = this.prettyPrinter_.customFormat_(expected);
|
||||
const useCustom = !(
|
||||
j$.util.isUndefined(actualCustom) &&
|
||||
j$.util.isUndefined(expectedCustom)
|
||||
);
|
||||
|
||||
withPath: function(pathComponent, block) {
|
||||
var oldPath = path;
|
||||
path = path.add(pathComponent);
|
||||
block();
|
||||
path = oldPath;
|
||||
if (useCustom) {
|
||||
messages.push(wrapPrettyPrinted(actualCustom, expectedCustom, path));
|
||||
return false; // don't recurse further
|
||||
}
|
||||
|
||||
if (isLeaf) {
|
||||
messages.push(this.defaultFormatter_(actual, expected, path));
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return messages.join('\n');
|
||||
}
|
||||
|
||||
withPath(pathComponent, block) {
|
||||
const oldPath = this.path_;
|
||||
this.path_ = this.path_.add(pathComponent);
|
||||
block();
|
||||
this.path_ = oldPath;
|
||||
}
|
||||
|
||||
dereferencePath_(objectPath) {
|
||||
let actual = this.actualRoot_;
|
||||
let expected = this.expectedRoot_;
|
||||
|
||||
const handleAsymmetricExpected = () => {
|
||||
if (
|
||||
j$.isAsymmetricEqualityTester_(expected) &&
|
||||
j$.isFunction_(expected.valuesForDiff_)
|
||||
) {
|
||||
const asymmetricResult = expected.valuesForDiff_(
|
||||
actual,
|
||||
this.prettyPrinter_
|
||||
);
|
||||
expected = asymmetricResult.self;
|
||||
actual = asymmetricResult.other;
|
||||
}
|
||||
};
|
||||
|
||||
handleAsymmetricExpected();
|
||||
|
||||
for (const pc of objectPath.components) {
|
||||
actual = actual[pc];
|
||||
expected = expected[pc];
|
||||
handleAsymmetricExpected();
|
||||
}
|
||||
};
|
||||
|
||||
function defaultFormatter(actual, expected, path, prettyPrinter) {
|
||||
return { actual: actual, expected: expected };
|
||||
}
|
||||
|
||||
defaultFormatter_(actual, expected, path) {
|
||||
return wrapPrettyPrinted(
|
||||
prettyPrinter(actual),
|
||||
prettyPrinter(expected),
|
||||
this.prettyPrinter_(actual),
|
||||
this.prettyPrinter_(expected),
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
function wrapPrettyPrinted(actual, expected, path) {
|
||||
return (
|
||||
'Expected ' +
|
||||
path +
|
||||
(path.depth() ? ' = ' : '') +
|
||||
actual +
|
||||
' to equal ' +
|
||||
expected +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
function dereferencePath(objectPath, actual, expected, pp) {
|
||||
function handleAsymmetricExpected() {
|
||||
if (
|
||||
j$.isAsymmetricEqualityTester_(expected) &&
|
||||
j$.isFunction_(expected.valuesForDiff_)
|
||||
) {
|
||||
var asymmetricResult = expected.valuesForDiff_(actual, pp);
|
||||
expected = asymmetricResult.self;
|
||||
actual = asymmetricResult.other;
|
||||
}
|
||||
}
|
||||
|
||||
var i;
|
||||
handleAsymmetricExpected();
|
||||
|
||||
for (i = 0; i < objectPath.components.length; i++) {
|
||||
actual = actual[objectPath.components[i]];
|
||||
expected = expected[objectPath.components[i]];
|
||||
handleAsymmetricExpected();
|
||||
}
|
||||
|
||||
return { actual: actual, expected: expected };
|
||||
}
|
||||
|
||||
function wrapPrettyPrinted(actual, expected, path) {
|
||||
return (
|
||||
'Expected ' +
|
||||
path +
|
||||
(path.depth() ? ' = ' : '') +
|
||||
actual +
|
||||
' to equal ' +
|
||||
expected +
|
||||
'.'
|
||||
);
|
||||
}
|
||||
|
||||
return DiffBuilder;
|
||||
};
|
||||
|
||||
@@ -6,56 +6,51 @@ getJasmineRequireObj().MismatchTree = function(j$) {
|
||||
the expected and actual object graphs. MismatchTree maintains that context
|
||||
and provides it via the traverse method.
|
||||
*/
|
||||
function MismatchTree(path) {
|
||||
this.path = path || new j$.ObjectPath([]);
|
||||
this.formatter = undefined;
|
||||
this.children = [];
|
||||
this.isMismatch = false;
|
||||
}
|
||||
|
||||
MismatchTree.prototype.add = function(path, formatter) {
|
||||
var key, child;
|
||||
|
||||
if (path.depth() === 0) {
|
||||
this.formatter = formatter;
|
||||
this.isMismatch = true;
|
||||
} else {
|
||||
key = path.components[0];
|
||||
path = path.shift();
|
||||
child = this.child(key);
|
||||
|
||||
if (!child) {
|
||||
child = new MismatchTree(this.path.add(key));
|
||||
this.children.push(child);
|
||||
}
|
||||
|
||||
child.add(path, formatter);
|
||||
class MismatchTree {
|
||||
constructor(path) {
|
||||
this.path = path || new j$.ObjectPath([]);
|
||||
this.formatter = undefined;
|
||||
this.children = [];
|
||||
this.isMismatch = false;
|
||||
}
|
||||
};
|
||||
|
||||
MismatchTree.prototype.traverse = function(visit) {
|
||||
var i,
|
||||
hasChildren = this.children.length > 0;
|
||||
add(path, formatter) {
|
||||
if (path.depth() === 0) {
|
||||
this.formatter = formatter;
|
||||
this.isMismatch = true;
|
||||
} else {
|
||||
const key = path.components[0];
|
||||
path = path.shift();
|
||||
let child = this.child(key);
|
||||
|
||||
if (this.isMismatch || hasChildren) {
|
||||
if (visit(this.path, !hasChildren, this.formatter)) {
|
||||
for (i = 0; i < this.children.length; i++) {
|
||||
this.children[i].traverse(visit);
|
||||
if (!child) {
|
||||
child = new MismatchTree(this.path.add(key));
|
||||
this.children.push(child);
|
||||
}
|
||||
|
||||
child.add(path, formatter);
|
||||
}
|
||||
}
|
||||
|
||||
traverse(visit) {
|
||||
const hasChildren = this.children.length > 0;
|
||||
|
||||
if (this.isMismatch || hasChildren) {
|
||||
if (visit(this.path, !hasChildren, this.formatter)) {
|
||||
for (const child of this.children) {
|
||||
child.traverse(visit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MismatchTree.prototype.child = function(key) {
|
||||
var i, pathEls;
|
||||
|
||||
for (i = 0; i < this.children.length; i++) {
|
||||
pathEls = this.children[i].path.components;
|
||||
if (pathEls[pathEls.length - 1] === key) {
|
||||
return this.children[i];
|
||||
}
|
||||
child(key) {
|
||||
return this.children.find(child => {
|
||||
const pathEls = child.path.components;
|
||||
return pathEls[pathEls.length - 1] === key;
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return MismatchTree;
|
||||
};
|
||||
|
||||
@@ -1,27 +1,29 @@
|
||||
getJasmineRequireObj().ObjectPath = function(j$) {
|
||||
function ObjectPath(components) {
|
||||
this.components = components || [];
|
||||
}
|
||||
|
||||
ObjectPath.prototype.toString = function() {
|
||||
if (this.components.length) {
|
||||
return '$' + map(this.components, formatPropertyAccess).join('');
|
||||
} else {
|
||||
return '';
|
||||
class ObjectPath {
|
||||
constructor(components) {
|
||||
this.components = components || [];
|
||||
}
|
||||
};
|
||||
|
||||
ObjectPath.prototype.add = function(component) {
|
||||
return new ObjectPath(this.components.concat([component]));
|
||||
};
|
||||
toString() {
|
||||
if (this.components.length) {
|
||||
return '$' + this.components.map(formatPropertyAccess).join('');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
ObjectPath.prototype.shift = function() {
|
||||
return new ObjectPath(this.components.slice(1));
|
||||
};
|
||||
add(component) {
|
||||
return new ObjectPath(this.components.concat([component]));
|
||||
}
|
||||
|
||||
ObjectPath.prototype.depth = function() {
|
||||
return this.components.length;
|
||||
};
|
||||
shift() {
|
||||
return new ObjectPath(this.components.slice(1));
|
||||
}
|
||||
|
||||
depth() {
|
||||
return this.components.length;
|
||||
}
|
||||
}
|
||||
|
||||
function formatPropertyAccess(prop) {
|
||||
if (typeof prop === 'number' || typeof prop === 'symbol') {
|
||||
@@ -32,15 +34,7 @@ getJasmineRequireObj().ObjectPath = function(j$) {
|
||||
return '.' + prop;
|
||||
}
|
||||
|
||||
return "['" + prop + "']";
|
||||
}
|
||||
|
||||
function map(array, fn) {
|
||||
var results = [];
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
results.push(fn(array[i]));
|
||||
}
|
||||
return results;
|
||||
return `['${prop}']`;
|
||||
}
|
||||
|
||||
function isValidIdentifier(string) {
|
||||
|
||||
@@ -14,7 +14,7 @@ getJasmineRequireObj().toEqual = function(j$) {
|
||||
var result = {
|
||||
pass: false
|
||||
},
|
||||
diffBuilder = j$.DiffBuilder({ prettyPrinter: matchersUtil.pp });
|
||||
diffBuilder = new j$.DiffBuilder({ prettyPrinter: matchersUtil.pp });
|
||||
|
||||
result.pass = matchersUtil.equals(actual, expected, diffBuilder);
|
||||
|
||||
|
||||
@@ -91,6 +91,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$.Falsy = jRequire.Falsy(j$);
|
||||
j$.Empty = jRequire.Empty(j$);
|
||||
j$.NotEmpty = jRequire.NotEmpty(j$);
|
||||
j$.Is = jRequire.Is(j$);
|
||||
|
||||
j$.matchers = jRequire.requireMatchers(jRequire, j$);
|
||||
j$.asyncMatchers = jRequire.requireAsyncMatchers(jRequire, j$);
|
||||
|
||||
Reference in New Issue
Block a user