Merge branch 'main' into 3.99

This commit is contained in:
Steve Gravrock
2021-04-22 17:23:08 -07:00
24 changed files with 504 additions and 100 deletions

163
.circleci/config.yml Normal file
View File

@@ -0,0 +1,163 @@
# Run tests against supported Node versions, and (except for pull requests)
# against supported browsers.
version: 2.1
orbs:
node: circleci/node@3.0.0
executors:
node14:
docker:
- image: circleci/node:14
working_directory: ~/workspace
node12:
docker:
- image: circleci/node:12
working_directory: ~/workspace
node10:
docker:
- image: circleci/node:10
working_directory: ~/workspace
jobs:
build:
parameters:
executor:
type: executor
executor: << parameters.executor >>
steps:
- checkout
- run:
name: Report Node and NPM versions
command: echo "Using Node $(node --version) and NPM $(npm --version)"
- run:
name: Install dependencies
command: npm install
- run:
name: Build
command: npm run build
- persist_to_workspace:
root: .
paths:
- .
test_node: &test_node
parameters:
executor:
type: executor
executor: << parameters.executor >>
steps:
- attach_workspace:
at: .
- run:
name: Run tests
command: npm test
# Warning: Sometimes takes a very long time (>25 minutes) on Circle.
# Probably not a good idea to run it from anything but a nightly.
test_node_with_long_property_tests:
<<: *test_node
environment:
JASMINE_LONG_PROPERTY_TESTS: y
test_browsers:
executor: node14
steps:
- attach_workspace:
at: .
- run:
name: Install Sauce Connect
command: |
cd /tmp
curl https://saucelabs.com/downloads/sc-4.6.4-linux.tar.gz | tar zxf -
chmod +x sc-4.6.4-linux/bin/sc
mkdir ~/workspace/bin
cp sc-4.6.4-linux/bin/sc ~/workspace/bin
~/workspace/bin/sc --version
- run:
name: Run tests
command: |
# Do everything in one step because Sauce Connect won't exit
# cleanly if we kill it from a different step than it started in.
export PATH=$PATH:$HOME/workspace/bin
export SAUCE_TUNNEL_IDENTIFIER=$CIRCLE_BUILD_NUM
scripts/start-sauce-connect sauce-pidfile
set +o errexit
scripts/run-all-browsers
exitcode=$?
set -o errexit
scripts/stop-sauce-connect $(cat sauce-pidfile)
exit $exitcode
workflows:
version: 2
cron:
triggers:
- schedule:
# The choice of hour is somewhat load-bearing. test_browser currently
# tends to fail if there are other Sauce tunnels open. So we only
# run it at a time when that's unlikely.
# Times are UTC.
cron: "0 10 * * *"
filters:
branches:
only:
- main
jobs:
- build:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
- build:
executor: node10
name: build_node_10
- test_node_with_long_property_tests:
executor: node14
requires:
- build_node_14
- test_node:
executor: node12
name: test_node_12
requires:
- build_node_12
- test_node:
executor: node10
name: test_node_10
requires:
- build_node_10
- test_browsers:
requires:
- build_node_14
filters:
branches:
only: main
push:
jobs:
- build:
executor: node14
name: build_node_14
- build:
executor: node12
name: build_node_12
- build:
executor: node10
name: build_node_10
- test_node:
executor: node14
name: test_node_14
requires:
- build_node_14
- test_node:
executor: node12
name: test_node_12
requires:
- build_node_12
- test_node:
executor: node10
name: test_node_10
requires:
- build_node_10

View File

@@ -56,15 +56,15 @@ Jasmine supports the following environments:
* Browsers
* IE10+
* Edge Latest
* Firefox Latest
* Chrome Latest
* Edge latest
* Firefox latest, 78, and 68
* Chrome latest
* Safari 8+
* Node.js
* 8
* 10
* 12
* 14
## Development
@@ -99,11 +99,18 @@ Follow these tips and your pull request, patch, or suggestion is much more likel
### Running Specs
Jasmine uses some internal tooling to test itself in browser on Travis. This tooling _should_ work locally as well.
Be sure to run the tests in at least one supported Node version and at least a
couple of supported browsers. It's also a good idea to run the tests in Internet
Explorer if you've touched code in `src/html`, if your change involves newer
JavaScript language/runtime features, or if you're unfamiliar with writing code
for older browsers. To run the tests in Node, simply use `npm test` as described
above. To run the tests in a browser, run `npm run serve` and then visit
`http://localhost:8888`.
$ node spec/support/ci.js
If you have the necessary Selenium drivers installed, you can also use Jasmine's
CI tooling:
You can also set the `JASMINE_BROWSER` environment variable to specify which browser should be used.
$ JASMINE_BROWSER=<name of browser> node spec/support/ci.js
The easiest way to run the tests in **Internet Explorer** is to run a VM that has IE installed. It's easy to do this with VirtualBox.
@@ -112,7 +119,7 @@ The easiest way to run the tests in **Internet Explorer** is to run a VM that ha
1. Unzip the downloaded archive. There should be an OVA file inside.
1. In VirtualBox, choose `File > Import Appliance` and select the OVA file. Accept the default settings in the dialog that appears. Now you have a Windows VM!
1. Run the VM and start IE.
1. With `npm run serve` running on your host machine, navigate to `http://10.0.2.2:8888` in IE.
1. With `npm run serve` running on your host machine, navigate to `http://<your IP address>:8888` in IE.
## Before Committing or Submitting a Pull Request
@@ -123,5 +130,5 @@ The easiest way to run the tests in **Internet Explorer** is to run a VM that ha
* We do this because `jasmine.js` and `jasmine-html.js` are auto-generated (as you've seen in the previous steps) and accepting multiple pull requests when this auto-generated file changes causes lots of headaches
* When we accept your pull request, we will generate these files as a separate commit and merge the entire branch into main
Note that we use Travis for Continuous Integration. We only accept green pull requests.
Note that we use Circle CI for Continuous Integration. We only accept green pull requests.

View File

@@ -16,7 +16,8 @@ jasmine-core.gemspec
.jshintrc
.rspec
.sass-cache/
.travis.yml
.circleci
scripts/
*.sh
*.py
Gruntfile.js

View File

@@ -1,60 +0,0 @@
language: node_js
node_js: 14
script: $TEST_COMMAND
env:
global:
- USE_SAUCE=true
- TEST_COMMAND="bash travis-core-script.sh"
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
matrix:
include:
- node_js: "14"
env: JASMINE_LONG_PROPERTY_TESTS="y" TEST_COMMAND="npm test"
- node_js: "12"
env: TEST_COMMAND="npm test"
- node_js: "10"
env: TEST_COMMAND="npm test"
- env: JASMINE_BROWSER="internet explorer" SAUCE_BROWSER_VERSION=11 SAUCE_OS="Windows 8.1"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="internet explorer" SAUCE_BROWSER_VERSION=10 SAUCE_OS="Windows 8"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="firefox" SAUCE_BROWSER_VERSION='' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="firefox" SAUCE_BROWSER_VERSION='78' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="firefox" SAUCE_BROWSER_VERSION='68' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="chrome" SAUCE_BROWSER_VERSION='' SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="safari" SAUCE_BROWSER_VERSION="14" SAUCE_OS="OS X 11.0"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="safari" SAUCE_BROWSER_VERSION="13" SAUCE_OS="OS X 10.13"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="safari" SAUCE_BROWSER_VERSION="8" SAUCE_OS="OS X 10.10"
if: type != pull_request
addons:
sauce_connect: true
- env: JASMINE_BROWSER="MicrosoftEdge" SAUCE_BROWSER_VERSION="" SAUCE_OS="Windows 10"
if: type != pull_request
addons:
sauce_connect: true

View File

@@ -1,6 +1,6 @@
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/main/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.com/jasmine/jasmine.svg?branch=main)](https://travis-ci.com/jasmine/jasmine)
[![Build Status](https://circleci.com/gh/jasmine/jasmine.svg?style=shield)](https://circleci.com/gh/jasmine/jasmine)
[![Open Source Helpers](https://www.codetriage.com/jasmine/jasmine/badges/users.svg)](https://www.codetriage.com/jasmine/jasmine)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fjasmine%2Fjasmine?ref=badge_shield)
@@ -11,8 +11,6 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html).
Upgrading from Jasmine 2.x? Check out the [3.0 release notes](https://github.com/jasmine/jasmine/blob/v3.0.0/release_notes/3.0.md) for a list of what's new (including breaking changes).
## Contributing
Please read the [contributors' guide](https://github.com/jasmine/jasmine/blob/main/.github/CONTRIBUTING.md).

View File

@@ -35,9 +35,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, version.rb, package.json)
1. Push
1. Wait for Travis to go green
1. Wait for Circle CI to go green
### Build standalone distribution
@@ -77,7 +78,7 @@ Probably only need to do this when releasing a minor version, and not a patch ve
1. Create release notes using Anchorman as above
1. In `package.json`, update both the package version and the jasmine-core dependency version
1. Commit and push.
1. Wait for Travis to go green again.
1. Wait for Circle CI to go green again.
1. `grunt release `. (Note: This will publish the package by running `npm publish`.)
#### Gem
@@ -86,7 +87,7 @@ Probably only need to do this when releasing a minor version, and not a patch ve
1. Update the version number in `lib/jasmine/version.rb`.
1. Update the jasmine-core dependency version in `jasmine.gemspec`.
1. Commit and push.
1. Wait for Travis to go green again.
1. Wait for Circle CI to go green again.
1. `rake release`
### Finally

View File

@@ -1710,6 +1710,13 @@ getJasmineRequireObj().Env = function(j$) {
defaultResourcesForRunnable(topSuite.id);
currentDeclarationSuite = topSuite;
/**
* Provides the root suite, through which all suites and specs can be
* accessed.
* @function
* @name Env#topSuite
* @return {Suite} the root suite
*/
this.topSuite = function() {
return topSuite;
};
@@ -3103,6 +3110,18 @@ getJasmineRequireObj().CallTracker = function(j$) {
return call ? call.args : [];
};
/**
* Get the "this" object that was passed to a specific invocation of this spy.
* @name Spy#calls#thisFor
* @function
* @param {Integer} index The 0-based invocation index.
* @return {Object?}
*/
this.thisFor = function(index) {
var call = calls[index];
return call ? call.object : undefined;
};
/**
* Get the raw calls array for this spy.
* @name Spy#calls#all
@@ -4243,7 +4262,22 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
this.jasmineHandlers = {};
this.installOne_ = function installOne_(errorType, jasmineMessage) {
function taggedOnError(error) {
error.jasmineMessage = jasmineMessage + ': ' + error;
var substituteMsg;
if (error) {
error.jasmineMessage = jasmineMessage + ': ' + error;
} else {
substituteMsg = jasmineMessage + ' with no error or message';
if (errorType === 'unhandledRejection') {
substituteMsg +=
'\n' +
'(Tip: to get a useful stack trace, use ' +
'Promise.reject(new Error(...)) instead of Promise.reject().)';
}
error = new Error(substituteMsg);
}
var handler = handlers[handlers.length - 1];
@@ -9173,10 +9207,26 @@ getJasmineRequireObj().StackTrace = function(j$) {
};
getJasmineRequireObj().Suite = function(j$) {
/**
* @interface Suite
* @see Env#topSuite
*/
function Suite(attrs) {
this.env = attrs.env;
this.id = attrs.id;
/**
* The parent of this suite, or null if this is the top suite.
* @name Suite#parentSuite
* @readonly
* @type {Suite}
*/
this.parentSuite = attrs.parentSuite;
/**
* The description passed to the {@link describe} that created this suite.
* @name Suite#description
* @readonly
* @type {string}
*/
this.description = attrs.description;
this.expectationFactory = attrs.expectationFactory;
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
@@ -9190,6 +9240,11 @@ getJasmineRequireObj().Suite = function(j$) {
this.timer = attrs.timer || new j$.Timer();
/**
* The suite's children.
* @name Suite#children
* @type {Array.<(Spec|Suite)>}
*/
this.children = [];
/**
@@ -9227,6 +9282,12 @@ getJasmineRequireObj().Suite = function(j$) {
return this.asyncExpectationFactory(actual, this);
};
/**
* The full description including all ancestors of this suite.
* @name Suite#getFullName
* @function
* @returns {string}
*/
Suite.prototype.getFullName = function() {
var fullName = [];
for (

View File

@@ -40,7 +40,7 @@
"grunt-css-url-embed": "^1.11.1",
"grunt-sass": "^3.0.2",
"jasmine": "^3.4.0",
"jasmine-browser-runner": "^0.4.0",
"jasmine-browser-runner": "github:jasmine/jasmine-browser#main",
"jsdom": "^15.0.0",
"load-grunt-tasks": "^4.0.0",
"node-sass": "^4.11.0",

45
scripts/run-all-browsers Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/sh
run_browser() {
browser=$1
version=$2
description="$browser $version"
if [ $version = "latest" ]; then
version=""
fi
echo
echo
echo "Running $description"
echo
USE_SAUCE=true JASMINE_BROWSER=$browser SAUCE_BROWSER_VERSION=$version npm run ci
if [ $? -eq 0 ]; then
echo "PASS: $description" >> "$passfile"
else
echo "FAIL: $description" >> "$failfile"
fi
}
passfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
failfile=`mktemp -t jasmine-results.XXXXXX` || exit 1
run_browser "internet explorer" 11
run_browser "internet explorer" 10
run_browser firefox latest
run_browser firefox 78
run_browser firefox 68
run_browser safari 14
run_browser safari 13
run_browser safari 12
run_browser safari 11
run_browser safari 10
run_browser safari 9
run_browser safari 8
run_browser MicrosoftEdge latest
echo
cat "$passfile" "$failfile"
if [ -s "$failfile" ]; then
exit 1
fi

37
scripts/start-sauce-connect Executable file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
if [ $# -gt 1 -o "$1" = "--help" ]; then
echo "Usage: $0 [pidfile]" 1>&2
exit
fi
if [ -z "$1" ]; then
pidfile=`mktemp`
else
pidfile="$1"
fi
outfile=`mktemp`
echo "Starting Sauce Connect"
if [ -z "$SAUCE_TUNNEL_IDENTIFIER" ]; then
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" 2>&1 | tee "$outfile" &
else
sc -u "$SAUCE_USERNAME" -k "$SAUCE_ACCESS_KEY" -X 4445 --pidfile "$pidfile" -i "$SAUCE_TUNNEL_IDENTIFIER" 2>&1 | tee "$outfile" &
fi
while ! fgrep "Sauce Connect is up, you may start your tests." "$outfile" > /dev/null; do
sleep 1
if ! ps -p $(cat "$pidfile") > /dev/null; then
echo "Sauce Connect exited"
exit 1
fi
done
if ! nc -z localhost 4445; then
echo "Can't connect to Sauce tunnel"
killall sc
exit 1
fi

33
scripts/stop-sauce-connect Executable file
View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -o errexit
set -o pipefail
if [ -z "$1" ]; then
echo "Usage: $0 sauce-connect-pid" 1>&2
exit
fi
pid="$1"
echo "PID: $pid"
echo "Stopping Sauce Connect"
# Sauce Connect docs say that we can just kill -9 it if we don't care about
# failing any ongoing sessions. In practice, that sometimes works but usually
# leaks a tunnel so badly that you can't even stop it from the web UI.
# Instead of doing that, we give Sauce Connect some time to shut down
# gracefully and then give up.
kill -INT $pid
# Wait up to 2 minutes, then give up if it's still running
n=0
while [ $n -lt 120 ] && ps -p $pid > /dev/null; do
sleep 1
kill -INT $pid 2> /dev/null || true
n=$(($n + 1))
done
if ps -p $pid > /dev/null; then
echo "Could not shut down Sauce Connect"
fi
exit $exitcode

View File

@@ -30,6 +30,20 @@ describe('CallTracker', function() {
expect(callTracker.argsFor(1)).toEqual([0, 'foo']);
});
it("tracks the 'this' object from each execution", function() {
var callTracker = new jasmineUnderTest.CallTracker();
var this0 = {},
this1 = {};
callTracker.track({ object: this0, args: [] });
callTracker.track({ object: this1, args: [] });
callTracker.track({ args: [] });
expect(callTracker.thisFor(0)).toBe(this0);
expect(callTracker.thisFor(1)).toBe(this1);
expect(callTracker.thisFor(2)).toBe(undefined);
});
it('returns any empty array when there was no call', function() {
var callTracker = new jasmineUnderTest.CallTracker();

View File

@@ -122,7 +122,7 @@ describe('GlobalErrors', function() {
errors.uninstall();
});
it('reports uncaughtException in node.js', function() {
it('reports uncaught exceptions in node.js', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
@@ -170,7 +170,7 @@ describe('GlobalErrors', function() {
);
});
it('reports unhandledRejection in node.js', function() {
it('reports unhandled promise rejections in node.js', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
@@ -218,6 +218,38 @@ describe('GlobalErrors', function() {
);
});
it('reports unhandled promise rejections in node.js when no error is provided', function() {
var fakeGlobal = {
process: {
on: jasmine.createSpy('process.on'),
removeListener: function() {},
listeners: function() {
return [];
},
removeAllListeners: function() {}
}
},
handler = jasmine.createSpy('errorHandler'),
errors = new jasmineUnderTest.GlobalErrors(fakeGlobal);
errors.install();
errors.pushListener(handler);
expect(fakeGlobal.process.on.calls.argsFor(1)[0]).toEqual(
'unhandledRejection'
);
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
addedListener(undefined);
expect(handler).toHaveBeenCalledWith(
new Error(
'Unhandled promise rejection with no error or message\n' +
'(Tip: to get a useful stack trace, use ' +
'Promise.reject(new Error(...)) instead of Promise.reject().)'
)
);
});
describe('Reporting unhandled promise rejections in the browser', function() {
it('subscribes and unsubscribes from the unhandledrejection event', function() {
var fakeGlobal = jasmine.createSpyObj('globalErrors', [

View File

@@ -90,7 +90,7 @@ describe('SpyStrategy', function() {
expect(function() {
spyStrategy.exec();
}).toThrow({ code: 'ESRCH' });
}).toThrow(jasmine.objectContaining({ code: 'ESRCH' }));
expect(originalFn).not.toHaveBeenCalled();
});

View File

@@ -93,7 +93,6 @@ describe('asymmetricEqualityTesterArgCompatShim', function() {
'flatMap',
'includes',
'keys',
'toSource',
'values'
],
shim = jasmineUnderTest.asymmetricEqualityTesterArgCompatShim({}, []),

View File

@@ -683,8 +683,8 @@ describe('Env integration', function() {
});
env.execute(null, function() {
// Expect >= 9 rather than >= 10 to compensate for clock imprecision
expect(duration).toBeGreaterThanOrEqual(9);
// Expect > 0 to compensate for clock imprecision
expect(duration).toBeGreaterThan(0);
done();
});
});
@@ -2886,6 +2886,8 @@ describe('Env integration', function() {
resolve = res;
});
env.configure({ random: false });
env.describe('a suite', function() {
env.it('does not wait', function() {
// Note: we intentionally don't return the result of each expectAsync.
@@ -2895,6 +2897,12 @@ describe('Env integration', function() {
});
});
env.it('another spec', function(done) {
// This is here to make sure that the async expectation evaluates
// before the Jasmine under test finishes, especially on Safari 8 and 9.
setTimeout(done, 10);
});
env.addReporter({
specDone: function() {
resolve();
@@ -2941,6 +2949,8 @@ describe('Env integration', function() {
resolve = res;
});
env.configure({ random: false });
env.describe('a suite', function() {
env.afterAll(function() {
// Note: we intentionally don't return the result of expectAsync.
@@ -2951,6 +2961,12 @@ describe('Env integration', function() {
env.it('is a spec', function() {});
});
env.it('another spec', function(done) {
// This is here to make sure that the async expectation evaluates
// before the Jasmine under test finishes, especially on Safari 8 and 9.
setTimeout(done, 10);
});
env.addReporter({
suiteDone: function() {
resolve();

View File

@@ -99,4 +99,13 @@ describe('npm package', function() {
expect(images).toContain('jasmine-horizontal.svg');
expect(images).toContain('jasmine_favicon.png');
});
it('does not have CI config files and scripts', function() {
expect(fs.existsSync(path.resolve(this.tmpDir, 'package/.circleci'))).toBe(
false
);
expect(fs.existsSync(path.resolve(this.tmpDir, 'package/scripts'))).toBe(
false
);
});
});

View File

@@ -43,9 +43,7 @@ module.exports = {
browserVersion: process.env.SAUCE_BROWSER_VERSION,
build: `Core ${process.env.TRAVIS_BUILD_NUMBER || 'Ran locally'}`,
tags: ['Jasmine-Core'],
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER
? process.env.TRAVIS_JOB_NUMBER.toString()
: null,
tunnelIdentifier: process.env.SAUCE_TUNNEL_IDENTIFIER,
username: process.env.SAUCE_USERNAME,
accessKey: process.env.SAUCE_ACCESS_KEY
}

View File

@@ -17,6 +17,7 @@
"helpers/integrationMatchers.js",
"helpers/promises.js",
"helpers/requireFastCheck.js",
"helpers/overrideConsoleLogForCircleCi.js",
"helpers/nodeDefineJasmineUnderTest.js",
"helpers/resetEnv.js"
],

View File

@@ -49,6 +49,18 @@ getJasmineRequireObj().CallTracker = function(j$) {
return call ? call.args : [];
};
/**
* Get the "this" object that was passed to a specific invocation of this spy.
* @name Spy#calls#thisFor
* @function
* @param {Integer} index The 0-based invocation index.
* @return {Object?}
*/
this.thisFor = function(index) {
var call = calls[index];
return call ? call.object : undefined;
};
/**
* Get the raw calls array for this spy.
* @name Spy#calls#all

View File

@@ -708,6 +708,13 @@ getJasmineRequireObj().Env = function(j$) {
defaultResourcesForRunnable(topSuite.id);
currentDeclarationSuite = topSuite;
/**
* Provides the root suite, through which all suites and specs can be
* accessed.
* @function
* @name Env#topSuite
* @return {Suite} the root suite
*/
this.topSuite = function() {
return topSuite;
};

View File

@@ -17,7 +17,22 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
this.jasmineHandlers = {};
this.installOne_ = function installOne_(errorType, jasmineMessage) {
function taggedOnError(error) {
error.jasmineMessage = jasmineMessage + ': ' + error;
var substituteMsg;
if (error) {
error.jasmineMessage = jasmineMessage + ': ' + error;
} else {
substituteMsg = jasmineMessage + ' with no error or message';
if (errorType === 'unhandledRejection') {
substituteMsg +=
'\n' +
'(Tip: to get a useful stack trace, use ' +
'Promise.reject(new Error(...)) instead of Promise.reject().)';
}
error = new Error(substituteMsg);
}
var handler = handlers[handlers.length - 1];

View File

@@ -1,8 +1,24 @@
getJasmineRequireObj().Suite = function(j$) {
/**
* @interface Suite
* @see Env#topSuite
*/
function Suite(attrs) {
this.env = attrs.env;
this.id = attrs.id;
/**
* The parent of this suite, or null if this is the top suite.
* @name Suite#parentSuite
* @readonly
* @type {Suite}
*/
this.parentSuite = attrs.parentSuite;
/**
* The description passed to the {@link describe} that created this suite.
* @name Suite#description
* @readonly
* @type {string}
*/
this.description = attrs.description;
this.expectationFactory = attrs.expectationFactory;
this.asyncExpectationFactory = attrs.asyncExpectationFactory;
@@ -16,6 +32,11 @@ getJasmineRequireObj().Suite = function(j$) {
this.timer = attrs.timer || new j$.Timer();
/**
* The suite's children.
* @name Suite#children
* @type {Array.<(Spec|Suite)>}
*/
this.children = [];
/**
@@ -53,6 +74,12 @@ getJasmineRequireObj().Suite = function(j$) {
return this.asyncExpectationFactory(actual, this);
};
/**
* The full description including all ancestors of this suite.
* @name Suite#getFullName
* @function
* @returns {string}
*/
Suite.prototype.getFullName = function() {
var fullName = [];
for (

View File

@@ -1,12 +0,0 @@
#!/bin/bash -e
if [ $USE_SAUCE == true ]
then
if [ $TRAVIS_SECURE_ENV_VARS != true ]
then
echo "skipping tests since we can't use sauce"
exit 0
fi
fi
npm run ci