Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a67b7276be | ||
|
|
47f3105ef0 | ||
|
|
aeb56539c9 | ||
|
|
75d45efa16 | ||
|
|
59d1c5bebb | ||
|
|
040983c979 | ||
|
|
2ddb344bac | ||
|
|
e56bd3918b | ||
|
|
59600a1c29 | ||
|
|
f8e4ea868f | ||
|
|
0ff56c53b1 |
@@ -80,7 +80,7 @@ jobs:
|
|||||||
# cleanly if we kill it from a different step than it started in.
|
# cleanly if we kill it from a different step than it started in.
|
||||||
|
|
||||||
export PATH=$PATH:$HOME/workspace/bin
|
export PATH=$PATH:$HOME/workspace/bin
|
||||||
export SAUCE_TUNNEL_IDENTIFIER=$CIRCLE_BUILD_NUM
|
export SAUCE_TUNNEL_IDENTIFIER=$CIRCLE_WORKFLOW_JOB_ID
|
||||||
scripts/start-sauce-connect sauce-pidfile
|
scripts/start-sauce-connect sauce-pidfile
|
||||||
set +o errexit
|
set +o errexit
|
||||||
scripts/run-all-browsers
|
scripts/run-all-browsers
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
name: Bug Report
|
name: Bug Report
|
||||||
description: I think I've found a bug in Jasmine
|
description: I think I've found a bug in Jasmine
|
||||||
labels: ["unconfirmed bug"]
|
labels: ["bug report"]
|
||||||
body:
|
body:
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
|
|||||||
@@ -809,14 +809,6 @@ getJasmineRequireObj().Spec = function(j$) {
|
|||||||
this.result.properties[key] = value;
|
this.result.properties[key] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
Spec.prototype.expect = function(actual) {
|
|
||||||
return this.expectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Spec.prototype.expectAsync = function(actual) {
|
|
||||||
return this.asyncExpectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Spec.prototype.execute = function(
|
Spec.prototype.execute = function(
|
||||||
queueRunnerFactory,
|
queueRunnerFactory,
|
||||||
onComplete,
|
onComplete,
|
||||||
@@ -1401,6 +1393,49 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleThrowUnlessFailure = function(passed, result) {
|
||||||
|
if (!passed) {
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
* @name ThrowUnlessFailure
|
||||||
|
* @extends Error
|
||||||
|
* @description Represents a failure of an expectation evaluated with
|
||||||
|
* {@link throwUnless}. Properties of this error are a subset of the
|
||||||
|
* properties of {@link Expectation} and have the same values.
|
||||||
|
* @property {String} matcherName - The name of the matcher that was executed for this expectation.
|
||||||
|
* @property {String} message - The failure message for the expectation.
|
||||||
|
* @property {Boolean} passed - Whether the expectation passed or failed.
|
||||||
|
* @property {Object} expected - If the expectation failed, what was the expected value.
|
||||||
|
* @property {Object} actual - If the expectation failed, what actual value was produced.
|
||||||
|
*/
|
||||||
|
const error = new Error(result.message);
|
||||||
|
error.passed = result.passed;
|
||||||
|
error.message = result.message;
|
||||||
|
error.expected = result.expected;
|
||||||
|
error.actual = result.actual;
|
||||||
|
error.matcherName = result.matcherName;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const throwUnlessFactory = function(actual, spec) {
|
||||||
|
return j$.Expectation.factory({
|
||||||
|
matchersUtil: runableResources.makeMatchersUtil(),
|
||||||
|
customMatchers: runableResources.customMatchers(),
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: handleThrowUnlessFailure
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const throwUnlessAsyncFactory = function(actual, spec) {
|
||||||
|
return j$.Expectation.asyncFactory({
|
||||||
|
matchersUtil: runableResources.makeMatchersUtil(),
|
||||||
|
customAsyncMatchers: runableResources.customAsyncMatchers(),
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: handleThrowUnlessFailure
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: Unify recordLateError with recordLateExpectation? The extra
|
// TODO: Unify recordLateError with recordLateExpectation? The extra
|
||||||
// diagnostic info added by the latter is probably useful in most cases.
|
// diagnostic info added by the latter is probably useful in most cases.
|
||||||
function recordLateError(error) {
|
function recordLateError(error) {
|
||||||
@@ -1904,23 +1939,37 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.expect = function(actual) {
|
this.expect = function(actual) {
|
||||||
if (!runner.currentRunable()) {
|
const runable = runner.currentRunable();
|
||||||
|
|
||||||
|
if (!runable) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'expect' was used when there was no current spec, this could be because an asynchronous test timed out"
|
"'expect' was used when there was no current spec, this could be because an asynchronous test timed out"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return runner.currentRunable().expect(actual);
|
return runable.expectationFactory(actual, runable);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.expectAsync = function(actual) {
|
this.expectAsync = function(actual) {
|
||||||
if (!runner.currentRunable()) {
|
const runable = runner.currentRunable();
|
||||||
|
|
||||||
|
if (!runable) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out"
|
"'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return runner.currentRunable().expectAsync(actual);
|
return runable.asyncExpectationFactory(actual, runable);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.throwUnless = function(actual) {
|
||||||
|
const runable = runner.currentRunable();
|
||||||
|
return throwUnlessFactory(actual, runable);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.throwUnlessAsync = function(actual) {
|
||||||
|
const runable = runner.currentRunable();
|
||||||
|
return throwUnlessAsyncFactory(actual, runable);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||||
@@ -3531,7 +3580,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
lines.unshift(stackTrace.message);
|
lines.unshift(stackTrace.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error.cause) {
|
if (error.cause && error.cause instanceof Error) {
|
||||||
const substack = this.stack_(error.cause, {
|
const substack = this.stack_(error.cause, {
|
||||||
messageHandling: 'require'
|
messageHandling: 'require'
|
||||||
});
|
});
|
||||||
@@ -3566,7 +3615,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
const result = {};
|
const result = {};
|
||||||
let empty = true;
|
let empty = true;
|
||||||
|
|
||||||
for (const prop in error) {
|
for (const prop of Object.keys(error)) {
|
||||||
if (ignoredProperties.includes(prop)) {
|
if (ignoredProperties.includes(prop)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -8232,6 +8281,54 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
|||||||
return env.expectAsync(actual);
|
return env.expectAsync(actual);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an asynchronous expectation for a spec and throw an error if it fails.
|
||||||
|
*
|
||||||
|
* This is intended to allow Jasmine matchers to be used with tools like
|
||||||
|
* testing-library's `waitFor`, which expect matcher failures to throw
|
||||||
|
* exceptions and not trigger a spec failure if the exception is caught.
|
||||||
|
* It can also be used to integration-test custom matchers.
|
||||||
|
*
|
||||||
|
* If the resulting expectation fails, a {@link ThrowUnlessFailure} will be
|
||||||
|
* thrown. A failed expectation will not result in a spec failure unless the
|
||||||
|
* exception propagates back to Jasmine, either via the call stack or via
|
||||||
|
* the global unhandled exception/unhandled promise rejection events.
|
||||||
|
* @name throwUnlessAsync
|
||||||
|
* @since 5.1.0
|
||||||
|
* @function
|
||||||
|
* @param actual
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {matchers}
|
||||||
|
*/
|
||||||
|
throwUnlessAsync: function(actual) {
|
||||||
|
return env.throwUnless(actual);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an expectation for a spec and throw an error if it fails.
|
||||||
|
*
|
||||||
|
* This is intended to allow Jasmine matchers to be used with tools like
|
||||||
|
* testing-library's `waitFor`, which expect matcher failures to throw
|
||||||
|
* exceptions and not trigger a spec failure if the exception is caught.
|
||||||
|
* It can also be used to integration-test custom matchers.
|
||||||
|
*
|
||||||
|
* If the resulting expectation fails, a {@link ThrowUnlessFailure} will be
|
||||||
|
* thrown. A failed expectation will not result in a spec failure unless the
|
||||||
|
* exception propagates back to Jasmine, either via the call stack or via
|
||||||
|
* the global unhandled exception/unhandled promise rejection events.
|
||||||
|
* @name throwUnless
|
||||||
|
* @since 5.1.0
|
||||||
|
* @function
|
||||||
|
* @param actual
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {matchers}
|
||||||
|
*/
|
||||||
|
throwUnless: function(actual) {
|
||||||
|
return env.throwUnless(actual);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a spec as pending, expectation results will be ignored.
|
* Mark a spec as pending, expectation results will be ignored.
|
||||||
* @name pending
|
* @name pending
|
||||||
@@ -9755,14 +9852,6 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
this.result.properties[key] = value;
|
this.result.properties[key] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
Suite.prototype.expect = function(actual) {
|
|
||||||
return this.expectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Suite.prototype.expectAsync = function(actual) {
|
|
||||||
return this.asyncExpectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Suite.prototype.getFullName = function() {
|
Suite.prototype.getFullName = function() {
|
||||||
const fullName = [];
|
const fullName = [];
|
||||||
for (
|
for (
|
||||||
@@ -10713,5 +10802,5 @@ getJasmineRequireObj().UserContext = function(j$) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getJasmineRequireObj().version = function() {
|
getJasmineRequireObj().version = function() {
|
||||||
return '5.0.1';
|
return '5.1.0';
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "jasmine-core",
|
"name": "jasmine-core",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"version": "5.0.1",
|
"version": "5.1.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/jasmine/jasmine.git"
|
"url": "https://github.com/jasmine/jasmine.git"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
"grunt-css-url-embed": "^1.11.1",
|
"grunt-css-url-embed": "^1.11.1",
|
||||||
"grunt-sass": "^3.0.2",
|
"grunt-sass": "^3.0.2",
|
||||||
"jasmine": "^5.0.0",
|
"jasmine": "^5.0.0",
|
||||||
"jasmine-browser-runner": "^2.0.0",
|
"jasmine-browser-runner": "github:jasmine/jasmine-browser-runner",
|
||||||
"jsdom": "^22.0.0",
|
"jsdom": "^22.0.0",
|
||||||
"load-grunt-tasks": "^5.1.0",
|
"load-grunt-tasks": "^5.1.0",
|
||||||
"prettier": "1.17.1",
|
"prettier": "1.17.1",
|
||||||
@@ -97,7 +97,8 @@
|
|||||||
],
|
],
|
||||||
"space-before-blocks": "error",
|
"space-before-blocks": "error",
|
||||||
"no-eval": "error",
|
"no-eval": "error",
|
||||||
"no-var": "error"
|
"no-var": "error",
|
||||||
|
"no-debugger": "error"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
|
|||||||
39
release_notes/5.1.0.md
Normal file
39
release_notes/5.1.0.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Jasmine Core 5.1.0 Release Notes
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
* Exclude inherited Error properties from stack trace
|
||||||
|
|
||||||
|
* Fixed error when formatting Error object with non-Error cause property
|
||||||
|
|
||||||
|
Merges [#2013](https://github.com/jasmine/jasmine/pull/2013) from @angrycat9000.
|
||||||
|
|
||||||
|
Fixes [#2011](https://github.com/jasmine/jasmine/issues/2011).
|
||||||
|
|
||||||
|
* Added `throwUnless` and `throwUnlessAsync`
|
||||||
|
|
||||||
|
These are similar to `expect` and `expectAsync` except that they throw
|
||||||
|
exceptions rather than recording matcher failures as spec/suite failures.
|
||||||
|
They're intended to support using Jasmine matchers in [testing-library's](https://testing-library.com/)
|
||||||
|
`waitFor`, and also provide a way to integration-test custom matchers.
|
||||||
|
|
||||||
|
Fixes [#2003](https://github.com/jasmine/jasmine/issues/2003).
|
||||||
|
|
||||||
|
Fixes [#1980](https://github.com/jasmine/jasmine/issues/1980).
|
||||||
|
|
||||||
|
## Supported environments
|
||||||
|
|
||||||
|
jasmine-core 5.1.0 has been tested in the following environments.
|
||||||
|
|
||||||
|
| Environment | Supported versions |
|
||||||
|
|-------------------|--------------------|
|
||||||
|
| Node | 18, 20 |
|
||||||
|
| Safari | 15-16 |
|
||||||
|
| Chrome | 114 |
|
||||||
|
| Firefox | 102, 113 |
|
||||||
|
| Edge | 113 |
|
||||||
|
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
|
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||||
@@ -197,7 +197,7 @@ describe('ExceptionFormatter', function() {
|
|||||||
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
|
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('includes error properties in stack', function() {
|
it("includes the error's own properties in stack", function() {
|
||||||
const error = new Error('an error');
|
const error = new Error('an error');
|
||||||
error.someProperty = 'hello there';
|
error.someProperty = 'hello there';
|
||||||
|
|
||||||
@@ -206,6 +206,19 @@ describe('ExceptionFormatter', function() {
|
|||||||
expect(result).toMatch(/error properties:.*someProperty.*hello there/);
|
expect(result).toMatch(/error properties:.*someProperty.*hello there/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not include inherited error properties', function() {
|
||||||
|
function CustomError(msg) {
|
||||||
|
Error.call(this, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomError.prototype = new Error();
|
||||||
|
CustomError.prototype.anInheritedProp = 'something';
|
||||||
|
const error = new CustomError('nope');
|
||||||
|
|
||||||
|
const result = new jasmineUnderTest.ExceptionFormatter().stack(error);
|
||||||
|
expect(result).not.toContain('anInheritedProp');
|
||||||
|
});
|
||||||
|
|
||||||
describe('When omitMessage is true', function() {
|
describe('When omitMessage is true', function() {
|
||||||
it('filters the message from V8-style stack traces', function() {
|
it('filters the message from V8-style stack traces', function() {
|
||||||
const error = {
|
const error = {
|
||||||
@@ -291,6 +304,26 @@ describe('ExceptionFormatter', function() {
|
|||||||
.withContext('first root cause stack frame')
|
.withContext('first root cause stack frame')
|
||||||
.toContain('ExceptionFormatterSpec.js');
|
.toContain('ExceptionFormatterSpec.js');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not throw if cause is a non Error', function() {
|
||||||
|
const formatter = new jasmineUnderTest.ExceptionFormatter();
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
formatter.stack(
|
||||||
|
new Error('error', {
|
||||||
|
cause: function() {}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}).not.toThrowError();
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
formatter.stack(
|
||||||
|
new Error('error', {
|
||||||
|
cause: 'another error'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}).not.toThrowError();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4334,6 +4334,115 @@ describe('Env integration', function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('throwUnless', function() {
|
||||||
|
it('throws when the matcher fails', async function() {
|
||||||
|
let thrown;
|
||||||
|
|
||||||
|
env.it('a spec', function() {
|
||||||
|
try {
|
||||||
|
env.throwUnless(1).toEqual(2);
|
||||||
|
} catch (e) {
|
||||||
|
thrown = e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(thrown).toBeInstanceOf(Error);
|
||||||
|
expect(thrown.passed).toEqual(false);
|
||||||
|
expect(thrown.matcherName).toEqual('toEqual');
|
||||||
|
expect(thrown.message).toEqual('Expected 1 to equal 2.');
|
||||||
|
expect(thrown.actual).toEqual(1);
|
||||||
|
expect(thrown.expected).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when the matcher passes', async function() {
|
||||||
|
let threw = false;
|
||||||
|
|
||||||
|
env.it('a spec', function() {
|
||||||
|
try {
|
||||||
|
env.throwUnless(1).toEqual(1);
|
||||||
|
} catch (e) {
|
||||||
|
threw = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(threw).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not cause a failure if the error does not propagate back to jasmine', async function() {
|
||||||
|
env.it('a spec', function() {
|
||||||
|
try {
|
||||||
|
env.throwUnless(1).toEqual(2);
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||||
|
env.addReporter(reporter);
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||||
|
jasmine.objectContaining({ status: 'passed' })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('throwUnlessAsync', function() {
|
||||||
|
it('throws when the matcher fails', async function() {
|
||||||
|
const promise = Promise.resolve('a');
|
||||||
|
let thrown;
|
||||||
|
|
||||||
|
env.it('a spec', async function() {
|
||||||
|
try {
|
||||||
|
await env.throwUnlessAsync(promise).toBeResolvedTo('b');
|
||||||
|
} catch (e) {
|
||||||
|
thrown = e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(thrown).toBeInstanceOf(Error);
|
||||||
|
expect(thrown.passed).toEqual(false);
|
||||||
|
expect(thrown.matcherName).toEqual('toBeResolvedTo');
|
||||||
|
expect(thrown.message).toEqual(
|
||||||
|
"Expected a promise to be resolved to 'b' but it was resolved to 'a'."
|
||||||
|
);
|
||||||
|
expect(thrown.actual).toBe(promise);
|
||||||
|
expect(thrown.expected).toEqual('b');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when the matcher passes', async function() {
|
||||||
|
let threw = false;
|
||||||
|
|
||||||
|
env.it('a spec', async function() {
|
||||||
|
try {
|
||||||
|
await env.throwUnlessAsync(Promise.resolve()).toBeResolved();
|
||||||
|
} catch (e) {
|
||||||
|
threw = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(threw).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not cause a failure if the error does not propagate back to jasmine', async function() {
|
||||||
|
env.it('a spec', async function() {
|
||||||
|
try {
|
||||||
|
await env.throwUnlessAsync(Promise.resolve()).toBeRejected();
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
const reporter = jasmine.createSpyObj('reporter', ['specDone']);
|
||||||
|
env.addReporter(reporter);
|
||||||
|
|
||||||
|
await env.execute();
|
||||||
|
expect(reporter.specDone).toHaveBeenCalledWith(
|
||||||
|
jasmine.objectContaining({ status: 'passed' })
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
function browserEventMethods() {
|
function browserEventMethods() {
|
||||||
return {
|
return {
|
||||||
listeners_: { error: [], unhandledrejection: [] },
|
listeners_: { error: [], unhandledrejection: [] },
|
||||||
|
|||||||
@@ -28,16 +28,19 @@ module.exports = {
|
|||||||
random: true,
|
random: true,
|
||||||
browser: {
|
browser: {
|
||||||
name: process.env.JASMINE_BROWSER || 'firefox',
|
name: process.env.JASMINE_BROWSER || 'firefox',
|
||||||
useSauce: process.env.USE_SAUCE === 'true',
|
useRemoteSeleniumGrid: process.env.USE_SAUCE === 'true',
|
||||||
sauce: {
|
remoteSeleniumGrid: {
|
||||||
name: `jasmine-core ${new Date().toISOString()}`,
|
url: 'https://ondemand.saucelabs.com/wd/hub',
|
||||||
os: process.env.SAUCE_OS,
|
|
||||||
browserVersion: process.env.SAUCE_BROWSER_VERSION,
|
browserVersion: process.env.SAUCE_BROWSER_VERSION,
|
||||||
build: `Core ${process.env.TRAVIS_BUILD_NUMBER || 'Ran locally'}`,
|
platformName: process.env.SAUCE_OS,
|
||||||
tags: ['Jasmine-Core'],
|
'sauce:options': {
|
||||||
tunnelIdentifier: process.env.SAUCE_TUNNEL_IDENTIFIER,
|
name: `jasmine-core ${new Date().toISOString()}`,
|
||||||
username: process.env.SAUCE_USERNAME,
|
build: `Core ${process.env.CIRCLE_BUILD_NUM || 'Ran locally'}`,
|
||||||
accessKey: process.env.SAUCE_ACCESS_KEY
|
tags: ['Jasmine-Core'],
|
||||||
|
tunnelIdentifier: process.env.SAUCE_TUNNEL_IDENTIFIER,
|
||||||
|
username: process.env.SAUCE_USERNAME,
|
||||||
|
accessKey: process.env.SAUCE_ACCESS_KEY
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -264,6 +264,49 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleThrowUnlessFailure = function(passed, result) {
|
||||||
|
if (!passed) {
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
* @name ThrowUnlessFailure
|
||||||
|
* @extends Error
|
||||||
|
* @description Represents a failure of an expectation evaluated with
|
||||||
|
* {@link throwUnless}. Properties of this error are a subset of the
|
||||||
|
* properties of {@link Expectation} and have the same values.
|
||||||
|
* @property {String} matcherName - The name of the matcher that was executed for this expectation.
|
||||||
|
* @property {String} message - The failure message for the expectation.
|
||||||
|
* @property {Boolean} passed - Whether the expectation passed or failed.
|
||||||
|
* @property {Object} expected - If the expectation failed, what was the expected value.
|
||||||
|
* @property {Object} actual - If the expectation failed, what actual value was produced.
|
||||||
|
*/
|
||||||
|
const error = new Error(result.message);
|
||||||
|
error.passed = result.passed;
|
||||||
|
error.message = result.message;
|
||||||
|
error.expected = result.expected;
|
||||||
|
error.actual = result.actual;
|
||||||
|
error.matcherName = result.matcherName;
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const throwUnlessFactory = function(actual, spec) {
|
||||||
|
return j$.Expectation.factory({
|
||||||
|
matchersUtil: runableResources.makeMatchersUtil(),
|
||||||
|
customMatchers: runableResources.customMatchers(),
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: handleThrowUnlessFailure
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const throwUnlessAsyncFactory = function(actual, spec) {
|
||||||
|
return j$.Expectation.asyncFactory({
|
||||||
|
matchersUtil: runableResources.makeMatchersUtil(),
|
||||||
|
customAsyncMatchers: runableResources.customAsyncMatchers(),
|
||||||
|
actual: actual,
|
||||||
|
addExpectationResult: handleThrowUnlessFailure
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// TODO: Unify recordLateError with recordLateExpectation? The extra
|
// TODO: Unify recordLateError with recordLateExpectation? The extra
|
||||||
// diagnostic info added by the latter is probably useful in most cases.
|
// diagnostic info added by the latter is probably useful in most cases.
|
||||||
function recordLateError(error) {
|
function recordLateError(error) {
|
||||||
@@ -767,23 +810,37 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.expect = function(actual) {
|
this.expect = function(actual) {
|
||||||
if (!runner.currentRunable()) {
|
const runable = runner.currentRunable();
|
||||||
|
|
||||||
|
if (!runable) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'expect' was used when there was no current spec, this could be because an asynchronous test timed out"
|
"'expect' was used when there was no current spec, this could be because an asynchronous test timed out"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return runner.currentRunable().expect(actual);
|
return runable.expectationFactory(actual, runable);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.expectAsync = function(actual) {
|
this.expectAsync = function(actual) {
|
||||||
if (!runner.currentRunable()) {
|
const runable = runner.currentRunable();
|
||||||
|
|
||||||
|
if (!runable) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out"
|
"'expectAsync' was used when there was no current spec, this could be because an asynchronous test timed out"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return runner.currentRunable().expectAsync(actual);
|
return runable.asyncExpectationFactory(actual, runable);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.throwUnless = function(actual) {
|
||||||
|
const runable = runner.currentRunable();
|
||||||
|
return throwUnlessFactory(actual, runable);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.throwUnlessAsync = function(actual) {
|
||||||
|
const runable = runner.currentRunable();
|
||||||
|
return throwUnlessAsyncFactory(actual, runable);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.beforeEach = function(beforeEachFunction, timeout) {
|
this.beforeEach = function(beforeEachFunction, timeout) {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
lines.unshift(stackTrace.message);
|
lines.unshift(stackTrace.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error.cause) {
|
if (error.cause && error.cause instanceof Error) {
|
||||||
const substack = this.stack_(error.cause, {
|
const substack = this.stack_(error.cause, {
|
||||||
messageHandling: 'require'
|
messageHandling: 'require'
|
||||||
});
|
});
|
||||||
@@ -102,7 +102,7 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
|||||||
const result = {};
|
const result = {};
|
||||||
let empty = true;
|
let empty = true;
|
||||||
|
|
||||||
for (const prop in error) {
|
for (const prop of Object.keys(error)) {
|
||||||
if (ignoredProperties.includes(prop)) {
|
if (ignoredProperties.includes(prop)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,14 +70,6 @@ getJasmineRequireObj().Spec = function(j$) {
|
|||||||
this.result.properties[key] = value;
|
this.result.properties[key] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
Spec.prototype.expect = function(actual) {
|
|
||||||
return this.expectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Spec.prototype.expectAsync = function(actual) {
|
|
||||||
return this.asyncExpectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Spec.prototype.execute = function(
|
Spec.prototype.execute = function(
|
||||||
queueRunnerFactory,
|
queueRunnerFactory,
|
||||||
onComplete,
|
onComplete,
|
||||||
|
|||||||
@@ -28,14 +28,6 @@ getJasmineRequireObj().Suite = function(j$) {
|
|||||||
this.result.properties[key] = value;
|
this.result.properties[key] = value;
|
||||||
};
|
};
|
||||||
|
|
||||||
Suite.prototype.expect = function(actual) {
|
|
||||||
return this.expectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Suite.prototype.expectAsync = function(actual) {
|
|
||||||
return this.asyncExpectationFactory(actual, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
Suite.prototype.getFullName = function() {
|
Suite.prototype.getFullName = function() {
|
||||||
const fullName = [];
|
const fullName = [];
|
||||||
for (
|
for (
|
||||||
|
|||||||
@@ -225,6 +225,54 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
|||||||
return env.expectAsync(actual);
|
return env.expectAsync(actual);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an asynchronous expectation for a spec and throw an error if it fails.
|
||||||
|
*
|
||||||
|
* This is intended to allow Jasmine matchers to be used with tools like
|
||||||
|
* testing-library's `waitFor`, which expect matcher failures to throw
|
||||||
|
* exceptions and not trigger a spec failure if the exception is caught.
|
||||||
|
* It can also be used to integration-test custom matchers.
|
||||||
|
*
|
||||||
|
* If the resulting expectation fails, a {@link ThrowUnlessFailure} will be
|
||||||
|
* thrown. A failed expectation will not result in a spec failure unless the
|
||||||
|
* exception propagates back to Jasmine, either via the call stack or via
|
||||||
|
* the global unhandled exception/unhandled promise rejection events.
|
||||||
|
* @name throwUnlessAsync
|
||||||
|
* @since 5.1.0
|
||||||
|
* @function
|
||||||
|
* @param actual
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {matchers}
|
||||||
|
*/
|
||||||
|
throwUnlessAsync: function(actual) {
|
||||||
|
return env.throwUnless(actual);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an expectation for a spec and throw an error if it fails.
|
||||||
|
*
|
||||||
|
* This is intended to allow Jasmine matchers to be used with tools like
|
||||||
|
* testing-library's `waitFor`, which expect matcher failures to throw
|
||||||
|
* exceptions and not trigger a spec failure if the exception is caught.
|
||||||
|
* It can also be used to integration-test custom matchers.
|
||||||
|
*
|
||||||
|
* If the resulting expectation fails, a {@link ThrowUnlessFailure} will be
|
||||||
|
* thrown. A failed expectation will not result in a spec failure unless the
|
||||||
|
* exception propagates back to Jasmine, either via the call stack or via
|
||||||
|
* the global unhandled exception/unhandled promise rejection events.
|
||||||
|
* @name throwUnless
|
||||||
|
* @since 5.1.0
|
||||||
|
* @function
|
||||||
|
* @param actual
|
||||||
|
* @global
|
||||||
|
* @param {Object} actual - Actual computed value to test expectations against.
|
||||||
|
* @return {matchers}
|
||||||
|
*/
|
||||||
|
throwUnless: function(actual) {
|
||||||
|
return env.throwUnless(actual);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark a spec as pending, expectation results will be ignored.
|
* Mark a spec as pending, expectation results will be ignored.
|
||||||
* @name pending
|
* @name pending
|
||||||
|
|||||||
Reference in New Issue
Block a user