Compare commits

...

43 Commits

Author SHA1 Message Date
Gregg Van Hove
557fb4ed72 proper links in release notes 2018-02-27 12:01:28 -08:00
Gregg Van Hove
ee52023b3d Bump version to 3.1 2018-02-27 11:57:20 -08:00
Gregg Van Hove
91296a44f2 Remove Safari 7 from Travis matrix 2018-02-27 11:10:07 -08:00
Gregg Van Hove
1923461b09 Ignore more browser fields when formatting Errors
- description from IE
- column from Safari
2018-02-27 09:52:19 -08:00
Gregg Van Hove
71116d3957 don't lock to 2.99 in dev 2018-02-27 09:33:10 -08:00
Gregg Van Hove
63cc7cafc8 Use Jasmine's arrayContains, instead of includes for better support 2018-02-26 17:57:37 -08:00
Gregg Van Hove
fdecf02472 Merge branch 'print_exception_properties' of https://github.com/jbunton-atlassian/jasmine into jbunton-atlassian-print_exception_properties
- Merges #1516 from @jbunton-atlassian
2018-02-26 17:48:28 -08:00
Gregg Van Hove
11f4d894a6 Merge branch 'node-load-errors'
- See #1519
2018-02-26 16:44:45 -08:00
James Bunton
1149d4edde Use j$.pp instead of JSON.stringify() for pretty printing 2018-02-27 10:22:06 +11:00
James Bunton
9ee85c35d2 Remove duplicate ignored property 2018-02-27 10:21:50 +11:00
Steve Gravrock
0367ca5294 Merge branch 'patch-closing-statement' of https://github.com/Sylhare/jasmine
- Merges #1512 from @Sylhare
2018-02-23 19:17:50 -08:00
James Bunton
763a83c833 Display error properties for failed specs 2018-02-23 14:43:47 +11:00
sylhare
7fb53dcdfa Fixing missing semi-colons 2018-02-21 09:01:24 -05:00
sgravrock
a9a112e88f Fixed release notes link 2018-02-18 21:08:52 -08:00
sgravrock
0184808a86 Updated README for 3.0 2018-02-18 21:06:51 -08:00
Steve Gravrock
1ac2a6f608 Allow node to report load time errors
[Fixes #153466462]
2018-02-17 15:45:42 -08:00
Gregg Van Hove
785f62c7a0 Fix naming and check functions for empty/notEmpty specs 2018-02-15 17:43:03 -08:00
Gregg Van Hove
d8c154a2c6 Update empty and notEmpty specs for better IE11 support 2018-02-15 17:23:44 -08:00
Gregg Van Hove
c974c4740c Merge branch 'master' of https://github.com/sjolicoeur/jasmine into sjolicoeur-master
- Merges #1460 from @sjolicoeur
2018-02-15 16:00:33 -08:00
Gregg Van Hove
2b27bd393f Add API docs for async reporters 2018-02-15 14:36:29 -08:00
Gregg Van Hove
3b77f38188 Return <anonymous> for functions that have no actual words between keyword and (
- Also fixes a potential catastrophic backtracking if someone has
severely damaged their own `toString` during test execution.
2018-02-15 12:31:10 -08:00
Steve Gravrock
11827572d3 Moved toHaveClass matcher into core so that it can be used in Karma
- Fixes #1503
2018-02-13 17:09:42 -08:00
Gregg Van Hove
8326ecf919 Merge branch 'deprecation-object' of https://github.com/UziTech/jasmine into UziTech-deprecation-object
- Merges #1498 from @UziTech
2018-02-13 16:57:24 -08:00
Gregg Van Hove
cd6a0de852 Merge pull request #1505 from codetriage-readme-bot/codetriage-badge
Add CodeTriage badge to jasmine/jasmine
2018-02-13 09:48:37 -08:00
codetriage-readme-bot
148d94558d Add CodeTriage badge to jasmine/jasmine
Adds a badge showing the number of people helping this repo on CodeTriage.

[![Open Source Helpers](https://www.codetriage.com/jasmine/jasmine/badges/users.svg)](https://www.codetriage.com/jasmine/jasmine)

## What is CodeTriage?

CodeTriage is an Open Source app that is designed to make contributing to Open Source projects easier. It works by sending subscribers a few open issues in their inbox. If subscribers get busy, there is an algorithm that backs off issue load so they do not get overwhelmed

[Read more about the CodeTriage project](https://www.codetriage.com/what).

## Why am I getting this PR?

Your project was picked by the human, @schneems. They selected it from the projects submitted to https://www.codetriage.com and hand edited the PR. How did your project get added to [CodeTriage](https://www.codetriage.com/what)? Roughly 8 months ago, [alopezsanchez](https://github.com/alopezsanchez) added this project to CodeTriage in order to start contributing. Since then, 2 people have subscribed to help this repo.

## What does adding a badge accomplish?

Adding a badge invites people to help contribute to your project. It also lets developers know that others are invested in the longterm success and maintainability of the project.

You can see an example of a CodeTriage badge on these popular OSS READMEs:

- [![](https://www.codetriage.com/rails/rails/badges/users.svg)](https://www.codetriage.com/rails/rails) https://github.com/rails/rails
- [![](https://www.codetriage.com/crystal-lang/crystal/badges/users.svg)](https://www.codetriage.com/crystal-lang/crystal) https://github.com/crystal-lang/crystal

## Have a question or comment?

While I am a bot, this PR was manually reviewed and monitored by a human - @schneems. My job is writing commit messages and handling PR logistics.

If you have any questions, you can reply back to this PR and they will be answered by @schneems. If you do not want a badge right now, no worries, close the PR, you will not hear from me again.

Thanks for making your project Open Source! Any feedback is greatly appreciated.
2018-02-13 10:29:49 -06:00
Gregg Van Hove
83beca6899 Merge branch '2.99-patch' 2018-02-09 09:32:09 -08:00
Gregg Van Hove
3c6308f1dc Don't include the specs in the ruby gem
- Bump to 2.99.2 for gem
2018-02-09 09:22:35 -08:00
Tony Brix
6193bc113b throw errors 2018-02-08 15:12:14 -06:00
Gregg Van Hove
fa6a80b76e Merge branch 'master' of https://github.com/aptx4869/jasmine into aptx4869-master
- Merges #1501 from @aptx4869
2018-02-08 10:22:36 -08:00
Gregg Van Hove
c861f6c6c2 Merge pull request #1499 from bcaudan/patch-1
Fix release note typo
2018-02-08 10:16:57 -08:00
aptx4869
4fcd4099ad Resolve merge conflict
Fixes #1500
2018-02-08 15:07:29 +08:00
Bastien Caudan
1d495587ff Fix release note typo 2018-02-08 08:02:13 +01:00
Tony Brix
c859128537 add tests 2018-02-07 23:58:26 -06:00
Tony Brix
a8a5b839ab allow adding a deprecation object 2018-02-07 22:44:32 -06:00
Gregg Van Hove
4e5d947faa Also lock for selenium runner 2018-02-07 14:58:14 -08:00
Gregg Van Hove
c2603efeb4 Specify Jasmine Gem 2.99 tag for bundle install 2018-02-07 14:55:28 -08:00
Gregg Van Hove
fbec3cc230 Only show deprecation for catch exceptions if you tell Jasmine not to catch
- Fixes #1497
2018-02-07 14:47:10 -08:00
Gregg Van Hove
1acbd1ef96 Add notes for environments that have lost support
- #1495
2018-02-07 09:19:33 -08:00
Gregg Van Hove
3d8e379fa6 bump dev dependency for npm 2018-02-06 15:37:21 -08:00
Gregg Van Hove
55267e11f6 Make sure ruby version is a string when passing to sauce labs 2018-02-06 13:37:12 -08:00
Gregg Van Hove
09a6e3714a Bump travis ruby version 2018-02-06 12:29:12 -08:00
Gregg Van Hove
8ec4d54685 no longer run specs for docs in CI 2018-02-06 11:54:25 -08:00
sjolicoeur
d90e20eb15 Added matchers: truthy, falsy, empty and notEmpty 2017-12-07 17:49:16 -08:00
44 changed files with 892 additions and 188 deletions

View File

@@ -2,7 +2,7 @@ language: ruby
cache: bundler cache: bundler
sudo: false sudo: false
rvm: 2.2.2 rvm: 2.5
script: $TEST_COMMAND script: $TEST_COMMAND
@@ -43,10 +43,6 @@ matrix:
- JASMINE_BROWSER="safari" - JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.10" - SAUCE_OS="OS X 10.10"
- SAUCE_BROWSER_VERSION=8 - SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="safari"
- SAUCE_OS="OS X 10.9"
- SAUCE_BROWSER_VERSION=7
- env: - env:
- JASMINE_BROWSER="MicrosoftEdge" - JASMINE_BROWSER="MicrosoftEdge"
- SAUCE_OS="Windows 10" - SAUCE_OS="Windows 10"
@@ -66,7 +62,3 @@ matrix:
- env: - env:
- JASMINE_BROWSER="phantomjs" - JASMINE_BROWSER="phantomjs"
- USE_SAUCE=false - USE_SAUCE=false
- env:
- USE_SAUCE=false
- JASMINE_BROWSER="phantomjs"
- TEST_COMMAND="bash travis-docs-script.sh"

View File

@@ -1,15 +1,16 @@
<a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a> <a name="README">[<img src="https://rawgithub.com/jasmine/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine) [![Build Status](https://travis-ci.org/jasmine/jasmine.svg?branch=master)](https://travis-ci.org/jasmine/jasmine)
[![Open Source Helpers](https://www.codetriage.com/jasmine/jasmine/badges/users.svg)](https://www.codetriage.com/jasmine/jasmine)
# A JavaScript Testing Framework # A JavaScript Testing Framework
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run. Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, [Node.js](http://nodejs.org) projects, or anywhere that JavaScript can run.
Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/) Documentation & guides live here: [http://jasmine.github.io](http://jasmine.github.io/)
For a quick start guide of Jasmine 2.x, see the beginning of [http://jasmine.github.io/edge/introduction.html](http://jasmine.github.io/edge/introduction.html) 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 1.x? Check out the [2.0 release notes](https://github.com/jasmine/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes). You can also read the [upgrade guide](http://jasmine.github.io/2.0/upgrading.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 ## Contributing
@@ -73,4 +74,4 @@ Jasmine tests itself across many browsers (Safari, Chrome, Firefox, PhantomJS, M
* [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry * [Christian Williams](mailto:antixian666@gmail.com), Cloud Foundry
* Sheel Choksi * Sheel Choksi
Copyright (c) 2008-2017 Pivotal Labs. This software is licensed under the MIT License. Copyright (c) 2008-2018 Pivotal Labs. This software is licensed under the MIT License.

View File

@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.rubyforge_project = "jasmine-core" s.rubyforge_project = "jasmine-core"
s.license = "MIT" s.license = "MIT"
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js") s.files = Dir.glob("./lib/**/*")
s.require_paths = ["lib"] s.require_paths = ["lib"]
s.add_development_dependency "rake" s.add_development_dependency "rake"
s.add_development_dependency "sauce-connect" s.add_development_dependency "sauce-connect"

View File

@@ -1,7 +1,7 @@
module.exports = function(jasmineRequire) { module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire); var jasmine = jasmineRequire.core(jasmineRequire);
var env = jasmine.getEnv(); var env = jasmine.getEnv({suppressLoadErrors: true});
var jasmineInterface = jasmineRequire.interface(jasmine, env); var jasmineInterface = jasmineRequire.interface(jasmine, env);

View File

@@ -25,7 +25,6 @@ jasmineRequire.html = function(j$) {
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
j$.QueryString = jasmineRequire.QueryString(); j$.QueryString = jasmineRequire.QueryString();
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
j$.matchers.toHaveClass = jasmineRequire.toHaveClass(j$);
}; };
jasmineRequire.HtmlReporter = function(j$) { jasmineRequire.HtmlReporter = function(j$) {
@@ -600,37 +599,3 @@ jasmineRequire.QueryString = function() {
return QueryString; return QueryString;
}; };
jasmineRequire.toHaveClass = function(j$) {
/**
* {@link expect} the actual value to be a DOM element that has the expected class
* @function
* @name matchers#toHaveClass
* @param {Object} expected - The class name to test for
* @example
* var el = document.createElement('div');
* el.className = 'foo bar baz';
* expect(el).toHaveClass('bar');
*/
function toHaveClass(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
if (!isElement(actual)) {
throw new Error(j$.pp(actual) + ' is not a DOM element');
}
return {
pass: actual.classList.contains(expected)
};
}
};
}
function isElement(maybeEl) {
return maybeEl &&
maybeEl.classList &&
j$.isFunction_(maybeEl.classList.contains);
}
return toHaveClass;
};

View File

@@ -33,13 +33,7 @@ body { overflow-y: scroll; }
.jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; } .jasmine_html-reporter .jasmine-bar.jasmine-passed { background-color: #007069; }
.jasmine_html-reporter .jasmine-bar.jasmine-incomplete { background-color: #bababa; } .jasmine_html-reporter .jasmine-bar.jasmine-incomplete { background-color: #bababa; }
.jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; } .jasmine_html-reporter .jasmine-bar.jasmine-skipped { background-color: #bababa; }
<<<<<<< HEAD
||||||| merged common ancestors
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
=======
.jasmine_html-reporter .jasmine-bar.jasmine-errored { background-color: #ca3a11; }
.jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; } .jasmine_html-reporter .jasmine-bar.jasmine-warning { background-color: #ba9d37; color: #333; }
>>>>>>> master
.jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; } .jasmine_html-reporter .jasmine-bar.jasmine-menu { background-color: #fff; color: #aaa; }
.jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; } .jasmine_html-reporter .jasmine-bar.jasmine-menu a { color: #333; }
.jasmine_html-reporter .jasmine-bar a { color: white; } .jasmine_html-reporter .jasmine-bar a { color: white; }

View File

@@ -85,6 +85,11 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
j$.ObjectPath = jRequire.ObjectPath(j$); j$.ObjectPath = jRequire.ObjectPath(j$);
j$.GlobalErrors = jRequire.GlobalErrors(j$); j$.GlobalErrors = jRequire.GlobalErrors(j$);
j$.Truthy = jRequire.Truthy(j$);
j$.Falsy = jRequire.Falsy(j$);
j$.Empty = jRequire.Empty(j$);
j$.NotEmpty = jRequire.NotEmpty(j$);
j$.matchers = jRequire.requireMatchers(jRequire, j$); j$.matchers = jRequire.requireMatchers(jRequire, j$);
return j$; return j$;
@@ -116,6 +121,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
'toHaveBeenCalledBefore', 'toHaveBeenCalledBefore',
'toHaveBeenCalledTimes', 'toHaveBeenCalledTimes',
'toHaveBeenCalledWith', 'toHaveBeenCalledWith',
'toHaveClass',
'toMatch', 'toMatch',
'toThrow', 'toThrow',
'toThrowError', 'toThrowError',
@@ -254,8 +260,8 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return func.name; return func.name;
} }
var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/) || var matches = func.toString().match(/^\s*function\s*(\w+)\s*\(/) ||
func.toString().match(/^\s*\[object\s*(\w*)Constructor\]/); func.toString().match(/^\s*\[object\s*(\w+)Constructor\]/);
return matches ? matches[1] : '<anonymous>'; return matches ? matches[1] : '<anonymous>';
}; };
@@ -281,6 +287,38 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return new j$.Anything(); return new j$.Anything();
}; };
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is `true` or anything truthy.
* @name jasmine.truthy
* @function
*/
j$.truthy = function() {return new j$.Truthy();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is `null`, `undefined`, `0`, `false` or anything falsey.
* @name jasmine.falsy
* @function
*/
j$.falsy = function() {return new j$.Falsy();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is empty.
* @name jasmine.empty
* @function
*/
j$.empty = function() {return new j$.Empty();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is not empty.
* @name jasmine.notEmpty
* @function
*/
j$.notEmpty = function() {return new j$.NotEmpty();};
/** /**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared contains at least the keys and values. * that will succeed if the actual value being compared contains at least the keys and values.
@@ -641,8 +679,11 @@ getJasmineRequireObj().Spec = function(j$) {
return this.getSpecName(this); return this.getSpecName(this);
}; };
Spec.prototype.addDeprecationWarning = function(msg) { Spec.prototype.addDeprecationWarning = function(deprecation) {
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); if (typeof deprecation === 'string') {
deprecation = { message: deprecation };
}
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
}; };
var extractCustomPendingMessage = function(e) { var extractCustomPendingMessage = function(e) {
@@ -753,17 +794,29 @@ getJasmineRequireObj().Env = function(j$) {
return currentSpec || currentSuite(); return currentSpec || currentSuite();
}; };
var globalErrors = new j$.GlobalErrors(); var globalErrors = null;
globalErrors.install();
globalErrors.pushListener(function(message, filename, lineno) { var installGlobalErrors = function() {
topSuite.result.failedExpectations.push({ if (globalErrors) {
passed: false, return;
globalErrorType: 'load', }
message: message,
filename: filename, globalErrors = new j$.GlobalErrors();
lineno: lineno globalErrors.install();
};
if (!options.suppressLoadErrors) {
installGlobalErrors();
globalErrors.pushListener(function(message, filename, lineno) {
topSuite.result.failedExpectations.push({
passed: false,
globalErrorType: 'load',
message: message,
filename: filename,
lineno: lineno
});
}); });
}); }
this.specFilter = function() { this.specFilter = function() {
return true; return true;
@@ -908,18 +961,11 @@ getJasmineRequireObj().Env = function(j$) {
return seed; return seed;
}; };
this.suppressLoadErrors = function() { this.deprecated = function(deprecation) {
if (handlingLoadErrors) {
globalErrors.popListener();
}
handlingLoadErrors = false;
};
this.deprecated = function(msg) {
var runnable = currentRunnable() || topSuite; var runnable = currentRunnable() || topSuite;
runnable.addDeprecationWarning(msg); runnable.addDeprecationWarning(deprecation);
if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') { if(typeof console !== 'undefined' && typeof console.error === 'function') {
console.error('DEPRECATION: ' + msg); console.error('DEPRECATION:', deprecation);
} }
}; };
@@ -967,6 +1013,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#jasmineStarted * @name Reporter#jasmineStarted
* @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run * @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'jasmineStarted', 'jasmineStarted',
/** /**
@@ -974,6 +1022,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#jasmineDone * @name Reporter#jasmineDone
* @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running. * @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running.
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'jasmineDone', 'jasmineDone',
/** /**
@@ -981,6 +1031,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#suiteStarted * @name Reporter#suiteStarted
* @param {SuiteResult} result Information about the individual {@link describe} being run * @param {SuiteResult} result Information about the individual {@link describe} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'suiteStarted', 'suiteStarted',
/** /**
@@ -990,6 +1042,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#suiteDone * @name Reporter#suiteDone
* @param {SuiteResult} result * @param {SuiteResult} result
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'suiteDone', 'suiteDone',
/** /**
@@ -997,6 +1051,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#specStarted * @name Reporter#specStarted
* @param {SpecResult} result Information about the individual {@link it} being run * @param {SpecResult} result Information about the individual {@link it} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'specStarted', 'specStarted',
/** /**
@@ -1006,13 +1062,15 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#specDone * @name Reporter#specDone
* @param {SpecResult} result * @param {SpecResult} result
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'specDone' 'specDone'
], queueRunnerFactory); ], queueRunnerFactory);
this.execute = function(runnablesToRun) { this.execute = function(runnablesToRun) {
var self = this; var self = this;
this.suppressLoadErrors(); installGlobalErrors();
if(!runnablesToRun) { if(!runnablesToRun) {
if (focusedRunnables.length) { if (focusedRunnables.length) {
@@ -1707,6 +1765,74 @@ getJasmineRequireObj().ArrayWithExactContents = function(j$) {
return ArrayWithExactContents; return ArrayWithExactContents;
}; };
getJasmineRequireObj().Empty = function (j$) {
function Empty() {}
Empty.prototype.asymmetricMatch = function (other) {
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
return other.length === 0;
}
if (j$.isMap(other) || j$.isSet(other)) {
return other.size === 0;
}
if (j$.isObject_(other)) {
return Object.keys(other).length === 0;
}
return false;
};
Empty.prototype.jasmineToString = function () {
return '<jasmine.empty>';
};
return Empty;
};
getJasmineRequireObj().Falsy = function(j$) {
function Falsy() {}
Falsy.prototype.asymmetricMatch = function(other) {
return !other;
};
Falsy.prototype.jasmineToString = function() {
return '<jasmine.falsy>';
};
return Falsy;
};
getJasmineRequireObj().NotEmpty = function (j$) {
function NotEmpty() {}
NotEmpty.prototype.asymmetricMatch = function (other) {
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
return other.length !== 0;
}
if (j$.isMap(other) || j$.isSet(other)) {
return other.size !== 0;
}
if (j$.isObject_(other)) {
return Object.keys(other).length !== 0;
}
return false;
};
NotEmpty.prototype.jasmineToString = function () {
return '<jasmine.notEmpty>';
};
return NotEmpty;
};
getJasmineRequireObj().ObjectContaining = function(j$) { getJasmineRequireObj().ObjectContaining = function(j$) {
function ObjectContaining(sample) { function ObjectContaining(sample) {
@@ -1778,6 +1904,21 @@ getJasmineRequireObj().StringMatching = function(j$) {
return StringMatching; return StringMatching;
}; };
getJasmineRequireObj().Truthy = function(j$) {
function Truthy() {}
Truthy.prototype.asymmetricMatch = function(other) {
return !!other;
};
Truthy.prototype.jasmineToString = function() {
return '<jasmine.truthy>';
};
return Truthy;
};
getJasmineRequireObj().CallTracker = function(j$) { getJasmineRequireObj().CallTracker = function(j$) {
/** /**
@@ -2357,18 +2498,22 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
var stackTrace = new j$.StackTrace(error.stack); var stackTrace = new j$.StackTrace(error.stack);
var lines = filterJasmine(stackTrace); var lines = filterJasmine(stackTrace);
var result = '';
if (stackTrace.message) { if (stackTrace.message) {
lines.unshift(stackTrace.message); lines.unshift(stackTrace.message);
} }
return lines.join('\n'); result += formatProperties(error);
result += lines.join('\n');
return result;
}; };
function filterJasmine(stackTrace) { function filterJasmine(stackTrace) {
var result = [], var result = [],
jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>'; jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
stackTrace.frames.forEach(function(frame) { stackTrace.frames.forEach(function(frame) {
if (frame.file && frame.file !== jasmineFile) { if (frame.file && frame.file !== jasmineFile) {
result.push(frame.raw); result.push(frame.raw);
@@ -2376,9 +2521,33 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
result.push(jasmineMarker); result.push(jasmineMarker);
} }
}); });
return result; return result;
} }
function formatProperties(error) {
if (!(error instanceof Object)) {
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)) {
continue;
}
result[prop] = error[prop];
empty = false;
}
if (!empty) {
return 'error properties: ' + j$.pp(result) + '\n';
}
return '';
}
} }
return ExceptionFormatter; return ExceptionFormatter;
@@ -2530,10 +2699,14 @@ getJasmineRequireObj().buildExpectationResult = function() {
var error = options.error; var error = options.error;
if (!error) { if (!error) {
try { if (options.stack) {
throw new Error(message()); error = options;
} catch (e) { } else {
error = e; try {
throw new Error(message());
} catch (e) {
error = e;
}
} }
} }
return stackFormatter(error); return stackFormatter(error);
@@ -3766,6 +3939,40 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
return toHaveBeenCalledWith; return toHaveBeenCalledWith;
}; };
getJasmineRequireObj().toHaveClass = function(j$) {
/**
* {@link expect} the actual value to be a DOM element that has the expected class
* @function
* @name matchers#toHaveClass
* @param {Object} expected - The class name to test for
* @example
* var el = document.createElement('div');
* el.className = 'foo bar baz';
* expect(el).toHaveClass('bar');
*/
function toHaveClass(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
if (!isElement(actual)) {
throw new Error(j$.pp(actual) + ' is not a DOM element');
}
return {
pass: actual.classList.contains(expected)
};
}
};
}
function isElement(maybeEl) {
return maybeEl &&
maybeEl.classList &&
j$.isFunction_(maybeEl.classList.contains);
}
return toHaveClass;
};
getJasmineRequireObj().toMatch = function(j$) { getJasmineRequireObj().toMatch = function(j$) {
var getErrorMsg = j$.formatErrorMsg('<toMatch>', 'expect(<expectation>).toMatch(<string> || <regexp>)'); var getErrorMsg = j$.formatErrorMsg('<toMatch>', 'expect(<expectation>).toMatch(<string> || <regexp>)');
@@ -5749,8 +5956,11 @@ getJasmineRequireObj().Suite = function(j$) {
} }
}; };
Suite.prototype.addDeprecationWarning = function(msg) { Suite.prototype.addDeprecationWarning = function(deprecation) {
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); if (typeof deprecation === 'string') {
deprecation = { message: deprecation };
}
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
}; };
function isFailure(args) { function isFailure(args) {
@@ -6020,5 +6230,5 @@ getJasmineRequireObj().UserContext = function(j$) {
}; };
getJasmineRequireObj().version = function() { getJasmineRequireObj().version = function() {
return '3.0.0'; return '3.1.0';
}; };

View File

@@ -23,7 +23,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
module.exports = function(jasmineRequire) { module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire); var jasmine = jasmineRequire.core(jasmineRequire);
var env = jasmine.getEnv(); var env = jasmine.getEnv({suppressLoadErrors: true});
var jasmineInterface = jasmineRequire.interface(jasmine, env); var jasmineInterface = jasmineRequire.interface(jasmine, env);

View File

@@ -1 +0,0 @@
../../spec

View File

@@ -4,6 +4,6 @@
# #
module Jasmine module Jasmine
module Core module Core
VERSION = "3.0.0" VERSION = "3.1.0"
end end
end end

View File

@@ -1,7 +1,7 @@
{ {
"name": "jasmine-core", "name": "jasmine-core",
"license": "MIT", "license": "MIT",
"version": "3.0.0", "version": "3.1.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/jasmine/jasmine.git" "url": "https://github.com/jasmine/jasmine.git"
@@ -26,7 +26,8 @@
"grunt-contrib-compress": "^1.3.0", "grunt-contrib-compress": "^1.3.0",
"grunt-contrib-concat": "^1.0.1", "grunt-contrib-concat": "^1.0.1",
"grunt-contrib-jshint": "^1.0.0", "grunt-contrib-jshint": "^1.0.0",
"jasmine": "^2.5.0", "jasmine": "^3.0.0",
"jsdom": "^9.12.0",
"load-grunt-tasks": "^0.4.0", "load-grunt-tasks": "^0.4.0",
"shelljs": "^0.7.0", "shelljs": "^0.7.0",
"temp": "~0.8.1" "temp": "~0.8.1"

View File

@@ -10,7 +10,7 @@ There is also a 2.99 release of Jasmine that will present deprecation warnings f
* Replace old "catch exceptions" logic with proper fail fast with error reporting * Replace old "catch exceptions" logic with proper fail fast with error reporting
- Fixes [#414](https://github.com/jasmine/jasmine/issues/414) - Fixes [#414](https://github.com/jasmine/jasmine/issues/414)
- Fixes [jasmine/jasmine-npm#16](https://github.com/jasmine/jasmine/jasmine-npm/issues/16) - Fixes [jasmine/jasmine-npm#16](https://github.com/jasmine/jasmine-npm/issues/16)
* Detect an Error passed to `done` and add an expectation failure * Detect an Error passed to `done` and add an expectation failure
- Fixes [#567](https://github.com/jasmine/jasmine/issues/567) - Fixes [#567](https://github.com/jasmine/jasmine/issues/567)
@@ -29,6 +29,13 @@ There is also a 2.99 release of Jasmine that will present deprecation warnings f
* Default to running tests in random order * Default to running tests in random order
* Additionally, Jasmine 3.0 drops support for older browsers and environments. Notably:
- Internet Explorer 8 and 9
- Ruby 1.x (for the Ruby gem)
- Rails 3.x (for the Ruby gem)
- Python 2.x (for the Python wheel)
- Nodejs 0.x (for the NPM package)
## Changes ## Changes
* Remove node modules from python wheel, and update languages * Remove node modules from python wheel, and update languages

54
release_notes/3.1.0.md Normal file
View File

@@ -0,0 +1,54 @@
# Jasmine-Core 3.1 Release Notes
## Summary
This release contains a number of fixes and pull requests
## Pull Requests and Issues
* Display error properties for failed specs
- Merges [#1516](https://github.com/jasmine/jasmine/issues/1516) from @jbunton-atlassian
* Allow node to report load time errors
- Fixes [#1519](https://github.com/jasmine/jasmine/issues/1519)
* Fixing missing semi-colons
- Merges [#1512](https://github.com/jasmine/jasmine/issues/1512) from @Sylhare
* Fixed release notes link
* Added matchers: truthy, falsy, empty and notEmpty
- Merges [#1460](https://github.com/jasmine/jasmine/issues/1460) from @sjolicoeur
* Add API docs for async reporters
* Return <anonymous> for functions that have no actual words between keyword and (
- Also fixes a potential catastrophic backtracking if someone has
severely damaged their own `toString` during test execution.
* Moved toHaveClass matcher into core so that it can be used in Karma
- Fixes [#1503](https://github.com/jasmine/jasmine/issues/1503)
* allow adding a deprecation object
- Merges [#1498](https://github.com/jasmine/jasmine/issues/1498) from @UziTech
* Add CodeTriage badge to jasmine/jasmine
- Merges [#1505](https://github.com/jasmine/jasmine/issues/1505) from @codetriage-readme-bot
* Resolve merge conflict
- Merges [#1501](https://github.com/jasmine/jasmine/issues/1501) from @aptx4869
- Fixes [#1500](https://github.com/jasmine/jasmine/issues/1500)
* Fix release note typo
- Merges [#1499](https://github.com/jasmine/jasmine/issues/1499) @bcaudan
* Only show deprecation for catch exceptions if you tell Jasmine not to catch
- Fixes [#1497](https://github.com/jasmine/jasmine/issues/1497)
* Add notes for environments that have lost support
- Fixes [#1495](https://github.com/jasmine/jasmine/issues/1495)
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

View File

@@ -669,7 +669,7 @@ describe("Clock (acceptance)", function() {
expect(global.Date().getTime()).toEqual(baseTime.getTime() + 5); expect(global.Date().getTime()).toEqual(baseTime.getTime() + 5);
expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]); expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]);
}) });
it('correctly clears a scheduled timeout while the Clock is advancing', function () { it('correctly clears a scheduled timeout while the Clock is advancing', function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(), var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),

View File

@@ -197,4 +197,24 @@ describe("Env", function() {
}).not.toThrow(); }).not.toThrow();
}); });
}); });
describe('when not constructed with suppressLoadErrors: true', function() {
it('installs a global error handler on construction', function() {
var globalErrors = jasmine.createSpyObj('globalErrors', ['install', 'pushListener', 'popListener']);
spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors);
new jasmineUnderTest.Env();
expect(globalErrors.install).toHaveBeenCalled();
});
});
describe('when constructed with suppressLoadErrors: true', function() {
it('does not install a global error handler until execute is called', function() {
var globalErrors = jasmine.createSpyObj('globalErrors', ['install', 'pushListener', 'popListener']);
spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors);
env = new jasmineUnderTest.Env({suppressLoadErrors: true});
expect(globalErrors.install).not.toHaveBeenCalled();
env.execute();
expect(globalErrors.install).toHaveBeenCalled();
});
});
}); });

View File

@@ -116,5 +116,16 @@ describe("ExceptionFormatter", function() {
it("returns null if no Error provided", function() { it("returns null if no Error provided", function() {
expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull(); expect(new jasmineUnderTest.ExceptionFormatter().stack()).toBeNull();
}); });
it("includes error properties in stack", function() {
var error;
try { throw new Error("an error") } catch(e) { error = e; }
error.someProperty = 'hello there';
var result = new jasmineUnderTest.ExceptionFormatter().stack(error);
expect(result).toMatch(/error properties:.*someProperty.*hello there/);
});
}); });
}); });

View File

@@ -32,7 +32,7 @@ describe("UserContext", function() {
describe('when using a regular object as parameter', function() { describe('when using a regular object as parameter', function() {
beforeEach(function() { beforeEach(function() {
this.context = {}; this.context = {};
this.value = 'value' this.value = 'value';
this.context.key = this.value; this.context.key = this.value;
this.cloned = jasmineUnderTest.UserContext.fromExisting(this.context); this.cloned = jasmineUnderTest.UserContext.fromExisting(this.context);
}); });

View File

@@ -0,0 +1,51 @@
describe("Empty", function () {
it("matches an empty object", function () {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch({})).toBe(true);
expect(empty.asymmetricMatch({undefined: false})).toBe(false);
});
it("matches an empty array", function () {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch([])).toBe(true);
expect(empty.asymmetricMatch([1, 12, 3])).toBe(false);
});
it("matches an empty string", function () {
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch("")).toBe(true);
expect(empty.asymmetricMatch('')).toBe(true);
expect(empty.asymmetricMatch('12312')).toBe(false);
});
it("matches an empty map", function () {
jasmine.getEnv().requireFunctioningMaps();
var empty = new jasmineUnderTest.Empty();
var fullMap = new Map();
fullMap.set('thing', 2);
expect(empty.asymmetricMatch(new Map())).toBe(true);
expect(empty.asymmetricMatch(fullMap)).toBe(false);
});
it("matches an empty set", function () {
jasmine.getEnv().requireFunctioningSets();
var empty = new jasmineUnderTest.Empty();
var fullSet = new Set();
fullSet.add(3);
expect(empty.asymmetricMatch(new Set())).toBe(true);
expect(empty.asymmetricMatch(fullSet)).toBe(false);
});
it("matches an empty typed array", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var empty = new jasmineUnderTest.Empty();
expect(empty.asymmetricMatch(new Int16Array())).toBe(true);
expect(empty.asymmetricMatch(new Int16Array([1,2]))).toBe(false);
});
});

View File

@@ -0,0 +1,38 @@
describe("Falsy", function() {
it("is true for an empty string", function() {
var falsy = new jasmineUnderTest.Falsy();
expect(falsy.asymmetricMatch("")).toBe(true);
expect(falsy.asymmetricMatch('')).toBe(true);
expect(falsy.asymmetricMatch('asdasdad')).toBe(false);
});
it("is false for a number that is 0", function() {
var falsy = new jasmineUnderTest.Falsy(Number);
expect(falsy.asymmetricMatch(1)).toBe(false);
expect(falsy.asymmetricMatch(0)).toBe(true);
expect(falsy.asymmetricMatch(-23)).toBe(false);
expect(falsy.asymmetricMatch(-3.1)).toBe(false);
});
it("is true for a null or undefined", function() {
var falsy = new jasmineUnderTest.Falsy(Function);
expect(falsy.asymmetricMatch(null)).toBe(true);
expect(falsy.asymmetricMatch(undefined )).toBe(true);
});
it("is true for NaN", function() {
var falsy = new jasmineUnderTest.Falsy(Object);
expect(falsy.asymmetricMatch(NaN)).toBe(true);
});
it("is true for a false Boolean", function() {
var falsy = new jasmineUnderTest.Falsy(Boolean);
expect(falsy.asymmetricMatch(false)).toBe(true);
expect(falsy.asymmetricMatch(true)).toBe(false);
});
});

View File

@@ -0,0 +1,53 @@
describe("NotEmpty", function () {
it("matches a non empty object", function () {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch({undefined: false})).toBe(true);
expect(notEmpty.asymmetricMatch({})).toBe(false);
});
it("matches a non empty array", function () {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch([1, 12, 3])).toBe(true);
expect(notEmpty.asymmetricMatch([])).toBe(false);
});
it("matches a non empty string", function () {
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch('12312')).toBe(true);
expect(notEmpty.asymmetricMatch("")).toBe(false);
expect(notEmpty.asymmetricMatch('')).toBe(false);
});
it("matches a non empty map", function () {
jasmine.getEnv().requireFunctioningMaps();
var notEmpty = new jasmineUnderTest.NotEmpty();
var fullMap = new Map();
fullMap.set('one', 1);
var emptyMap = new Map();
expect(notEmpty.asymmetricMatch(fullMap)).toBe(true);
expect(notEmpty.asymmetricMatch(emptyMap)).toBe(false);
});
it("matches a non empty set", function () {
jasmine.getEnv().requireFunctioningSets();
var notEmpty = new jasmineUnderTest.NotEmpty();
var filledSet = new Set();
filledSet.add(1);
var emptySet = new Set();
expect(notEmpty.asymmetricMatch(filledSet)).toBe(true);
expect(notEmpty.asymmetricMatch(emptySet)).toBe(false);
});
it("matches a non empty typed array", function() {
jasmine.getEnv().requireFunctioningTypedArrays();
var notEmpty = new jasmineUnderTest.NotEmpty();
expect(notEmpty.asymmetricMatch(new Int16Array([1,2,3]))).toBe(true);
expect(notEmpty.asymmetricMatch(new Int16Array())).toBe(false);
});
});

View File

@@ -0,0 +1,63 @@
describe("Truthy", function () {
it("is true for a non empty string", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch("foo")).toBe(true);
expect(truthy.asymmetricMatch("")).toBe(false);
});
it("is true for a number that is not 0", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(1)).toBe(true);
expect(truthy.asymmetricMatch(0)).toBe(false);
expect(truthy.asymmetricMatch(-23)).toBe(true);
expect(truthy.asymmetricMatch(-3.1)).toBe(true);
});
it("is true for a function", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(function () {
})).toBe(true);
});
it("is true for an Object", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch({})).toBe(true);
});
it("is true for a truthful Boolean", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(true)).toBe(true);
expect(truthy.asymmetricMatch(false)).toBe(false);
});
it("is true for an empty object", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch({})).toBe(true);
});
it("is true for an empty array", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch([])).toBe(true);
});
it("is true for a date", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(new Date())).toBe(true);
});
it("is true for a infiniti", function () {
var truthy = new jasmineUnderTest.Truthy();
expect(truthy.asymmetricMatch(Infinity)).toBe(true);
expect(truthy.asymmetricMatch(-Infinity)).toBe(true);
});
});

View File

@@ -121,7 +121,7 @@ describe("Custom Matchers (Integration)", function() {
var specExpectations = function(result) { var specExpectations = function(result) {
expect(result.status).toEqual('passed'); expect(result.status).toEqual('passed');
} };
env.addReporter({ specDone: specExpectations, jasmineDone: done }); env.addReporter({ specDone: specExpectations, jasmineDone: done });
env.execute(); env.execute();

View File

@@ -892,7 +892,7 @@ describe("Env integration", function() {
}; };
env.describe('test suite', function() { env.describe('test suite', function() {
env.beforeAll(function() { env.spyOn(testObj, 'foo');}) env.beforeAll(function() { env.spyOn(testObj, 'foo');});
env.it('spec 0', function() { env.it('spec 0', function() {
expect(jasmineUnderTest.isSpy(testObj.foo)).toBe(true); expect(jasmineUnderTest.isSpy(testObj.foo)).toBe(true);
@@ -2060,11 +2060,13 @@ describe("Env integration", function() {
env.execute(); env.execute();
}); });
describe('If suppressLoadErrors was called', function() { describe('If suppressLoadErrors: true was passed', function() {
it('does not report or handle errors that occur during loading', function(done) { it('does not install a global error handler during loading', function(done) {
var originalOnerror = jasmine.createSpy('original onerror')
var global = { var global = {
setTimeout: function(fn, delay) { setTimeout(fn, delay) }, setTimeout: function(fn, delay) { setTimeout(fn, delay) },
clearTimeout: function(fn, delay) { clearTimeout(fn, delay) } clearTimeout: function(fn, delay) { clearTimeout(fn, delay) },
onerror: originalOnerror
}; };
spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global); spyOn(jasmineUnderTest, 'getGlobal').and.returnValue(global);
var globalErrors = new jasmineUnderTest.GlobalErrors(global); var globalErrors = new jasmineUnderTest.GlobalErrors(global);
@@ -2072,17 +2074,16 @@ describe("Env integration", function() {
globalErrors.pushListener(onerror); globalErrors.pushListener(onerror);
spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors); spyOn(jasmineUnderTest, 'GlobalErrors').and.returnValue(globalErrors);
var env = new jasmineUnderTest.Env(), var env = new jasmineUnderTest.Env({suppressLoadErrors: true});
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']);
reporter.jasmineDone.and.callFake(function(e) { reporter.jasmineDone.and.callFake(function(e) {
expect(e.failedExpectations).toEqual([]); expect(e.failedExpectations).toEqual([]);
expect(onerror).toHaveBeenCalledWith('Uncaught Error: ENOCHEESE'); expect(originalOnerror).toHaveBeenCalledWith('Uncaught Error: ENOCHEESE');
done(); done();
}); });
env.addReporter(reporter); env.addReporter(reporter);
env.suppressLoadErrors(true);
global.onerror('Uncaught Error: ENOCHEESE'); global.onerror('Uncaught Error: ENOCHEESE');
env.execute(); env.execute();
@@ -2303,6 +2304,9 @@ describe("Env integration", function() {
var env = new jasmineUnderTest.Env(), var env = new jasmineUnderTest.Env(),
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']); reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']);
// prevent deprecation from being desplayed
spyOn(console, "error");
reporter.jasmineDone.and.callFake(function(result) { reporter.jasmineDone.and.callFake(function(result) {
expect(result.deprecationWarnings).toEqual([ expect(result.deprecationWarnings).toEqual([
jasmine.objectContaining({ message: 'top level deprecation' }) jasmine.objectContaining({ message: 'top level deprecation' })
@@ -2341,4 +2345,65 @@ describe("Env integration", function() {
env.execute(); env.execute();
}); });
it('should report deprecation stack with an error object', function(done) {
var env = new jasmineUnderTest.Env(),
exceptionFormatter = new jasmineUnderTest.ExceptionFormatter(),
reporter = jasmine.createSpyObj('reporter', ['jasmineDone', 'suiteDone', 'specDone']),
topLevelError, suiteLevelError, specLevelError;
try { throw new Error('top level deprecation') } catch (err) { topLevelError = err; }
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
spyOn(console, "error");
reporter.jasmineDone.and.callFake(function(result) {
expect(result.deprecationWarnings).toEqual([
jasmine.objectContaining({
message: topLevelError.message,
stack: exceptionFormatter.stack(topLevelError)
})
]);
expect(reporter.suiteDone).toHaveBeenCalledWith(jasmine.objectContaining({
fullName: 'suite',
deprecationWarnings: [
jasmine.objectContaining({
message: suiteLevelError.message,
stack: exceptionFormatter.stack(suiteLevelError)
})
]
}));
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({
fullName: 'suite spec',
deprecationWarnings: [
jasmine.objectContaining({
message: specLevelError.message,
stack: exceptionFormatter.stack(specLevelError)
})
]
}));
done();
});
env.addReporter(reporter);
env.deprecated(topLevelError);
env.describe('suite', function() {
env.beforeAll(function() {
env.deprecated(suiteLevelError);
});
env.it('spec', function() {
env.deprecated(specLevelError);
});
});
env.execute();
});
}); });

View File

@@ -145,7 +145,7 @@ describe("matchersUtil", function() {
actual = { b: 1 }; actual = { b: 1 };
expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(false); expect(jasmineUnderTest.matchersUtil.equals(actual, expected)).toBe(false);
}) });
it("fails when comparing an empty object to an empty array (issue #114)", function() { it("fails when comparing an empty object to an empty array (issue #114)", function() {
var emptyObject = {}, var emptyObject = {},
@@ -211,11 +211,11 @@ describe("matchersUtil", function() {
return; return;
} }
var a = document.createElement("div"); var a = document.createElement("div");
a.setAttribute("test-attr", "attr-value") a.setAttribute("test-attr", "attr-value");
a.appendChild(document.createTextNode('test')); a.appendChild(document.createTextNode('test'));
var b = document.createElement("div"); var b = document.createElement("div");
b.setAttribute("test-attr", "attr-value2") b.setAttribute("test-attr", "attr-value2");
b.appendChild(document.createTextNode('test')); b.appendChild(document.createTextNode('test'));
expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false); expect(jasmineUnderTest.matchersUtil.equals(a,b)).toBe(false);

View File

@@ -14,7 +14,7 @@ describe("toBeGreaterThanOrEqual", function() {
result = matcher.compare(1.0, 1.0); result = matcher.compare(1.0, 1.0);
expect(result.pass).toBe(true); expect(result.pass).toBe(true);
}) });
it("fails when actual < expected", function() { it("fails when actual < expected", function() {
var matcher = jasmineUnderTest.matchers.toBeGreaterThanOrEqual(), var matcher = jasmineUnderTest.matchers.toBeGreaterThanOrEqual(),

View File

@@ -95,7 +95,7 @@ describe("toEqual", function() {
expected = {x: {}}, expected = {x: {}},
message = message =
"Expected $.x not to have properties\n" + "Expected $.x not to have properties\n" +
" y: 'foo bar'" " y: 'foo bar'";
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -594,15 +594,15 @@ describe("toEqual", function() {
var nodeA = document.createElement('div'), var nodeA = document.createElement('div'),
nodeB = document.createElement('div'); nodeB = document.createElement('div');
nodeA.innerText = 'foo' nodeA.innerText = 'foo';
nodeB.innerText = 'bar' nodeB.innerText = 'bar';
var actual = {a: nodeA}, var actual = {a: nodeA},
expected = {a: nodeB}, expected = {a: nodeB},
message = 'Expected $.a = <div>...</div> to equal <div>...</div>.'; message = 'Expected $.a = <div>...</div> to equal <div>...</div>.';
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}) });
it("reports mismatches between a DOM node and a bare Object", function() { it("reports mismatches between a DOM node and a bare Object", function() {
if(isNotRunningInBrowser()) { if(isNotRunningInBrowser()) {
@@ -658,7 +658,7 @@ describe("toEqual", function() {
boolean: false, boolean: false,
notDefined: 0, notDefined: 0,
aNull: void 0 aNull: void 0
} };
var expected = { var expected = {
foo: [ foo: [
@@ -675,7 +675,7 @@ describe("toEqual", function() {
boolean: true, boolean: true,
notDefined: void 0, notDefined: void 0,
aNull: null aNull: null
} };
var message = var message =
'Expected $.foo[0].bar = 1 to equal 2.\n' + 'Expected $.foo[0].bar = 1 to equal 2.\n' +
@@ -690,10 +690,10 @@ describe("toEqual", function() {
'Expected $.inf = -Infinity to equal Infinity.\n' + 'Expected $.inf = -Infinity to equal Infinity.\n' +
'Expected $.boolean = false to equal true.\n' + 'Expected $.boolean = false to equal true.\n' +
'Expected $.notDefined = 0 to equal undefined.\n' + 'Expected $.notDefined = 0 to equal undefined.\n' +
'Expected $.aNull = undefined to equal null.' 'Expected $.aNull = undefined to equal null.';
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}) });
describe("different length arrays", function() { describe("different length arrays", function() {
it("actual array is longer", function() { it("actual array is longer", function() {
@@ -702,7 +702,7 @@ describe("toEqual", function() {
message = 'Expected $.length = 5 to equal 4.\n' + message = 'Expected $.length = 5 to equal 4.\n' +
'Expected $[4] = 5 to equal undefined.'; 'Expected $[4] = 5 to equal undefined.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -712,7 +712,7 @@ describe("toEqual", function() {
message = 'Expected $.length = 4 to equal 5.\n' + message = 'Expected $.length = 4 to equal 5.\n' +
'Expected $[4] = undefined to equal 5.'; 'Expected $[4] = undefined to equal 5.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -725,7 +725,7 @@ describe("toEqual", function() {
'Expected $[5] = undefined to equal 8.\n' + 'Expected $[5] = undefined to equal 8.\n' +
'Expected $[6] = undefined to equal 13.'; 'Expected $[6] = undefined to equal 13.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -736,7 +736,7 @@ describe("toEqual", function() {
'Expected $[0] = 1 to equal 2.\n' + 'Expected $[0] = 1 to equal 2.\n' +
'Expected $[1] = undefined to equal 3.'; 'Expected $[1] = undefined to equal 3.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -746,7 +746,7 @@ describe("toEqual", function() {
message = 'Expected $.values.length = 4 to equal 3.\n' + message = 'Expected $.values.length = 4 to equal 3.\n' +
'Expected $.values[3] = 3 to equal undefined.'; 'Expected $.values[3] = 3 to equal undefined.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -756,7 +756,7 @@ describe("toEqual", function() {
message = 'Expected $.length = 4 to equal 3.\n' + message = 'Expected $.length = 4 to equal 3.\n' +
'Expected $[3] = Object({ value: 3 }) to equal undefined.'; 'Expected $[3] = Object({ value: 3 }) to equal undefined.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -769,7 +769,7 @@ describe("toEqual", function() {
'Expected $[1][0] = 1 to equal 2.\n' + 'Expected $[1][0] = 1 to equal 2.\n' +
'Expected $[1][1] = 2 to equal undefined.'; 'Expected $[1][1] = 2 to equal undefined.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
@@ -778,7 +778,7 @@ describe("toEqual", function() {
expected = [1, 2, void 0], expected = [1, 2, void 0],
message = 'Expected $.length = 2 to equal 3.'; message = 'Expected $.length = 2 to equal 3.';
expect(compareEquals(actual, expected).pass).toBe(false) expect(compareEquals(actual, expected).pass).toBe(false);
expect(compareEquals(actual, expected).message).toEqual(message); expect(compareEquals(actual, expected).message).toEqual(message);
}); });
}) })

View File

@@ -1,16 +1,38 @@
describe('toHaveClass', function() { describe('toHaveClass', function() {
beforeEach(function(done) {
this.createElementWithClassName = function(className) {
var el = this.doc.createElement('div');
el.className = className;
return el;
};
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();
}
});
}
});
it('fails for a DOM element that lacks the expected class', function() { it('fails for a DOM element that lacks the expected class', function() {
var matcher = jasmineUnderTest.matchers.toHaveClass(), var matcher = jasmineUnderTest.matchers.toHaveClass(),
result = matcher.compare(document.createElement('div'), 'foo'); result = matcher.compare(this.createElementWithClassName(''), 'foo');
expect(result.pass).toBe(false); expect(result.pass).toBe(false);
}); });
it('passes for a DOM element that has the expected class', function() { it('passes for a DOM element that has the expected class', function() {
var matcher = jasmineUnderTest.matchers.toHaveClass(), var matcher = jasmineUnderTest.matchers.toHaveClass(),
el = document.createElement('div'); el = this.createElementWithClassName('foo bar baz');
el.className = 'foo bar baz';
expect(matcher.compare(el, 'foo').pass).toBe(true); expect(matcher.compare(el, 'foo').pass).toBe(true);
expect(matcher.compare(el, 'bar').pass).toBe(true); expect(matcher.compare(el, 'bar').pass).toBe(true);
@@ -19,9 +41,7 @@ describe('toHaveClass', function() {
it('fails for a DOM element that only has other classes', function() { it('fails for a DOM element that only has other classes', function() {
var matcher = jasmineUnderTest.matchers.toHaveClass(), var matcher = jasmineUnderTest.matchers.toHaveClass(),
el = document.createElement('div'); el = this.createElementWithClassName('foo bar');
el.className = 'foo bar';
expect(matcher.compare(el, 'fo').pass).toBe(false); expect(matcher.compare(el, 'fo').pass).toBe(false);
}); });
@@ -37,8 +57,9 @@ describe('toHaveClass', function() {
matcher.compare(undefined, 'foo'); matcher.compare(undefined, 'foo');
}).toThrowError('undefined is not a DOM element'); }).toThrowError('undefined is not a DOM element');
var textNode = this.doc.createTextNode('');
expect(function() { expect(function() {
matcher.compare(document.createTextNode(''), 'foo') matcher.compare(textNode, 'foo')
}).toThrowError('HTMLNode is not a DOM element'); }).toThrowError('HTMLNode is not a DOM element');
expect(function() { expect(function() {

View File

@@ -1047,7 +1047,7 @@ describe("HtmlReporter", function() {
beforeEach(function() { beforeEach(function() {
env = new jasmineUnderTest.Env(); env = new jasmineUnderTest.Env();
container = document.createElement("div"); container = document.createElement("div");
var getContainer = function() { return container; } var getContainer = function() { return container; };
reporter = new jasmineUnderTest.HtmlReporter({ reporter = new jasmineUnderTest.HtmlReporter({
env: env, env: env,
getContainer: getContainer, getContainer: getContainer,

View File

@@ -6,10 +6,10 @@ sauce:
name: jasmine-core <%= Time.now.to_s %> name: jasmine-core <%= Time.now.to_s %>
username: <%= ENV['SAUCE_USERNAME'] %> username: <%= ENV['SAUCE_USERNAME'] %>
access_key: <%= ENV['SAUCE_ACCESS_KEY'] %> access_key: <%= ENV['SAUCE_ACCESS_KEY'] %>
build: <%= ENV['TRAVIS_BUILD_NUMBER'] || 'Ran locally' %> build: Core <%= ENV['TRAVIS_BUILD_NUMBER'] || 'Ran locally' %>
tags: tags:
- <%= ENV['TRAVIS_RUBY_VERSION'] || RUBY_VERSION %> - Jasmine-Core
- CI - "<%= ENV['TRAVIS_JOB_NUMBER'] %>"
tunnel_identifier: <%= ENV['TRAVIS_JOB_NUMBER'] ? %Q("#{ENV['TRAVIS_JOB_NUMBER']}") : nil %> tunnel_identifier: <%= ENV['TRAVIS_JOB_NUMBER'] ? %Q("#{ENV['TRAVIS_JOB_NUMBER']}") : nil %>
os: <%= ENV['SAUCE_OS'] %> os: <%= ENV['SAUCE_OS'] %>
browser_version: "<%= ENV['SAUCE_BROWSER_VERSION'] %>" browser_version: "<%= ENV['SAUCE_BROWSER_VERSION'] %>"

View File

@@ -38,17 +38,29 @@ getJasmineRequireObj().Env = function(j$) {
return currentSpec || currentSuite(); return currentSpec || currentSuite();
}; };
var globalErrors = new j$.GlobalErrors(); var globalErrors = null;
globalErrors.install();
globalErrors.pushListener(function(message, filename, lineno) { var installGlobalErrors = function() {
topSuite.result.failedExpectations.push({ if (globalErrors) {
passed: false, return;
globalErrorType: 'load', }
message: message,
filename: filename, globalErrors = new j$.GlobalErrors();
lineno: lineno globalErrors.install();
};
if (!options.suppressLoadErrors) {
installGlobalErrors();
globalErrors.pushListener(function(message, filename, lineno) {
topSuite.result.failedExpectations.push({
passed: false,
globalErrorType: 'load',
message: message,
filename: filename,
lineno: lineno
});
}); });
}); }
this.specFilter = function() { this.specFilter = function() {
return true; return true;
@@ -193,18 +205,11 @@ getJasmineRequireObj().Env = function(j$) {
return seed; return seed;
}; };
this.suppressLoadErrors = function() { this.deprecated = function(deprecation) {
if (handlingLoadErrors) {
globalErrors.popListener();
}
handlingLoadErrors = false;
};
this.deprecated = function(msg) {
var runnable = currentRunnable() || topSuite; var runnable = currentRunnable() || topSuite;
runnable.addDeprecationWarning(msg); runnable.addDeprecationWarning(deprecation);
if(typeof console !== 'undefined' && typeof console.warn !== 'undefined') { if(typeof console !== 'undefined' && typeof console.error === 'function') {
console.error('DEPRECATION: ' + msg); console.error('DEPRECATION:', deprecation);
} }
}; };
@@ -252,6 +257,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#jasmineStarted * @name Reporter#jasmineStarted
* @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run * @param {JasmineStartedInfo} suiteInfo Information about the full Jasmine suite that is being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'jasmineStarted', 'jasmineStarted',
/** /**
@@ -259,6 +266,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#jasmineDone * @name Reporter#jasmineDone
* @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running. * @param {JasmineDoneInfo} suiteInfo Information about the full Jasmine suite that just finished running.
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'jasmineDone', 'jasmineDone',
/** /**
@@ -266,6 +275,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#suiteStarted * @name Reporter#suiteStarted
* @param {SuiteResult} result Information about the individual {@link describe} being run * @param {SuiteResult} result Information about the individual {@link describe} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'suiteStarted', 'suiteStarted',
/** /**
@@ -275,6 +286,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#suiteDone * @name Reporter#suiteDone
* @param {SuiteResult} result * @param {SuiteResult} result
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'suiteDone', 'suiteDone',
/** /**
@@ -282,6 +295,8 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#specStarted * @name Reporter#specStarted
* @param {SpecResult} result Information about the individual {@link it} being run * @param {SpecResult} result Information about the individual {@link it} being run
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'specStarted', 'specStarted',
/** /**
@@ -291,13 +306,15 @@ getJasmineRequireObj().Env = function(j$) {
* @function * @function
* @name Reporter#specDone * @name Reporter#specDone
* @param {SpecResult} result * @param {SpecResult} result
* @param {Function} [done] Used to specify to Jasmine that this callback is asynchronous and Jasmine should wait until it has been called before moving on.
* @returns {} Optionally return a Promise instead of using `done` to cause Jasmine to wait for completion.
*/ */
'specDone' 'specDone'
], queueRunnerFactory); ], queueRunnerFactory);
this.execute = function(runnablesToRun) { this.execute = function(runnablesToRun) {
var self = this; var self = this;
this.suppressLoadErrors(); installGlobalErrors();
if(!runnablesToRun) { if(!runnablesToRun) {
if (focusedRunnables.length) { if (focusedRunnables.length) {

View File

@@ -29,18 +29,22 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
var stackTrace = new j$.StackTrace(error.stack); var stackTrace = new j$.StackTrace(error.stack);
var lines = filterJasmine(stackTrace); var lines = filterJasmine(stackTrace);
var result = '';
if (stackTrace.message) { if (stackTrace.message) {
lines.unshift(stackTrace.message); lines.unshift(stackTrace.message);
} }
return lines.join('\n'); result += formatProperties(error);
result += lines.join('\n');
return result;
}; };
function filterJasmine(stackTrace) { function filterJasmine(stackTrace) {
var result = [], var result = [],
jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>'; jasmineMarker = stackTrace.style === 'webkit' ? '<Jasmine>' : ' at <Jasmine>';
stackTrace.frames.forEach(function(frame) { stackTrace.frames.forEach(function(frame) {
if (frame.file && frame.file !== jasmineFile) { if (frame.file && frame.file !== jasmineFile) {
result.push(frame.raw); result.push(frame.raw);
@@ -48,9 +52,33 @@ getJasmineRequireObj().ExceptionFormatter = function(j$) {
result.push(jasmineMarker); result.push(jasmineMarker);
} }
}); });
return result; return result;
} }
function formatProperties(error) {
if (!(error instanceof Object)) {
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)) {
continue;
}
result[prop] = error[prop];
empty = false;
}
if (!empty) {
return 'error properties: ' + j$.pp(result) + '\n';
}
return '';
}
} }
return ExceptionFormatter; return ExceptionFormatter;

View File

@@ -45,10 +45,14 @@ getJasmineRequireObj().buildExpectationResult = function() {
var error = options.error; var error = options.error;
if (!error) { if (!error) {
try { if (options.stack) {
throw new Error(message()); error = options;
} catch (e) { } else {
error = e; try {
throw new Error(message());
} catch (e) {
error = e;
}
} }
} }
return stackFormatter(error); return stackFormatter(error);

View File

@@ -152,8 +152,11 @@ getJasmineRequireObj().Spec = function(j$) {
return this.getSpecName(this); return this.getSpecName(this);
}; };
Spec.prototype.addDeprecationWarning = function(msg) { Spec.prototype.addDeprecationWarning = function(deprecation) {
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); if (typeof deprecation === 'string') {
deprecation = { message: deprecation };
}
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
}; };
var extractCustomPendingMessage = function(e) { var extractCustomPendingMessage = function(e) {

View File

@@ -148,8 +148,11 @@ getJasmineRequireObj().Suite = function(j$) {
} }
}; };
Suite.prototype.addDeprecationWarning = function(msg) { Suite.prototype.addDeprecationWarning = function(deprecation) {
this.result.deprecationWarnings.push(this.expectationResultFactory({ message: msg })); if (typeof deprecation === 'string') {
deprecation = { message: deprecation };
}
this.result.deprecationWarnings.push(this.expectationResultFactory(deprecation));
}; };
function isFailure(args) { function isFailure(args) {

View File

@@ -0,0 +1,25 @@
getJasmineRequireObj().Empty = function (j$) {
function Empty() {}
Empty.prototype.asymmetricMatch = function (other) {
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
return other.length === 0;
}
if (j$.isMap(other) || j$.isSet(other)) {
return other.size === 0;
}
if (j$.isObject_(other)) {
return Object.keys(other).length === 0;
}
return false;
};
Empty.prototype.jasmineToString = function () {
return '<jasmine.empty>';
};
return Empty;
};

View File

@@ -0,0 +1,14 @@
getJasmineRequireObj().Falsy = function(j$) {
function Falsy() {}
Falsy.prototype.asymmetricMatch = function(other) {
return !other;
};
Falsy.prototype.jasmineToString = function() {
return '<jasmine.falsy>';
};
return Falsy;
};

View File

@@ -0,0 +1,26 @@
getJasmineRequireObj().NotEmpty = function (j$) {
function NotEmpty() {}
NotEmpty.prototype.asymmetricMatch = function (other) {
if (j$.isString_(other) || j$.isArray_(other) || j$.isTypedArray_(other)) {
return other.length !== 0;
}
if (j$.isMap(other) || j$.isSet(other)) {
return other.size !== 0;
}
if (j$.isObject_(other)) {
return Object.keys(other).length !== 0;
}
return false;
};
NotEmpty.prototype.jasmineToString = function () {
return '<jasmine.notEmpty>';
};
return NotEmpty;
};

View File

@@ -0,0 +1,14 @@
getJasmineRequireObj().Truthy = function(j$) {
function Truthy() {}
Truthy.prototype.asymmetricMatch = function(other) {
return !!other;
};
Truthy.prototype.jasmineToString = function() {
return '<jasmine.truthy>';
};
return Truthy;
};

View File

@@ -121,8 +121,8 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return func.name; return func.name;
} }
var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/) || var matches = func.toString().match(/^\s*function\s*(\w+)\s*\(/) ||
func.toString().match(/^\s*\[object\s*(\w*)Constructor\]/); func.toString().match(/^\s*\[object\s*(\w+)Constructor\]/);
return matches ? matches[1] : '<anonymous>'; return matches ? matches[1] : '<anonymous>';
}; };
@@ -148,6 +148,38 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
return new j$.Anything(); return new j$.Anything();
}; };
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is `true` or anything truthy.
* @name jasmine.truthy
* @function
*/
j$.truthy = function() {return new j$.Truthy();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is `null`, `undefined`, `0`, `false` or anything falsey.
* @name jasmine.falsy
* @function
*/
j$.falsy = function() {return new j$.Falsy();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is empty.
* @name jasmine.empty
* @function
*/
j$.empty = function() {return new j$.Empty();};
/**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared is not empty.
* @name jasmine.notEmpty
* @function
*/
j$.notEmpty = function() {return new j$.NotEmpty();};
/** /**
* Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}), * Get a matcher, usable in any {@link matchers|matcher} that uses Jasmine's equality (e.g. {@link matchers#toEqual|toEqual}, {@link matchers#toContain|toContain}, or {@link matchers#toHaveBeenCalledWith|toHaveBeenCalledWith}),
* that will succeed if the actual value being compared contains at least the keys and values. * that will succeed if the actual value being compared contains at least the keys and values.

View File

@@ -21,6 +21,7 @@ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
'toHaveBeenCalledBefore', 'toHaveBeenCalledBefore',
'toHaveBeenCalledTimes', 'toHaveBeenCalledTimes',
'toHaveBeenCalledWith', 'toHaveBeenCalledWith',
'toHaveClass',
'toMatch', 'toMatch',
'toThrow', 'toThrow',
'toThrowError', 'toThrowError',

View File

@@ -1,4 +1,4 @@
jasmineRequire.toHaveClass = function(j$) { getJasmineRequireObj().toHaveClass = function(j$) {
/** /**
* {@link expect} the actual value to be a DOM element that has the expected class * {@link expect} the actual value to be a DOM element that has the expected class
* @function * @function

View File

@@ -63,6 +63,11 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
j$.ObjectPath = jRequire.ObjectPath(j$); j$.ObjectPath = jRequire.ObjectPath(j$);
j$.GlobalErrors = jRequire.GlobalErrors(j$); j$.GlobalErrors = jRequire.GlobalErrors(j$);
j$.Truthy = jRequire.Truthy(j$);
j$.Falsy = jRequire.Falsy(j$);
j$.Empty = jRequire.Empty(j$);
j$.NotEmpty = jRequire.NotEmpty(j$);
j$.matchers = jRequire.requireMatchers(jRequire, j$); j$.matchers = jRequire.requireMatchers(jRequire, j$);
return j$; return j$;

View File

@@ -3,5 +3,4 @@ jasmineRequire.html = function(j$) {
j$.HtmlReporter = jasmineRequire.HtmlReporter(j$); j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
j$.QueryString = jasmineRequire.QueryString(); j$.QueryString = jasmineRequire.QueryString();
j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter(); j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
j$.matchers.toHaveClass = jasmineRequire.toHaveClass(j$);
}; };

View File

@@ -1,12 +0,0 @@
#!/bin/bash -e
set -e
git clone https://github.com/jasmine/jasmine.github.io.git
cd jasmine.github.io
export BUNDLE_GEMFILE=$PWD/Gemfile
bundle
bundle exec rake update_edge_jasmine
bundle exec rake phantom