Compare commits

..

117 Commits

Author SHA1 Message Date
slackersoft
89232db2ee Version bump to 2.0.2 2014-08-22 22:20:38 -07:00
slackersoft
8b0d9c83bb keep the files for running in a webpage around in the npm package
[Fixes #656]
2014-08-21 12:56:04 -07:00
slackersoft
60533ca868 Expose files and paths necessary to embed jasmine in an html page for nodejs 2014-08-21 08:17:02 -07:00
slackersoft
048ab728ec Pull out the building of the jasmine interface so node and web both get the same one. 2014-08-15 08:14:59 -07:00
slackersoft
488df899fb Merge branch 'javenwang-suite-start' 2014-08-06 13:24:25 -07:00
slackersoft
753f4b44b4 Merge branch 'suite-start' of https://github.com/javenwang/jasmine into javenwang-suite-start 2014-08-06 13:24:01 -07:00
slackersoft
2c23d35b03 Merge branch 'javenwang-disabled-suite' 2014-08-06 13:14:00 -07:00
Javen Wang
2b0be0c74b a disabled suite should call resultCallback with status being disabled
close #574
2014-08-06 13:09:44 -07:00
slackersoft
b4f49db6bd Show a dot with color of pending spec when no expectations
[fix #76307802]
2014-08-04 12:48:35 -07:00
slackersoft
cee3cc56e6 fix casing for jshint 2014-07-31 13:42:09 -07:00
slackersoft
f2346d357f Allow mocked Date constructor to be called with a subset of full params
Fix #643 #624
2014-07-31 13:42:05 -07:00
Sheel Choksi
ee09301d8d Console reporter prints out failed expectation's message
Previously, was only printing out the stack while the html reporter
would print out the message as well as the stack. Now they should be
more consistent.

As noticed by @despairblue in #638
2014-07-27 18:31:47 -07:00
Davis W. Frank
760b50d969 Adding NPM instructions 2014-07-21 13:56:15 -07:00
Davis W. Frank
773b15e450 Fixed typo in 2.0.1.md 2014-07-21 13:24:10 -07:00
Davis W. Frank
227698f5fa Updating source and standalone distribution to 2.0.1 2014-07-21 12:36:24 -07:00
Davis W. Frank
ff1fa6a893 Updating version to 2.0.1 2014-07-21 12:35:34 -07:00
Davis W. Frank
ba1f8bc036 Merge branch 'master' of https://github.com/pivotal/jasmine 2014-07-21 12:33:42 -07:00
Davis W. Frank
a5be51f912 First cut at 2.0.1 release notes 2014-07-21 12:33:39 -07:00
Rajan Agaskar
d64ed6ebe9 Merge pull request #632 from kissrobber/bug_fix
Fixes incorrect use of signature args

- Not currently an issue, since always called with '2', but could break unexpectedly if argSlice is used without reading the body.
2014-07-21 06:46:05 -07:00
kissrobber
062dc6b15a fix a potential bug 2014-07-21 00:35:33 +09:00
slackersoft
33641578e6 update release doc to use github releases 2014-07-18 14:27:18 -07:00
slackersoft
a1c109ea17 Contains is explicitly false if actual is undefined or null
Fix #627
2014-07-18 13:18:22 -07:00
slackersoft
62212bbfa4 use released jasmine selenium runner 2014-07-18 13:07:11 -07:00
Rajan Agaskar
6a89d084f4 Merge pull request #621 from bengrunfeld/docs-installation
Add installation instructions to README
2014-07-07 12:56:32 -07:00
bengrunfeld
013c4f725f Add Ruby Gem and Python Egg to docs 2014-07-07 10:11:13 -06:00
bengrunfeld
c064488192 Add installation instructions to README 2014-07-07 09:37:44 -06:00
Sheel Choksi
f20df57607 Keeping jasmine_selenium_runner in Gemfile only for now 2014-06-28 18:09:41 -07:00
Sheel Choksi
48f7a5f17b Point to head of jasmine_selenium_runner
jasmine_selenium_runner on master now has a fix for printing circular
objects which is needed since Jasmine has some circular objects that are
included now that we return passedExpectations (but was a bug with
    failedExpectations anyways)
2014-06-28 17:59:29 -07:00
Sheel Choksi
f7ff47706c Remove 'empty' as an option as a spec result
- Having the 'empty' state for a spec result can be considered a
breaking change to the reporter interface
- Instead, we determine if a spec has no expectations using the added
key of 'passedExpectations' in combination of the 'failedExpectations'
to determine that there a spec is 'empty'

[fixes #73741032]
2014-06-27 23:50:28 -07:00
Alex Treppass
5f34be446c keeping track of passed expectations 2014-06-27 22:34:05 -07:00
Sheel Choksi
e1e49e8292 Bumping built distribution 2014-06-27 22:19:44 -07:00
Lee Penkman
eb1bd25445 namespace html-reporter -> jasmine_html-reporter 2014-06-22 21:47:46 -07:00
Lee Penkman
aac6968ed8 Stop Jasmine's CSS affecting the style of the body tag
[fixes #600]
2014-06-22 21:47:07 -07:00
Sheel Choksi
7d93541c09 Throw a more specific error when 'expect' is used without a currentSpec
If an async test has timed-out, there could still be some expectations
that are scheduled to run after the fact in which case curerntSpec will
be null. Rather than the type error that would result, we now indicate
that 'expect' was used at an unexpected time.

This also helps cases where an 'expect' is being used at a top-level,
showing an error message in the console for this case as well.

[fixes #602]
2014-06-06 23:49:58 -07:00
Drew Freyling
29aad761d9 Smushed with PNG Gauntlet. 2014-06-06 23:09:08 -07:00
Sheel Choksi
7d3de92cef Merge pull request #594 from plukevdh/reporter-reset
HTML Reporter reset previous DOM when re-initialized
2014-06-06 22:59:52 -07:00
Sheel Choksi
13e0dd27c9 Narrow down raise exceptions query selector
Finding by any input tag is a little bit broad [#605]
2014-06-06 22:20:18 -07:00
Sheel Choksi
fc6603e99f Merge pull request #580 from pablofiu/detailedGeneralWorkflow
added detailed steps on how to contribute coding
2014-06-02 23:04:35 -07:00
Luke van der Hoeven
07cce0b1d1 clear prior test results on multiple inits 2014-05-23 15:59:56 -04:00
Luke van der Hoeven
6750559211 failing spec for multiple inits 2014-05-23 15:58:09 -04:00
Pablo Alejandro Fiumara
0419780682 added detailed steps on how to contribute coding 2014-04-25 01:18:38 -03:00
Javen Wang
7ad261837a disabled suite should still call onStart callback 2014-04-12 00:35:47 +08:00
Sheel Choksi
00c8e37257 Pass through custom equality testers in toHaveBeenCalledWith [fixes #536] 2014-03-26 22:19:03 -07:00
Christopher Amavisca and Davis W Frank
e53b487017 - Add a main entry point for the jasmine-core npm
- jasmine-core can now self test with the jasmine-npm
- Add node examples files
- Add node_boot.js for node environment
- Move jasmine-core npm packaging to .npmignore
- removing src_dir and src_files from jasmine.json b/c jasmine-npm does not support requiring source files automatically.
2014-03-21 17:21:52 -07:00
Sheel Choksi
ed5cd6ba2c Merge pull request #550 from slothmonster/fix-copyright-year
Fix outdated copyright year (update to 2014)

[skip ci]
2014-03-16 18:36:21 -07:00
Greg Cobb and Luan Santos
213a6023fd Add package.json to egg to get correct version number
[#67556148][#551]
2014-03-14 10:51:26 -07:00
Adam Deibert
7d220fcd1b Fix outdated copyright year (update to 2014) 2014-03-14 01:42:39 -07:00
Greg Cobb and Luan Santos
c1382c77b4 Enable bundler cache 2014-03-12 13:46:25 -07:00
Greg Cobb and Luan Santos
311263a3df Fix build in IE8 (IE8 doesn't support Object.freeze) 2014-03-12 13:45:46 -07:00
mikemoraned
33e4f5efbe Allow users to set the maximum length of array that the pretty-printer
will print out.

Currently, jasmine's pretty printer will iterate over an entire array,
formatting every element recursively. For very large arrays, this can
crash the page, or cause a 'slow script' warning.

This commit exposes a 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option. If an
array larger than this is encountered, recursion will stop and the
array length will be printed instead e.g. "Array[20000000]".

The 'MAX_PRETTY_PRINT_ARRAY_LENGTH' option defaults to 100. This is
length of array will not kill your browser, but will allow you
to see big arrays, if you can stomach the output.
2014-03-12 12:16:01 -07:00
Greg Cobb and Luan Santos
367d3dcf66 Rebuild distribution 2014-03-12 11:51:49 -07:00
Greg Cobb and Luan Santos
21de44a204 Remove space between key and colon when pretty printing objects
[#4005255]
2014-03-12 11:47:47 -07:00
Greg Cobb and Luan Santos
c9e37a2a1c Refactor prettyPrinter to work with immutable objects
[#50766813][#266]
2014-03-12 11:41:18 -07:00
Davis W. Frank
9e927af56e Merge pull request #548 from pivotal/python
Create jasmine-core python egg
2014-03-11 14:05:45 -07:00
Greg Cobb
fc173e9a5e Add logo image to readme 2014-03-11 13:54:47 -07:00
Greg Cobb
62a7f64659 Update readme with correct code climate link 2014-03-11 13:49:51 -07:00
Greg Cobb and Luan Santos
3e739e4bc9 Create jasmine-core python egg 2014-03-11 13:40:28 -07:00
Greg Cobb and Luan Santos
ba6f99423f Add jasmine logo image to html runner
[#3984585]
2014-03-10 17:16:31 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
3a5672cd33 Show message if no specs are found in console reporter
[#12784235]
2014-03-10 12:00:49 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
af4cc76e2a Show message if no specs are found
[#12784235]
2014-03-10 11:23:27 -07:00
Christopher Amavisca, Greg Cobb and Luan Santos
1922514f2d Specs without expectations should be alerted to the user
- Add console.error to the HtmlReporter when there is a spec without any expectation
- Change the spec's link text and color to include a warning
- Create a status for specs to label them as "empty"
- console is not accessible to IE unless you have developer tools open,
  so protect against that by mocking console.

[#59424794]
2014-03-10 11:19:07 -07:00
slackersoft
71dbffeaef Merge branch 'recursive-containing' of https://github.com/cbandy/jasmine into cbandy-recursive-containing 2014-03-05 21:01:34 -08:00
Rajan Agaskar
9c6d03d3ac README.md: Add link to Jasmine 2.0 release notes
- To help people upgrading find a list of what they'll need to change.
2014-03-05 11:31:39 -08:00
Chris Bandy
47884032ad Fix ObjectContaining to match recursively
matchersUtil.equals() does not expect a matcher as its first argument,
so send the "actual" value first and the "expected" value second.
2014-03-02 11:42:37 -06:00
slackersoft
d7053612f5 Build distribution to include MockDate
- Forgot to do this when merging the pull request
- Also fix quotes for string to match jshint rules
2014-03-01 13:18:15 -08:00
Christopher Amavisca and Sheel Choksi
9d1e92f5e2 Clean up more remnants of dev_boot 2014-02-27 18:02:14 -08:00
Elana Koren and Gregg Van Hove
eebba2ecca Support browsers that don't supply a Date.now()
- install the mockDate by calling `mockDate` on `clock` instead of
  passing an argument to `clock.install()`

[Finishes #66606132] Closes #361
2014-02-27 11:55:25 -08:00
Elana Koren and Gregg Van Hove
627a262085 Merge branch 'mock-date' of https://github.com/jalopez/jasmine into jalopez-mock-date 2014-02-27 10:03:35 -08:00
Christopher Amavisca and Sheel Choksi
305bd73142 Instead of dev boot use a custom helper to defined j$ 2014-02-26 17:35:10 -08:00
Elana Koren and Gregg Van Hove
fb853ad5b5 Don't include jasmine_selenium_runner from github, now that it's
published to rubygems

[finish #66472672]
2014-02-26 15:30:17 -08:00
Greg Cobb and Sheel Choksi
640f94a1bd Don't allow calling the same done callback multiple times
[finishes #62585700][fixes #523]
2014-02-25 18:06:30 -08:00
Greg Cobb and Sheel Choksi
5aac3e3292 Refactor Spec and QueueRunner [#62585700]
- QueueRunner now responsible for timing out async specs instead of
   Spec
 - Make sure only spec functions are timeoutable and not suites (due to
   the refactor)
2014-02-25 18:06:30 -08:00
Charles Hansen and Gregg Van Hove
84160ff51d revert to old version of checking the docs 2014-02-25 11:28:02 -08:00
Charles Hansen and Gregg Van Hove
e972bac80d No longer try to push to github, we'll update jasmine in docs manually 2014-02-25 10:58:59 -08:00
Charles Hansen and Gregg Van Hove
455b6bade8 bundle install in docs repo 2014-02-25 10:56:41 -08:00
Charles Hansen and Gregg Van Hove
23c0e379e0 update edge docs when changes are made to jasmine 2014-02-25 10:42:59 -08:00
Robin Böhm
31d71ac22f add single quote check to jshint and fix src files for that
[fixes #522]
2014-02-24 16:28:16 -08:00
Greg Cobb and Sheel Choksi
095b02ad83 Follow redirects when trying to connect to sauce 2014-02-24 16:13:25 -08:00
Greg Cobb and Sheel Choksi
98c258a659 Bump built distribution [#503][finishes #66350898] 2014-02-24 15:47:34 -08:00
Michal Mocny
85fa148f18 Support running jasmine within CSP (remove eval)
[fixes #503]
2014-02-24 15:44:11 -08:00
Sheel Choksi
76ca5ef6d4 Allow matcher custom failure messages to be a function
By deferring the evaluation of these messages, we can avoid the
expensive creation of them when in the majority use case (tests are
    passing) they are not needed.

These failure messages were causing performance problems with larger
objects needed to be pretty printed as discussed in #520 and brought up
by @rdy.

[fixes #65925900][fixes #520]
2014-02-18 20:05:30 -08:00
Sheel Choksi
46d2c43da1 Revert "Use default failure message for toBeNaN"
Forgot that NaN has special casing that it needs a custom error message
for

This reverts commit b6c03a34e7.
2014-02-18 19:14:16 -08:00
Sheel Choksi
b6c03a34e7 Use default failure message for toBeNaN
It is providing the same functionality by default without a custom error message
2014-02-17 22:45:54 -08:00
Sheel Choksi
4ddf316388 Add in default rake task 2014-02-16 14:57:14 -08:00
Sheel Choksi
a8cbef3123 More color blind friendly CSS from @dleppik
Updating the passing and failing colors in HTML reporter to
help red/green color blind users using the colors suggested by @dleppik

Console reporter still likely needs similar changes but there's less
options there

[#463, #509, finishes #60613086]
2014-02-16 14:56:18 -08:00
Sheel Choksi
a937d8d74f Merge pull request #521 from robinboehm/load-grunt-tasks
use load-grunt-tasks
2014-02-16 14:53:07 -08:00
Robin Böhm
2fc2802809 use load-grunt-tasks 2014-02-16 22:13:53 +01:00
Sheel Choksi
7cf899a4ea Special case printing -0
Use the 1/x trick to determine if a value is -0 and special case the
printing of it.

[closes #496]
2014-02-09 14:14:33 -08:00
Sheel Choksi
83c0ea7f91 Fix error message in jasmine.any
The expected any 'class' was not being included in the error message
due to accessing the wrong property
2014-02-09 14:06:47 -08:00
Sheel Choksi
289c8313d1 Short spec to document why we close over Date and ensure cross-browser compatibility
[closes #506]
2014-02-09 12:20:03 -08:00
tcorral
b5775aec4f Allow stub or spy Date object safely using a closure to get a clean copy
[closes #506]
2014-02-09 12:20:03 -08:00
Davis W. Frank
21b01f4a5d Whitespace Markdown fix 2014-01-24 09:32:20 -08:00
Davis W. Frank
71faeea7b0 First attempt at publishing an npm 2014-01-24 09:31:38 -08:00
Sheel Choksi
de7d005b3d Break out quick start guide on newline
[skip ci]
2014-01-19 14:21:21 -08:00
Sheel Choksi
7acf5d4220 Add in link to quick start of Jasmine, closes #498
[skip ci]
2014-01-19 14:16:00 -08:00
slackersoft
2a8b5a30b6 Use \d7 instead of plain 'x' for more square appearance
[finishes #48434179]
2014-01-18 17:33:57 -10:00
Sheel Choksi
9c7ba43ebd Clean up a bunch of spec global variable leaks
Also some formatting changes to highlight when using one 'var' with comma operator
2014-01-18 14:17:14 -08:00
Sheel Choksi
8ca08ff999 Run Object.create(null) spec on all browsers not IE 8
IE 8 doesn't support Object.create so there shouldn't be a need to run this spec in IE 8
2014-01-18 13:12:07 -08:00
slackersoft
15aa3ecb5d Better support in pretty printer when an object has null prototype
- Fixes #500
2014-01-17 19:56:43 -10:00
Davis W. Frank
2670bb40a7 Get rid of freeze property for now - it's not adding value. 2014-01-10 10:23:14 -08:00
Sheel Choksi
c8ffa6000b Reproducing change made in #479 that was made to build distribution instead of src
It was lost when I rebuilt the distribution
2014-01-09 22:14:04 -08:00
Sheel Choksi
06a553503d Better failure message when something is thrown that's not an error
Change from 'undefined : undefined' to '<thing that was thrown> thrown'

Pointed out by @charleshansen
2014-01-09 22:10:40 -08:00
Sheel Choksi
aab4808410 Bump built distribution 2014-01-09 22:07:59 -08:00
Sheel Choksi
b525313cdb Make the check for pending spec exception work for values that don't have toString 2014-01-04 23:11:20 -08:00
Sheel Choksi
f576395620 Bump built distribution copyright's for 2014 2014-01-04 23:11:20 -08:00
Sheel Choksi
b161e9e3df Merge pull request #486 from nextmat/link_fix
Update link at top of README
2014-01-01 20:00:18 -08:00
Matt Sanders
94ecb998bb Update link at top of README
Allows access to Jasmine 2.0 docs
2013-12-27 00:29:35 -07:00
Davis W. Frank
38daa43c7e Merge pull request #479 from shprink/fix_jasmine_html
force query selector to seek within the html-reporter element
2013-12-19 09:42:15 -08:00
Davis W. Frank
9fb9c12066 Merge pull request #478 from shprink/adding_netbeans_to_gitignore
adding netbeans project folder to the gitignore list
2013-12-19 09:37:19 -08:00
shprink
de2fb225b0 adding netbeans project folder to the gitignore list 2013-12-19 10:20:49 +01:00
shprink
4f4ae086aa force query selector to seek within the html-reporter element 2013-12-19 10:19:02 +01:00
Sheel Choksi
8510bdd947 Update mailing list link
It seems that Github was interpreting it as a repository link. Made it an explicit mailto instead.
2013-12-17 18:37:10 -08:00
Sheel Choksi
66bd8c7825 Adding older standalone zips from downloads page to our dist folder 2013-12-17 12:19:53 -08:00
Christopher Jobst and Sheel Choksi
a736e664ea Remove the old RC standalone distributions. 2013-12-16 15:49:27 -08:00
Javier López Pardo
3186b24a66 add acceptance tests for mock clock with date 2013-10-25 14:59:07 +02:00
Javier López Pardo
81b822fea9 Add specs for mock date 2013-10-25 14:41:32 +02:00
Javier López Pardo
fb8bede8ea Add FakeDate object 2013-10-25 13:25:09 +02:00
121 changed files with 2864 additions and 1489 deletions

5
.gitignore vendored
View File

@@ -15,5 +15,10 @@ pkg/*
.sass-cache/*
src/html/.sass-cache/*
node_modules/
*.pyc
sauce_connect.log
*.swp
build/
*.egg-info/
dist/*.tar.gz
nbproject/

View File

@@ -1,9 +1,9 @@
{
"bitwise": true,
"curly": true,
"freeze": true,
"immed": true,
"newcap": true,
"trailing": true,
"loopfunc": true
"loopfunc": true,
"quotmark": "single"
}

20
.npmignore Normal file
View File

@@ -0,0 +1,20 @@
dist/
grunt/
images/
node_modules
release_notes/
spec/
src/
Gemfile
Gemfile.lock
Rakefile
jasmine-core.gemspec
.rspec
.travis.yml
.jshintrc
.gitignore
*.sh
Gruntfile.js
lib/jasmine-core/boot/
lib/jasmine-core/spec
lib/jasmine-core/version.rb

View File

@@ -1,6 +1,7 @@
---
script: $TEST_COMMAND
language: ruby
cache: bundler
rvm: 1.9.3
env:
global:

View File

@@ -7,6 +7,11 @@ We welcome your contributions - Thanks for helping make Jasmine a better project
Please submit pull requests via feature branches using the semi-standard workflow of:
1. Fork it
1. Clone your fork: (`git clone git@github.com:yourUserName/jasmine.git`)
1. Change directory: (`cd jasmine`)
1. Asign original repository to a remote named 'upstream': (`git remote add
upstream https://github.com/pivotal/jasmine.git`)
1. Pull in changes not present in your local repository: (`git fetch upstream`)
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
@@ -104,7 +109,7 @@ Jasmine uses Node.js with a custom runner to test outside of a browser.
## Before Committing or Submitting a Pull Request
1. Ensure all specs are green in browser *and* node
1. Ensure JSHint is green with `grunt jsHint`
1. Ensure JSHint is green with `grunt jshint`
1. Build `jasmine.js` with `grunt buildDistribution` and run all specs again - this ensures that your changes self-test well
## Submitting a Pull Request

View File

@@ -9,6 +9,4 @@ end
gemspec
gem "jasmine_selenium_runner", :git => 'https://github.com/jasmine/jasmine_selenium_runner.git'
gem "anchorman"

View File

@@ -10,10 +10,7 @@ module.exports = function(grunt) {
compress: require('./grunt/config/compress.js')
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-compress');
require('load-grunt-tasks')(grunt);
grunt.loadTasks('grunt/tasks');
@@ -37,12 +34,20 @@ module.exports = function(grunt) {
]
);
var spec = require('./grunt/tasks/spec.js');
grunt.registerTask("execSpecsInNode",
"Run Jasmine core specs in Node.js",
spec.execSpecsInNode
"Run Jasmine core specs in Node.js",
function() {
var exitInfo = require("shelljs").exec("node_modules/.bin/jasmine");
if (exitInfo.code !== 0) {
grunt.fail.fatal("Specs Failed", exitInfo.code);
}
}
);
grunt.registerTask("execSpecsInNode:performance",
"Run Jasmine performance specs in Node.js",
function() {
require("shelljs").exec("node_modules/.bin/jasmine JASMINE_CONFIG_PATH=spec/support/jasmine-performance.json");
}
);
};

5
MANIFEST.in Normal file
View File

@@ -0,0 +1,5 @@
recursive-include . *.py
include lib/jasmine-core/*.js
include lib/jasmine-core/*.css
include images/*.png
include package.json

View File

@@ -1,4 +1,4 @@
Copyright (c) 2008-2011 Pivotal Labs
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,20 +1,53 @@
<a name="README">[Jasmine](http://pivotal.github.com/jasmine/)</a> [![Build Status](https://travis-ci.org/pivotal/jasmine.png?branch=master)](https://travis-ci.org/pivotal/jasmine) [![Code Climate](https://codeclimate.com/repos/5269970a13d6374b6c01d632/badges/8bc25526da64e02065f4/gpa.png)](https://codeclimate.com/repos/5269970a13d6374b6c01d632/feed)
<a name="README">[<img src="https://rawgithub.com/pivotal/jasmine/master/images/jasmine-horizontal.svg" width="400px" />](http://jasmine.github.io)</a>
[![Build Status](https://travis-ci.org/pivotal/jasmine.png?branch=master)](https://travis-ci.org/pivotal/jasmine) [![Code Climate](https://codeclimate.com/github/pivotal/jasmine.png)](https://codeclimate.com/github/pivotal/jasmine)
=======
**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.
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.0, see the beginning of [http://jasmine.github.io/2.0/introduction.html](http://jasmine.github.io/2.0/introduction.html)
Upgrading from Jasmine 1.x? Check out the [2.0 release notes](https://github.com/pivotal/jasmine/blob/v2.0.0/release_notes/20.md) for a list of what's new (including breaking interface changes).
## Contributing
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md)
## Installation
To install Jasmine on your local box:
* Clone Jasmine - `git clone https://github.com/pivotal/jasmine.git`
* Create a Jasmine directory in your project - `mkdir my-project/jasmine`
* Move latest dist to your project directory - `mv jasmine/dist/jasmine-standalone-2.0.0.zip my-project/jasmine`
* Change directory - `cd my-project/jasmine`
* Unzip the dist - `unzip jasmine-standalone-2.0.0.zip`
Add the following to your HTML file:
<link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="jasmine/lib/jasmine-2.0.0/jasmine.css">
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="jasmine/lib/jasmine-2.0.0/boot.js"></script>
For the Jasmine Ruby Gem:<br>
[https://github.com/pivotal/jasmine-gem](https://github.com/pivotal/jasmine-gem)
For the Jasmine Python Egg:<br>
[https://github.com/pivotal/jasmine-py](https://github.com/pivotal/jasmine-py)
## Support
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
* Send an email to the list: [jasmine-js@googlegroups.com](mailto:jasmine-js@googlegroups.com)
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
@@ -28,4 +61,4 @@ Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/ma
* [Christian Williams](mailto:antixian666@gmail.com), Square
Copyright (c) 2008-2013 Pivotal Labs. This software is licensed under the MIT License.
Copyright (c) 2008-2014 Pivotal Labs. This software is licensed under the MIT License.

View File

@@ -20,14 +20,6 @@ The current version lives in the file `/package.json`. This file should be set t
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
Note that Jasmine should *not* use the "patch" version number. Let downstream projects rev their patch versions as needed, keeping their major and minor version numbers in sync with Jasmine core.
### Update the Github Pages (as needed)
___Note: This is going to change right after 2.0___
Github pages have to exist in a branch called `gh-pages` in order for their app to serve them. This repo adds that branch as a submodule under the `pages` directory. This is a bit of a hack, but it allows us to work with the pages and the source at the same time and with one set of rake tasks.
If you want to submit changes to this repo and aren't a Pivotal Labs employee, you can fork and work in the `gh-pages` branch. You won't be able to edit the pages in the submodule off of master.
## Release
@@ -36,14 +28,36 @@ When ready to release - specs are all green and the stories are done:
1. Update the release notes in `release_notes` - use the Anchorman gem to generate the markdown file and edit accordingly
1. Update the version in `package.json` to a release candidate
1. Update any links or top-level landing page for the Github Pages
### Build standalone distribution
1. Build the standalone distribution with `grunt buildStandaloneDist`
1. Make sure you add the new ZIP file to git
1. Should we still do this? Given we want to use guthub releases...
### Release the Python egg
1. `python setup.py register sdist upload` You will need pypi credentials to upload the egg.
### Release the Ruby gem
1. Copy version to the Ruby gem with `grunt build:copyVersionToGem`
1. __NOTE__: You will likely need to point to a local jasmine gem in order to run tests locally. _Do not_ push this version of the Gemfile.
1. __NOTE__: You will likely need to push a new jasmine gem with a dependent version right after this release.
1. Push these changes to GitHub and verify that this SHA is green
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org. In order to release you will have to ensure you have rubygems creds locally.
1. Visit the [Releases page for Jasmine](https://github.com/pivotal/jasmine/releases), find the tag just pushed. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes. If it is a pre-release, mark it as such.
### Release the NPM
1. `npm adduser` to save your credentials locally
1. `npm publish .` to publish what's in `package.json`
### Finally
1. Visit the [Releases page for Jasmine](https://github.com/pivotal/jasmine/releases), find the tag just pushed.
1. Paste in a link to the correct release notes for this release. The link should reference the blob and tag correctly, and the markdown file for the notes.
1. If it is a pre-release, mark it as such.
1. Attach the standalone zipfile
There should be a post to Pivotal Labs blog and a tweet to that link.

View File

@@ -15,3 +15,4 @@ end
task "jasmine:configure" => "jasmine:set_env"
task :default => "jasmine:ci"

BIN
dist/jasmine-standalone-1.0.0.zip vendored Normal file

Binary file not shown.

BIN
dist/jasmine-standalone-1.1.0.zip vendored Normal file

Binary file not shown.

BIN
dist/jasmine-standalone-1.2.0.zip vendored Normal file

Binary file not shown.

BIN
dist/jasmine-standalone-1.3.0.zip vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dist/jasmine-standalone-2.0.1.zip vendored Normal file

Binary file not shown.

BIN
dist/jasmine-standalone-2.0.2.zip vendored Normal file

Binary file not shown.

View File

@@ -39,6 +39,10 @@ module.exports = {
src: ['lib/jasmine-core/boot/boot.js'],
dest: 'lib/jasmine-core/boot.js'
},
nodeBoot: {
src: ['lib/jasmine-core/boot/node_boot.js'],
dest: 'lib/jasmine-core/node_boot.js'
},
console: {
src: [
'src/console/requireConsole.js',

View File

@@ -1,11 +0,0 @@
var shell = require('shelljs');
var grunt = require('grunt');
module.exports = {
execSpecsInNode: function() {
var exit_code = shell.exec("node spec/node_suite.js --color=true").code;
if (exit_code !== 0) {
grunt.fail.fatal("Specs Failed", exit_code);
}
}
};

0
images/__init__.py Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="681.96252"
height="187.5"
id="svg2"
xml:space="preserve"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
id="clipPath18"><path
d="M 0,1500 0,0 l 5455.74,0 0,1500 L 0,1500 z"
inkscape:connector-curvature="0"
id="path20" /></clipPath></defs><g
transform="matrix(1.25,0,0,-1.25,0,187.5)"
id="g10"><g
transform="scale(0.1,0.1)"
id="g12"><g
id="g14"><g
clip-path="url(#clipPath18)"
id="g16"><path
d="m 1544,599.434 c 0.92,-40.352 25.68,-81.602 71.53,-81.602 27.51,0 47.68,12.832 61.44,35.754 12.83,22.93 12.83,56.852 12.83,82.527 l 0,329.184 -71.52,0 0,104.543 266.83,0 0,-104.543 -70.6,0 0,-344.77 c 0,-58.691 -3.68,-104.531 -44.93,-152.218 -36.68,-42.18 -96.28,-66.02 -153.14,-66.02 -117.37,0 -207.24,77.941 -202.64,197.145 l 130.2,0"
inkscape:connector-curvature="0"
id="path22"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2301.4,662.695 c 0,80.703 -66.94,145.813 -147.63,145.813 -83.44,0 -147.63,-68.781 -147.63,-151.301 0,-79.785 66.94,-145.801 145.8,-145.801 84.35,0 149.46,67.852 149.46,151.289 z m -1.83,-181.547 c -35.77,-54.097 -93.53,-78.859 -157.72,-78.859 -140.3,0 -251.24,116.449 -251.24,254.918 0,142.129 113.7,260.41 256.74,260.41 63.27,0 118.29,-29.336 152.22,-82.523 l 0,69.687 175.14,0 0,-104.527 -61.44,0 0,-280.598 61.44,0 0,-104.527 -175.14,0 0,66.019"
inkscape:connector-curvature="0"
id="path24"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2622.33,557.258 c 3.67,-44.016 33.01,-73.348 78.86,-73.348 33.93,0 66.93,23.824 66.93,60.504 0,48.606 -45.84,56.856 -83.44,66.941 -85.28,22.004 -178.81,48.606 -178.81,155.879 0,93.536 78.86,147.633 165.98,147.633 44,0 83.43,-9.176 110.94,-44.008 l 0,33.922 82.53,0 0,-132.965 -108.21,0 c -1.83,34.856 -28.42,57.774 -63.26,57.774 -30.26,0 -62.35,-17.422 -62.35,-51.348 0,-45.847 44.93,-55.93 80.69,-64.18 88.02,-20.175 182.47,-47.695 182.47,-157.734 0,-99.027 -83.44,-154.039 -175.13,-154.039 -49.53,0 -94.46,15.582 -126.55,53.18 l 0,-40.34 -85.27,0 0,142.129 114.62,0"
inkscape:connector-curvature="0"
id="path26"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 2988.18,800.254 -63.26,0 0,104.527 165.05,0 0,-73.355 c 31.18,51.347 78.86,85.277 141.21,85.277 67.85,0 124.71,-41.258 152.21,-102.699 26.6,62.351 92.62,102.699 160.47,102.699 53.19,0 105.46,-22 141.21,-62.351 38.52,-44.938 38.52,-93.532 38.52,-149.457 l 0,-185.239 63.27,0 0,-104.527 -238.42,0 0,104.527 63.28,0 0,157.715 c 0,32.102 0,60.527 -14.67,88.957 -18.34,26.582 -48.61,40.344 -79.77,40.344 -30.26,0 -63.28,-12.844 -82.53,-36.672 -22.93,-29.355 -22.93,-56.863 -22.93,-92.629 l 0,-157.715 63.27,0 0,-104.527 -238.41,0 0,104.527 63.28,0 0,150.383 c 0,29.348 0,66.023 -14.67,91.699 -15.59,29.336 -47.69,44.934 -80.7,44.934 -31.18,0 -57.77,-11.008 -77.94,-35.774 -24.77,-30.253 -26.6,-62.343 -26.6,-99.941 l 0,-151.301 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,280.598"
inkscape:connector-curvature="0"
id="path28"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 3998.66,951.547 -111.87,0 0,118.293 111.87,0 0,-118.293 z m 0,-431.891 63.27,0 0,-104.527 -239.33,0 0,104.527 64.19,0 0,280.598 -63.27,0 0,104.527 175.14,0 0,-385.125"
inkscape:connector-curvature="0"
id="path30"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 4159.12,800.254 -63.27,0 0,104.527 175.14,0 0,-69.687 c 29.35,54.101 84.36,80.699 144.87,80.699 53.19,0 105.45,-22.016 141.22,-60.527 40.34,-44.934 41.26,-88.032 41.26,-143.957 l 0,-191.653 63.27,0 0,-104.527 -238.4,0 0,104.527 63.26,0 0,158.637 c 0,30.262 0,61.434 -19.26,88.035 -20.17,26.582 -53.18,39.414 -86.19,39.414 -33.93,0 -68.77,-13.75 -88.94,-41.25 -21.09,-27.5 -21.09,-69.687 -21.09,-102.707 l 0,-142.129 63.26,0 0,-104.527 -238.4,0 0,104.527 63.27,0 0,280.598"
inkscape:connector-curvature="0"
id="path32"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 5082.48,703.965 c -19.24,70.605 -81.6,115.547 -154.04,115.547 -66.04,0 -129.3,-51.348 -143.05,-115.547 l 297.09,0 z m 85.27,-144.883 c -38.51,-93.523 -129.27,-156.793 -231.05,-156.793 -143.07,0 -257.68,111.871 -257.68,255.836 0,144.883 109.12,261.328 254.91,261.328 67.87,0 135.72,-30.258 183.39,-78.863 48.62,-51.344 68.79,-113.695 68.79,-183.383 l -3.67,-39.434 -396.13,0 c 14.67,-67.863 77.03,-117.363 146.72,-117.363 48.59,0 90.76,18.328 118.28,58.672 l 116.44,0"
inkscape:connector-curvature="0"
id="path34"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 690.895,850.703 90.75,0 22.543,31.035 0,243.122 -135.829,0 0,-243.141 22.536,-31.016"
inkscape:connector-curvature="0"
id="path36"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 632.395,742.258 28.039,86.304 -22.551,31.04 -231.223,75.128 -41.976,-129.183 231.257,-75.137 36.454,11.848"
inkscape:connector-curvature="0"
id="path38"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 717.449,653.105 -73.41,53.36 -36.488,-11.875 -142.903,-196.692 109.883,-79.828 142.918,196.703 0,38.332"
inkscape:connector-curvature="0"
id="path40"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 828.52,706.465 -73.426,-53.34 0.011,-38.359 L 898.004,418.07 1007.9,497.898 864.973,694.609 828.52,706.465"
inkscape:connector-curvature="0"
id="path42"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 812.086,828.586 28.055,-86.32 36.484,-11.836 231.225,75.117 -41.97,129.183 -231.239,-75.14 -22.555,-31.004"
inkscape:connector-curvature="0"
id="path44"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 736.301,1335.88 c -323.047,0 -585.875,-262.78 -585.875,-585.782 0,-323.118 262.828,-585.977 585.875,-585.977 323.019,0 585.809,262.859 585.809,585.977 0,323.002 -262.79,585.782 -585.809,585.782 l 0,0 z m 0,-118.61 c 257.972,0 467.189,-209.13 467.189,-467.172 0,-258.129 -209.217,-467.348 -467.189,-467.348 -258.074,0 -467.254,209.219 -467.254,467.348 0,258.042 209.18,467.172 467.254,467.172"
inkscape:connector-curvature="0"
id="path46"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 1091.13,619.883 -175.771,57.121 11.629,35.808 175.762,-57.121 -11.62,-35.808"
inkscape:connector-curvature="0"
id="path48"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="M 866.957,902.074 836.5,924.199 945.121,1073.73 975.586,1051.61 866.957,902.074"
inkscape:connector-curvature="0"
id="path50"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="M 607.465,903.445 498.855,1052.97 529.32,1075.1 637.93,925.566 607.465,903.445"
inkscape:connector-curvature="0"
id="path52"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 380.688,622.129 -11.626,35.801 175.758,57.09 11.621,-35.801 -175.753,-57.09"
inkscape:connector-curvature="0"
id="path54"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /><path
d="m 716.289,376.59 37.6406,0 0,184.816 -37.6406,0 0,-184.816 z"
inkscape:connector-curvature="0"
id="path56"
style="fill:#8a4182;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -18,6 +18,6 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.add_development_dependency "rake"
s.add_development_dependency "sauce-connect"
s.add_development_dependency "jasmine_selenium_runner"
s.add_development_dependency "compass"
s.add_development_dependency "jasmine_selenium_runner", ">= 0.2.0"
end

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -21,7 +21,7 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
function getJasmineRequireObj() {
if (typeof module !== "undefined" && module.exports) {
if (typeof module !== 'undefined' && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};
@@ -60,7 +60,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
specCount = 0;
failureCount = 0;
pendingCount = 0;
print("Started");
print('Started');
printNewline();
timer.start();
};
@@ -71,19 +71,24 @@ getJasmineRequireObj().ConsoleReporter = function() {
specFailureDetails(failedSpecs[i]);
}
printNewline();
var specCounts = specCount + " " + plural("spec", specCount) + ", " +
failureCount + " " + plural("failure", failureCount);
if(specCount > 0) {
printNewline();
if (pendingCount) {
specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount);
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);
if (pendingCount) {
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
}
print(specCounts);
} else {
print('No specs found');
}
print(specCounts);
printNewline();
var seconds = timer.elapsed() / 1000;
print("Finished in " + seconds + " " + plural("second", seconds));
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
@@ -93,28 +98,28 @@ getJasmineRequireObj().ConsoleReporter = function() {
this.specDone = function(result) {
specCount++;
if (result.status == "pending") {
if (result.status == 'pending') {
pendingCount++;
print(colored("yellow", "*"));
print(colored('yellow', '*'));
return;
}
if (result.status == "passed") {
print(colored("green", '.'));
if (result.status == 'passed') {
print(colored('green', '.'));
return;
}
if (result.status == "failed") {
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
print(colored("red", 'F'));
print(colored('red', 'F'));
}
};
return this;
function printNewline() {
print("\n");
print('\n');
}
function colored(color, str) {
@@ -122,7 +127,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function plural(str, count) {
return count == 1 ? str : str + "s";
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
@@ -134,12 +139,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function indent(str, spaces) {
var lines = (str || '').split("\n");
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(" ", spaces).join("") + lines[i]);
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join("\n");
return newArr.join('\n');
}
function specFailureDetails(result) {
@@ -149,6 +154,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent(failedExpectation.message, 2));
print(indent(failedExpectation.stack, 2));
}

29
lib/jasmine-core.js Normal file
View File

@@ -0,0 +1,29 @@
module.exports = require("./jasmine-core/jasmine.js");
module.exports.boot = require('./jasmine-core/node_boot.js');
module.exports.files = (function() {
var path = require('path'),
fs = require('fs'),
glob = require('glob');
var rootPath = path.join(__dirname, "jasmine-core"),
bootFiles = ['boot.js'],
nodeBootFiles = ['node_boot.js'];
var cssFiles = glob.sync(path.join(rootPath, '*.css')).map(path.basename);
var jsFiles = glob.sync(path.join(rootPath, '*.js')).map(path.basename);
['jasmine.js'].concat(bootFiles, nodeBootFiles).forEach(function(file) {
jsFiles.splice(jsFiles.indexOf(file), 1);
});
return {
path: rootPath,
bootDir: rootPath,
bootFiles: bootFiles,
nodeBootFiles: nodeBootFiles,
cssFiles: cssFiles,
jsFiles: ['jasmine.js'].concat(jsFiles),
imagesDir: path.join(__dirname, '../images')
};
}());

View File

@@ -6,7 +6,7 @@ module Jasmine
end
def js_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq - boot_files - node_boot_files
end
SPEC_TYPES = ["core", "html", "node"]
@@ -27,8 +27,12 @@ module Jasmine
["boot.js"]
end
def node_boot_files
["node_boot.js"]
end
def boot_dir
File.join(path, 'boot')
path
end
def spec_files(type)

View File

@@ -0,0 +1 @@
from .core import Core

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -54,47 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
*/
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
pending: function() {
return env.pending();
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
var jasmineInterface = jasmineRequire.interface(jasmine, env);
/**
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
@@ -105,27 +65,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extend(window, jasmineInterface);
}
/**
* Expose the interface for adding custom equality testers.
*/
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
/**
* Expose the interface for adding custom expectation matchers
*/
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
/**
* Expose the mock interface for the JavaScript timeout functions
*/
jasmine.clock = function() {
return env.clock;
};
/**
* ## Runner Parameters
*

View File

@@ -32,47 +32,7 @@
*
* Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged.
*/
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
pending: function() {
return env.pending();
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
var jasmineInterface = jasmineRequire.interface(jasmine, env);
/**
* Add all of the Jasmine global/public interface to the proper global, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`.
@@ -83,27 +43,6 @@
extend(window, jasmineInterface);
}
/**
* Expose the interface for adding custom equality testers.
*/
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
/**
* Expose the interface for adding custom expectation matchers
*/
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
/**
* Expose the mock interface for the JavaScript timeout functions
*/
jasmine.clock = function() {
return env.clock;
};
/**
* ## Runner Parameters
*

View File

@@ -0,0 +1,19 @@
module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire);
var consoleFns = require('../console/console.js');
consoleFns.console(consoleFns, jasmine);
var env = jasmine.getEnv();
var jasmineInterface = jasmineRequire.interface(jasmine, env);
extend(global, jasmineInterface);
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
return jasmine;
};

60
lib/jasmine-core/core.py Normal file
View File

@@ -0,0 +1,60 @@
import pkg_resources
try:
from collections import OrderedDict
except ImportError:
from ordereddict import OrderedDict
class Core(object):
@classmethod
def js_package(cls):
return __package__
@classmethod
def css_package(cls):
return __package__
@classmethod
def image_package(cls):
return __package__ + ".images"
@classmethod
def js_files(cls):
js_files = sorted(list(filter(lambda x: '.js' in x, pkg_resources.resource_listdir(cls.js_package(), '.'))))
# jasmine.js needs to be first
js_files.insert(0, 'jasmine.js')
# boot needs to be last
js_files.remove('boot.js')
js_files.append('boot.js')
return cls._uniq(js_files)
@classmethod
def css_files(cls):
return cls._uniq(sorted(filter(lambda x: '.css' in x, pkg_resources.resource_listdir(cls.css_package(), '.'))))
@classmethod
def favicon(cls):
return 'jasmine_favicon.png'
@classmethod
def _uniq(self, items, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in items:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen:
continue
seen[marker] = 1
result.append(item)
return result

View File

@@ -0,0 +1,60 @@
describe("Player", function() {
var Player = require('../../jasmine_examples/Player.js');
var Song = require('../../jasmine_examples/Song.js');
var player;
var song;
beforeEach(function() {
player = new Player();
song = new Song();
});
it("should be able to play a Song", function() {
player.play(song);
expect(player.currentlyPlayingSong).toEqual(song);
//demonstrates use of custom matcher
expect(player).toBePlaying(song);
});
describe("when song has been paused", function() {
beforeEach(function() {
player.play(song);
player.pause();
});
it("should indicate that the song is currently paused", function() {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", function() {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", function() {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", function() {
it("should throw an exception if song is already playing", function() {
player.play(song);
expect(function() {
player.resume();
}).toThrowError("song is already playing");
});
});
});

View File

@@ -0,0 +1,15 @@
beforeEach(function () {
jasmine.addMatchers({
toBePlaying: function () {
return {
compare: function (actual, expected) {
var player = actual;
return {
pass: player.currentlyPlayingSong === expected && player.isPlaying
}
}
};
}
});
});

View File

@@ -0,0 +1,24 @@
function Player() {
}
Player.prototype.play = function(song) {
this.currentlyPlayingSong = song;
this.isPlaying = true;
};
Player.prototype.pause = function() {
this.isPlaying = false;
};
Player.prototype.resume = function() {
if (this.isPlaying) {
throw new Error("song is already playing");
}
this.isPlaying = true;
};
Player.prototype.makeFavorite = function() {
this.currentlyPlayingSong.persistFavoriteStatus(true);
};
module.exports = Player;

View File

@@ -0,0 +1,9 @@
function Song() {
}
Song.prototype.persistFavoriteStatus = function(value) {
// something complicated
throw new Error("not yet implemented");
};
module.exports = Song;

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2013 Pivotal Labs
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -49,20 +49,21 @@ jasmineRequire.HtmlReporter = function(j$) {
symbols;
this.initialize = function() {
htmlReporterMain = createDom("div", {className: "html-reporter"},
createDom("div", {className: "banner"},
createDom("span", {className: "title"}, "Jasmine"),
createDom("span", {className: "version"}, j$.version)
clearPrior();
htmlReporterMain = createDom('div', {className: 'jasmine_html-reporter'},
createDom('div', {className: 'banner'},
createDom('a', {className: 'title', href: 'http://jasmine.github.io/', target: '_blank'}),
createDom('span', {className: 'version'}, j$.version)
),
createDom("ul", {className: "symbol-summary"}),
createDom("div", {className: "alert"}),
createDom("div", {className: "results"},
createDom("div", {className: "failures"})
createDom('ul', {className: 'symbol-summary'}),
createDom('div', {className: 'alert'}),
createDom('div', {className: 'results'},
createDom('div', {className: 'failures'})
)
);
getContainer().appendChild(htmlReporterMain);
symbols = find(".symbol-summary");
symbols = find('.symbol-summary');
};
var totalSpecsDefined;
@@ -71,13 +72,13 @@ jasmineRequire.HtmlReporter = function(j$) {
timer.start();
};
var summary = createDom("div", {className: "summary"});
var summary = createDom('div', {className: 'summary'});
var topResults = new j$.ResultsNode({}, "", null),
var topResults = new j$.ResultsNode({}, '', null),
currentParent = topResults;
this.suiteStarted = function(result) {
currentParent.addChild(result, "suite");
currentParent.addChild(result, 'suite');
currentParent = currentParent.last();
};
@@ -90,82 +91,94 @@ jasmineRequire.HtmlReporter = function(j$) {
};
this.specStarted = function(result) {
currentParent.addChild(result, "spec");
currentParent.addChild(result, 'spec');
};
var failures = [];
this.specDone = function(result) {
if (result.status != "disabled") {
if(noExpectations(result) && console && console.error) {
console.error('Spec \'' + result.fullName + '\' has no expectations.');
}
if (result.status != 'disabled') {
specsExecuted++;
}
symbols.appendChild(createDom("li", {
className: result.status,
id: "spec_" + result.id,
symbols.appendChild(createDom('li', {
className: noExpectations(result) ? 'empty' : result.status,
id: 'spec_' + result.id,
title: result.fullName
}
));
if (result.status == "failed") {
if (result.status == 'failed') {
failureCount++;
var failure =
createDom("div", {className: "spec-detail failed"},
createDom("div", {className: "description"},
createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
createDom('div', {className: 'spec-detail failed'},
createDom('div', {className: 'description'},
createDom('a', {title: result.fullName, href: specHref(result)}, result.fullName)
),
createDom("div", {className: "messages"})
createDom('div', {className: 'messages'})
);
var messages = failure.childNodes[1];
for (var i = 0; i < result.failedExpectations.length; i++) {
var expectation = result.failedExpectations[i];
messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack));
messages.appendChild(createDom('div', {className: 'result-message'}, expectation.message));
messages.appendChild(createDom('div', {className: 'stack-trace'}, expectation.stack));
}
failures.push(failure);
}
if (result.status == "pending") {
if (result.status == 'pending') {
pendingSpecCount++;
}
};
this.jasmineDone = function() {
var banner = find(".banner");
banner.appendChild(createDom("span", {className: "duration"}, "finished in " + timer.elapsed() / 1000 + "s"));
var banner = find('.banner');
banner.appendChild(createDom('span', {className: 'duration'}, 'finished in ' + timer.elapsed() / 1000 + 's'));
var alert = find(".alert");
var alert = find('.alert');
alert.appendChild(createDom("span", { className: "exceptions" },
createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
createDom("input", {
className: "raise",
id: "raise-exceptions",
type: "checkbox"
alert.appendChild(createDom('span', { className: 'exceptions' },
createDom('label', { className: 'label', 'for': 'raise-exceptions' }, 'raise exceptions'),
createDom('input', {
className: 'raise',
id: 'raise-exceptions',
type: 'checkbox'
})
));
var checkbox = find("input");
var checkbox = find('#raise-exceptions');
checkbox.checked = !env.catchingExceptions();
checkbox.onclick = onRaiseExceptionsClick;
if (specsExecuted < totalSpecsDefined) {
var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
var skippedMessage = 'Ran ' + specsExecuted + ' of ' + totalSpecsDefined + ' specs - run all';
alert.appendChild(
createDom("span", {className: "bar skipped"},
createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
createDom('span', {className: 'bar skipped'},
createDom('a', {href: '?', title: 'Run all specs'}, skippedMessage)
)
);
}
var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
var statusBarMessage = '';
var statusBarClassName = 'bar ';
var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
if (totalSpecsDefined > 0) {
statusBarMessage += pluralize('spec', specsExecuted) + ', ' + pluralize('failure', failureCount);
if (pendingSpecCount) { statusBarMessage += ', ' + pluralize('pending spec', pendingSpecCount); }
statusBarClassName += (failureCount > 0) ? 'failed' : 'passed';
} else {
statusBarClassName += 'skipped';
statusBarMessage += 'No specs found';
}
var results = find(".results");
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
var results = find('.results');
results.appendChild(summary);
summaryList(topResults, summary);
@@ -174,27 +187,31 @@ jasmineRequire.HtmlReporter = function(j$) {
var specListNode;
for (var i = 0; i < resultsTree.children.length; i++) {
var resultNode = resultsTree.children[i];
if (resultNode.type == "suite") {
var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
createDom("li", {className: "suite-detail"},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
if (resultNode.type == 'suite') {
var suiteListNode = createDom('ul', {className: 'suite', id: 'suite-' + resultNode.result.id},
createDom('li', {className: 'suite-detail'},
createDom('a', {href: specHref(resultNode.result)}, resultNode.result.description)
)
);
summaryList(resultNode, suiteListNode);
domParent.appendChild(suiteListNode);
}
if (resultNode.type == "spec") {
if (domParent.getAttribute("class") != "specs") {
specListNode = createDom("ul", {className: "specs"});
if (resultNode.type == 'spec') {
if (domParent.getAttribute('class') != 'specs') {
specListNode = createDom('ul', {className: 'specs'});
domParent.appendChild(specListNode);
}
var specDescription = resultNode.result.description;
if(noExpectations(resultNode.result)) {
specDescription = 'SPEC HAS NO EXPECTATIONS ' + specDescription;
}
specListNode.appendChild(
createDom("li", {
createDom('li', {
className: resultNode.result.status,
id: "spec-" + resultNode.result.id
id: 'spec-' + resultNode.result.id
},
createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
createDom('a', {href: specHref(resultNode.result)}, specDescription)
)
);
}
@@ -203,24 +220,24 @@ jasmineRequire.HtmlReporter = function(j$) {
if (failures.length) {
alert.appendChild(
createDom('span', {className: "menu bar spec-list"},
createDom("span", {}, "Spec List | "),
createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
createDom('span', {className: 'menu bar spec-list'},
createDom('span', {}, 'Spec List | '),
createDom('a', {className: 'failures-menu', href: '#'}, 'Failures')));
alert.appendChild(
createDom('span', {className: "menu bar failure-list"},
createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
createDom("span", {}, " | Failures ")));
createDom('span', {className: 'menu bar failure-list'},
createDom('a', {className: 'spec-list-menu', href: '#'}, 'Spec List'),
createDom('span', {}, ' | Failures ')));
find(".failures-menu").onclick = function() {
find('.failures-menu').onclick = function() {
setMenuModeTo('failure-list');
};
find(".spec-list-menu").onclick = function() {
find('.spec-list-menu').onclick = function() {
setMenuModeTo('spec-list');
};
setMenuModeTo('failure-list');
var failureNode = find(".failures");
var failureNode = find('.failures');
for (var i = 0; i < failures.length; i++) {
failureNode.appendChild(failures[i]);
}
@@ -230,7 +247,16 @@ jasmineRequire.HtmlReporter = function(j$) {
return this;
function find(selector) {
return getContainer().querySelector(selector);
return getContainer().querySelector('.jasmine_html-reporter ' + selector);
}
function clearPrior() {
// return the reporter
var oldReporter = find('');
if(oldReporter) {
getContainer().removeChild(oldReporter);
}
}
function createDom(type, attrs, childrenVarArgs) {
@@ -249,7 +275,7 @@ jasmineRequire.HtmlReporter = function(j$) {
}
for (var attr in attrs) {
if (attr == "className") {
if (attr == 'className') {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
@@ -260,17 +286,22 @@ jasmineRequire.HtmlReporter = function(j$) {
}
function pluralize(singular, count) {
var word = (count == 1 ? singular : singular + "s");
var word = (count == 1 ? singular : singular + 's');
return "" + count + " " + word;
return '' + count + ' ' + word;
}
function specHref(result) {
return "?spec=" + encodeURIComponent(result.fullName);
return '?spec=' + encodeURIComponent(result.fullName);
}
function setMenuModeTo(mode) {
htmlReporterMain.setAttribute("class", "html-reporter " + mode);
htmlReporterMain.setAttribute('class', 'jasmine_html-reporter ' + mode);
}
function noExpectations(result) {
return (result.failedExpectations.length + result.passedExpectations.length) === 0 &&
result.status === 'passed';
}
}
@@ -279,7 +310,7 @@ jasmineRequire.HtmlReporter = function(j$) {
jasmineRequire.HtmlSpecFilter = function() {
function HtmlSpecFilter(options) {
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
var filterString = options && options.filterString() && options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
var filterPattern = new RegExp(filterString);
this.matches = function(specName) {
@@ -328,9 +359,9 @@ jasmineRequire.QueryString = function() {
function toQueryString(paramMap) {
var qStrPairs = [];
for (var prop in paramMap) {
qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
qStrPairs.push(encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop]));
}
return "?" + qStrPairs.join('&');
return '?' + qStrPairs.join('&');
}
function queryStringToParamMap() {
@@ -343,7 +374,7 @@ jasmineRequire.QueryString = function() {
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
var value = decodeURIComponent(p[1]);
if (value === "true" || value === "false") {
if (value === 'true' || value === 'false') {
value = JSON.parse(value);
}
paramMap[decodeURIComponent(p[0])] = value;

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,41 @@
/*
Copyright (c) 2008-2014 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
module.exports = function(jasmineRequire) {
var jasmine = jasmineRequire.core(jasmineRequire);
var consoleFns = require('../console/console.js');
consoleFns.console(consoleFns, jasmine);
var env = jasmine.getEnv();
var jasmineInterface = jasmineRequire.interface(jasmine, env);
extend(global, jasmineInterface);
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
return jasmine;
};

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "2.0.0"
VERSION = "2.0.2"
end
end

View File

@@ -1,17 +1,23 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "2.0.0",
"version": "2.0.2",
"repository": {
"type": "git",
"url": "https://github.com/pivotal/jasmine.git"
},
"description": "Official packaging of Jasmine's core files for use by Node.js projects.",
"homepage": "http://jasmine.github.io",
"main": "./lib/jasmine-core.js",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.7.0",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-compass": "~0.6.0",
"grunt-contrib-compress": "~0.5.2",
"shelljs": "~0.1.4"
"shelljs": "~0.1.4",
"glob": "~3.2.9",
"jasmine": "https://github.com/pivotal/jasmine-npm/archive/master.tar.gz",
"load-grunt-tasks": "^0.4.0"
}
}

70
release_notes/2.0.1.md Normal file
View File

@@ -0,0 +1,70 @@
# Jasmine Core 2.0.1 Release Notes
## Summary
This release is for small bug fixes and enhancements ahead of a real-soon-now 2.1.
## Changes
### Features
* NodeJS is now supported with a jasmine-core npm
* [Support browsers that don't supply a `Date.now()` by having a `mockDate` object](http://www.pivotaltracker.com/story/66606132) - Closes #361
* [Show message if no specs where loaded](http://www.pivotaltracker.com/story/12784235)
* When using `jasmine.any`, the `class` will now be included in the error message
* Reporters now receive the number of passed expectations in a spec
* Use default failure message for `toBeNaN`
* Use the latest `jasmine_selenium_runner` so we use the fix for printing objects with cycles
* Add jasmine logo image to HTML runner
* Stop Jasmine's CSS affecting the style of the body tag - Closes #600
* Standardized location of the standalone distributions - they now live in the repo in `/dist` as well as on the Releases page
### Bugs
* Don't allow calling the same done callback multiple times - Fixes #523
* [Remove 'empty' as an option as a spec result](http://www.pivotaltracker.com/story/73741032) as this was a breaking change
* Instead, we determine if a spec has no expectations using the added
key of `passedExpectations` in combination of the `failedExpectations`
to determine that there a spec is 'empty'
* Fix build in IE8 (IE8 doesn't support `Object.freeze`)
* Fix `ObjectContaining` to match recursively
### Documentation
* Update release doc to use GitHub releases
* Add installation instructions to README - Merges #621
* Add Ruby Gem and Python Egg to docs
* Add detailed steps on how to contribute - Merges #580 from @pablofiu
## Pull Requests and Issues
* Contains is explicitly false if actual is `undefined` or `null` - Fixes #627
* namespace `html-reporter` -> `jasmine_html-reporter` - Fixes #600
* Throw a more specific error when `expect` is used without a `currentSpec` - Fixes #602
* Reduced size of logo with PNG Gauntlet - Merges #588
* HTML Reporter resets previous DOM when re-initialized - Merges #594 from @plukevdh
* Narrow down raise exceptions query selector; Finding by any input tag is a little bit broad - Closes #605
* Pass through custom equality testers in toHaveBeenCalledWith - Fixes #536
* Fix outdated copyright year (update to 2014) - Merges #550 from @slothmonster
* [Add package.json to Python egg to get correct version number](http://www.pivotaltracker.com/story/67556148) - Fixes #551
* Allow users to set the maximum length of array that the pretty-printer
will print out - Fixes #323 @mikemoraned and #374 @futuraprime
* `matchersUtil.equals()` does not expect a matcher as its first argument,
so send the "actual" value first and the "expected" value second. - Merges #538 from @cbandy
* Add single quote check to `jshint` and fix src files for that - Closes #522
* Remove an `eval` in order to support running jasmine within CSP - Closes #503
* Allow matcher custom failure messages to be a function - Closes #520
* More color blind friendly CSS from @dleppik - Closes #463 &amp; #509
* Use `load-grunt-tasks` Merges #521 from @robinboehm
* Special case printing `-0` - Closes #496
* Allow stub or spy Date object safely using a closure to get a clean copy - Closes #506
* [Use `\d7` instead of plain 'x' for more square appearance](http://www.pivotaltracker.com/story/48434179)
* Better support in pretty printer when an object has null prototype - Fixes #500
* Update link at top of README to improve access to Jasmine 2.0 docs - Merges #486 from @nextmat
* Force query selector to seek within the html-reporter element - Merges #479 from @shprink
* Netbeans files are in gitignore - Merges #478 from @shprink
------
_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_

25
release_notes/2.0.2.md Normal file
View File

@@ -0,0 +1,25 @@
# Release Notes
## Summary
## Changes
* keep the files for running in a webpage around in the npm package
* Expose files and paths necessary to embed jasmine in an html page for nodejs
* Pull out the building of the jasmine interface so node and web both get the same one.
* Show a dot with color of pending spec when no expectations
* Console reporter prints out failed expectation's message
### Bugs
* Allow mocked Date constructor to be called with a subset of full params
## Pull Requests and Issues
* a disabled suite should call resultCallback with status being disabled
* disabled suite should still call onStart callback
------
_Release Notes generated with _[Anchorman](http://github.com/infews/anchorman)_

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
ordereddict==1.1

47
setup.py Normal file
View File

@@ -0,0 +1,47 @@
from setuptools import setup, find_packages, os
import json
with open('package.json') as packageFile:
version = json.load(packageFile)['version']
setup(
name="jasmine-core",
version=version,
url="http://pivotal.github.io/jasmine/",
author="Pivotal Labs",
author_email="jasmine-js@googlegroups.com",
description=('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.'),
license='MIT',
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Environment :: Web Environment',
'Framework :: Django',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Software Development :: Build Tools',
'Topic :: Software Development :: Quality Assurance',
'Topic :: Software Development :: Testing',
],
packages=['jasmine_core', 'jasmine_core.images'],
package_dir={'jasmine_core': 'lib/jasmine-core', 'jasmine_core.images': 'images'},
package_data={'jasmine_core': ['*.js', '*.css'], 'jasmine_core.images': ['*.png']},
include_package_data=True,
install_requires=['glob2>=0.4.1', 'ordereddict==1.1']
)

View File

@@ -80,6 +80,18 @@ describe("ConsoleReporter", function() {
expect(out.getOutput()).toEqual("*");
});
it("alerts user if there are no specs", function(){
var reporter = new j$.ConsoleReporter({
print: out.print
});
reporter.jasmineStarted();
out.clear();
reporter.jasmineDone();
expect(out.getOutput()).toMatch(/No specs found/);
});
it("reports a summary when done (singular spec and time)", function() {
var timerSpy = jasmine.createSpyObj('timer', ['start', 'elapsed']),
reporter = new j$.ConsoleReporter({
@@ -161,6 +173,7 @@ describe("ConsoleReporter", function() {
reporter.jasmineDone({});
expect(out.getOutput()).toMatch(/true to be false/);
expect(out.getOutput()).toMatch(/foo bar baz/);
});

View File

@@ -40,6 +40,7 @@ describe("Any", function() {
var any = new j$.Any(Number);
expect(any.jasmineToString()).toMatch('<jasmine.any');
expect(any.jasmineToString()).toMatch('Number');
});
});

View File

@@ -5,7 +5,8 @@ describe("Clock", function() {
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
fakeGlobal.setTimeout(delayedFn, 0);
@@ -26,7 +27,8 @@ describe("Clock", function() {
fakeGlobal = { clearTimeout: fakeClearTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
fakeGlobal.clearTimeout("foo");
@@ -47,7 +49,8 @@ describe("Clock", function() {
fakeGlobal = { setInterval: fakeSetInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
fakeGlobal.setInterval(delayedFn, 0);
@@ -68,7 +71,8 @@ describe("Clock", function() {
fakeGlobal = { clearInterval: fakeClearInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
fakeGlobal.clearInterval("foo");
@@ -97,7 +101,8 @@ describe("Clock", function() {
},
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
clock.install();
clock.uninstall();
@@ -119,7 +124,8 @@ describe("Clock", function() {
delayedFunctionScheduler = { scheduleFunction: scheduleFunction },
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
clock.install();
clock.setTimeout(delayedFn, 0, 'a', 'b');
@@ -135,7 +141,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
timeoutId;
clock.install();
@@ -149,7 +156,8 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
fakeGlobal = { setTimeout: fakeClearTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
clock.install();
clock.clearTimeout(123);
@@ -164,7 +172,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
clock.install();
clock.setInterval(delayedFn, 0, 'a', 'b');
@@ -180,7 +189,8 @@ describe("Clock", function() {
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate),
intervalId;
clock.install();
@@ -194,7 +204,8 @@ describe("Clock", function() {
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
fakeGlobal = { setInterval: clearInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
clock.install();
clock.clearInterval(123);
@@ -220,7 +231,8 @@ describe("Clock", function() {
setTimeout: fakeSetTimeout,
setInterval: fakeSetInterval
},
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler, mockDate);
fakeSetTimeout.apply = null;
fakeSetInterval.apply = null;
@@ -249,7 +261,8 @@ describe("Clock (acceptance)", function() {
delayedFn3 = jasmine.createSpy('delayedFn3'),
recurring1 = jasmine.createSpy('recurring1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
clock.install();
@@ -295,7 +308,8 @@ describe("Clock (acceptance)", function() {
it("can clear a previously set timeout", function() {
var clearedFn = jasmine.createSpy('clearedFn'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler),
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate),
timeoutId;
clock.install();
@@ -312,7 +326,8 @@ describe("Clock (acceptance)", function() {
it("correctly schedules functions after the Clock has advanced", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
clock.install();
@@ -328,7 +343,8 @@ describe("Clock (acceptance)", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
clock.install();
@@ -346,7 +362,8 @@ describe("Clock (acceptance)", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
mockDate = { install: function() {}, tick: function() {}, uninstall: function() {} },
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler, mockDate);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 1); });
clock.install();
@@ -356,4 +373,73 @@ describe("Clock (acceptance)", function() {
expect(delayedFn1).toHaveBeenCalled();
expect(delayedFn2).toHaveBeenCalled();
});
it("does not mock the Date object by default", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
clock.install();
expect(global.Date).toEqual(Date);
var now = new global.Date().getTime();
clock.tick(50);
expect(new global.Date().getTime() - now).not.toEqual(50);
});
it("mocks the Date object and sets it to current time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate);
clock.install().mockDate();
var now = new global.Date().getTime();
clock.tick(50);
expect(new global.Date().getTime() - now).toEqual(50);
var timeoutDate = 0;
clock.setTimeout(function() {
timeoutDate = new global.Date().getTime();
}, 100);
clock.tick(100);
expect(timeoutDate - now).toEqual(150);
});
it("mocks the Date object and sets it to a given time", function() {
var delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
global = {Date: Date},
mockDate = new j$.MockDate(global),
clock = new j$.Clock({setTimeout: setTimeout}, delayedFunctionScheduler, mockDate),
baseTime = new Date(2013, 9, 23);
clock.install().mockDate(baseTime);
var now = new global.Date().getTime();
expect(now).toEqual(baseTime.getTime());
clock.tick(50);
expect(new global.Date().getTime()).toEqual(baseTime.getTime() + 50);
var timeoutDate = 0;
clock.setTimeout(function() {
timeoutDate = new global.Date().getTime();
}, 100);
clock.tick(100);
expect(timeoutDate).toEqual(baseTime.getTime() + 150);
});
});

View File

@@ -14,7 +14,7 @@ describe("DelayedFunctionScheduler", function() {
it("schedules a string for later execution", function() {
var scheduler = new j$.DelayedFunctionScheduler(),
strfn = "horrible = true;";
strfn = "horrible = true;";
scheduler.scheduleFunction(strfn, 0);

View File

@@ -6,20 +6,20 @@ describe("Env", function() {
});
it('removes all spies when env is executed', function(done) {
originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
var originalFoo = function() {},
testObj = {
foo: originalFoo
},
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
env.spyOn(testObj, 'foo');
}),
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
expect(testObj.foo).toBe(originalFoo);
});
env.describe('test suite', function() {
env.it('spec 0', firstSpec);
env.it('spec 1', secondSpec);
});
var assertions = function() {
expect(firstSpec).toHaveBeenCalled();

View File

@@ -35,7 +35,14 @@ describe("ExceptionFormatter", function() {
message = exceptionFormatter.message(sampleV8);
expect(message).toEqual('A Classic Mistake: you got your foo in my bar');
});
it("formats thrown exceptions that aren't errors", function() {
var thrown = "crazy error",
exceptionFormatter = new j$.ExceptionFormatter(),
message = exceptionFormatter.message(thrown);
expect(message).toEqual("crazy error thrown");
});
});

View File

@@ -35,7 +35,7 @@ describe('Exceptions:', function() {
env.it('should be a passing test that runs after exceptions are thrown from a async test', secondTest);
});
expectations = function() {
var expectations = function() {
expect(secondTest).toHaveBeenCalled();
done();
};
@@ -55,7 +55,7 @@ describe('Exceptions:', function() {
});
env.describe("a suite that doesn't throw an exception", secondDescribe);
expectations = function() {
var expectations = function() {
expect(secondDescribe).toHaveBeenCalled();
done();
};

View File

@@ -193,6 +193,40 @@ describe("Expectation", function() {
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
actual: "an actual",
addExpectationResult: addExpectationResult
});
expectation.toFoo("hello");
expect(addExpectationResult).toHaveBeenCalledWith(false, {
matcherName: "toFoo",
passed: false,
expected: "hello",
actual: "an actual",
message: "I am a custom message"
});
});
it("reports a failing result with a custom fail message function to the spec when the comparison fails", function() {
var matchers = {
toFoo: function() {
return {
compare: function() {
return {
pass: false,
message: function() { return "I am a custom message"; }
};
}
};
}
},
addExpectationResult = jasmine.createSpy("addExpectationResult"),
expectation;
j$.Expectation.addMatchers(matchers);
expectation = new j$.Expectation({
matchers: matchers,
actual: "an actual",

199
spec/core/MockDateSpec.js Normal file
View File

@@ -0,0 +1,199 @@
describe("FakeDate", function() {
it("does not fail if no global date is found", function() {
var fakeGlobal = {},
mockDate = new j$.MockDate(fakeGlobal);
expect(function() {
mockDate.install();
mockDate.tick(0);
mockDate.uninstall();
}).not.toThrow();
});
it("replaces the global Date when it is installed", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
expect(fakeGlobal.Date).toEqual(globalDate);
mockDate.install();
expect(fakeGlobal.Date).not.toEqual(globalDate);
});
it("replaces the global Date on uninstall", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.uninstall();
expect(fakeGlobal.Date).toEqual(globalDate);
});
it("takes the current time as the base when installing without parameters", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
globalDate.calls.reset();
new fakeGlobal.Date();
expect(globalDate).toHaveBeenCalledWith(1000);
});
it("can accept a date as time base when installing", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
baseDate = new Date();
spyOn(baseDate, 'getTime').and.returnValue(123);
mockDate.install(baseDate);
expect(new fakeGlobal.Date().getTime()).toEqual(123);
});
it("makes real dates", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(new fakeGlobal.Date()).toEqual(jasmine.any(Date));
});
it("fakes current time when using Date.now()", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.now()).toEqual(1000);
});
it("does not stub Date.now() if it doesn't already exist", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.now).toThrowError("Browser does not support Date.now()");
});
it("makes time passes using tick", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.tick(100);
expect(fakeGlobal.Date.now()).toEqual(1100);
mockDate.tick(1000);
expect(fakeGlobal.Date.now()).toEqual(2100);
});
it("allows to increase 0 milliseconds using tick", function() {
var globalDate = jasmine.createSpy("global Date").and.callFake(function() {
return {
getTime: function() {
return 1000;
}
}
}),
fakeGlobal = { Date: globalDate };
globalDate.now = function() {};
var mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
mockDate.tick(0);
expect(fakeGlobal.Date.now()).toEqual(1000);
mockDate.tick();
expect(fakeGlobal.Date.now()).toEqual(1000);
});
it("allows creation of a Date in a different time than the mocked time", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
var otherDate = new fakeGlobal.Date(2013, 9, 23, 0, 0, 1, 0);
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23, 0, 0, 1, 0).getTime());
});
it("allows creation of a Date that isn't fully specified", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
var otherDate = new fakeGlobal.Date(2013, 9, 23);
expect(otherDate.getTime()).toEqual(new Date(2013, 9, 23).getTime());
});
it('allows creation of a Date with millis', function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal),
now = new Date(2014, 3, 15).getTime();
mockDate.install();
var otherDate = new fakeGlobal.Date(now);
expect(otherDate.getTime()).toEqual(now);
});
it("copies all Date properties to the mocked date", function() {
var fakeGlobal = { Date: Date },
mockDate = new j$.MockDate(fakeGlobal);
mockDate.install();
expect(fakeGlobal.Date.UTC(2013, 9, 23)).toEqual(Date.UTC(2013, 9, 23));
});
});

View File

@@ -61,4 +61,10 @@ describe("ObjectContaining", function() {
expect(containing.jasmineToString()).toMatch("<jasmine.objectContaining");
});
it("matches recursively", function() {
var containing = new j$.ObjectContaining({one: new j$.ObjectContaining({two: {}})});
expect(containing.jasmineMatches({one: {two: {}}})).toBe(true);
});
});

View File

@@ -11,6 +11,7 @@ describe("j$.pp", function () {
expect(j$.pp(jasmine.undefined)).toEqual("undefined");
expect(j$.pp(3)).toEqual("3");
expect(j$.pp(-3.14)).toEqual("-3.14");
expect(j$.pp(-0)).toEqual("-0");
});
it("should stringify arrays properly", function() {
@@ -26,10 +27,10 @@ describe("j$.pp", function () {
});
it("should stringify objects properly", function() {
expect(j$.pp({foo: 'bar'})).toEqual("{ foo : 'bar' }");
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo : 'bar', baz : 3, nullValue : null, undefinedValue : undefined }");
expect(j$.pp({foo: 'bar'})).toEqual("{ foo: 'bar' }");
expect(j$.pp({foo:'bar', baz:3, nullValue: null, undefinedValue: jasmine.undefined})).toEqual("{ foo: 'bar', baz: 3, nullValue: null, undefinedValue: undefined }");
expect(j$.pp({foo: function () {
}, bar: [1, 2, 3]})).toEqual("{ foo : Function, bar : [ 1, 2, 3 ] }");
}, bar: [1, 2, 3]})).toEqual("{ foo: Function, bar: [ 1, 2, 3 ] }");
});
it("should not include inherited properties when stringifying an object", function() {
@@ -37,7 +38,7 @@ describe("j$.pp", function () {
SomeClass.prototype.foo = "inherited foo";
var instance = new SomeClass();
instance.bar = "my own bar";
expect(j$.pp(instance)).toEqual("{ bar : 'my own bar' }");
expect(j$.pp(instance)).toEqual("{ bar: 'my own bar' }");
});
it("should not recurse objects and arrays more deeply than j$.MAX_PRETTY_PRINT_DEPTH", function() {
@@ -47,21 +48,42 @@ describe("j$.pp", function () {
try {
j$.MAX_PRETTY_PRINT_DEPTH = 2;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : Object } }");
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: Object } }");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, Array ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 3;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : Object } } }");
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: Object } } }");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, Array ] ] ]");
j$.MAX_PRETTY_PRINT_DEPTH = 4;
expect(j$.pp(nestedObject)).toEqual("{ level1 : { level2 : { level3 : { level4 : 'leaf' } } } }");
expect(j$.pp(nestedObject)).toEqual("{ level1: { level2: { level3: { level4: 'leaf' } } } }");
expect(j$.pp(nestedArray)).toEqual("[ 1, [ 2, [ 3, [ 4, 'leaf' ] ] ] ]");
} finally {
j$.MAX_PRETTY_PRINT_DEPTH = originalMaxDepth;
}
});
it("should stringify immutable circular objects", function(){
if(Object.freeze){
var frozenObject = {foo: {bar: 'baz'}};
frozenObject.circular = frozenObject;
frozenObject = Object.freeze(frozenObject);
expect(j$.pp(frozenObject)).toEqual("{ foo: { bar: 'baz' }, circular: <circular reference: Object> }");
}
});
it("should truncate arrays that are longer than j$.MAX_PRETTY_PRINT_ARRAY_LENGTH", function() {
var originalMaxLength = j$.MAX_PRETTY_PRINT_ARRAY_LENGTH;
var array = [1, 2, 3];
try {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = 2;
expect(j$.pp(array)).toEqual("[ 1, 2, ... ]");
} finally {
j$.MAX_PRETTY_PRINT_ARRAY_LENGTH = originalMaxLength;
}
});
it("should stringify RegExp objects properly", function() {
expect(j$.pp(/x|y|z/)).toEqual("/x|y|z/");
});
@@ -69,7 +91,7 @@ describe("j$.pp", function () {
it("should indicate circular object references", function() {
var sampleValue = {foo: 'hello'};
sampleValue.nested = sampleValue;
expect(j$.pp(sampleValue)).toEqual("{ foo : 'hello', nested : <circular reference: Object> }");
expect(j$.pp(sampleValue)).toEqual("{ foo: 'hello', nested: <circular reference: Object> }");
});
it("should indicate getters on objects as such", function() {
@@ -81,10 +103,10 @@ describe("j$.pp", function () {
});
}
if (sampleValue.__defineGetter__) {
expect(j$.pp(sampleValue)).toEqual("{ id : 1, calculatedValue : <getter> }");
expect(j$.pp(sampleValue)).toEqual("{ id: 1, calculatedValue: <getter> }");
}
else {
expect(j$.pp(sampleValue)).toEqual("{ id : 1 }");
expect(j$.pp(sampleValue)).toEqual("{ id: 1 }");
}
});
@@ -121,5 +143,14 @@ describe("j$.pp", function () {
expect(j$.pp(obj)).toEqual("strung");
});
it("should handle objects with null prototype", function() {
if (jasmine.getEnv().ieVersion < 9) { return; }
var obj = Object.create(null);
obj.foo = 'bar';
expect(j$.pp(obj)).toEqual("{ foo: 'bar' }");
});
});

View File

@@ -50,31 +50,25 @@ describe("QueueRunner", function() {
//createSpy('asyncfn').and.callFake(function(done) {});
var onComplete = jasmine.createSpy('onComplete'),
beforeCallback = jasmine.createSpy('beforeCallback'),
fnCallback = jasmine.createSpy('fnCallback'),
afterCallback = jasmine.createSpy('afterCallback'),
fn1 = function(done) {
beforeCallback();
setTimeout(function() {
done()
}, 100);
},
fn2 = function(done) {
fnCallback();
setTimeout(function() {
done()
}, 100);
},
fn3 = function(done) {
afterCallback();
setTimeout(function() {
done()
}, 100);
},
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2, fn3],
onComplete: onComplete
});
beforeCallback = jasmine.createSpy('beforeCallback'),
fnCallback = jasmine.createSpy('fnCallback'),
afterCallback = jasmine.createSpy('afterCallback'),
fn1 = function(done) {
beforeCallback();
setTimeout(done, 100);
},
fn2 = function(done) {
fnCallback();
setTimeout(done, 100);
},
fn3 = function(done) {
afterCallback();
setTimeout(done, 100);
},
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2, fn3],
onComplete: onComplete
});
queueRunner.execute();
@@ -98,6 +92,112 @@ describe("QueueRunner", function() {
expect(onComplete).toHaveBeenCalled();
});
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
var beforeFn = function(done) { },
fn = jasmine.createSpy('fn'),
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
fns: [beforeFn, fn],
onComplete: onComplete,
onException: onException,
enforceTimeout: function() { return true; }
});
queueRunner.execute();
expect(fn).not.toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
expect(fn).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});
it("by default does not set a timeout for asynchronous functions", function() {
var beforeFn = function(done) { },
fn = jasmine.createSpy('fn'),
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
fns: [beforeFn, fn],
onComplete: onComplete,
onException: onException,
});
queueRunner.execute();
expect(fn).not.toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).not.toHaveBeenCalled();
expect(fn).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
});
it("clears the timeout when an async function throws an exception, to prevent additional onException calls", function() {
var fn = function(done) { throw new Error("error!"); },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
fns: [fn],
onComplete: onComplete,
onException: onException
});
queueRunner.execute();
expect(onComplete).toHaveBeenCalled();
expect(onException).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException.calls.count()).toEqual(1);
});
it("clears the timeout when the done callback is called", function() {
var fn = function(done) { done(); },
onComplete = jasmine.createSpy('onComplete'),
onException = jasmine.createSpy('onException'),
queueRunner = new j$.QueueRunner({
fns: [fn],
onComplete: onComplete,
onException: onException
});
queueRunner.execute();
expect(onComplete).toHaveBeenCalled();
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
expect(onException).not.toHaveBeenCalled();
});
it("only moves to the next spec the first time you call done", function() {
var fn = function(done) {done(); done();},
nextFn = jasmine.createSpy('nextFn');
queueRunner = new j$.QueueRunner({
fns: [fn, nextFn]
});
queueRunner.execute();
expect(nextFn.calls.count()).toEqual(1);
});
it("does not move to the next spec if done is called after an exception has ended the spec", function() {
var fn = function(done) {
setTimeout(done, 1);
throw new Error('error!');
},
nextFn = jasmine.createSpy('nextFn');
queueRunner = new j$.QueueRunner({
fns: [fn, nextFn]
});
queueRunner.execute();
jasmine.clock().tick(1);
expect(nextFn.calls.count()).toEqual(1);
});
});
it("calls an exception handler when an exception is thrown in a fn", function() {
@@ -124,16 +224,15 @@ describe("QueueRunner", function() {
catchException: function(e) { return false; }
});
expect(function() { queueRunner.execute(); }).toThrow();
expect(queueRunner.execute).toThrow();
});
it("continues running the functions even after an exception is thrown in an async spec", function() {
var fn = function(done) { throw new Error("error"); },
nextFn = jasmine.createSpy("nextFunction");
queueRunner = new j$.QueueRunner({
fns: [fn, nextFn]
});
nextFn = jasmine.createSpy("nextFunction"),
queueRunner = new j$.QueueRunner({
fns: [fn, nextFn]
});
queueRunner.execute();
expect(nextFn).toHaveBeenCalled();

View File

@@ -20,6 +20,10 @@ describe("Spec", function() {
expect(j$.Spec.isPendingSpecException(e)).toBe(false);
});
it("#isPendingSpecException returns false for thrown values that don't have toString", function() {
expect(j$.Spec.isPendingSpecException(void 0)).toBe(false);
});
it("delegates execution to a QueueRunner", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
spec = new j$.Spec({
@@ -171,7 +175,8 @@ describe("Spec", function() {
status: 'pending',
description: 'with a spec',
fullName: 'a suite with a spec',
failedExpectations: []
failedExpectations: [],
passedExpectations: []
});
});
@@ -189,9 +194,9 @@ describe("Spec", function() {
expect(done).toHaveBeenCalled();
});
it("#status returns passing by default", function() {
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
expect(spec.status()).toEqual('passed');
it("#status returns passing by default", function(){
var spec = new j$.Spec({ fn: function () {} });
expect(spec.status()).toBe("passed");
});
it("#status returns passed if all expectations in the spec have passed", function() {
@@ -207,6 +212,23 @@ describe("Spec", function() {
expect(spec.status()).toBe('failed');
});
it("keeps track of passed and failed expectations", function() {
var resultCallback = jasmine.createSpy('resultCallback'),
spec = new j$.Spec({
fn: jasmine.createSpy("spec body"),
expectationResultFactory: function (data) { return data; },
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
resultCallback: resultCallback
});
spec.addExpectationResult(true, 'expectation1');
spec.addExpectationResult(false, 'expectation2');
spec.execute();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual(['expectation1']);
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual(['expectation2']);
});
it("can return its full name", function() {
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
@@ -218,90 +240,7 @@ describe("Spec", function() {
expect(specNameSpy.calls.mostRecent().args[0].id).toEqual(spec.id);
});
it("sets a timeout for async functions to keep them from running forever", function() {
var queueRunnerSpy = jasmine.createSpy('queue runner'),
setTimeoutSpy = jasmine.createSpy('setTimeout'),
spec = new j$.Spec({
beforeFns: function() { return [function(done) { }]; },
fn: function(done) { },
afterFns: function() { return [function(done) { }]; },
timer: {
setTimeout: setTimeoutSpy,
clearTimeout: function() {}
},
queueRunnerFactory: queueRunnerSpy
});
spec.execute();
var fns = queueRunnerSpy.calls.mostRecent().args[0].fns;
for (var i = 0; i < fns.length; i++) {
fns[i]();
}
expect(setTimeoutSpy.calls.count()).toEqual(3);
expect(setTimeoutSpy).toHaveBeenCalledWith(jasmine.any(Function), j$.DEFAULT_TIMEOUT_INTERVAL);
});
it("resets the timeout timer when an async before throws an exception", function() {
var queueRunnerSpy = jasmine.createSpy('queueRunner'),
clearTimeoutSpy = jasmine.createSpy('clear timeout'),
spec = new j$.Spec({
beforeFns: function() { return [function(done) {}]; },
fn: function() { },
timer: {
setTimeout: function () { return 920; },
clearTimeout: clearTimeoutSpy
},
queueRunnerFactory: queueRunnerSpy
});
spec.execute();
queueRunnerSpy.calls.mostRecent().args[0].fns[0]();
queueRunnerSpy.calls.mostRecent().args[0].onException(new Error());
expect(clearTimeoutSpy).toHaveBeenCalledWith(920);
});
it("resets the timeout timer when an async spec throws an exception", function() {
var queueRunnerSpy = jasmine.createSpy('queueRunner'),
clearTimeoutSpy = jasmine.createSpy('clear timeout'),
spec = new j$.Spec({
fn: function(done) { },
timer: {
setTimeout: function () { return 920; },
clearTimeout: clearTimeoutSpy
},
queueRunnerFactory: queueRunnerSpy
});
spec.execute();
queueRunnerSpy.calls.mostRecent().args[0].fns[0]();
queueRunnerSpy.calls.mostRecent().args[0].onException(new Error());
expect(clearTimeoutSpy).toHaveBeenCalledWith(920);
});
it("resets the timeout timer when an async after spec throws an exception", function() {
var queueRunnerSpy = jasmine.createSpy('queueRunner'),
clearTimeoutSpy = jasmine.createSpy('clear timeout'),
spec = new j$.Spec({
fn: function() { },
afterFns: function() { return [function(done) {}]; },
timer: {
setTimeout: function () { return 920; },
clearTimeout: clearTimeoutSpy
},
queueRunnerFactory: queueRunnerSpy
});
spec.execute();
queueRunnerSpy.calls.mostRecent().args[0].fns[1]();
queueRunnerSpy.calls.mostRecent().args[0].onException(new Error());
expect(clearTimeoutSpy).toHaveBeenCalledWith(920);
});
describe("when a spec is marked pending during execution", function() {
describe("when a spec is marked pending during execution", function() {
it("should mark the spec as pending", function() {
var fakeQueueRunner = function(opts) {
opts.onException(new Error(j$.Spec.pendingSpecExceptionMessage));

View File

@@ -67,12 +67,17 @@ describe("Suite", function() {
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
});
it("can be disabled", function() {
it("can be disabled, but still calls callbacks", function() {
var env = new j$.Env(),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
onStart = jasmine.createSpy('onStart'),
resultCallback = jasmine.createSpy('resultCallback'),
onComplete = jasmine.createSpy('onComplete'),
suite = new j$.Suite({
env: env,
description: "with a child suite",
onStart: onStart,
resultCallback: resultCallback,
queueRunner: fakeQueueRunner
});
@@ -80,9 +85,12 @@ describe("Suite", function() {
expect(suite.disabled).toBe(true);
suite.execute();
suite.execute(onComplete);
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(onStart).toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalled();
});
it("delegates execution of its specs and suites", function() {
@@ -179,4 +187,30 @@ describe("Suite", function() {
fullName: "with a child suite"
});
});
it("calls a provided result callback with status being disabled when disabled and done", function() {
var env = new j$.Env(),
suiteResultsCallback = jasmine.createSpy('suite result callback'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new j$.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner,
resultCallback: suiteResultsCallback
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.disable();
suite.execute();
expect(suiteResultsCallback).toHaveBeenCalledWith({
id: suite.id,
status: 'disabled',
description: "with a child suite",
fullName: "with a child suite"
});
});
});

View File

@@ -10,4 +10,22 @@ describe("Timer", function() {
expect(timer.elapsed()).toEqual(100);
});
describe("when date is stubbed, perhaps by other testing helpers", function() {
var origDate = Date;
beforeEach(function() {
Date = jasmine.createSpy('date spy');
});
afterEach(function() {
Date = origDate;
});
it("does not throw even though Date was taken away", function() {
var timer = new j$.Timer();
expect(timer.start).not.toThrow();
expect(timer.elapsed()).toEqual(jasmine.any(Number));
});
});
});

View File

@@ -299,10 +299,14 @@ describe("Env integration", function() {
it("should wait a specified interval before failing specs haven't called done yet", function(done) {
var env = new j$.Env(),
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone" ]);
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone", "jasmineDone" ]);
reporter.specDone.and.callFake(function() {
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'failed'}));
});
reporter.jasmineDone.and.callFake(function() {
expect(reporter.jasmineDone.calls.count()).toEqual(1);
done();
});
@@ -311,7 +315,7 @@ describe("Env integration", function() {
env.it("async spec that doesn't call done", function(underTestCallback) {
env.expect(true).toBeTruthy();
jasmine.getEnv().clock.tick(8415);
jasmine.getEnv().clock.tick(8416);
});
env.execute();
@@ -484,5 +488,19 @@ describe("Env integration", function() {
env.execute();
});
it("produces an understandable error message when an 'expect' is used outside of a current spec", function(done) {
var env = new j$.Env();
env.describe("A Suite", function() {
env.it("an async spec that is actually synchronous", function(underTestCallback) {
underTestCallback();
expect(function() { env.expect('a').toEqual('a'); }).toThrowError(/'expect' was used when there was no current spec/);
done();
});
});
env.execute();
});
});

View File

@@ -199,6 +199,14 @@ describe("matchersUtil", function() {
expect(j$.matchersUtil.contains([1, 2], 2, [customTester])).toBe(true);
});
it("fails when actual is undefined", function() {
expect(j$.matchersUtil.contains(undefined, 'A')).toBe(false);
});
it("fails when actual is null", function() {
expect(j$.matchersUtil.contains(null, 'A')).toBe(false);
});
});
describe("buildMessage", function() {

View File

@@ -8,7 +8,8 @@ describe("toBeGreaterThan", function() {
});
it("fails when actual <= expected", function() {
var matcher = j$.matchers.toBeGreaterThan();
var matcher = j$.matchers.toBeGreaterThan(),
result;
result = matcher.compare(1, 1);
expect(result.pass).toBe(false);

View File

@@ -9,7 +9,8 @@ describe("toBeNaN", function() {
});
it("fails for anything not a NaN", function() {
var matcher = j$.matchers.toBeNaN();
var matcher = j$.matchers.toBeNaN(),
result;
result = matcher.compare(1);
expect(result.pass).toBe(false);
@@ -31,6 +32,6 @@ describe("toBeNaN", function() {
var matcher = j$.matchers.toBeNaN(),
result = matcher.compare(0);
expect(result.message).toEqual("Expected 0 to be NaN.");
expect(result.message()).toEqual("Expected 0 to be NaN.");
});
});

View File

@@ -9,7 +9,8 @@ describe("toBeUndefined", function() {
});
it("fails when matching defined values", function() {
var matcher = j$.matchers.toBeUndefined();
var matcher = j$.matchers.toBeUndefined(),
result;
result = matcher.compare('foo');
expect(result.pass).toBe(false);

View File

@@ -3,7 +3,8 @@ describe("toContain", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
matcher = j$.matchers.toContain(util);
matcher = j$.matchers.toContain(util),
result;
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", []);
@@ -15,7 +16,8 @@ describe("toContain", function() {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toContain(util, customEqualityTesters);
matcher = j$.matchers.toContain(util, customEqualityTesters),
result;
result = matcher.compare("ABC", "B");
expect(util.contains).toHaveBeenCalledWith("ABC", "B", ['a', 'b']);

View File

@@ -13,7 +13,8 @@ describe("toHaveBeenCalled", function() {
it("fails when the actual was not called", function() {
var matcher = j$.matchers.toHaveBeenCalled(),
uncalledSpy = j$.createSpy('uncalled spy');
uncalledSpy = j$.createSpy('uncalled spy'),
result;
result = matcher.compare(uncalledSpy);
expect(result.pass).toBe(false);

View File

@@ -11,7 +11,21 @@ describe("toHaveBeenCalledWith", function() {
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected spy called-spy not to have been called with [ 'a', 'b' ] but it was.");
expect(result.message()).toEqual("Expected spy called-spy not to have been called with [ 'a', 'b' ] but it was.");
});
it("passes through the custom equality testers", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
customEqualityTesters = [function() { return true; }],
matcher = j$.matchers.toHaveBeenCalledWith(util, customEqualityTesters),
calledSpy = j$.createSpy('called-spy');
calledSpy('a', 'b');
matcher.compare(calledSpy, 'a', 'b');
expect(util.contains).toHaveBeenCalledWith([['a', 'b']], ['a', 'b'], customEqualityTesters);
});
it("fails when the actual was not called", function() {
@@ -24,7 +38,7 @@ describe("toHaveBeenCalledWith", function() {
result = matcher.compare(uncalledSpy);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy uncalled spy to have been called with [ ] but it was never called.");
expect(result.message()).toEqual("Expected spy uncalled spy to have been called with [ ] but it was never called.");
});
it("fails when the actual was called with different parameters", function() {
@@ -40,7 +54,7 @@ describe("toHaveBeenCalledWith", function() {
result = matcher.compare(calledSpy, 'a', 'b');
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected spy called spy to have been called with [ 'a', 'b' ] but actual calls were [ 'a' ], [ 'c', 'd' ].");
expect(result.message()).toEqual("Expected spy called spy to have been called with [ 'a', 'b' ] but actual calls were [ 'a' ], [ 'c', 'd' ].");
});
it("throws an exception when the actual is not a spy", function() {

View File

@@ -62,7 +62,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an Error, but it threw 4.");
expect(result.message()).toEqual("Expected function to throw an Error, but it threw 4.");
});
it("fails with the correct message if thrown is a falsy value", function() {
@@ -74,7 +74,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an Error, but it threw undefined.");
expect(result.message()).toEqual("Expected function to throw an Error, but it threw undefined.");
});
it("passes if thrown is a type of Error, but there is no expected error", function() {
@@ -100,7 +100,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, "foo");
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception with message 'foo'.");
expect(result.message()).toEqual("Expected function not to throw an exception with message 'foo'.");
});
it("fails if thrown is an Error and the expected is not the same message", function() {
@@ -113,7 +113,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, "bar");
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception with message 'bar', but it threw an exception with message 'foo'.");
expect(result.message()).toEqual("Expected function to throw an exception with message 'bar', but it threw an exception with message 'foo'.");
});
it("passes if thrown is an Error and the expected is a RegExp that matches the message", function() {
@@ -126,7 +126,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, /long/);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw an exception with a message matching /long/.");
expect(result.message()).toEqual("Expected function not to throw an exception with a message matching /long/.");
});
it("fails if thrown is an Error and the expected is a RegExp that does not match the message", function() {
@@ -139,7 +139,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, /foo/);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw an exception with a message matching /foo/, but it threw an exception with message 'a long message'.");
expect(result.message()).toEqual("Expected function to throw an exception with a message matching /foo/, but it threw an exception with message 'a long message'.");
});
it("passes if thrown is an Error and the expected the same Error", function() {
@@ -207,7 +207,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, TypeError, "foo");
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw TypeError with message \"foo\".");
expect(result.message()).toEqual("Expected function not to throw TypeError with message 'foo'.");
});
it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() {
@@ -227,7 +227,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, CustomError, "foo");
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw CustomError with message \"foo\".");
expect(result.message()).toEqual("Expected function not to throw CustomError with message 'foo'.");
});
it("fails if thrown is a type of Error and the expected is a different Error", function() {
@@ -243,7 +243,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, TypeError, "bar");
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw TypeError with message \"bar\", but it threw TypeError with message \"foo\".");
expect(result.message()).toEqual("Expected function to throw TypeError with message 'bar', but it threw TypeError with message 'foo'.");
});
it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the expected message", function() {
@@ -259,7 +259,7 @@ describe("toThrowError", function() {
result = matcher.compare(fn, TypeError, /foo/);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw TypeError with message matching /foo/.");
expect(result.message()).toEqual("Expected function not to throw TypeError with message matching /foo/.");
});
it("fails if thrown is a type of Error and the expected is a different Error", function() {
@@ -275,6 +275,6 @@ describe("toThrowError", function() {
result = matcher.compare(fn, TypeError, /bar/);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw TypeError with message matching /bar/, but it threw TypeError with message \"foo\".");
expect(result.message()).toEqual("Expected function to throw TypeError with message matching /bar/, but it threw TypeError with message 'foo'.");
});
});

View File

@@ -34,7 +34,7 @@ describe("toThrow", function() {
result = matcher.compare(fn);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw, but it threw 5.");
expect(result.message()).toEqual("Expected function not to throw, but it threw 5.");
});
it("passes even if what is thrown is falsy", function() {
@@ -46,7 +46,7 @@ describe("toThrow", function() {
result = matcher.compare(fn);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw, but it threw undefined.");
expect(result.message()).toEqual("Expected function not to throw, but it threw undefined.");
});
it("passes if what is thrown is equivalent to what is expected", function() {
@@ -62,7 +62,7 @@ describe("toThrow", function() {
result = matcher.compare(fn, 5);
expect(result.pass).toBe(true);
expect(result.message).toEqual("Expected function not to throw 5.");
expect(result.message()).toEqual("Expected function not to throw 5.");
});
it("fails if what is thrown is not equivalent to what is expected", function() {
@@ -78,7 +78,7 @@ describe("toThrow", function() {
result = matcher.compare(fn, "foo");
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw 'foo', but it threw 5.");
expect(result.message()).toEqual("Expected function to throw 'foo', but it threw 5.");
});
it("fails if what is thrown is not equivalent to undefined", function() {
@@ -94,6 +94,6 @@ describe("toThrow", function() {
result = matcher.compare(fn, void 0);
expect(result.pass).toBe(false);
expect(result.message).toEqual("Expected function to throw undefined, but it threw 5.");
expect(result.message()).toEqual("Expected function to throw undefined, but it threw 5.");
});
});

View File

@@ -0,0 +1,7 @@
(function() {
// By the time onload is called, jasmineRequire will be redefined to point
// to the Jasmine source files (and not jasmine.js). So re-require
window.j$ = jasmineRequire.core(jasmineRequire);
jasmineRequire.html(j$);
jasmineRequire.console(jasmineRequire, j$);
})();

View File

@@ -0,0 +1,33 @@
(function() {
var path = require("path"),
fs = require("fs");
var glob = require("glob");
var j$Require = require(path.join(__dirname, "../../src/core/requireCore.js"));
global.getJasmineRequireObj = function () {
return j$Require;
};
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
function getSourceFiles() {
var src_files = ['core/**/*.js', 'console/**/*.js', 'version.js'];
src_files.forEach(function(file) {
var filePath = path.join(__dirname, "../../", 'src/', file);
glob.sync(filePath).forEach(function(resolvedFile) {
require(resolvedFile);
});
});
}
extend(j$Require, require(path.join(__dirname,"../../src/console/requireConsole.js")));
getSourceFiles();
global.j$ = j$Require.core(j$Require);
j$Require.console(j$Require, j$);
})();

View File

@@ -13,7 +13,7 @@ describe("New HtmlReporter", function() {
reporter.initialize();
// Main top-level elements
expect(container.querySelector("div.html-reporter")).toBeTruthy();
expect(container.querySelector("div.jasmine_html-reporter")).toBeTruthy();
expect(container.querySelector("div.banner")).toBeTruthy();
expect(container.querySelector("div.alert")).toBeTruthy();
expect(container.querySelector("div.results")).toBeTruthy();
@@ -23,18 +23,36 @@ describe("New HtmlReporter", function() {
// title banner
var banner = container.querySelector(".banner");
var title = banner.querySelector(".title");
expect(title.innerHTML).toMatch(/Jasmine/);
var title = banner.querySelector("a.title");
expect(title.getAttribute('href')).toEqual('http://jasmine.github.io/');
expect(title.getAttribute('target')).toEqual('_blank');
var version = banner.querySelector(".version"),
versionText = 'textContent' in version ? version.textContent : version.innerText;
expect(versionText).toEqual(j$.version);
});
it("builds a single reporter even if initialized multiple times", function() {
var env = new j$.Env(),
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.initialize();
reporter.initialize();
expect(container.querySelectorAll("div.jasmine_html-reporter").length).toEqual(1);
});
it("starts the timer when jasmine begins", function() {
var env = new jasmine.Env(),
startTimerSpy = jasmine.createSpy("start-timer-spy"),
reporter = new jasmine.HtmlReporter({
reporter = new j$.HtmlReporter({
env: env,
createElement: function() { return document.createElement.apply(document, arguments); },
timer: { start: startTimerSpy }
@@ -46,6 +64,36 @@ describe("New HtmlReporter", function() {
});
describe("when a spec is done", function() {
it("logs errors to the console and prints a special symbol if it is an empty spec", function() {
if (!window.console) {
window.console = { error: function(){} };
}
var env = new j$.Env(),
container = document.createElement('div'),
getContainer = function() {return container;},
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
spyOn(console, 'error');
reporter.initialize();
reporter.specDone({
status: "passed",
fullName: 'Some Name',
passedExpectations: [],
failedExpectations: []
});
expect(console.error).toHaveBeenCalledWith("Spec \'Some Name\' has no expectations.");
var specEl = container.querySelector('.symbol-summary li');
expect(specEl.getAttribute("class")).toEqual("empty");
});
it("reports the status symbol of a disabled spec", function() {
var env = new j$.Env(),
container = document.createElement("div"),
@@ -58,7 +106,7 @@ describe("New HtmlReporter", function() {
});
reporter.initialize();
reporter.specDone({id: 789, status: "disabled", fullName: "symbols should have titles"});
reporter.specDone({id: 789, status: "disabled", fullName: "symbols should have titles", passedExpectations: [], failedExpectations: []});
var specEl = container.querySelector('.symbol-summary li');
expect(specEl.getAttribute("class")).toEqual("disabled");
@@ -78,7 +126,7 @@ describe("New HtmlReporter", function() {
});
reporter.initialize();
reporter.specDone({id: 789, status: "pending"});
reporter.specDone({id: 789, status: "pending", passedExpectations: [], failedExpectations: []});
var specEl = container.querySelector('.symbol-summary li');
expect(specEl.getAttribute("class")).toEqual("pending");
@@ -97,7 +145,7 @@ describe("New HtmlReporter", function() {
});
reporter.initialize();
reporter.specDone({id: 123, status: "passed"});
reporter.specDone({id: 123, status: "passed", passedExpectations: [{passed: true}], failedExpectations: []});
var statuses = container.querySelector(".symbol-summary");
var specEl = statuses.querySelector("li");
@@ -121,7 +169,8 @@ describe("New HtmlReporter", function() {
reporter.specDone({
id: 345,
status: "failed",
failedExpectations: []
failedExpectations: [],
passedExpectations: []
});
var specEl = container.querySelector(".symbol-summary li");
@@ -131,6 +180,44 @@ describe("New HtmlReporter", function() {
});
describe("when Jasmine is done", function() {
it("adds EMPTY to the link title of specs that have no expectations", function() {
if (!window.console) {
window.console = { error: function(){} };
}
var env = new j$.Env(),
container = document.createElement('div'),
getContainer = function() {return container;},
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
spyOn(console, 'error');
reporter.initialize();
reporter.jasmineStarted({});
reporter.suiteStarted({id: 1});
reporter.specStarted({id: 1, status: 'passed', passedExpectations: [], failedExpectations: []});
reporter.specDone({
id: 1,
status: 'passed',
description: 'Spec Description',
passedExpectations: [],
failedExpectations: []
});
reporter.suiteDone({id: 1});
reporter.jasmineDone({});
var summary = container.querySelector('.summary');
var suite = summary.childNodes[0];
var specs = suite.childNodes[1];
var spec = specs.childNodes[0];
var specLink = spec.childNodes[0];
expect(specLink.innerHTML).toMatch(/SPEC HAS NO EXPECTATIONS/);
});
it("reports the run time", function() {
var env = new j$.Env(),
container = document.createElement("div"),
@@ -178,7 +265,9 @@ describe("New HtmlReporter", function() {
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "passed"
status: "passed",
failedExpectations: [],
passedExpectations: [{passed: true}]
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
@@ -193,7 +282,9 @@ describe("New HtmlReporter", function() {
id: 124,
description: "with another spec",
fullName: "A Suite inner suite with another spec",
status: "passed"
status: "passed",
failedExpectations: [],
passedExpectations: [{passed: true}]
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
@@ -205,7 +296,8 @@ describe("New HtmlReporter", function() {
description: "with a failing spec",
fullName: "A Suite inner with a failing spec",
status: "failed",
failedExpectations: []
failedExpectations: [{}],
passedExpectations: []
};
reporter.specStarted(specResult);
reporter.specDone(specResult);
@@ -321,12 +413,33 @@ describe("New HtmlReporter", function() {
});
});
it("shows a message if no specs are run", function(){
var env, container, reporter;
env = new j$.Env();
container = document.createElement("div");
var getContainer = function() { return container; },
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.jasmineDone({});
var alertBars = container.querySelectorAll(".alert .bar");
expect(alertBars[0].getAttribute('class')).toMatch(/skipped/);
expect(alertBars[0].innerHTML).toMatch(/No specs found/);
});
describe("and all specs pass", function() {
var env, container, reporter;
beforeEach(function() {
env = new j$.Env();
container = document.createElement("div");
getContainer = function() { return container; },
var getContainer = function() { return container; },
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
@@ -335,18 +448,22 @@ describe("New HtmlReporter", function() {
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.jasmineStarted({ totalSpecsDefined: 2 });
reporter.specDone({
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "passed"
status: "passed",
passedExpectations: [{passed: true}],
failedExpectations: []
});
reporter.specDone({
id: 124,
description: "with another spec",
fullName: "A Suite inner suite with another spec",
status: "passed"
status: "passed",
passedExpectations: [{passed: true}],
failedExpectations: []
});
reporter.jasmineDone({});
});
@@ -377,21 +494,23 @@ describe("New HtmlReporter", function() {
beforeEach(function() {
env = new j$.Env();
container = document.createElement("div");
getContainer = function() { return container; },
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
var getContainer = function() { return container; };
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.jasmineStarted({ totalSpecsDefined: 1 });
reporter.specDone({
id: 123,
description: "with a spec",
fullName: "A Suite with a spec",
status: "pending"
status: "pending",
passedExpectations: [],
failedExpectations: []
});
reporter.jasmineDone({});
});
@@ -414,19 +533,19 @@ describe("New HtmlReporter", function() {
beforeEach(function() {
env = new j$.Env();
container = document.createElement("div"),
getContainer = function() { return container; },
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
container = document.createElement("div");
var getContainer = function() { return container; }
reporter = new j$.HtmlReporter({
env: env,
getContainer: getContainer,
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
});
reporter.initialize();
reporter.jasmineStarted({});
reporter.jasmineStarted({ totalSpecsDefined: 1 });
var passingResult = {id: 123, status: "passed"};
var passingResult = {id: 123, status: "passed", passedExpectations: [{passed: true}], failedExpectations: []};
reporter.specStarted(passingResult);
reporter.specDone(passingResult);
@@ -435,6 +554,7 @@ describe("New HtmlReporter", function() {
status: "failed",
description: "a failing spec",
fullName: "a suite with a failing spec",
passedExpectations: [],
failedExpectations: [
{
message: "a failure message",
@@ -488,7 +608,7 @@ describe("New HtmlReporter", function() {
});
it("sets the reporter to 'Failures List' mode", function() {
var reporterNode = container.querySelector(".html-reporter");
var reporterNode = container.querySelector(".jasmine_html-reporter");
expect(reporterNode.getAttribute("class")).toMatch("failure-list");
});
});

View File

@@ -3,7 +3,7 @@ describe("j$.pp (HTML Dependent)", function () {
var sampleNode = document.createElement('div');
sampleNode.innerHTML = 'foo<b>bar</b>';
expect(j$.pp(sampleNode)).toEqual("HTMLNode");
expect(j$.pp({foo: sampleNode})).toEqual("{ foo : HTMLNode }");
expect(j$.pp({foo: sampleNode})).toEqual("{ foo: HTMLNode }");
});
it("should print Firefox's wrapped native objects correctly", function() {

View File

@@ -1,187 +0,0 @@
var fs = require('fs');
var util = require('util');
var path = require('path');
// boot code for jasmine
var jasmineRequire = require('../lib/jasmine-core/jasmine.js');
var jasmine = jasmineRequire.core(jasmineRequire);
var consoleFns = require('../lib/console/console.js');
extend(jasmineRequire, consoleFns);
jasmineRequire.console(jasmineRequire, jasmine);
var env = jasmine.getEnv();
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
extend(global, jasmineInterface);
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
jasmine.clock = function() {
return env.clock;
};
// Jasmine "runner"
function executeSpecs(specs, done, isVerbose, showColors) {
global.jasmine = jasmine;
for (var i = 0; i < specs.length; i++) {
var filename = specs[i];
require(filename.replace(/\.\w+$/, ""));
}
var env = jasmine.getEnv();
var consoleReporter = new jasmine.ConsoleReporter({
print: util.print,
onComplete: done,
showColors: showColors,
timer: new jasmine.Timer()
});
env.addReporter(consoleReporter);
env.execute();
}
function getFiles(dir, matcher) {
var allFiles = [];
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
allFiles.push(dir);
} else {
var files = fs.readdirSync(dir);
for (var i = 0, len = files.length; i < len; ++i) {
var filename = dir + '/' + files[i];
if (fs.statSync(filename).isFile() && filename.match(matcher)) {
allFiles.push(filename);
} else if (fs.statSync(filename).isDirectory()) {
var subfiles = getFiles(filename);
subfiles.forEach(function(result) {
allFiles.push(result);
});
}
}
}
return allFiles;
}
function getSpecFiles(dir) {
return getFiles(dir, new RegExp("Spec.js$"));
}
var j$require = (function() {
var exported = {},
j$req;
global.getJasmineRequireObj = getJasmineRequireObj;
j$req = require(__dirname + "/../src/core/requireCore.js");
extend(j$req, require(__dirname + "/../src/console/requireConsole.js"));
var srcFiles = getFiles(__dirname + "/../src/core");
srcFiles.push(__dirname + "/../src/version.js");
srcFiles.push(__dirname + "/../src/console/ConsoleReporter.js");
for (var i = 0; i < srcFiles.length; i++) {
require(srcFiles[i]);
}
extend(j$req, exported);
delete global.getJasmineRequireObj;
return j$req;
function getJasmineRequireObj() {
return exported;
}
}());
j$ = j$require.core(j$require);
j$require.console(j$require, j$);
// options from command line
var isVerbose = false;
var showColors = true;
var perfSuite = false;
process.argv.forEach(function(arg) {
switch (arg) {
case '--color':
showColors = true;
break;
case '--noColor':
showColors = false;
break;
case '--verbose':
isVerbose = true;
break;
case '--perf':
perfSuite = true;
break;
}
});
specs = [];
if (perfSuite) {
specs = getFiles(__dirname + '/performance', new RegExp("test.js$"));
} else {
var consoleSpecs = getSpecFiles(__dirname + "/console"),
coreSpecs = getSpecFiles(__dirname + "/core"),
specs = consoleSpecs.concat(coreSpecs);
}
executeSpecs(specs, function(passed) {
if (passed) {
process.exit(0);
} else {
process.exit(1);
}
}, isVerbose, showColors);

View File

@@ -0,0 +1,36 @@
describe('Printing a big object', function(){
var bigObject;
function rand(upper) {
return Math.round(upper * Math.random());
}
function generateObject(level) {
var object = {};
for (var i = 0; i < 50; i++) {
var decide = rand(2);
switch (decide) {
case 0:
object["cycle" + i] = object;
break;
case 1:
object["number" + i] = rand(100);
break;
case 2:
if (level < 3) {
object["nesting" + i] = generateObject(level + 1);
}
break;
}
}
return object;
}
it('takes a resonable amount of time', function(){
bigObject = generateObject(0);
expect(j$.pp(bigObject)).toMatch(/cycle/);
});
});

View File

@@ -1,124 +0,0 @@
// Jasmine boot.js for browser runners - exposes external/global interface, builds the Jasmine environment and executes it.
(function() {
window.jasmine = jasmineRequire.core(jasmineRequire);
jasmineRequire.html(jasmine);
var env = jasmine.getEnv();
var jasmineInterface = {
describe: function(description, specDefinitions) {
return env.describe(description, specDefinitions);
},
xdescribe: function(description, specDefinitions) {
return env.xdescribe(description, specDefinitions);
},
it: function(desc, func) {
return env.it(desc, func);
},
xit: function(desc, func) {
return env.xit(desc, func);
},
beforeEach: function(beforeEachFunction) {
return env.beforeEach(beforeEachFunction);
},
afterEach: function(afterEachFunction) {
return env.afterEach(afterEachFunction);
},
expect: function(actual) {
return env.expect(actual);
},
pending: function() {
return env.pending();
},
spyOn: function(obj, methodName) {
return env.spyOn(obj, methodName);
},
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})
};
if (typeof window == "undefined" && typeof exports == "object") {
extend(exports, jasmineInterface);
} else {
extend(window, jasmineInterface);
}
jasmine.addCustomEqualityTester = function(tester) {
env.addCustomEqualityTester(tester);
};
jasmine.addMatchers = function(matchers) {
return env.addMatchers(matchers);
};
jasmine.clock = function() {
return env.clock;
};
var queryString = new jasmine.QueryString({
getWindowLocation: function() { return window.location; }
});
// TODO: move all of catching to raise so we don't break our brains
var catchingExceptions = queryString.getParam("catch");
env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
var htmlReporter = new jasmine.HtmlReporter({
env: env,
onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
getContainer: function() { return document.body; },
createElement: function() { return document.createElement.apply(document, arguments); },
createTextNode: function() { return document.createTextNode.apply(document, arguments); },
timer: new jasmine.Timer()
});
env.addReporter(jasmineInterface.jsApiReporter);
env.addReporter(htmlReporter);
var specFilter = new jasmine.HtmlSpecFilter({
filterString: function() { return queryString.getParam("spec"); }
});
env.specFilter = function(spec) {
return specFilter.matches(spec.getFullName());
};
window.setTimeout = window.setTimeout;
window.setInterval = window.setInterval;
window.clearTimeout = window.clearTimeout;
window.clearInterval = window.clearInterval;
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
htmlReporter.initialize();
// By the time onload is called, jasmineRequire will be redefined to point
// to the Jasmine source files (and not jasmine.js). So re-require
window.j$ = jasmineRequire.core(jasmineRequire);
jasmineRequire.html(j$);
jasmineRequire.console(jasmineRequire, j$);
env.execute();
};
function extend(destination, source) {
for (var property in source) destination[property] = source[property];
return destination;
}
}());

View File

@@ -0,0 +1,9 @@
{
"spec_dir": "spec",
"spec_files": [
"performance/performance_test.js"
],
"helper_files": [
"helpers/nodeDefineJasmineUnderTest.js"
]
}

View File

@@ -2,13 +2,8 @@ src_dir:
- 'src'
src_files:
- '**/*.js'
boot_dir: 'spec/support'
boot_files:
- 'dev_boot.js'
helpers:
- 'helpers/**/*.js'
spec_files:
- 'performance/performance_test.js'
spec_dir: spec

10
spec/support/jasmine.json Normal file
View File

@@ -0,0 +1,10 @@
{
"spec_dir": "spec",
"spec_files": [
"core/**/*.js",
"console/**/*.js"
],
"helpers": [
"helpers/nodeDefineJasmineUnderTest.js"
]
}

View File

@@ -15,11 +15,9 @@ src_files:
- 'html/**.js'
- '**/*.js'
stylesheets:
boot_dir: 'spec/support'
boot_files:
- 'dev_boot.js'
helpers:
- 'helpers/**/*.js'
- 'helpers/BrowserFlags.js'
- 'helpers/defineJasmineUnderTest.js'
spec_files:
- '**/*[Ss]pec.js'
spec_dir: spec

View File

@@ -25,7 +25,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
specCount = 0;
failureCount = 0;
pendingCount = 0;
print("Started");
print('Started');
printNewline();
timer.start();
};
@@ -36,19 +36,24 @@ getJasmineRequireObj().ConsoleReporter = function() {
specFailureDetails(failedSpecs[i]);
}
printNewline();
var specCounts = specCount + " " + plural("spec", specCount) + ", " +
failureCount + " " + plural("failure", failureCount);
if(specCount > 0) {
printNewline();
if (pendingCount) {
specCounts += ", " + pendingCount + " pending " + plural("spec", pendingCount);
var specCounts = specCount + ' ' + plural('spec', specCount) + ', ' +
failureCount + ' ' + plural('failure', failureCount);
if (pendingCount) {
specCounts += ', ' + pendingCount + ' pending ' + plural('spec', pendingCount);
}
print(specCounts);
} else {
print('No specs found');
}
print(specCounts);
printNewline();
var seconds = timer.elapsed() / 1000;
print("Finished in " + seconds + " " + plural("second", seconds));
print('Finished in ' + seconds + ' ' + plural('second', seconds));
printNewline();
@@ -58,28 +63,28 @@ getJasmineRequireObj().ConsoleReporter = function() {
this.specDone = function(result) {
specCount++;
if (result.status == "pending") {
if (result.status == 'pending') {
pendingCount++;
print(colored("yellow", "*"));
print(colored('yellow', '*'));
return;
}
if (result.status == "passed") {
print(colored("green", '.'));
if (result.status == 'passed') {
print(colored('green', '.'));
return;
}
if (result.status == "failed") {
if (result.status == 'failed') {
failureCount++;
failedSpecs.push(result);
print(colored("red", 'F'));
print(colored('red', 'F'));
}
};
return this;
function printNewline() {
print("\n");
print('\n');
}
function colored(color, str) {
@@ -87,7 +92,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function plural(str, count) {
return count == 1 ? str : str + "s";
return count == 1 ? str : str + 's';
}
function repeat(thing, times) {
@@ -99,12 +104,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
}
function indent(str, spaces) {
var lines = (str || '').split("\n");
var lines = (str || '').split('\n');
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(" ", spaces).join("") + lines[i]);
newArr.push(repeat(' ', spaces).join('') + lines[i]);
}
return newArr.join("\n");
return newArr.join('\n');
}
function specFailureDetails(result) {
@@ -114,6 +119,7 @@ getJasmineRequireObj().ConsoleReporter = function() {
for (var i = 0; i < result.failedExpectations.length; i++) {
var failedExpectation = result.failedExpectations[i];
printNewline();
print(indent(failedExpectation.message, 2));
print(indent(failedExpectation.stack, 2));
}

View File

@@ -1,5 +1,5 @@
function getJasmineRequireObj() {
if (typeof module !== "undefined" && module.exports) {
if (typeof module !== 'undefined' && module.exports) {
return exports;
} else {
window.jasmineRequire = window.jasmineRequire || {};

View File

@@ -29,7 +29,7 @@ getJasmineRequireObj().Any = function() {
};
Any.prototype.jasmineToString = function() {
return '<jasmine.any(' + this.expectedClass + ')>';
return '<jasmine.any(' + this.expectedObject + ')>';
};
return Any;

View File

@@ -1,5 +1,5 @@
getJasmineRequireObj().Clock = function() {
function Clock(global, delayedFunctionScheduler) {
function Clock(global, delayedFunctionScheduler, mockDate) {
var self = this,
realTimingFunctions = {
setTimeout: global.setTimeout,
@@ -16,23 +16,32 @@ getJasmineRequireObj().Clock = function() {
installed = false,
timer;
self.install = function() {
replace(global, fakeTimingFunctions);
timer = fakeTimingFunctions;
installed = true;
return self;
};
self.uninstall = function() {
delayedFunctionScheduler.reset();
mockDate.uninstall();
replace(global, realTimingFunctions);
timer = realTimingFunctions;
installed = false;
};
self.mockDate = function(initialDate) {
mockDate.install(initialDate);
};
self.setTimeout = function(fn, delay, params) {
if (legacyIE()) {
if (arguments.length > 2) {
throw new Error("IE < 9 cannot support extra params to setTimeout without a polyfill");
throw new Error('IE < 9 cannot support extra params to setTimeout without a polyfill');
}
return timer.setTimeout(fn, delay);
}
@@ -42,7 +51,7 @@ getJasmineRequireObj().Clock = function() {
self.setInterval = function(fn, delay, params) {
if (legacyIE()) {
if (arguments.length > 2) {
throw new Error("IE < 9 cannot support extra params to setInterval without a polyfill");
throw new Error('IE < 9 cannot support extra params to setInterval without a polyfill');
}
return timer.setInterval(fn, delay);
}
@@ -59,9 +68,10 @@ getJasmineRequireObj().Clock = function() {
self.tick = function(millis) {
if (installed) {
mockDate.tick(millis);
delayedFunctionScheduler.tick(millis);
} else {
throw new Error("Mock clock is not installed, use jasmine.clock().install()");
throw new Error('Mock clock is not installed, use jasmine.clock().install()');
}
};
@@ -95,7 +105,7 @@ getJasmineRequireObj().Clock = function() {
}
function argSlice(argsObj, n) {
return Array.prototype.slice.call(argsObj, 2);
return Array.prototype.slice.call(argsObj, n);
}
}

View File

@@ -11,7 +11,7 @@ getJasmineRequireObj().Env = function(j$) {
var realSetTimeout = j$.getGlobal().setTimeout;
var realClearTimeout = j$.getGlobal().clearTimeout;
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
var runnableLookupTable = {};
@@ -21,12 +21,12 @@ getJasmineRequireObj().Env = function(j$) {
var currentSuite = null;
var reporter = new j$.ReportDispatcher([
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
'jasmineStarted',
'jasmineDone',
'suiteStarted',
'suiteDone',
'specStarted',
'specDone'
]);
this.specFilter = function() {
@@ -136,6 +136,7 @@ getJasmineRequireObj().Env = function(j$) {
var queueRunnerFactory = function(options) {
options.catchException = catchException;
options.clearStack = options.clearStack || clearStack;
options.timer = {setTimeout: realSetTimeout, clearTimeout: realClearTimeout};
new j$.QueueRunner(options).execute();
};
@@ -180,7 +181,7 @@ getJasmineRequireObj().Env = function(j$) {
this.spyOn = function(obj, methodName) {
if (j$.util.isUndefined(obj)) {
throw new Error("spyOn could not find an object to spy upon for " + methodName + "()");
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
}
if (j$.util.isUndefined(obj[methodName])) {
@@ -238,7 +239,7 @@ getJasmineRequireObj().Env = function(j$) {
}
if (declarationError) {
this.it("encountered a declaration exception", function() {
this.it('encountered a declaration exception', function() {
throw declarationError;
});
}
@@ -271,8 +272,7 @@ getJasmineRequireObj().Env = function(j$) {
description: description,
expectationResultFactory: expectationResultFactory,
queueRunnerFactory: queueRunnerFactory,
fn: fn,
timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}
fn: fn
});
runnableLookupTable[spec.id] = spec;
@@ -317,6 +317,10 @@ getJasmineRequireObj().Env = function(j$) {
};
this.expect = function(actual) {
if (!currentSpec) {
throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
}
return currentSpec.expect(actual);
};

View File

@@ -1,16 +1,20 @@
getJasmineRequireObj().ExceptionFormatter = function() {
function ExceptionFormatter() {
this.message = function(error) {
var message = error.name +
': ' +
error.message;
var message = '';
if (error.name && error.message) {
message += error.name + ': ' + error.message;
} else {
message += error.toString() + ' thrown';
}
if (error.fileName || error.sourceURL) {
message += " in " + (error.fileName || error.sourceURL);
message += ' in ' + (error.fileName || error.sourceURL);
}
if (error.line || error.lineNumber) {
message += " (line " + (error.line || error.lineNumber) + ")";
message += ' (line ' + (error.line || error.lineNumber) + ')';
}
return message;

View File

@@ -18,7 +18,7 @@ getJasmineRequireObj().Expectation = function() {
return function() {
var args = Array.prototype.slice.call(arguments, 0),
expected = args.slice(0),
message = "";
message = '';
args.unshift(this.actual);
@@ -43,7 +43,11 @@ getJasmineRequireObj().Expectation = function() {
args.unshift(name);
message = this.util.buildFailureMessage.apply(null, args);
} else {
message = result.message;
if (Object.prototype.toString.apply(result.message) === '[object Function]') {
message = result.message();
} else {
message = result.message;
}
}
}

View File

@@ -15,18 +15,18 @@ getJasmineRequireObj().buildExpectationResult = function() {
function message() {
if (options.passed) {
return "Passed.";
return 'Passed.';
} else if (options.message) {
return options.message;
} else if (options.error) {
return messageFormatter(options.error);
}
return "";
return '';
}
function stack() {
if (options.passed) {
return "";
return '';
}
var error = options.error;

View File

@@ -7,7 +7,7 @@ getJasmineRequireObj().JsApiReporter = function() {
function JsApiReporter(options) {
var timer = options.timer || noopTimer,
status = "loaded";
status = 'loaded';
this.started = false;
this.finished = false;

81
src/core/MockDate.js Normal file
View File

@@ -0,0 +1,81 @@
getJasmineRequireObj().MockDate = function() {
function MockDate(global) {
var self = this;
var currentTime = 0;
if (!global || !global.Date) {
self.install = function() {};
self.tick = function() {};
self.uninstall = function() {};
return self;
}
var GlobalDate = global.Date;
self.install = function(mockDate) {
if (mockDate instanceof GlobalDate) {
currentTime = mockDate.getTime();
} else {
currentTime = new GlobalDate().getTime();
}
global.Date = FakeDate;
};
self.tick = function(millis) {
millis = millis || 0;
currentTime = currentTime + millis;
};
self.uninstall = function() {
currentTime = 0;
global.Date = GlobalDate;
};
createDateProperties();
return self;
function FakeDate() {
switch(arguments.length) {
case 0:
return new GlobalDate(currentTime);
case 1:
return new GlobalDate(arguments[0]);
case 2:
return new GlobalDate(arguments[0], arguments[1]);
case 3:
return new GlobalDate(arguments[0], arguments[1], arguments[2]);
case 4:
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3]);
case 5:
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
arguments[4]);
case 6:
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
arguments[4], arguments[5]);
case 7:
return new GlobalDate(arguments[0], arguments[1], arguments[2], arguments[3],
arguments[4], arguments[5], arguments[6]);
}
}
function createDateProperties() {
FakeDate.now = function() {
if (GlobalDate.now) {
return currentTime;
} else {
throw new Error('Browser does not support Date.now()');
}
};
FakeDate.toSource = GlobalDate.toSource;
FakeDate.toString = GlobalDate.toString;
FakeDate.parse = GlobalDate.parse;
FakeDate.UTC = GlobalDate.UTC;
}
}
return MockDate;
};

View File

@@ -5,7 +5,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
}
ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
if (typeof(this.sample) !== "object") { throw new Error("You must provide an object to objectContaining, not '"+this.sample+"'."); }
if (typeof(this.sample) !== 'object') { throw new Error('You must provide an object to objectContaining, not \''+this.sample+'\'.'); }
mismatchKeys = mismatchKeys || [];
mismatchValues = mismatchValues || [];
@@ -16,10 +16,10 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
for (var property in this.sample) {
if (!hasKey(other, property) && hasKey(this.sample, property)) {
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
mismatchKeys.push('expected has key \'' + property + '\', but missing from actual.');
}
else if (!j$.matchersUtil.equals(this.sample[property], other[property])) {
mismatchValues.push("'" + property + "' was '" + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + "' in actual, but was '" + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in expected.");
else if (!j$.matchersUtil.equals(other[property], this.sample[property])) {
mismatchValues.push('\'' + property + '\' was \'' + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + '\' in actual, but was \'' + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + '\' in expected.');
}
}
@@ -27,7 +27,7 @@ getJasmineRequireObj().ObjectContaining = function(j$) {
};
ObjectContaining.prototype.jasmineToString = function() {
return "<jasmine.objectContaining(" + j$.pp(this.sample) + ")>";
return '<jasmine.objectContaining(' + j$.pp(this.sample) + ')>';
};
return ObjectContaining;

View File

@@ -2,6 +2,7 @@ getJasmineRequireObj().pp = function(j$) {
function PrettyPrinter() {
this.ppNestLevel_ = 0;
this.seen = [];
}
PrettyPrinter.prototype.format = function(value) {
@@ -11,6 +12,8 @@ getJasmineRequireObj().pp = function(j$) {
this.emitScalar('undefined');
} else if (value === null) {
this.emitScalar('null');
} else if (value === 0 && 1/value === -Infinity) {
this.emitScalar('-0');
} else if (value === j$.getGlobal()) {
this.emitScalar('<global>');
} else if (value.jasmineToString) {
@@ -18,7 +21,7 @@ getJasmineRequireObj().pp = function(j$) {
} else if (typeof value === 'string') {
this.emitString(value);
} else if (j$.isSpy(value)) {
this.emitScalar("spy on " + value.and.identity());
this.emitScalar('spy on ' + value.and.identity());
} else if (value instanceof RegExp) {
this.emitScalar(value.toString());
} else if (typeof value === 'function') {
@@ -27,16 +30,16 @@ getJasmineRequireObj().pp = function(j$) {
this.emitScalar('HTMLNode');
} else if (value instanceof Date) {
this.emitScalar('Date(' + value + ')');
} else if (value.__Jasmine_been_here_before__) {
} else if (j$.util.arrayContains(this.seen, value)) {
this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
value.__Jasmine_been_here_before__ = true;
this.seen.push(value);
if (j$.isArray_(value)) {
this.emitArray(value);
} else {
this.emitObject(value);
}
delete value.__Jasmine_been_here_before__;
this.seen.pop();
} else {
this.emitScalar(value.toString());
}
@@ -47,8 +50,7 @@ getJasmineRequireObj().pp = function(j$) {
PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) {
if (!obj.hasOwnProperty(property)) { continue; }
if (property == '__Jasmine_been_here_before__') { continue; }
if (!Object.prototype.hasOwnProperty.call(obj, property)) { continue; }
fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&
obj.__lookupGetter__(property) !== null) : false);
}
@@ -72,28 +74,31 @@ getJasmineRequireObj().pp = function(j$) {
};
StringPrettyPrinter.prototype.emitString = function(value) {
this.append("'" + value + "'");
this.append('\'' + value + '\'');
};
StringPrettyPrinter.prototype.emitArray = function(array) {
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
this.append("Array");
this.append('Array');
return;
}
var length = Math.min(array.length, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH);
this.append('[ ');
for (var i = 0; i < array.length; i++) {
for (var i = 0; i < length; i++) {
if (i > 0) {
this.append(', ');
}
this.format(array[i]);
}
if(array.length > length){
this.append(', ...');
}
this.append(' ]');
};
StringPrettyPrinter.prototype.emitObject = function(obj) {
if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
this.append("Object");
this.append('Object');
return;
}
@@ -109,7 +114,7 @@ getJasmineRequireObj().pp = function(j$) {
}
self.append(property);
self.append(' : ');
self.append(': ');
if (isGetter) {
self.append('<getter>');
} else {

View File

@@ -1,4 +1,14 @@
getJasmineRequireObj().QueueRunner = function() {
getJasmineRequireObj().QueueRunner = function(j$) {
function once(fn) {
var called = false;
return function() {
if (!called) {
called = true;
fn();
}
};
}
function QueueRunner(attrs) {
this.fns = attrs.fns || [];
@@ -6,7 +16,9 @@ getJasmineRequireObj().QueueRunner = function() {
this.clearStack = attrs.clearStack || function(fn) {fn();};
this.onException = attrs.onException || function() {};
this.catchException = attrs.catchException || function() { return true; };
this.enforceTimeout = attrs.enforceTimeout || function() { return false; };
this.userContext = {};
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
}
QueueRunner.prototype.execute = function() {
@@ -42,7 +54,21 @@ getJasmineRequireObj().QueueRunner = function() {
}
function attemptAsync(fn) {
var next = function () { self.run(fns, iterativeIndex + 1); };
var clearTimeout = function () {
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]);
},
next = once(function () {
clearTimeout(timeoutId);
self.run(fns, iterativeIndex + 1);
}),
timeoutId;
if (self.enforceTimeout()) {
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
self.onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
next();
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
}
try {
fn.call(self.userContext, next);

View File

@@ -14,8 +14,6 @@ getJasmineRequireObj().Spec = function(j$) {
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
this.timer = attrs.timer || {setTimeout: setTimeout, clearTimeout: clearTimeout};
if (!this.fn) {
this.pend();
}
@@ -24,15 +22,18 @@ getJasmineRequireObj().Spec = function(j$) {
id: this.id,
description: this.description,
fullName: this.getFullName(),
failedExpectations: []
failedExpectations: [],
passedExpectations: []
};
}
Spec.prototype.addExpectationResult = function(passed, data) {
var expectationResult = this.expectationResultFactory(data);
if (passed) {
return;
this.result.passedExpectations.push(expectationResult);
} else {
this.result.failedExpectations.push(expectationResult);
}
this.result.failedExpectations.push(this.expectationResultFactory(data));
};
Spec.prototype.expect = function(actual) {
@@ -40,8 +41,7 @@ getJasmineRequireObj().Spec = function(j$) {
};
Spec.prototype.execute = function(onComplete) {
var self = this,
timeout;
var self = this;
this.onStart(this);
@@ -50,52 +50,26 @@ getJasmineRequireObj().Spec = function(j$) {
return;
}
function timeoutable(fn) {
return function(done) {
timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
done();
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
var callDone = function() {
clearTimeoutable();
done();
};
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
};
}
function clearTimeoutable() {
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
timeout = void 0;
}
var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns()),
allTimeoutableFns = [];
for (var i = 0; i < allFns.length; i++) {
var fn = allFns[i];
allTimeoutableFns.push(fn.length > 0 ? timeoutable(fn) : fn);
}
var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns());
this.queueRunnerFactory({
fns: allTimeoutableFns,
fns: allFns,
onException: onException,
onComplete: complete
onComplete: complete,
enforceTimeout: function() { return true; }
});
function onException(e) {
clearTimeoutable();
if (Spec.isPendingSpecException(e)) {
self.pend();
return;
}
self.addExpectationResult(false, {
matcherName: "",
matcherName: '',
passed: false,
expected: "",
actual: "",
expected: '',
actual: '',
error: e
});
}
@@ -138,15 +112,15 @@ getJasmineRequireObj().Spec = function(j$) {
return this.getSpecName(this);
};
Spec.pendingSpecExceptionMessage = "=> marked Pending";
Spec.pendingSpecExceptionMessage = '=> marked Pending';
Spec.isPendingSpecException = function(e) {
return e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1;
return !!(e && e.toString && e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1);
};
return Spec;
};
if (typeof window == void 0 && typeof exports == "object") {
if (typeof window == void 0 && typeof exports == 'object') {
exports.Spec = jasmineRequire.Spec;
}

Some files were not shown because too many files have changed in this diff Show More