Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fca3b4c11 | ||
|
|
e636f5f822 | ||
|
|
74fd0e08e7 | ||
|
|
618e24b2f8 | ||
|
|
5c7e25e228 | ||
|
|
54af109d40 | ||
|
|
873a237e3d | ||
|
|
8ca4463e01 | ||
|
|
449eb516cc | ||
|
|
a5df5a6ee9 | ||
|
|
be583232b4 | ||
|
|
d389d3c002 | ||
|
|
994d11d4f3 | ||
|
|
828d14f48e | ||
|
|
f5663a9076 | ||
|
|
a8c2399dd8 | ||
|
|
7c0f013003 | ||
|
|
ca2b62b00e | ||
|
|
4108deca02 | ||
|
|
def278f90f | ||
|
|
6bd4a29360 | ||
|
|
fd037f53a3 | ||
|
|
348242b712 | ||
|
|
b74e0abee1 | ||
|
|
e33b12b17c | ||
|
|
dde93ade18 | ||
|
|
63f900287c | ||
|
|
239a615770 | ||
|
|
92d5957a59 | ||
|
|
4991f2a713 | ||
|
|
0d6db64eb1 | ||
|
|
489fb79d6e | ||
|
|
eba8c775f3 | ||
|
|
c36a005893 | ||
|
|
37dfe50d99 | ||
|
|
c67a5b830c | ||
|
|
d803bd12a6 | ||
|
|
a621d05fa7 | ||
|
|
473f5cd359 | ||
|
|
a81e9626df |
44
.travis.yml
44
.travis.yml
@@ -1,19 +1,16 @@
|
||||
language: ruby
|
||||
cache: bundler
|
||||
sudo: false
|
||||
language: node_js
|
||||
node_js:
|
||||
- "11"
|
||||
- "10"
|
||||
- "8"
|
||||
|
||||
rvm: 2.5
|
||||
|
||||
before_install:
|
||||
- gem update --system
|
||||
- gem install bundler
|
||||
script: $TEST_COMMAND
|
||||
|
||||
env:
|
||||
global:
|
||||
- USE_SAUCE=true
|
||||
- USE_SAUCE=false
|
||||
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- TEST_COMMAND="npm test"
|
||||
- secure: WSPWhlnC4mWSnSPquX+m1/BCu5ch5NygkaHuM2Nea7lD8oS3XLX8QncZZAsQ4lnNfqoDDuBOizG0AESiqNvE4y6x5qvLLTS6q+ce255ZEMZ71TBdZgDEEvGMEjOPPsVXiXyTQOP1lwOPlrbZvaPgWV7e11KIBab6DfFcQpnvDgo=
|
||||
- secure: SW7CJhZnwaNT749Gdnhvqb5rbXlAOsygUAzh9qhtyvbqXKkmJdBIEsO01YF6pbju1X2twE9JvWCOxeZju43NgQChJlPsGbjY2j3k/TdQeTAJesQe2K7ytwghunI30gjEovtRH0T3w1EmcKPH8yj5eBIcB2OYoJHx8KEC7e68q1g=
|
||||
|
||||
@@ -23,46 +20,55 @@ addons:
|
||||
matrix:
|
||||
include:
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v4"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v8"
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-node-script.sh v9"
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="firefox"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.12"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.11"
|
||||
- SAUCE_BROWSER_VERSION=9
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="safari"
|
||||
- SAUCE_OS="OS X 10.10"
|
||||
- SAUCE_BROWSER_VERSION=8
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="MicrosoftEdge"
|
||||
- SAUCE_OS="Windows 10"
|
||||
- SAUCE_BROWSER_VERSION="15"
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8.1"
|
||||
- SAUCE_BROWSER_VERSION=11
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="internet explorer"
|
||||
- SAUCE_OS="Windows 8"
|
||||
- SAUCE_BROWSER_VERSION=10
|
||||
- env:
|
||||
- USE_SAUCE=true
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="chrome"
|
||||
- SAUCE_OS="Linux"
|
||||
- SAUCE_BROWSER_VERSION=''
|
||||
- env:
|
||||
- USE_SAUCE=false
|
||||
- TEST_COMMAND="bash travis-core-script.sh"
|
||||
- JASMINE_BROWSER="phantomjs"
|
||||
- USE_SAUCE=false
|
||||
|
||||
13
Gruntfile.js
13
Gruntfile.js
@@ -6,15 +6,16 @@ module.exports = function(grunt) {
|
||||
pkg: pkg,
|
||||
jshint: require('./grunt/config/jshint.js'),
|
||||
concat: require('./grunt/config/concat.js'),
|
||||
compass: require('./grunt/config/compass.js'),
|
||||
compress: require('./grunt/config/compress.js')
|
||||
sass: require('./grunt/config/sass.js'),
|
||||
compress: require('./grunt/config/compress.js'),
|
||||
cssUrlEmbed: require('./grunt/config/cssUrlEmbed.js')
|
||||
});
|
||||
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.loadTasks('grunt/tasks');
|
||||
|
||||
grunt.registerTask('default', ['jshint:all']);
|
||||
grunt.registerTask('default', ['jshint:all', 'sass:dist', "cssUrlEmbed"]);
|
||||
|
||||
var version = require('./grunt/tasks/version.js');
|
||||
|
||||
@@ -25,11 +26,11 @@ module.exports = function(grunt) {
|
||||
grunt.registerTask('buildDistribution',
|
||||
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
||||
[
|
||||
'compass',
|
||||
'sass:dist',
|
||||
"cssUrlEmbed",
|
||||
'jshint:beforeConcat',
|
||||
'concat',
|
||||
'jshint:afterConcat',
|
||||
'build:copyVersionToGem'
|
||||
'jshint:afterConcat'
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
208
ci.js
Normal file
208
ci.js
Normal file
@@ -0,0 +1,208 @@
|
||||
const path = require("path"),
|
||||
fs = require('fs'),
|
||||
port = 5555,
|
||||
colors = {
|
||||
"passed" : "\x1B[32m",
|
||||
"failed": "\x1B[31m",
|
||||
"pending": "\x1B[33m",
|
||||
"excluded": "\x1B[0m",
|
||||
"none": "\x1B[0m"
|
||||
},
|
||||
symbols = {
|
||||
"passed" : ".",
|
||||
"failed": "F",
|
||||
"pending": "*",
|
||||
"excluded": "",
|
||||
"none": ""
|
||||
},
|
||||
host = `http://localhost:${port}`,
|
||||
useSauce = process.env.USE_SAUCE === 'true';
|
||||
let driver, server;
|
||||
|
||||
function pageGenerator() {
|
||||
const ejs = require("ejs"),
|
||||
fg = require("fast-glob"),
|
||||
templatePath = path.resolve(__dirname, 'spec/support/index.html.ejs'),
|
||||
template = ejs.compile(fs.readFileSync(templatePath).toString()),
|
||||
patterns = [
|
||||
"lib/jasmine-core/jasmine.js",
|
||||
"lib/jasmine-core/json2.js",
|
||||
"lib/jasmine-core/jasmine-html.js",
|
||||
"lib/jasmine-core/boot.js",
|
||||
"src/core/requireCore.js",
|
||||
"src/core/base.js",
|
||||
"src/core/util.js",
|
||||
"src/core/Spec.js",
|
||||
"src/core/Env.js",
|
||||
"src/**/*.js",
|
||||
"spec/helpers/*.js",
|
||||
"spec/**/*[Ss]pec.js"
|
||||
],
|
||||
ignore = [
|
||||
"spec/helpers/nodeDefineJasmineUnderTest.js",
|
||||
"spec/npmPackage/**/*",
|
||||
"lib/jasmine-core/node_boot.js"
|
||||
];
|
||||
|
||||
return function toHtml() {
|
||||
const files = fg.sync(patterns, {ignore});
|
||||
return template({files});
|
||||
}
|
||||
}
|
||||
|
||||
function buildWebdriver() {
|
||||
const webdriver = require("selenium-webdriver"),
|
||||
Capability = webdriver.Capability;
|
||||
if (useSauce) {
|
||||
const username = process.env['SAUCE_USERNAME'],
|
||||
accessKey = process.env['SAUCE_ACCESS_KEY'];
|
||||
return new webdriver.Builder()
|
||||
.withCapabilities({
|
||||
name: `jasmine-core ${new Date().toISOString()}`,
|
||||
[Capability.PLATFORM]: process.env['SAUCE_OS'],
|
||||
[Capability.BROWSER_NAME]: process.env['JASMINE_BROWSER'],
|
||||
[Capability.VERSION]: process.env['SAUCE_BROWSER_VERSION'],
|
||||
build: `Core ${process.env['TRAVIS_BUILD_NUMBER'] || 'Ran locally'}`,
|
||||
tags: ['Jasmine-Core'],
|
||||
"tunnel-identifier": process.env['TRAVIS_JOB_NUMBER'] ? process.env['TRAVIS_JOB_NUMBER'].toString() : null
|
||||
})
|
||||
.usingServer(`http://${username}:${accessKey}@localhost:4445/wd/hub`)
|
||||
.build();
|
||||
} else {
|
||||
return new webdriver.Builder()
|
||||
.forBrowser(process.env["JASMINE_BROWSER"] || "firefox")
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
async function resultsWithoutCircularReferences(driver, resultType, index, batchSize) {
|
||||
return await driver.executeScript(
|
||||
`var results = jsApiReporter.${resultType}Results(${index}, ${batchSize});\n` +
|
||||
'for (var i = 0; i < results.length; i++) {\n' +
|
||||
'var expectations = results[i].failedExpectations;\n' +
|
||||
'if (results[i].passedExpectations) {\n' +
|
||||
'expectations = expectations.concat(results[i].passedExpectations);\n' +
|
||||
'}\n' +
|
||||
'for (var j = 0; j < expectations.length; j++) {\n' +
|
||||
'var expectation = expectations[j];\n' +
|
||||
"try { JSON.stringify(expectation.expected); } catch (e) { expectation.expected = '<circular expected>'; }\n" +
|
||||
"try { JSON.stringify(expectation.actual); } catch (e) { expectation.actual = '<circular actual>'; }\n" +
|
||||
'}\n' +
|
||||
'}\n' +
|
||||
'return results;'
|
||||
);
|
||||
}
|
||||
|
||||
function flatten(arr) {
|
||||
return Array.prototype.concat.apply([], arr);
|
||||
}
|
||||
|
||||
async function getResults(driver) {
|
||||
const batchSize = 50,
|
||||
specResults = [],
|
||||
failedSuiteResults = [];
|
||||
let index = 0,
|
||||
slice = [];
|
||||
|
||||
do {
|
||||
slice = await resultsWithoutCircularReferences(driver, 'spec', index, batchSize);
|
||||
specResults.push(slice);
|
||||
index += batchSize;
|
||||
} while (slice.length === batchSize);
|
||||
|
||||
index = 0;
|
||||
do {
|
||||
slice = await resultsWithoutCircularReferences(driver, 'suite', index, batchSize);
|
||||
failedSuiteResults.push(slice.filter(function(suite) { return suite.status === 'failed' }));
|
||||
index += batchSize;
|
||||
} while (slice.length === batchSize);
|
||||
|
||||
return {specResults: flatten(specResults), failedSuiteResults: flatten(failedSuiteResults)};
|
||||
}
|
||||
|
||||
(async function () {
|
||||
await new Promise(resolve => {
|
||||
console.log("Creating an express app for browers to run the tests...")
|
||||
const express = require("express"),
|
||||
app = express(),
|
||||
html = pageGenerator();
|
||||
|
||||
app.use(express.static(__dirname));
|
||||
app.get("/", (req, res) => res.send(html()));
|
||||
server = app.listen(port, resolve);
|
||||
});
|
||||
|
||||
|
||||
console.log("Running the tests in browser...")
|
||||
driver = buildWebdriver();
|
||||
await driver.get(`${host}/?throwFailures=false&failFast=false&random=true`)
|
||||
await new Promise(resolve => {
|
||||
const intervalId = setInterval(async () => {
|
||||
const isFinished = await driver.executeScript("return jsApiReporter && jsApiReporter.finished")
|
||||
if (isFinished) {
|
||||
clearInterval(intervalId)
|
||||
resolve();
|
||||
}
|
||||
}, 500)
|
||||
});
|
||||
|
||||
const {specResults, failedSuiteResults} = await getResults(driver);
|
||||
console.log(specResults.map(spec => `${colors[spec.status]}${symbols[spec.status]}`).join("") + colors["none"]);
|
||||
|
||||
const result = specResults.reduce((result, spec) => {
|
||||
result[spec.status] = [...result[spec.status], spec];
|
||||
return result;
|
||||
}, {pending: [], failed: [], passed: [], excluded: []});
|
||||
|
||||
if (result.pending.length) {
|
||||
console.log(`${colors["pending"]}Pending:`);
|
||||
result.pending.forEach((spec, index) => {
|
||||
console.log(`${colors["none"]}${index}) ${spec.fullName}`)
|
||||
console.group();
|
||||
console.log(`${colors["pending"]}${spec.pendingReason || "no reason given"}`);
|
||||
console.groupEnd();
|
||||
console.log();
|
||||
});
|
||||
}
|
||||
|
||||
if (result.failed.length) {
|
||||
console.log(`${colors["failed"]}Failed:`);
|
||||
result["failed"].forEach((spec, index) => {
|
||||
console.log(`${colors["none"]}${index}) ${spec.fullName}`)
|
||||
console.group();
|
||||
spec.failedExpectations.forEach((expect) => {
|
||||
console.log(`${colors["none"]}Message:`);
|
||||
console.group();
|
||||
console.log(`${colors["failed"]}${expect.message}`);
|
||||
console.groupEnd();
|
||||
console.log(`${colors["none"]}Stack:`);
|
||||
console.group();
|
||||
console.log(`${colors["failed"]}${expect.stack}`);
|
||||
console.groupEnd();
|
||||
console.groupEnd();
|
||||
})
|
||||
console.groupEnd();
|
||||
console.log();
|
||||
});
|
||||
}
|
||||
|
||||
const details = await driver.executeScript(`
|
||||
return {
|
||||
overallStatus: jsApiReporter.runDetails.overallStatus,
|
||||
executionTime: jsApiReporter.executionTime(),
|
||||
random: jsApiReporter.runDetails.order.random,
|
||||
seed: jsApiReporter.runDetails.order.seed
|
||||
}`);
|
||||
|
||||
console.log(`${colors["none"]}${specResults.length} spec(s), ${result.failed.length} failure(s), ${result.pending.length} pending spec(s)`);
|
||||
console.log(`Finished in ${details.executionTime / 1000} second(s)`);
|
||||
console.log(`Randomized with seed ${details.seed} ( ${host}/?random=${details.random}&seed=${details.seed} )`);
|
||||
process.exitCode = details.overallStatus === 'passed' ? 0 : 1;
|
||||
|
||||
if (useSauce) {
|
||||
driver.executeScript(`sauce:job-result=${process.exitCode === 0}`);
|
||||
}
|
||||
})().finally(() => {
|
||||
return Promise.all([driver.close(), new Promise(resolve => server.close(resolve))]);
|
||||
});
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
jasmine: {
|
||||
options: {
|
||||
cssDir: 'lib/jasmine-core/',
|
||||
sassDir: 'src/html',
|
||||
outputStyle: 'compact',
|
||||
noLineComments: true,
|
||||
bundleExec: true
|
||||
}
|
||||
}
|
||||
};
|
||||
7
grunt/config/cssUrlEmbed.js
Normal file
7
grunt/config/cssUrlEmbed.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
encodeWithBaseDir: {
|
||||
files: {
|
||||
"lib/jasmine-core/jasmine.css": ["lib/jasmine-core/jasmine.css"]
|
||||
}
|
||||
}
|
||||
};
|
||||
14
grunt/config/sass.js
Normal file
14
grunt/config/sass.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const sass = require('node-sass');
|
||||
|
||||
module.exports = {
|
||||
options: {
|
||||
implementation: sass,
|
||||
outputStyle: 'compact',
|
||||
sourceComments: false
|
||||
},
|
||||
dist: {
|
||||
files: {
|
||||
"lib/jasmine-core/jasmine.css": "src/html/jasmine.scss"
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2018 Pivotal Labs
|
||||
Copyright (c) 2008-2019 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2018 Pivotal Labs
|
||||
Copyright (c) 2008-2019 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -28,12 +28,6 @@ jasmineRequire.html = function(j$) {
|
||||
};
|
||||
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var noopTimer = {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
function ResultsStateBuilder() {
|
||||
this.topResults = new j$.ResultsNode({}, '', null);
|
||||
this.currentParent = this.topResults;
|
||||
@@ -87,7 +81,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
navigateWithNewParam = options.navigateWithNewParam || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
timer = options.timer || j$.noopTimer,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
deprecationWarnings = [];
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2018 Pivotal Labs
|
||||
Copyright (c) 2008-2019 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
@@ -63,7 +63,8 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.Expector = jRequire.Expector(j$);
|
||||
j$.Expectation = jRequire.Expectation(j$);
|
||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||
j$.noopTimer = jRequire.noopTimer();
|
||||
j$.JsApiReporter = jRequire.JsApiReporter(j$);
|
||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||
j$.ObjectContaining = jRequire.ObjectContaining(j$);
|
||||
j$.ArrayContaining = jRequire.ArrayContaining(j$);
|
||||
@@ -160,7 +161,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
|
||||
/**
|
||||
* Maximum number of charasters to display when pretty printing objects.
|
||||
* Maximum number of characters to display when pretty printing objects.
|
||||
* Characters past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_CHARS
|
||||
*/
|
||||
@@ -232,9 +233,15 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
if (value instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
if (value && value.constructor && value.constructor.constructor &&
|
||||
(value instanceof (value.constructor.constructor('return this')()).Error)) {
|
||||
return true;
|
||||
if (value && value.constructor && value.constructor.constructor) {
|
||||
var valueGlobal = value.constructor.constructor('return this');
|
||||
if (j$.isFunction_(valueGlobal)) {
|
||||
valueGlobal = valueGlobal();
|
||||
}
|
||||
|
||||
if (valueGlobal.Error && value instanceof valueGlobal.Error) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -556,6 +563,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
@@ -571,6 +579,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
|
||||
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
|
||||
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
|
||||
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
@@ -579,7 +588,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
pendingReason: '',
|
||||
duration: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -609,6 +619,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
|
||||
var onStart = {
|
||||
fn: function(done) {
|
||||
self.timer.start();
|
||||
self.onStart(self, done);
|
||||
}
|
||||
};
|
||||
@@ -632,6 +643,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
self.onException.apply(self, arguments);
|
||||
},
|
||||
onComplete: function() {
|
||||
self.result.duration = self.timer.elapsed();
|
||||
onComplete(self.result.status === 'failed' && new j$.StopExecutionError('spec failed'));
|
||||
},
|
||||
userContext: this.userContext()
|
||||
@@ -753,7 +765,7 @@ getJasmineRequireObj().Order = function() {
|
||||
}
|
||||
|
||||
// Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
|
||||
// used to get a different output when the key changes slighly.
|
||||
// used to get a different output when the key changes slightly.
|
||||
// We use your return to sort the children randomly in a consistent way when
|
||||
// used in conjunction with a seed
|
||||
|
||||
@@ -877,11 +889,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (!options.suppressLoadErrors) {
|
||||
installGlobalErrors();
|
||||
globalErrors.pushListener(function(message, filename, lineno) {
|
||||
globalErrors.pushListener(function(message, filename, lineno, colNo, err) {
|
||||
topSuite.result.failedExpectations.push({
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: message,
|
||||
stack: err && err.stack,
|
||||
filename: filename,
|
||||
lineno: lineno
|
||||
});
|
||||
@@ -1288,6 +1301,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result, next);
|
||||
suite.startTimer();
|
||||
},
|
||||
nodeComplete: function(suite, result, next) {
|
||||
if (suite !== currentSuite()) {
|
||||
@@ -1300,7 +1314,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
if (result.status === 'failed') {
|
||||
hasFailures = true;
|
||||
}
|
||||
|
||||
suite.endTimer();
|
||||
reporter.suiteDone(result, next);
|
||||
},
|
||||
orderChildren: function(node) {
|
||||
@@ -1347,7 +1361,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
/**
|
||||
* Information passed to the {@link Reporter#jasmineDone} event.
|
||||
* @typedef JasmineDoneInfo
|
||||
* @property {OverallStatus} overallStatus - The overall result of the sute: 'passed', 'failed', or 'incomplete'.
|
||||
* @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
|
||||
* @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
|
||||
* @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
|
||||
* @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
|
||||
@@ -1580,9 +1594,9 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
fn: fn,
|
||||
timeout: timeout || 0
|
||||
},
|
||||
throwOnExpectationFailure: config.oneFailurePerSpec
|
||||
throwOnExpectationFailure: config.oneFailurePerSpec,
|
||||
timer: new j$.Timer(),
|
||||
});
|
||||
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result, next) {
|
||||
@@ -1737,13 +1751,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return Env;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().JsApiReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* @name jsApiReporter
|
||||
* @classdesc {@link Reporter} added by default in `boot.js` to record results for retrieval in javascript code. An instance is made available as `jsApiReporter` on the global object.
|
||||
@@ -1751,7 +1759,7 @@ getJasmineRequireObj().JsApiReporter = function() {
|
||||
* @hideconstructor
|
||||
*/
|
||||
function JsApiReporter(options) {
|
||||
var timer = options.timer || noopTimer,
|
||||
var timer = options.timer || j$.noopTimer,
|
||||
status = 'loaded';
|
||||
|
||||
this.started = false;
|
||||
@@ -2400,7 +2408,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
* The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes.
|
||||
* @name Clock#withMock
|
||||
* @function
|
||||
* @param {closure} Function The function to be called.
|
||||
* @param {Function} closure The function to be called.
|
||||
*/
|
||||
self.withMock = function(closure) {
|
||||
this.install();
|
||||
@@ -2697,12 +2705,16 @@ getJasmineRequireObj().errors = function() {
|
||||
};
|
||||
getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
|
||||
var ignoredProperties = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description', 'jasmineMessage'];
|
||||
|
||||
function ExceptionFormatter(options) {
|
||||
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
this.message = function(error) {
|
||||
var message = '';
|
||||
|
||||
if (error.name && error.message) {
|
||||
if (error.jasmineMessage) {
|
||||
message += error.jasmineMessage;
|
||||
} else if (error.name && error.message) {
|
||||
message += error.name + ': ' + error.message;
|
||||
} else if (error.message) {
|
||||
message += error.message;
|
||||
@@ -2760,12 +2772,11 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var ignored = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description'];
|
||||
var result = {};
|
||||
var empty = true;
|
||||
|
||||
for (var prop in error) {
|
||||
if (j$.util.arrayContains(ignored, prop)) {
|
||||
if (j$.util.arrayContains(ignoredProperties, prop)) {
|
||||
continue;
|
||||
}
|
||||
result[prop] = error[prop];
|
||||
@@ -3192,28 +3203,44 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
};
|
||||
|
||||
this.originalHandlers = {};
|
||||
this.installOne_ = function installOne_(errorType) {
|
||||
this.jasmineHandlers = {};
|
||||
this.installOne_ = function installOne_(errorType, jasmineMessage) {
|
||||
function taggedOnError(error) {
|
||||
error.jasmineMessage = jasmineMessage + ': ' + error;
|
||||
|
||||
var handler = handlers[handlers.length - 1];
|
||||
|
||||
if (handler) {
|
||||
handler(error);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
this.originalHandlers[errorType] = global.process.listeners(errorType);
|
||||
this.jasmineHandlers[errorType] = taggedOnError;
|
||||
|
||||
global.process.removeAllListeners(errorType);
|
||||
global.process.on(errorType, onerror);
|
||||
global.process.on(errorType, taggedOnError);
|
||||
|
||||
this.uninstall = function uninstall() {
|
||||
var errorTypes = Object.keys(this.originalHandlers);
|
||||
for (var iType = 0; iType < errorTypes.length; iType++) {
|
||||
var errorType = errorTypes[iType];
|
||||
global.process.removeListener(errorType, onerror);
|
||||
global.process.removeListener(errorType, this.jasmineHandlers[errorType]);
|
||||
for (var i = 0; i < this.originalHandlers[errorType].length; i++) {
|
||||
global.process.on(errorType, this.originalHandlers[errorType][i]);
|
||||
}
|
||||
delete this.originalHandlers[errorType];
|
||||
delete this.jasmineHandlers[errorType];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.install = function install() {
|
||||
if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
|
||||
this.installOne_('uncaughtException');
|
||||
this.installOne_('unhandledRejection');
|
||||
this.installOne_('uncaughtException', 'Uncaught exception');
|
||||
this.installOne_('unhandledRejection', 'Unhandled promise rejection');
|
||||
} else {
|
||||
var originalHandler = global.onerror;
|
||||
global.onerror = onerror;
|
||||
@@ -5055,10 +5082,12 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
} else if (value.nodeType === 1) {
|
||||
this.emitDomElement(value);
|
||||
} else if (typeof value.nodeType === 'number') {
|
||||
this.emitScalar('HTMLNode');
|
||||
} 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)) {
|
||||
@@ -5249,15 +5278,29 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitDomElement = function(el) {
|
||||
var closingTag = '</' + el.tagName.toLowerCase() + '>';
|
||||
var tagName = el.tagName.toLowerCase(),
|
||||
attrs = el.attributes,
|
||||
i,
|
||||
len = attrs.length,
|
||||
out = '<' + tagName,
|
||||
attr;
|
||||
|
||||
if (el.innerHTML === '') {
|
||||
this.append(el.outerHTML.replace(closingTag, ''));
|
||||
} else {
|
||||
var tagEnd = el.outerHTML.indexOf('>');
|
||||
this.append(el.outerHTML.substring(0, tagEnd + 1));
|
||||
this.append('...' + closingTag);
|
||||
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);
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
@@ -5413,7 +5456,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
cleanup();
|
||||
|
||||
if (j$.isError_(err)) {
|
||||
if (!(err instanceof StopExecutionError)) {
|
||||
if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
|
||||
self.fail(err);
|
||||
}
|
||||
self.errored = errored = true;
|
||||
@@ -6047,7 +6090,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
|
||||
if (!strategy) {
|
||||
if (argsStrategies.any() && !baseStrategy.isConfigured()) {
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' receieved a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' received a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
} else {
|
||||
strategy = baseStrategy;
|
||||
}
|
||||
@@ -6551,6 +6594,8 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
|
||||
this.children = [];
|
||||
|
||||
/**
|
||||
@@ -6561,13 +6606,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
|
||||
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
|
||||
* @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
description: this.description,
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: [],
|
||||
deprecationWarnings: []
|
||||
deprecationWarnings: [],
|
||||
duration: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6609,6 +6656,14 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.afterAllFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.startTimer = function() {
|
||||
this.timer.start();
|
||||
};
|
||||
|
||||
Suite.prototype.endTimer = function() {
|
||||
this.result.duration = this.timer.elapsed();
|
||||
};
|
||||
|
||||
function removeFns(queueableFns) {
|
||||
for(var i = 0; i < queueableFns.length; i++) {
|
||||
queueableFns[i].fn = null;
|
||||
@@ -6732,6 +6787,12 @@ getJasmineRequireObj().Timer = function() {
|
||||
return Timer;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().noopTimer = function() {
|
||||
return {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
};
|
||||
getJasmineRequireObj().TreeProcessor = function() {
|
||||
function TreeProcessor(attrs) {
|
||||
var tree = attrs.tree,
|
||||
@@ -6968,5 +7029,5 @@ getJasmineRequireObj().UserContext = function(j$) {
|
||||
};
|
||||
|
||||
getJasmineRequireObj().version = function() {
|
||||
return '3.3.0';
|
||||
return '3.4.0';
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2008-2018 Pivotal Labs
|
||||
Copyright (c) 2008-2019 Pivotal Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
#
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "3.3.0"
|
||||
VERSION = "3.4.0"
|
||||
end
|
||||
end
|
||||
|
||||
27
package.json
27
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "jasmine-core",
|
||||
"license": "MIT",
|
||||
"version": "3.3.0",
|
||||
"version": "3.4.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasmine/jasmine.git"
|
||||
@@ -19,17 +19,22 @@
|
||||
"homepage": "https://jasmine.github.io",
|
||||
"main": "./lib/jasmine-core.js",
|
||||
"devDependencies": {
|
||||
"glob": "~7.1.2",
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-cli": "^1.2.0",
|
||||
"grunt-contrib-compass": "^1.1.1",
|
||||
"ejs": "^2.5.5",
|
||||
"express": "^4.16.4",
|
||||
"fast-glob": "^2.2.6",
|
||||
"grunt": "^1.0.4",
|
||||
"grunt-cli": "^1.3.2",
|
||||
"grunt-contrib-compress": "^1.3.0",
|
||||
"grunt-contrib-concat": "^1.0.1",
|
||||
"grunt-contrib-jshint": "^1.0.0",
|
||||
"jasmine": "^3.0.0",
|
||||
"jsdom": "^9.12.0",
|
||||
"load-grunt-tasks": "^0.4.0",
|
||||
"shelljs": "^0.7.0",
|
||||
"temp": "~0.8.1"
|
||||
"grunt-contrib-jshint": "^2.0.0",
|
||||
"grunt-css-url-embed": "^1.11.1",
|
||||
"grunt-sass": "^3.0.2",
|
||||
"jasmine": "^3.3.1",
|
||||
"jsdom": "^13.1.0",
|
||||
"load-grunt-tasks": "^4.0.0",
|
||||
"node-sass": "^4.11.0",
|
||||
"selenium-webdriver": "^3.6.0",
|
||||
"shelljs": "^0.8.3",
|
||||
"temp": "^0.9.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ There is also a 2.99 release of Jasmine that will present deprecation warnings f
|
||||
|
||||
* Default to running tests in random order
|
||||
|
||||
* The `identity` of a Jasmnine Spy is now a property and no longer a method
|
||||
|
||||
* Additionally, Jasmine 3.0 drops support for older browsers and environments. Notably:
|
||||
- Internet Explorer 8 and 9
|
||||
- Ruby 1.x (for the Ruby gem)
|
||||
|
||||
49
release_notes/3.4.0.md
Normal file
49
release_notes/3.4.0.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Jasmine Core 3.4 Release Notes
|
||||
|
||||
## Summary
|
||||
|
||||
This is a maintenance release of Jasmine with a number of new features and fixes
|
||||
|
||||
## Changes
|
||||
|
||||
* Handle WebSocket events in IE when detecting Errors
|
||||
- Fixes [#1623](https://github.com/jasmine/jasmine/issues/1623)
|
||||
|
||||
* bump dependencies for security fixes
|
||||
- Merges [#1672](https://github.com/jasmine/jasmine/issues/1672) from @wood1986
|
||||
|
||||
* Make node execution default and override for browsers
|
||||
- Merges [#1658](https://github.com/jasmine/jasmine/issues/1658) from @wood1986
|
||||
- Fixes [#883](https://github.com/jasmine/jasmine/issues/883)
|
||||
|
||||
* feat(result.duration): report test duration in ms
|
||||
- Merges [#1660](https://github.com/jasmine/jasmine/issues/1660) from @johnjbarton
|
||||
- Fixes [#1646](https://github.com/jasmine/jasmine/issues/1646)
|
||||
|
||||
* refactor(Timer): share htmlReporter noopTimer via Timer.js
|
||||
- Merges [#1669](https://github.com/jasmine/jasmine/issues/1669) from @johnjbarton
|
||||
|
||||
* Fix various typos
|
||||
- Merges [#1666](https://github.com/jasmine/jasmine/issues/1666) from @FelixRilling
|
||||
- Merges [#1667](https://github.com/jasmine/jasmine/issues/1667) from @FelixRilling
|
||||
- Merges [#1665](https://github.com/jasmine/jasmine/issues/1665) from @FelixRilling
|
||||
- Merges [#1664](https://github.com/jasmine/jasmine/issues/1664) from @FelixRilling
|
||||
- Fixes [#1663](https://github.com/jasmine/jasmine/issues/1663)
|
||||
|
||||
* When catching a global error in Node.js, print the type of error
|
||||
- Merges [#1632](https://github.com/jasmine/jasmine/issues/1632) from @jbunton-atlassian
|
||||
|
||||
* Support Error.stack in globalErrors.
|
||||
- Merges [#1644](https://github.com/jasmine/jasmine/issues/1644) from @johnjbarton
|
||||
|
||||
* Stop treating objects with a `nodeType` as if they are DOM Nodes
|
||||
- Fixes [#1638](https://github.com/jasmine/jasmine/issues/1638)
|
||||
|
||||
* Fixes issue where PhantomJS 2 and IE 10 - 11 crashed when reporting SVG element equality
|
||||
- Merges [#1621](https://github.com/jasmine/jasmine/issues/1621) from @Havunen
|
||||
- Fixes [#1618](https://github.com/jasmine/jasmine/issues/1618)
|
||||
|
||||
|
||||
------
|
||||
|
||||
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_
|
||||
@@ -96,7 +96,7 @@ describe("ExceptionFormatter", function() {
|
||||
);
|
||||
});
|
||||
|
||||
it("filters Jamine stack frames from Webkit style traces", function() {
|
||||
it("filters Jasmine stack frames from Webkit style traces", function() {
|
||||
var error = {
|
||||
stack: 'http://localhost:8888/__spec__/core/UtilSpec.js:115:28\n' +
|
||||
'fn1@http://localhost:8888/__jasmine__/jasmine.js:4320:27\n' +
|
||||
|
||||
@@ -101,6 +101,7 @@ describe("GlobalErrors", function() {
|
||||
addedListener(new Error('bar'));
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(new Error('bar'));
|
||||
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe('Uncaught exception: Error: bar');
|
||||
|
||||
errors.uninstall();
|
||||
|
||||
@@ -127,10 +128,11 @@ describe("GlobalErrors", function() {
|
||||
|
||||
errors.pushListener(handler);
|
||||
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(0)[1];
|
||||
var addedListener = fakeGlobal.process.on.calls.argsFor(1)[1];
|
||||
addedListener(new Error('bar'));
|
||||
|
||||
expect(handler).toHaveBeenCalledWith(new Error('bar'));
|
||||
expect(handler.calls.argsFor(0)[0].jasmineMessage).toBe('Unhandled promise rejection: Error: bar');
|
||||
|
||||
errors.uninstall();
|
||||
|
||||
|
||||
@@ -209,7 +209,7 @@ describe("JsApiReporter", function() {
|
||||
expect(reporter.suiteResults(1, 1)).toEqual([suiteResult2]);
|
||||
});
|
||||
|
||||
it("returns nothing for out of bounds indicies", function() {
|
||||
it("returns nothing for out of bounds indices", function() {
|
||||
expect(reporter.suiteResults(0, 3)).toEqual([suiteResult1, suiteResult2]);
|
||||
expect(reporter.suiteResults(2, 3)).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("jasmineUnderTest.pp", function () {
|
||||
expect(jasmineUnderTest.pp(set)).toEqual("Set( 1, 2 )");
|
||||
});
|
||||
|
||||
it("should truncate sets with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
it("should truncate sets with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
jasmine.getEnv().requireFunctioningSets();
|
||||
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("jasmineUnderTest.pp", function () {
|
||||
expect(jasmineUnderTest.pp(map)).toEqual("Map( [ 1, 2 ] )");
|
||||
});
|
||||
|
||||
it("should truncate maps with more elments than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
it("should truncate maps with more elements than jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
|
||||
jasmine.getEnv().requireFunctioningMaps();
|
||||
var originalMaxSize = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
|
||||
@@ -132,6 +132,10 @@ describe("jasmineUnderTest.pp", function () {
|
||||
}, bar: [1, 2, 3]})).toEqual("Object({ foo: Function, bar: [ 1, 2, 3 ] })");
|
||||
});
|
||||
|
||||
it("should stringify objects that almost look like DOM nodes", function() {
|
||||
expect(jasmineUnderTest.pp({nodeType: 1})).toEqual("Object({ nodeType: 1 })");
|
||||
});
|
||||
|
||||
it("should truncate objects with too many keys", function () {
|
||||
var originalMaxLength = jasmineUnderTest.MAX_PRETTY_PRINT_ARRAY_LENGTH;
|
||||
var long = {a: 1, b: 2, c: 3};
|
||||
|
||||
@@ -207,7 +207,8 @@ describe("Spec", function() {
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
pendingReason: '',
|
||||
duration: null,
|
||||
}, 'things');
|
||||
});
|
||||
|
||||
@@ -242,6 +243,22 @@ describe("Spec", function() {
|
||||
expect(done).toHaveBeenCalledWith(jasmine.any(jasmineUnderTest.StopExecutionError));
|
||||
});
|
||||
|
||||
it("should report the duration of the test", function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
timer = jasmine.createSpyObj('timer', {'start': null, elapsed: 77000}),
|
||||
spec = new jasmineUnderTest.Spec({
|
||||
queueableFn: { fn: jasmine.createSpy("spec body")},
|
||||
catchExceptions: function() { return false; },
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) {
|
||||
attrs.onComplete();
|
||||
},
|
||||
timer: timer,
|
||||
});
|
||||
spec.execute(done);
|
||||
expect(spec.result.duration).toBe(77000);
|
||||
});
|
||||
|
||||
it("#status returns passing by default", function() {
|
||||
var spec = new jasmineUnderTest.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
expect(spec.status()).toBe('passed');
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('Spies', function () {
|
||||
var spy = env.createSpy('foo');
|
||||
spy.withArgs('bar').and.returnValue(-1);
|
||||
|
||||
expect(function() { spy('baz', {qux: 42}); }).toThrowError('Spy \'foo\' receieved a call with arguments [ \'baz\', Object({ qux: 42 }) ] but all configured strategies specify other arguments.');
|
||||
expect(function() { spy('baz', {qux: 42}); }).toThrowError('Spy \'foo\' received a call with arguments [ \'baz\', Object({ qux: 42 }) ] but all configured strategies specify other arguments.');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -111,6 +111,19 @@ describe("Suite", function() {
|
||||
expect(suite.getResult().failedExpectations).toEqual([]);
|
||||
});
|
||||
|
||||
it("calls timer to compute duration", function(){
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
suite = new jasmineUnderTest.Suite({
|
||||
env: env,
|
||||
id: 456,
|
||||
description: "I am a suite",
|
||||
timer: jasmine.createSpyObj('timer', {'start': null, elapsed: 77000}),
|
||||
});
|
||||
suite.startTimer();
|
||||
suite.endTimer();
|
||||
expect(suite.getResult().duration).toEqual(77000);
|
||||
});
|
||||
|
||||
describe('#sharedUserContext', function() {
|
||||
beforeEach(function() {
|
||||
this.suite = new jasmineUnderTest.Suite({});
|
||||
|
||||
30
spec/core/baseSpec.js
Normal file
30
spec/core/baseSpec.js
Normal file
@@ -0,0 +1,30 @@
|
||||
describe('base helpers', function() {
|
||||
describe('isError_', function() {
|
||||
it("correctly handles WebSocket events", function(done) {
|
||||
if (typeof jasmine.getGlobal().WebSocket === 'undefined') {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = (function() {
|
||||
var sock = new WebSocket('ws://localhost');
|
||||
var event;
|
||||
sock.onerror = function(e) {
|
||||
event = e
|
||||
};
|
||||
return function() { return event };
|
||||
})();
|
||||
var left = 20;
|
||||
|
||||
var int = setInterval(function() {
|
||||
if (obj() || left === 0) {
|
||||
var result = jasmineUnderTest.isError_(obj());
|
||||
expect(result).toBe(false);
|
||||
done();
|
||||
} else {
|
||||
left--;
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1436,6 +1436,9 @@ describe("Env integration", function() {
|
||||
status: 'pending'
|
||||
}));
|
||||
|
||||
var suiteDone = reporter.suiteDone.calls.argsFor(0)[0];
|
||||
expect(typeof suiteDone.duration).toBe('number');
|
||||
|
||||
var suiteResult = reporter.suiteStarted.calls.argsFor(0)[0];
|
||||
expect(suiteResult.description).toEqual("A Suite");
|
||||
|
||||
@@ -1942,10 +1945,10 @@ describe("Env integration", function() {
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpectationsForRunnable('async suite', [
|
||||
/^(((Uncaught )?Error: suite( thrown)?)|(suite thrown))$/
|
||||
/^(((Uncaught )?(exception: )?Error: suite( thrown)?)|(suite thrown))$/
|
||||
]);
|
||||
expect(reporter.specDone).toHaveFailedExpectationsForRunnable('suite async spec', [
|
||||
/^(((Uncaught )?Error: spec( thrown)?)|(spec thrown))$/
|
||||
/^(((Uncaught )?(exception: )?Error: spec( thrown)?)|(spec thrown))$/
|
||||
]);
|
||||
done();
|
||||
});
|
||||
@@ -2046,6 +2049,7 @@ describe("Env integration", function() {
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: 'Uncaught SyntaxError: Unexpected end of input',
|
||||
stack: 'a stack',
|
||||
filename: 'borkenSpec.js',
|
||||
lineno: 42
|
||||
},
|
||||
@@ -2053,6 +2057,7 @@ describe("Env integration", function() {
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: 'Uncaught Error: ENOCHEESE',
|
||||
stack: undefined,
|
||||
filename: undefined,
|
||||
lineno: undefined
|
||||
}
|
||||
@@ -2062,7 +2067,7 @@ describe("Env integration", function() {
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
global.onerror('Uncaught SyntaxError: Unexpected end of input', 'borkenSpec.js', 42);
|
||||
global.onerror('Uncaught SyntaxError: Unexpected end of input', 'borkenSpec.js', 42, undefined, {stack: 'a stack'});
|
||||
global.onerror('Uncaught Error: ENOCHEESE');
|
||||
|
||||
env.execute();
|
||||
@@ -2312,7 +2317,7 @@ describe("Env integration", function() {
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']);
|
||||
|
||||
// prevent deprecation from being desplayed
|
||||
// prevent deprecation from being displayed
|
||||
spyOn(console, "error");
|
||||
|
||||
reporter.jasmineDone.and.callFake(function(result) {
|
||||
@@ -2364,7 +2369,7 @@ describe("Env integration", function() {
|
||||
try { throw new Error('suite level deprecation') } catch (err) { suiteLevelError = err; }
|
||||
try { throw new Error('spec level deprecation') } catch (err) { specLevelError = err; }
|
||||
|
||||
// prevent deprecation from being desplayed
|
||||
// prevent deprecation from being displayed
|
||||
spyOn(console, "error");
|
||||
|
||||
reporter.jasmineDone.and.callFake(function(result) {
|
||||
|
||||
@@ -575,23 +575,15 @@ describe("toEqual", function() {
|
||||
return typeof document === 'undefined'
|
||||
}
|
||||
|
||||
beforeEach(function(done) {
|
||||
beforeEach(function() {
|
||||
this.nonBrowser = isNotRunningInBrowser();
|
||||
if (this.nonBrowser) {
|
||||
var jsdom = require('jsdom');
|
||||
var self = this;
|
||||
jsdom.env('', function(err, win) {
|
||||
if (err) {
|
||||
done.fail(err);
|
||||
} else {
|
||||
jasmineUnderTest.getGlobal().Node = win.Node;
|
||||
self.doc = win.document;
|
||||
done();
|
||||
}
|
||||
});
|
||||
var JSDOM = require('jsdom').JSDOM;
|
||||
var dom = new JSDOM();
|
||||
jasmineUnderTest.getGlobal().Node = dom.window.Node;
|
||||
this.doc = dom.window.document;
|
||||
} else {
|
||||
this.doc = document;
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -624,6 +616,99 @@ describe("toEqual", function() {
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it("reports mismatches between SVG nodes", function () {
|
||||
var nodeA = this.doc.createElementNS('http://www.w3.org/2000/svg', 'svg'),
|
||||
nodeB = this.doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
|
||||
nodeA.setAttribute('height', '50');
|
||||
nodeB.setAttribute('height', '30');
|
||||
|
||||
var rect = this.doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
rect.setAttribute('width', '50');
|
||||
nodeA.appendChild(rect);
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <svg height="50">...</svg> to equal <svg height="30">.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it("reports whole DOM node when attribute contains > character", function () {
|
||||
var nodeA = this.doc.createElement('div'),
|
||||
nodeB = this.doc.createElement('div');
|
||||
|
||||
nodeA.setAttribute('thing', '>>>');
|
||||
nodeB.setAttribute('thing', 'bar');
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div thing=">>>"> to equal <div thing="bar">.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it('reports no content when DOM node has multiple empty text nodes', function () {
|
||||
var nodeA = this.doc.createElement('div'),
|
||||
nodeB = this.doc.createElement('div');
|
||||
|
||||
nodeA.appendChild(this.doc.createTextNode(''));
|
||||
nodeA.appendChild(this.doc.createTextNode(''));
|
||||
nodeA.appendChild(this.doc.createTextNode(''));
|
||||
nodeA.appendChild(this.doc.createTextNode(''));
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div> to equal <div>.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it('reports content when DOM node has non empty text node', function () {
|
||||
var nodeA = this.doc.createElement('div'),
|
||||
nodeB = this.doc.createElement('div');
|
||||
|
||||
nodeA.appendChild(this.doc.createTextNode('Hello Jasmine!'));
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div>...</div> to equal <div>.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it('reports empty DOM attributes', function () {
|
||||
var nodeA = this.doc.createElement('div'),
|
||||
nodeB = this.doc.createElement('div');
|
||||
|
||||
nodeA.setAttribute('contenteditable', '');
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div contenteditable> to equal <div>.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it('reports 0 attr value as non empty DOM attribute', function () {
|
||||
var nodeA = this.doc.createElement('div'),
|
||||
nodeB = this.doc.createElement('div');
|
||||
|
||||
nodeA.setAttribute('contenteditable', 0);
|
||||
|
||||
expect(nodeA.isEqualNode(nodeB)).toBe(false);
|
||||
var actual = {a: nodeA},
|
||||
expected = {a: nodeB},
|
||||
message = 'Expected $.a = <div contenteditable="0"> to equal <div>.';
|
||||
|
||||
expect(compareEquals(actual, expected).message).toEqual(message);
|
||||
});
|
||||
|
||||
it("reports mismatches between a DOM node and a bare Object", function() {
|
||||
var actual = {a: this.doc.createElement('div')},
|
||||
expected = {a: {}},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe('toHaveClass', function() {
|
||||
beforeEach(function(done) {
|
||||
beforeEach(function() {
|
||||
this.createElementWithClassName = function(className) {
|
||||
var el = this.doc.createElement('div');
|
||||
el.className = className;
|
||||
@@ -8,18 +8,10 @@ describe('toHaveClass', function() {
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
this.doc = document;
|
||||
done();
|
||||
} else {
|
||||
var jsdom = require('jsdom');
|
||||
var self = this;
|
||||
jsdom.env('', function(err, win) {
|
||||
if (err) {
|
||||
done.fail(err);
|
||||
} else {
|
||||
self.doc = win.document;
|
||||
done();
|
||||
}
|
||||
});
|
||||
var JSDOM = require('jsdom').JSDOM;
|
||||
var dom = new JSDOM();
|
||||
this.doc = dom.window.document;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
(function() {
|
||||
var path = require("path"),
|
||||
fs = require("fs");
|
||||
|
||||
var glob = require("glob");
|
||||
fg = require("fast-glob");
|
||||
|
||||
var jasmineUnderTestRequire = require(path.join(__dirname, "../../src/core/requireCore.js"));
|
||||
|
||||
@@ -16,12 +14,12 @@
|
||||
}
|
||||
|
||||
function getSourceFiles() {
|
||||
var src_files = ['core/**/*.js', 'version.js'];
|
||||
src_files.forEach(function(file) {
|
||||
var filePath = path.join(__dirname, "../../", 'src/', file);
|
||||
glob.sync(filePath).forEach(function(resolvedFile) {
|
||||
require(resolvedFile);
|
||||
});
|
||||
var src_files = ['core/**/*.js', 'version.js'].map(function(file) {
|
||||
return path.join(__dirname, "../../", 'src/', file);
|
||||
});
|
||||
|
||||
fg.sync(src_files).forEach(function(resolvedFile) {
|
||||
require(resolvedFile);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('Printing a big object', function(){
|
||||
return object;
|
||||
}
|
||||
|
||||
it('takes a resonable amount of time', function(){
|
||||
it('takes a reasonable amount of time', function(){
|
||||
bigObject = generateObject(0);
|
||||
expect(jasmineUnderTest.pp(bigObject)).toMatch(/cycle/);
|
||||
});
|
||||
|
||||
12
spec/support/index.html.ejs
Normal file
12
spec/support/index.html.ejs
Normal file
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine suite</title>
|
||||
<link rel="shortcut icon" href="images/jasmine_favicon.png" type="image/png" />
|
||||
<link rel="stylesheet" href="lib/jasmine-core/jasmine.css" type="text/css" media="screen" />
|
||||
<% files.forEach(function(file) { %>
|
||||
<script src="<%= file %>" type="text/javascript"></script>
|
||||
<% }) %>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -66,7 +66,7 @@ getJasmineRequireObj().Clock = function() {
|
||||
* The clock will be {@link Clock#install|install}ed before the function is called and {@link Clock#uninstall|uninstall}ed in a `finally` after the function completes.
|
||||
* @name Clock#withMock
|
||||
* @function
|
||||
* @param {closure} Function The function to be called.
|
||||
* @param {Function} closure The function to be called.
|
||||
*/
|
||||
self.withMock = function(closure) {
|
||||
this.install();
|
||||
|
||||
@@ -100,11 +100,12 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
if (!options.suppressLoadErrors) {
|
||||
installGlobalErrors();
|
||||
globalErrors.pushListener(function(message, filename, lineno) {
|
||||
globalErrors.pushListener(function(message, filename, lineno, colNo, err) {
|
||||
topSuite.result.failedExpectations.push({
|
||||
passed: false,
|
||||
globalErrorType: 'load',
|
||||
message: message,
|
||||
stack: err && err.stack,
|
||||
filename: filename,
|
||||
lineno: lineno
|
||||
});
|
||||
@@ -511,6 +512,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result, next);
|
||||
suite.startTimer();
|
||||
},
|
||||
nodeComplete: function(suite, result, next) {
|
||||
if (suite !== currentSuite()) {
|
||||
@@ -523,7 +525,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
if (result.status === 'failed') {
|
||||
hasFailures = true;
|
||||
}
|
||||
|
||||
suite.endTimer();
|
||||
reporter.suiteDone(result, next);
|
||||
},
|
||||
orderChildren: function(node) {
|
||||
@@ -570,7 +572,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
/**
|
||||
* Information passed to the {@link Reporter#jasmineDone} event.
|
||||
* @typedef JasmineDoneInfo
|
||||
* @property {OverallStatus} overallStatus - The overall result of the sute: 'passed', 'failed', or 'incomplete'.
|
||||
* @property {OverallStatus} overallStatus - The overall result of the suite: 'passed', 'failed', or 'incomplete'.
|
||||
* @property {IncompleteReason} incompleteReason - Explanation of why the suite was incomplete.
|
||||
* @property {Order} order - Information about the ordering (random or not) of this execution of the suite.
|
||||
* @property {Expectation[]} failedExpectations - List of expectations that failed in an {@link afterAll} at the global level.
|
||||
@@ -803,9 +805,9 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
fn: fn,
|
||||
timeout: timeout || 0
|
||||
},
|
||||
throwOnExpectationFailure: config.oneFailurePerSpec
|
||||
throwOnExpectationFailure: config.oneFailurePerSpec,
|
||||
timer: new j$.Timer(),
|
||||
});
|
||||
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result, next) {
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
|
||||
var ignoredProperties = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description', 'jasmineMessage'];
|
||||
|
||||
function ExceptionFormatter(options) {
|
||||
var jasmineFile = (options && options.jasmineFile) || j$.util.jasmineFile();
|
||||
this.message = function(error) {
|
||||
var message = '';
|
||||
|
||||
if (error.name && error.message) {
|
||||
if (error.jasmineMessage) {
|
||||
message += error.jasmineMessage;
|
||||
} else if (error.name && error.message) {
|
||||
message += error.name + ': ' + error.message;
|
||||
} else if (error.message) {
|
||||
message += error.message;
|
||||
@@ -63,12 +67,11 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var ignored = ['name', 'message', 'stack', 'fileName', 'sourceURL', 'line', 'lineNumber', 'column', 'description'];
|
||||
var result = {};
|
||||
var empty = true;
|
||||
|
||||
for (var prop in error) {
|
||||
if (j$.util.arrayContains(ignored, prop)) {
|
||||
if (j$.util.arrayContains(ignoredProperties, prop)) {
|
||||
continue;
|
||||
}
|
||||
result[prop] = error[prop];
|
||||
|
||||
@@ -14,28 +14,44 @@ getJasmineRequireObj().GlobalErrors = function(j$) {
|
||||
};
|
||||
|
||||
this.originalHandlers = {};
|
||||
this.installOne_ = function installOne_(errorType) {
|
||||
this.jasmineHandlers = {};
|
||||
this.installOne_ = function installOne_(errorType, jasmineMessage) {
|
||||
function taggedOnError(error) {
|
||||
error.jasmineMessage = jasmineMessage + ': ' + error;
|
||||
|
||||
var handler = handlers[handlers.length - 1];
|
||||
|
||||
if (handler) {
|
||||
handler(error);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
this.originalHandlers[errorType] = global.process.listeners(errorType);
|
||||
this.jasmineHandlers[errorType] = taggedOnError;
|
||||
|
||||
global.process.removeAllListeners(errorType);
|
||||
global.process.on(errorType, onerror);
|
||||
global.process.on(errorType, taggedOnError);
|
||||
|
||||
this.uninstall = function uninstall() {
|
||||
var errorTypes = Object.keys(this.originalHandlers);
|
||||
for (var iType = 0; iType < errorTypes.length; iType++) {
|
||||
var errorType = errorTypes[iType];
|
||||
global.process.removeListener(errorType, onerror);
|
||||
global.process.removeListener(errorType, this.jasmineHandlers[errorType]);
|
||||
for (var i = 0; i < this.originalHandlers[errorType].length; i++) {
|
||||
global.process.on(errorType, this.originalHandlers[errorType][i]);
|
||||
}
|
||||
delete this.originalHandlers[errorType];
|
||||
delete this.jasmineHandlers[errorType];
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.install = function install() {
|
||||
if (global.process && global.process.listeners && j$.isFunction_(global.process.on)) {
|
||||
this.installOne_('uncaughtException');
|
||||
this.installOne_('unhandledRejection');
|
||||
this.installOne_('uncaughtException', 'Uncaught exception');
|
||||
this.installOne_('unhandledRejection', 'Unhandled promise rejection');
|
||||
} else {
|
||||
var originalHandler = global.onerror;
|
||||
global.onerror = onerror;
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
getJasmineRequireObj().JsApiReporter = function() {
|
||||
|
||||
var noopTimer = {
|
||||
start: function(){},
|
||||
elapsed: function(){ return 0; }
|
||||
};
|
||||
|
||||
getJasmineRequireObj().JsApiReporter = function(j$) {
|
||||
/**
|
||||
* @name jsApiReporter
|
||||
* @classdesc {@link Reporter} added by default in `boot.js` to record results for retrieval in javascript code. An instance is made available as `jsApiReporter` on the global object.
|
||||
@@ -12,7 +6,7 @@ getJasmineRequireObj().JsApiReporter = function() {
|
||||
* @hideconstructor
|
||||
*/
|
||||
function JsApiReporter(options) {
|
||||
var timer = options.timer || noopTimer,
|
||||
var timer = options.timer || j$.noopTimer,
|
||||
status = 'loaded';
|
||||
|
||||
this.started = false;
|
||||
|
||||
@@ -23,7 +23,7 @@ getJasmineRequireObj().Order = function() {
|
||||
}
|
||||
|
||||
// Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
|
||||
// used to get a different output when the key changes slighly.
|
||||
// used to get a different output when the key changes slightly.
|
||||
// We use your return to sort the children randomly in a consistent way when
|
||||
// used in conjunction with a seed
|
||||
|
||||
|
||||
@@ -34,10 +34,12 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (typeof value === 'function') {
|
||||
this.emitScalar('Function');
|
||||
} else if (value.nodeType === 1) {
|
||||
this.emitDomElement(value);
|
||||
} else if (typeof value.nodeType === 'number') {
|
||||
this.emitScalar('HTMLNode');
|
||||
} 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)) {
|
||||
@@ -228,15 +230,29 @@ getJasmineRequireObj().pp = function(j$) {
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.emitDomElement = function(el) {
|
||||
var closingTag = '</' + el.tagName.toLowerCase() + '>';
|
||||
var tagName = el.tagName.toLowerCase(),
|
||||
attrs = el.attributes,
|
||||
i,
|
||||
len = attrs.length,
|
||||
out = '<' + tagName,
|
||||
attr;
|
||||
|
||||
if (el.innerHTML === '') {
|
||||
this.append(el.outerHTML.replace(closingTag, ''));
|
||||
} else {
|
||||
var tagEnd = el.outerHTML.indexOf('>');
|
||||
this.append(el.outerHTML.substring(0, tagEnd + 1));
|
||||
this.append('...' + closingTag);
|
||||
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);
|
||||
};
|
||||
|
||||
PrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) {
|
||||
|
||||
@@ -78,7 +78,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
cleanup();
|
||||
|
||||
if (j$.isError_(err)) {
|
||||
if (!(err instanceof StopExecutionError)) {
|
||||
if (!(err instanceof StopExecutionError) && !err.jasmineMessage) {
|
||||
self.fail(err);
|
||||
}
|
||||
self.errored = errored = true;
|
||||
|
||||
@@ -14,6 +14,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
this.throwOnExpectationFailure = !!attrs.throwOnExpectationFailure;
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
@@ -29,6 +30,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred during execution this spec.
|
||||
* @property {String} pendingReason - If the spec is {@link pending}, this will be the reason.
|
||||
* @property {String} status - Once the spec has completed, this string represents the pass/fail status of this spec.
|
||||
* @property {number} duration - The time in ms used by the spec execution, including any before/afterEach.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
@@ -37,7 +39,8 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
failedExpectations: [],
|
||||
passedExpectations: [],
|
||||
deprecationWarnings: [],
|
||||
pendingReason: ''
|
||||
pendingReason: '',
|
||||
duration: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -67,6 +70,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
|
||||
var onStart = {
|
||||
fn: function(done) {
|
||||
self.timer.start();
|
||||
self.onStart(self, done);
|
||||
}
|
||||
};
|
||||
@@ -90,6 +94,7 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
self.onException.apply(self, arguments);
|
||||
},
|
||||
onComplete: function() {
|
||||
self.result.duration = self.timer.elapsed();
|
||||
onComplete(self.result.status === 'failed' && new j$.StopExecutionError('spec failed'));
|
||||
},
|
||||
userContext: this.userContext()
|
||||
|
||||
@@ -112,7 +112,7 @@ getJasmineRequireObj().Spy = function (j$) {
|
||||
|
||||
if (!strategy) {
|
||||
if (argsStrategies.any() && !baseStrategy.isConfigured()) {
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' receieved a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
throw new Error('Spy \'' + strategyArgs.name + '\' received a call with arguments ' + j$.pp(Array.prototype.slice.call(args)) + ' but all configured strategies specify other arguments.');
|
||||
} else {
|
||||
strategy = baseStrategy;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
|
||||
this.timer = attrs.timer || j$.noopTimer;
|
||||
|
||||
this.children = [];
|
||||
|
||||
/**
|
||||
@@ -24,13 +26,15 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
* @property {Expectation[]} failedExpectations - The list of expectations that failed in an {@link afterAll} for this suite.
|
||||
* @property {Expectation[]} deprecationWarnings - The list of deprecation warnings that occurred on this suite.
|
||||
* @property {String} status - Once the suite has completed, this string represents the pass/fail status of this suite.
|
||||
* @property {number} duration - The time in ms for Suite execution, including any before/afterAll, before/afterEach.
|
||||
*/
|
||||
this.result = {
|
||||
id: this.id,
|
||||
description: this.description,
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: [],
|
||||
deprecationWarnings: []
|
||||
deprecationWarnings: [],
|
||||
duration: null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,6 +76,14 @@ getJasmineRequireObj().Suite = function(j$) {
|
||||
this.afterAllFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.startTimer = function() {
|
||||
this.timer.start();
|
||||
};
|
||||
|
||||
Suite.prototype.endTimer = function() {
|
||||
this.result.duration = this.timer.elapsed();
|
||||
};
|
||||
|
||||
function removeFns(queueableFns) {
|
||||
for(var i = 0; i < queueableFns.length; i++) {
|
||||
queueableFns[i].fn = null;
|
||||
|
||||
@@ -20,3 +20,10 @@ getJasmineRequireObj().Timer = function() {
|
||||
|
||||
return Timer;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().noopTimer = function() {
|
||||
return {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
};
|
||||
@@ -17,7 +17,7 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
*/
|
||||
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 50;
|
||||
/**
|
||||
* Maximum number of charasters to display when pretty printing objects.
|
||||
* Maximum number of characters to display when pretty printing objects.
|
||||
* Characters past this number will be ellipised.
|
||||
* @name jasmine.MAX_PRETTY_PRINT_CHARS
|
||||
*/
|
||||
@@ -89,9 +89,15 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
if (value instanceof Error) {
|
||||
return true;
|
||||
}
|
||||
if (value && value.constructor && value.constructor.constructor &&
|
||||
(value instanceof (value.constructor.constructor('return this')()).Error)) {
|
||||
return true;
|
||||
if (value && value.constructor && value.constructor.constructor) {
|
||||
var valueGlobal = value.constructor.constructor('return this');
|
||||
if (j$.isFunction_(valueGlobal)) {
|
||||
valueGlobal = valueGlobal();
|
||||
}
|
||||
|
||||
if (valueGlobal.Error && value instanceof valueGlobal.Error) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -41,7 +41,8 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.Expector = jRequire.Expector(j$);
|
||||
j$.Expectation = jRequire.Expectation(j$);
|
||||
j$.buildExpectationResult = jRequire.buildExpectationResult();
|
||||
j$.JsApiReporter = jRequire.JsApiReporter();
|
||||
j$.noopTimer = jRequire.noopTimer();
|
||||
j$.JsApiReporter = jRequire.JsApiReporter(j$);
|
||||
j$.matchersUtil = jRequire.matchersUtil(j$);
|
||||
j$.ObjectContaining = jRequire.ObjectContaining(j$);
|
||||
j$.ArrayContaining = jRequire.ArrayContaining(j$);
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
var noopTimer = {
|
||||
start: function() {},
|
||||
elapsed: function() { return 0; }
|
||||
};
|
||||
|
||||
function ResultsStateBuilder() {
|
||||
this.topResults = new j$.ResultsNode({}, '', null);
|
||||
this.currentParent = this.topResults;
|
||||
@@ -58,7 +52,7 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
navigateWithNewParam = options.navigateWithNewParam || function() {},
|
||||
addToExistingQueryString = options.addToExistingQueryString || defaultQueryString,
|
||||
filterSpecs = options.filterSpecs,
|
||||
timer = options.timer || noopTimer,
|
||||
timer = options.timer || j$.noopTimer,
|
||||
htmlReporterMain,
|
||||
symbols,
|
||||
deprecationWarnings = [];
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
@import "compass";
|
||||
|
||||
$line-height: 14px;
|
||||
$margin-unit: 14px;
|
||||
|
||||
@@ -68,9 +66,12 @@ body {
|
||||
}
|
||||
|
||||
.jasmine-banner .jasmine-title {
|
||||
background: inline-image('jasmine-horizontal.png') no-repeat;
|
||||
background: inline-image('jasmine-horizontal.svg') no-repeat, none;
|
||||
@include background-size(100%);
|
||||
background: url('../../images/jasmine-horizontal.png') no-repeat;
|
||||
background: url('../../images/jasmine-horizontal.svg') no-repeat, none;
|
||||
-moz-background-size: 100%;
|
||||
-o-background-size: 100%;
|
||||
-webkit-background-size: 100%;
|
||||
background-size: 100%;
|
||||
display: block;
|
||||
float: left;
|
||||
width: 90px;
|
||||
@@ -110,7 +111,7 @@ body {
|
||||
//--- Symbol summary ---//
|
||||
|
||||
.jasmine-symbol-summary {
|
||||
@include clearfix;
|
||||
overflow: hidden;
|
||||
margin: $line-height 0;
|
||||
|
||||
li {
|
||||
|
||||
@@ -9,4 +9,4 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
bundle exec rake jasmine:ci
|
||||
node ci.js
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
rm -rf ~/.nvm
|
||||
git clone https://github.com/creationix/nvm.git ~/.nvm
|
||||
(cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`)
|
||||
source ~/.nvm/nvm.sh
|
||||
nvm install ${1:-"v0.12.18"}
|
||||
|
||||
npm install
|
||||
npm test
|
||||
Reference in New Issue
Block a user