Compare commits

...

49 Commits

Author SHA1 Message Date
Gregg Van Hove and Tim Jarratt
18e1ab93ea Release for rc3 2013-10-03 09:55:36 -07:00
Davis W. Frank
0c4113e167 Quick fix - Spec needs j$ at execute time 2013-10-02 22:45:33 -07:00
Gregg Van Hove and Tim Jarratt
a563e67015 Move selenium_runner.yml to spec/javascripts/support
- The selenium runner gem should support configurable path as the main
  gem does so we don't need to do this. This workaround is kind of
  gross.
2013-10-02 16:48:13 -07:00
Gregg Van Hove and Tim Jarratt
fab489851e Fix paths for node specs
[#58126010]
2013-10-02 16:41:07 -07:00
Gregg Van Hove and Tim Jarratt
1c19b8e38a Move spec files back out of spec/javascripts
- Jasmine gem allows us to specify a path to jasmine.yml via ENV

[finish #58126010]
2013-10-02 16:32:35 -07:00
Gregg Van Hove and Tim Jarratt
fc258b3d36 Make it easy to copy the title of failing specs
[finish #58121820]
2013-10-02 15:14:41 -07:00
Gregg Van Hove and Tim Jarratt
51dd66a4cc Turn the exceptions spec back on, it still works 2013-10-02 10:24:24 -07:00
Gregg Van Hove and Tim Jarratt
37a3135d6a cleanup whitespace 2013-10-01 16:30:17 -07:00
Gregg Van Hove and Tim Jarratt
cb8ba74937 Don't add periods to the full name of a spec
- Breaks links for spec filters
- Looks strange if users add their own

[fix #58043244] fix #427
2013-10-01 16:28:33 -07:00
Gregg Van Hove and Tim Jarratt
70fb0f0ed5 Update Firefox pretty print test
At some point, firefox changed the exception message.
2013-09-30 15:43:44 -07:00
Sheel Choksi
15889494c5 Update node suites to not rely on previous accidental global j$ and create its own 2013-09-29 14:59:58 -07:00
Sheel Choksi
da33c7823e Add missing var in front of j$ to avoid polluting global namespace
Users should only have 'jasmine' in global namespace, j$ should be
fully internal unless developing for jasmine

As brought up by Morten Maxild
2013-09-29 14:46:55 -07:00
Gregg Van Hove
04e1d8420e Ensure tunnel_identifier is properly quoted for travis builds 2013-09-25 14:24:57 -07:00
Gregg Van Hove and Rajan Agaskar
19b2472761 Really make tunnel_identifier a string.
yay.
2013-09-25 11:24:41 -07:00
Gregg Van Hove and Rajan Agaskar
1fc614ad19 Tunnel identifier must be a string
- Travis provides a float.
2013-09-25 11:03:45 -07:00
Gregg Van Hove and Rajan Agaskar
84692f545c Use jasmine_selenium_runner to run specs via Sauce 2013-09-25 10:45:53 -07:00
Gregg Van Hove and Rajan Agaskar
5017d1a4f1 Make rake jasmine:ci run specs correctly.
- Will replace rake core_specs.
- Remove obsolete dependencies & files -- most of these were for build tasks we
  are no longer using. Notably, rspec and spec_helper were deleted.
2013-09-25 10:11:02 -07:00
Gregg Van Hove and Rajan Agaskar
963cd5e850 Make rake dev dependency 2013-09-24 11:31:21 -07:00
Gregg Van Hove and Rajan Agaskar
527394068e Update specs to use new HTTP Runner interface. 2013-09-24 11:30:50 -07:00
Gregg Van Hove and Rajan Agaskar
5e279a1393 Remove unnecessary Jasmine.configure. 2013-09-20 11:16:40 -07:00
Gregg Van Hove and Rajan Agaskar
8f0f0a607e update self test to work with gem runner interface 2013-09-20 11:09:35 -07:00
Gregg Van Hove and Rajan Agaskar
4891d578e3 Set default rake task 2013-09-19 10:15:15 -07:00
Sheel Choksi
efc384c6d6 Allow Env to take optional spec/suite ids when asked to execute 2013-09-17 19:55:49 -07:00
Sheel Choksi
d60786a06c More clearly differentiate between spec and suite ids 2013-09-17 19:55:48 -07:00
Sheel Choksi
66010d01ec Give reporting symbols a little bit more height
Ensures they don't appear cut off when in the last row
2013-09-16 21:05:24 -07:00
Sheel Choksi
1619067ddd Merge pull request #428 from tjgrathwell/htmlreporter-inline-block-dots
Change HTMLReporter symbols to be inline-block instead of floated
2013-09-16 20:55:49 -07:00
Travis Grathwell
79a75f5bdb HTMLReporter symbols are inline-block rather than floated
On a very large test suite (8000 specs), a significant amount
of time is spent just drawing the spec dots. Some sort of
worse-than-linear artifact that summons itself only when you
have 8000 floated elements trying to hang out together.

This performance penalty is not seen with inline-block.

In Chrome 29:
  Floated dots: 16.795s
  Inline-block dots: 2.774s

Setting the dots to 'display: none;' takes about the same time
as the inline-block figure, so this is probably a low enough bound
(no need for chunked rendering or who knows what).
2013-09-10 19:46:51 -07:00
Sheel Choksi
7158e048a6 Update Jasmine CSS build process
- Update compass configuration to build jasmine.scss into lib
- Remove src/html/jasmine.css (since jasmine.scss builds directly into
    lib now)
- Bump lib/jasmine-core/jasmine.css to be latest from scss
2013-09-09 21:41:24 -07:00
Sheel Choksi
f8f064d12d Update jasmine-performance.yml
Get it back into working condition and more similar to jasmine.yml
2013-09-09 21:41:24 -07:00
Sheel Choksi
8ac085c103 Use jasmine.DEFAULT_TIMEOUT_INTERVAL for async timeout
Allows a user to specify their desired timeout interval for async specs
and change it on a per spec basis (for particularly slow specs, for example).

As pointed out by @Eric-Wright in #422. [finishes #55996798]
2013-09-08 21:41:45 -07:00
Sheel Choksi
03dfea967c Remove unused jasmine.DEFAULT_UPDATE_INTERVAL 2013-09-08 14:18:34 -07:00
Sheel Choksi
f463e1f7aa Consistent 'this' between befores/it/afters
Change the 'this' user functions are called with to be an empty object
instead of the QueueRunner so that if the user puts properties on it,
        they won't conflict.

Also, changes async specs to be called with a proper 'this', as pointed
out by @Eric-Wright in #419 and #420.

[finishes #56030080]
2013-09-07 18:28:03 -07:00
Sheel Choksi
4bff199c2a Rename a spy's callReturn and callThrow
.and.callReturn is now .and.returnValue
.and.callThrow is now .and.throwError

[finishes #56281634]
2013-09-06 21:55:14 -07:00
Sheel Choksi
e3f0389ac2 Change andThrow to always throw an Error
If an error is passed in, it is thrown, otherwise the argument passed
in is wrapped in an Error

[finishes #50607615][closes #372]
2013-09-05 23:05:45 -07:00
Sheel Choksi
be0f7b4117 EnvSpec for timing out async spec fix
Spec still can't work for maximumSpecCallbackDepth = 1 until further
mock clock enhancements. Fixes the specs running twice issue caused by
the previous commit.
2013-09-02 21:48:44 -07:00
Sheel Choksi
edb46a6f7c Fix spec in EnvSpec.js for specs that hang
This spec would hang when maximumSpecCallbackDepth was set to 1
[Fixes #54168730]
2013-09-02 20:39:37 -07:00
Sheel Choksi
a442acb8aa Mock Clock now correctly schedules delayed functions during a 'tick' 2013-09-02 18:50:17 -07:00
Davis W. Frank
fc409f39a1 Workaround and bug exposure for IE8 and PrettyPrinter, which doesn't work well when trying to pretty print the native timer functions on IE. Make Jasmine's suite green and call out for a fix once we re-write the pretty printer. [Finishes #54168708] 2013-09-01 15:38:14 -07:00
Davis W. Frank
ba55cb5e38 Mock clock now less intrusive, replacing global timer funcions only when clock is installed. [Fixes #54168708] 2013-08-27 22:46:01 -07:00
Davis W. Frank
2d4f398dd6 Merge branch 'master' of https://github.com/pivotal/jasmine 2013-08-27 22:43:06 -07:00
Sheel Choksi
5ba6e51e1c Restore custom failure messages for toHaveBeenCalledWith
As pointed out by @tjgrathwell
2013-08-26 23:24:43 -07:00
Davis W. Frank
ba43e37356 Updating GOALS doc after rc2 2013-08-06 08:04:37 -07:00
Sheel Choksi
0f42f2709a Update PrettyPrinter to better check for an Object
Includes test case to fix FF as suggested by @ondras
Fixes #409
2013-08-03 11:49:20 -07:00
Sheel Choksi
4c4317b80e Update BrowserFlags to include Firefox
- DRYs up the browser checking code
- Adds in Firefox as another flag
- Makes it possible to do checks like `if (env.ieVersion)` to target all
IE versions
2013-08-03 11:45:13 -07:00
Davis W. Frank
b4bb99dfdf Merge pull request #410 from martyhines/fix-broken-link
Updated contribute.markdown links
2013-07-31 07:54:42 -07:00
martyhines
d721418490 Updated contribute.markdown links 2013-07-31 10:40:28 -04:00
Davis W. Frank
45fd8df861 Adding ignores for latest RVM/RbEnv convention 2013-07-30 08:08:24 -07:00
Davis W. Frank
0e800ee243 Rename to GitHub convention; Makes this doc available during pull request creation 2013-07-30 08:07:22 -07:00
Davis W. Frank
8a8cc03dea Add release notes & GitHub releases instructions 2013-07-28 20:59:57 -07:00
60 changed files with 637 additions and 648 deletions

3
.gitignore vendored
View File

@@ -5,6 +5,8 @@ site/
.bundle/
.pairs
.rvmrc
.ruby-gemset
.ruby-version
*.gem
.bundle
tags
@@ -13,4 +15,5 @@ pkg/*
.sass-cache/*
src/html/.sass-cache/*
node_modules/
sauce_connect.log
*.swp

View File

@@ -16,32 +16,32 @@ matrix:
- TEST_COMMAND="bash travis-node-script.sh"
- env:
- JASMINE_BROWSER="firefox"
- SAUCE_PLATFORM="Linux"
- SAUCE_VERSION=''
- SAUCE_OS="Linux"
- SAUCE_BROWSER_VERSION=''
- env:
- JASMINE_BROWSER="safari"
- SAUCE_PLATFORM="OS X 10.8"
- SAUCE_VERSION=6
- SAUCE_OS="OS X 10.8"
- SAUCE_BROWSER_VERSION=6
- env:
- JASMINE_BROWSER="safari"
- SAUCE_PLATFORM="OS X 10.6"
- SAUCE_VERSION=5
- SAUCE_OS="OS X 10.6"
- SAUCE_BROWSER_VERSION=5
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_PLATFORM="Windows 8"
- SAUCE_VERSION=10
- SAUCE_OS="Windows 8"
- SAUCE_BROWSER_VERSION=10
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_PLATFORM="Windows 7"
- SAUCE_VERSION=9
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=9
- env:
- JASMINE_BROWSER="internet explorer"
- SAUCE_PLATFORM="Windows 7"
- SAUCE_VERSION=8
- SAUCE_OS="Windows 7"
- SAUCE_BROWSER_VERSION=8
- env:
- JASMINE_BROWSER="chrome"
- SAUCE_PLATFORM="Linux"
- SAUCE_VERSION=''
- SAUCE_OS="Linux"
- SAUCE_BROWSER_VERSION=''
- env:
- JASMINE_BROWSER="phantomjs"
- USE_SAUCE=false

View File

@@ -20,8 +20,6 @@
* Top level (i.e., any `jasmine` property) should only be referenced inside the `Env` constructor
* should better allow any object to get jasmine code (Node-friendly)
* review everything in base.js
* Spies
* break these out into their own tests/file
* Remove isA functions:
* isArray_ - used in matchers and spies
* isString_
@@ -33,11 +31,6 @@
* inherit is only for PrettyPrinter now
* formatException is used only inside Env/spec
* htmlEscape is for messages in matchers - should this be HTML at all?
* Matchers improvements
* unit testable DONE
* better equality (from Underscore) DONE
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1?
* addCustomMatchers doesn't explode stack
* Pretty printing
* move away from pretty printer and to a JSON.stringify implementation?
* jasmineToString vs. custom toString ?
@@ -47,6 +40,16 @@
* unify params to ctors: options vs. attrs.
* This will be a lot of the TODOs, but clean up & simplify Env.js (is this a 2.1 task?)
### DONE
* Matchers improvements
* unit testable DONE
* better equality (from Underscore) DONE
* addCustomMatchers doesn't explode stack DONE
* refactor equals function so that it just loops & recurses over a list of fns (custom and built-in) - 2.1? (Tracker story)
* Spies
* break these out into their own tests/file DONE
## Other Topics
* Docs

View File

@@ -1,7 +1,6 @@
source 'https://rubygems.org'
gem "rake"
gem "jasmine", :git => 'https://github.com/pivotal/jasmine-gem.git'
#gem "jasmine", path: "/Users/pivotal/workspace/jasmine-gem"
# gem "jasmine", path: "/Users/pivotal/workspace/jasmine-gem"
unless ENV["TRAVIS"]
group :debug do
gem 'debugger'
@@ -9,3 +8,5 @@ unless ENV["TRAVIS"]
end
gemspec
gem "jasmine_selenium_runner", :git => 'https://github.com/jasmine/jasmine_selenium_runner.git'

View File

@@ -9,7 +9,7 @@ Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pi
## Contributing
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/Contribute.markdown)
Please read the [contributors' guide](https://github.com/pivotal/jasmine/blob/master/CONTRIBUTING.md)
## Support

View File

@@ -2,38 +2,16 @@ require "bundler"
Bundler::GemHelper.install_tasks
require "json"
require "jasmine"
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rb"].each do |file|
require file
end
# TODO: Is there better way to invoke this using Jasmine gem???
task :core_spec do
exec "ruby spec/jasmine_self_test_spec.rb"
unless ENV["JASMINE_BROWSER"] == 'phantomjs'
require "jasmine_selenium_runner"
end
load "jasmine/tasks/jasmine.rake"
namespace :jasmine do
task :server do
port = ENV['JASMINE_PORT'] || 8888
jasmine_yml = ENV['JASMINE_YML'] || 'jasmine.yml'
Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', jasmine_yml))
config = Jasmine.config
server = Jasmine::Server.new(port, Jasmine::Application.app(config))
server.start
puts "your tests are here:"
puts " http://localhost:#{port}/"
end
desc "Copy examples from Jasmine JS to the gem"
task :copy_examples_to_gem do
require "fileutils"
# copy jasmine's example tree into our generator templates dir
FileUtils.rm_r('generators/jasmine/templates/jasmine-example', :force => true)
FileUtils.cp_r(File.join(Jasmine::Core.path, 'example'), 'generators/jasmine/templates/jasmine-example', :preserve => true)
task :set_env do
ENV['JASMINE_CONFIG_PATH'] = 'spec/support/jasmine.yml'
end
end
desc "Run specs via server"
task :jasmine => ['jasmine:server']
task "jasmine:configure" => "jasmine:set_env"

View File

@@ -3,7 +3,7 @@
## Development
___Jasmine Core Maintainers Only___
Follow the instructions in `Contribute.markdown` during development.
Follow the instructions in `CONTRIBUTING.md` during development.
### Git Rules
@@ -33,6 +33,7 @@ If you want to submit changes to this repo and aren't a Pivotal Labs employee, y
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
1. Build the standalone distribution with `grunt buildStandaloneDist`
@@ -42,6 +43,7 @@ When ready to release - specs are all green and the stories are done:
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.
There should be a post to Pivotal Labs blog and a tweet to that link.

BIN
dist/jasmine-standalone-2.0.0-rc3.zip vendored Normal file

Binary file not shown.

View File

@@ -1,10 +1,10 @@
module.exports = {
jasmine: {
options: {
cssDir: 'src/html',
cssDir: 'lib/jasmine-core/',
sassDir: 'src/html',
outputStyle: 'compact',
lineComments: false
noLineComments: true,
}
}
};
};

View File

@@ -16,12 +16,7 @@ Gem::Specification.new do |s|
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
s.require_paths = ["lib"]
s.add_development_dependency "json_pure", ">= 1.4.3"
s.add_development_dependency "sass"
s.add_development_dependency "compass"
s.add_development_dependency "rspec"
s.add_development_dependency "fuubar"
s.add_development_dependency "awesome_print"
s.add_development_dependency "nokogiri"
s.add_development_dependency "rake"
s.add_development_dependency "sauce-connect"
s.add_development_dependency "jasmine_selenium_runner"
end

View File

@@ -69,10 +69,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
},
clock: env.clock,
setTimeout: env.clock.setTimeout,
clearTimeout: env.clock.clearTimeout,
setInterval: env.clock.setInterval,
clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})

View File

@@ -47,10 +47,6 @@
},
clock: env.clock,
setTimeout: env.clock.setTimeout,
clearTimeout: env.clock.clearTimeout,
setInterval: env.clock.setInterval,
clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})

View File

@@ -109,7 +109,9 @@ jasmineRequire.HtmlReporter = function(j$) {
var failure =
createDom("div", {className: "spec-detail failed"},
createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
createDom("div", {className: "description"},
createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
),
createDom("div", {className: "messages"})
);
var messages = failure.childNodes[1];

View File

@@ -11,7 +11,7 @@ body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
.html-reporter .banner { margin-top: 14px; }
.html-reporter .duration { color: #aaaaaa; float: right; }
.html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
.html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
.html-reporter .symbol-summary li { display: inline-block; height: 8px; width: 14px; font-size: 16px; }
.html-reporter .symbol-summary li.passed { font-size: 14px; }
.html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
.html-reporter .symbol-summary li.failed { line-height: 9px; }
@@ -48,7 +48,8 @@ body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
.html-reporter .suite { margin-top: 14px; }
.html-reporter .suite a { color: #333333; }
.html-reporter .failures .spec-detail { margin-bottom: 28px; }
.html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
.html-reporter .failures .spec-detail .description { background-color: #b03911; }
.html-reporter .failures .spec-detail .description a { color: white; }
.html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
.html-reporter .result-message span.result { display: block; }
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #dddddd; background: white; white-space: pre; }
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }

View File

@@ -30,7 +30,7 @@ function getJasmineRequireObj() {
}
getJasmineRequireObj().core = function(jRequire) {
j$ = {};
var j$ = {};
jRequire.base(j$);
j$.util = jRequire.util();
@@ -48,7 +48,7 @@ getJasmineRequireObj().core = function(jRequire) {
j$.pp = jRequire.pp(j$);
j$.QueueRunner = jRequire.QueueRunner();
j$.ReportDispatcher = jRequire.ReportDispatcher();
j$.Spec = jRequire.Spec();
j$.Spec = jRequire.Spec(j$);
j$.SpyStrategy = jRequire.SpyStrategy();
j$.Suite = jRequire.Suite();
j$.Timer = jRequire.Timer();
@@ -94,7 +94,6 @@ getJasmineRequireObj().base = function(j$) {
throw new Error("unimplemented method");
};
j$.DEFAULT_UPDATE_INTERVAL = 250;
j$.MAX_PRETTY_PRINT_DEPTH = 40;
j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
@@ -221,7 +220,7 @@ getJasmineRequireObj().util = function() {
return util;
};
getJasmineRequireObj().Spec = function() {
getJasmineRequireObj().Spec = function(j$) {
function Spec(attrs) {
this.encounteredExpectations = false;
this.expectationFactory = attrs.expectationFactory;
@@ -281,14 +280,14 @@ getJasmineRequireObj().Spec = function() {
var timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
onException(new Error('timeout'));
done();
}, 10000]]);
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
var callDone = function() {
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
done();
};
fn(callDone); //TODO: do we care about more than 1 arg?
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
};
}
@@ -382,6 +381,8 @@ getJasmineRequireObj().Env = function(j$) {
var realClearTimeout = j$.getGlobal().clearTimeout;
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());
var runnableLookupTable = {};
var spies = [];
this.currentSpec = null;
@@ -450,7 +451,7 @@ getJasmineRequireObj().Env = function(j$) {
};
var getSpecName = function(spec, currentSuite) {
return currentSuite.getFullName() + ' ' + spec.description + '.';
return currentSuite.getFullName() + ' ' + spec.description;
};
// TODO: we may just be able to pass in the fn instead of wrapping here
@@ -519,6 +520,8 @@ getJasmineRequireObj().Env = function(j$) {
timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}
});
runnableLookupTable[spec.id] = spec;
if (!self.specFilter(spec)) {
spec.disable();
}
@@ -557,10 +560,11 @@ getJasmineRequireObj().Env = function(j$) {
completeCallback: function() {}, // TODO - hook this up
resultCallback: function() {} // TODO - hook this up
});
runnableLookupTable[this.topSuite.id] = this.topSuite;
this.currentSuite = this.topSuite;
this.suiteFactory = function(description) {
return new suiteConstructor({
var suite = new suiteConstructor({
env: self,
id: self.nextSuiteId(),
description: description,
@@ -571,13 +575,25 @@ getJasmineRequireObj().Env = function(j$) {
self.reporter.suiteDone(attrs);
}
});
runnableLookupTable[suite.id] = suite;
return suite;
};
this.execute = function() {
this.execute = function(runnablesToRun) {
runnablesToRun = runnablesToRun || [this.topSuite.id];
var allFns = [];
for(var i = 0; i < runnablesToRun.length; i++) {
var runnable = runnableLookupTable[runnablesToRun[i]];
allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
}
this.reporter.jasmineStarted({
totalSpecsDefined: totalSpecsDefined
});
this.topSuite.execute(self.reporter.jasmineDone);
queueRunnerFactory({fns: allFns, onComplete: this.reporter.jasmineDone});
};
this.spyOn = function(obj, methodName) {
@@ -630,12 +646,12 @@ getJasmineRequireObj().Env = function(j$) {
// TODO: move this to closure
Env.prototype.nextSpecId = function() {
return this.nextSpecId_++;
return 'spec' + this.nextSpecId_++;
};
// TODO: move this to closure
Env.prototype.nextSuiteId = function() {
return this.nextSuiteId_++;
return 'suite' + this.nextSuiteId_++;
};
// TODO: move this to closure
@@ -889,18 +905,19 @@ getJasmineRequireObj().Clock = function() {
setInterval: setInterval,
clearInterval: clearInterval
},
timer = realTimingFunctions,
installed = false;
self.install = function() {
installed = true;
replace(global, fakeTimingFunctions);
timer = fakeTimingFunctions;
installed = true;
};
self.uninstall = function() {
delayedFunctionScheduler.reset();
installed = false;
replace(global, realTimingFunctions);
timer = realTimingFunctions;
installed = false;
};
self.setTimeout = function(fn, delay, params) {
@@ -935,7 +952,7 @@ getJasmineRequireObj().Clock = function() {
if (installed) {
delayedFunctionScheduler.tick(millis);
} else {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
throw new Error("Mock clock is not installed, use jasmine.getEnv().clock.install()");
}
};
@@ -945,7 +962,13 @@ getJasmineRequireObj().Clock = function() {
//if these methods are polyfilled, apply will be present
//TODO: it may be difficult to load the polyfill before jasmine loads
//(env should be new-ed inside of onload)
return !(global.setTimeout || global.setInterval).apply;
return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
}
function replace(dest, source) {
for (var prop in source) {
dest[prop] = source[prop];
}
}
function setTimeout(fn, delay) {
@@ -981,8 +1004,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
self.tick = function(millis) {
millis = millis || 0;
runFunctionsWithinRange(currentTime, currentTime + millis);
currentTime = currentTime + millis;
runFunctionsWithinRange(currentTime - millis, currentTime);
};
self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
@@ -1323,7 +1346,7 @@ getJasmineRequireObj().pp = function(j$) {
this.emitScalar('Date(' + value + ')');
} else if (value.__Jasmine_been_here_before__) {
this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
} else if (j$.isArray_(value) || typeof value == 'object') {
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
value.__Jasmine_been_here_before__ = true;
if (j$.isArray_(value)) {
this.emitArray(value);
@@ -1433,6 +1456,7 @@ getJasmineRequireObj().QueueRunner = function() {
this.clearStack = attrs.clearStack || function(fn) {fn();};
this.onException = attrs.onException || function() {};
this.catchException = attrs.catchException || function() { return true; };
this.userContext = {};
}
QueueRunner.prototype.execute = function() {
@@ -1461,7 +1485,7 @@ getJasmineRequireObj().QueueRunner = function() {
function attemptSync(fn) {
try {
fn.call(self);
fn.call(self.userContext);
} catch (e) {
handleException(e);
}
@@ -1471,7 +1495,7 @@ getJasmineRequireObj().QueueRunner = function() {
var next = function () { self.run(fns, iterativeIndex + 1); };
try {
fn.call(self, next);
fn.call(self.userContext, next);
} catch (e) {
handleException(e);
next();
@@ -1550,16 +1574,17 @@ getJasmineRequireObj().SpyStrategy = function() {
return getSpy();
};
this.callReturn = function(value) {
this.returnValue = function(value) {
plan = function() {
return value;
};
return getSpy();
};
this.callThrow = function(something) {
this.throwError = function(something) {
var error = (something instanceof Error) ? something : new Error(something);
plan = function() {
throw something;
throw error;
};
return getSpy();
};
@@ -2114,21 +2139,26 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
compare: function() {
var args = Array.prototype.slice.call(arguments, 0),
actual = args[0],
expectedArgs = args.slice(1);
expectedArgs = args.slice(1),
result = { pass: false };
if (!j$.isSpy(actual)) {
throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
}
return {
pass: util.contains(actual.calls.allArgs(), expectedArgs)
};
},
message: function(actual) {
return {
affirmative: "Expected spy " + actual.and.identity() + " to have been called.",
negative: "Expected spy " + actual.and.identity() + " not to have been called."
};
if (!actual.calls.any()) {
result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called.";
return result;
}
if (util.contains(actual.calls.allArgs(), expectedArgs)) {
result.pass = true;
result.message = "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was.";
} else {
result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + ".";
}
return result;
}
};
}

View File

@@ -4,6 +4,6 @@
#
module Jasmine
module Core
VERSION = "2.0.0.rc2"
VERSION = "2.0.0.rc3"
end
end

View File

@@ -1,7 +1,7 @@
{
"name": "jasmine-core",
"license": "MIT",
"version": "2.0.0-rc2",
"version": "2.0.0-rc3",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.2.0",

View File

@@ -90,7 +90,7 @@ describe("ConsoleReporter", function() {
reporter.jasmineStarted();
reporter.specDone({status: "passed"});
timerSpy.elapsed.and.callReturn(1000);
timerSpy.elapsed.and.returnValue(1000);
out.clear();
reporter.jasmineDone();
@@ -127,7 +127,7 @@ describe("ConsoleReporter", function() {
out.clear();
timerSpy.elapsed.and.callReturn(100);
timerSpy.elapsed.and.returnValue(100);
reporter.jasmineDone();

View File

@@ -1,41 +1,141 @@
describe("Clock", function() {
it("calls the global setTimeout directly if Clock is not installed", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
global = { setTimeout: setTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
it("does not replace setTimeout until it is installed", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.setTimeout(delayedFn, 0);
fakeGlobal.setTimeout(delayedFn, 0);
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
expect(setTimeout).toHaveBeenCalledWith(delayedFn, 0);
fakeSetTimeout.calls.reset();
clock.install();
fakeGlobal.setTimeout(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
expect(fakeSetTimeout).not.toHaveBeenCalled();
});
it("schedules the delayed function with the fake timer", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
it("does not replace clearTimeout until it is installed", function() {
var fakeClearTimeout = jasmine.createSpy("global cleartimeout"),
fakeGlobal = { clearTimeout: fakeClearTimeout },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
fakeGlobal.clearTimeout("foo");
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
expect(delayedFunctionScheduler.removeFunctionWithId).not.toHaveBeenCalled();
fakeClearTimeout.calls.reset();
clock.install();
fakeGlobal.clearTimeout("foo");
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalled();
expect(fakeClearTimeout).not.toHaveBeenCalled();
});
it("does not replace setInterval until it is installed", function() {
var fakeSetInterval = jasmine.createSpy("global setInterval"),
fakeGlobal = { setInterval: fakeSetInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
fakeGlobal.setInterval(delayedFn, 0);
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
fakeSetInterval.calls.reset();
clock.install();
fakeGlobal.setInterval(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalled();
expect(fakeSetInterval).not.toHaveBeenCalled();
});
it("does not replace clearInterval until it is installed", function() {
var fakeClearInterval = jasmine.createSpy("global clearinterval"),
fakeGlobal = { clearInterval: fakeClearInterval },
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["removeFunctionWithId"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
fakeGlobal.clearInterval("foo");
expect(fakeClearInterval).toHaveBeenCalledWith("foo");
expect(delayedFunctionScheduler.removeFunctionWithId).not.toHaveBeenCalled();
fakeClearInterval.calls.reset();
clock.install();
fakeGlobal.clearInterval("foo");
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalled();
expect(fakeClearInterval).not.toHaveBeenCalled();
});
it("replaces the global timer functions on uninstall", function() {
var fakeSetTimeout = jasmine.createSpy("global setTimeout"),
fakeClearTimeout = jasmine.createSpy("global clearTimeout"),
fakeSetInterval = jasmine.createSpy("global setInterval"),
fakeClearInterval = jasmine.createSpy("global clearInterval"),
fakeGlobal = {
setTimeout: fakeSetTimeout,
clearTimeout: fakeClearTimeout,
setInterval: fakeSetInterval,
clearInterval: fakeClearInterval
},
delayedFunctionScheduler = jasmine.createSpyObj("delayedFunctionScheduler", ["scheduleFunction", "reset"]),
delayedFn = jasmine.createSpy("delayedFn"),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.install();
clock.uninstall();
fakeGlobal.setTimeout(delayedFn, 0);
fakeGlobal.clearTimeout("foo");
fakeGlobal.setInterval(delayedFn, 10);
fakeGlobal.clearInterval("bar");
expect(fakeSetTimeout).toHaveBeenCalledWith(delayedFn, 0);
expect(fakeClearTimeout).toHaveBeenCalledWith("foo");
expect(fakeSetInterval).toHaveBeenCalledWith(delayedFn, 10);
expect(fakeClearInterval).toHaveBeenCalledWith("bar");
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
});
it("schedules the delayed function (via setTimeout) with the fake timer", function() {
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
scheduleFunction = jasmine.createSpy('scheduleFunction'),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setTimeout: setTimeout },
delayedFunctionScheduler = { scheduleFunction: scheduleFunction },
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.install();
clock.setTimeout(delayedFn, 0, 'a', 'b');
expect(setTimeout).not.toHaveBeenCalled();
expect(fakeSetTimeout).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b']);
});
it("returns an id for the delayed function", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
scheduleId = 123,
scheduleFunction = jasmine.createSpy('scheduleFunction').and.callReturn(scheduleId),
scheduleFunction = jasmine.createSpy('scheduleFunction').and.returnValue(scheduleId),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setTimeout: setTimeout },
fakeGlobal = { setTimeout: fakeSetTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
timeoutId;
clock.install();
@@ -44,67 +144,43 @@ describe("Clock", function() {
expect(timeoutId).toEqual(123);
});
it("calls the global clearTimeout directly if Clock is not installed", function() {
var clearTimeout = jasmine.createSpy('clearTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
global = { clearTimeout: clearTimeout },
clock = new j$.Clock(global, delayedFunctionScheduler);
clock.clearTimeout(123);
expect(clearTimeout).toHaveBeenCalledWith(123);
});
it("clears the scheduled function with the scheduler", function() {
var clearTimeout = jasmine.createSpy('clearTimeout'),
var fakeClearTimeout = jasmine.createSpy('clearTimeout'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
global = { setTimeout: clearTimeout },
fakeGlobal = { setTimeout: fakeClearTimeout },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.install();
clock.clearTimeout(123);
expect(clearTimeout).not.toHaveBeenCalled();
expect(fakeClearTimeout).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.removeFunctionWithId).toHaveBeenCalledWith(123);
});
it("calls the global setInterval directly if Clock is not installed", function() {
var setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
global = { setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock.setInterval(delayedFn, 0);
expect(delayedFunctionScheduler.scheduleFunction).not.toHaveBeenCalled();
expect(setInterval).toHaveBeenCalledWith(delayedFn, 0);
});
it("schedules the delayed function with the fake timer", function() {
var setInterval = jasmine.createSpy('setInterval'),
var fakeSetInterval = jasmine.createSpy('setInterval'),
scheduleFunction = jasmine.createSpy('scheduleFunction'),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setInterval: setInterval },
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.install();
clock.setInterval(delayedFn, 0, 'a', 'b');
expect(setInterval).not.toHaveBeenCalled();
expect(fakeSetInterval).not.toHaveBeenCalled();
expect(delayedFunctionScheduler.scheduleFunction).toHaveBeenCalledWith(delayedFn, 0, ['a', 'b'], true);
});
it("returns an id for the delayed function", function() {
var setInterval = jasmine.createSpy('setInterval'),
var fakeSetInterval = jasmine.createSpy('setInterval'),
scheduleId = 123,
scheduleFunction = jasmine.createSpy('scheduleFunction').and.callReturn(scheduleId),
scheduleFunction = jasmine.createSpy('scheduleFunction').and.returnValue(scheduleId),
delayedFunctionScheduler = {scheduleFunction: scheduleFunction},
global = { setInterval: setInterval },
fakeGlobal = { setInterval: fakeSetInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler),
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler),
intervalId;
clock.install();
@@ -113,23 +189,12 @@ describe("Clock", function() {
expect(intervalId).toEqual(123);
});
it("calls the global clearInterval directly if Clock is not installed", function() {
var clearInterval = jasmine.createSpy('clearInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearInterval']),
global = { clearInterval: clearInterval },
clock = new j$.Clock(global, delayedFunctionScheduler);
clock.clearInterval(123);
expect(clearInterval).toHaveBeenCalledWith(123);
});
it("clears the scheduled function with the scheduler", function() {
var clearInterval = jasmine.createSpy('clearInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['removeFunctionWithId']),
global = { setInterval: clearInterval },
fakeGlobal = { setInterval: clearInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
clock.install();
clock.clearInterval(123);
@@ -145,53 +210,20 @@ describe("Clock", function() {
}).toThrow();
});
it("can be uninstalled", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction', 'tick', 'reset']),
global = { setTimeout: setTimeout, setInterval: setInterval },
delayedFn = jasmine.createSpy('delayedFn'),
clock = new j$.Clock(global, delayedFunctionScheduler);
clock.install();
clock.setTimeout(delayedFn, 0);
expect(setTimeout).not.toHaveBeenCalled();
clock.setInterval(delayedFn, 0);
expect(setInterval).not.toHaveBeenCalled();
expect(function() {
clock.tick(0);
}).not.toThrow();
clock.uninstall();
expect(delayedFunctionScheduler.reset).toHaveBeenCalled();
clock.setTimeout(delayedFn, 0);
expect(setTimeout).toHaveBeenCalled();
clock.setInterval(delayedFn, 0);
expect(setInterval).toHaveBeenCalled();
expect(function() {
clock.tick(0);
}).toThrow();
});
it("on IE < 9, fails if extra args are passed to fake clock", function() {
//fail, because this would break in IE9.
var setTimeout = jasmine.createSpy('setTimeout'),
setInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
fn = jasmine.createSpy('fn'),
global = { setTimeout: setTimeout, setInterval: setInterval },
clock = new j$.Clock(global, delayedFunctionScheduler);
var fakeSetTimeout = jasmine.createSpy('setTimeout'),
fakeSetInterval = jasmine.createSpy('setInterval'),
delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['scheduleFunction']),
fn = jasmine.createSpy('fn'),
fakeGlobal = {
setTimeout: fakeSetTimeout,
setInterval: fakeSetInterval
},
clock = new j$.Clock(fakeGlobal, delayedFunctionScheduler);
setTimeout.apply = null;
setInterval.apply = null;
fakeSetTimeout.apply = null;
fakeSetInterval.apply = null;
clock.install();
@@ -221,8 +253,8 @@ describe("Clock (acceptance)", function() {
clock.install();
clock.setTimeout(delayedFn1, 0, 'some', 'arg');
var intervalId = clock.setInterval(recurring1, 50, 'some', 'other', 'args');
clock.setTimeout(delayedFn1, 0);
var intervalId = clock.setInterval(recurring1, 50);
clock.setTimeout(delayedFn2, 100);
clock.setTimeout(delayedFn3, 200);
@@ -232,13 +264,13 @@ describe("Clock (acceptance)", function() {
clock.tick(0);
expect(delayedFn1).toHaveBeenCalledWith('some', 'arg');
expect(delayedFn1).toHaveBeenCalled();
expect(delayedFn2).not.toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
clock.tick(50);
expect(recurring1).toHaveBeenCalledWith('some', 'other', 'args');
expect(recurring1).toHaveBeenCalled();
expect(recurring1.calls.count()).toBe(1);
expect(delayedFn2).not.toHaveBeenCalled();
expect(delayedFn3).not.toHaveBeenCalled();
@@ -280,7 +312,7 @@ 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);
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
clock.install();
@@ -292,7 +324,25 @@ describe("Clock (acceptance)", function() {
expect(delayedFn1).toHaveBeenCalled();
});
it("calls the global clearTimeout correctly when not installed", function () {
it("correctly schedules functions while the Clock is advancing", function() {
var delayedFn1 = jasmine.createSpy('delayedFn1'),
delayedFn2 = jasmine.createSpy('delayedFn2'),
delayedFunctionScheduler = new j$.DelayedFunctionScheduler(),
clock = new j$.Clock({setTimeout: function() {}}, delayedFunctionScheduler);
delayedFn1.and.callFake(function() { clock.setTimeout(delayedFn2, 0); });
clock.install();
clock.setTimeout(delayedFn1, 5);
clock.tick(5);
expect(delayedFn1).toHaveBeenCalled();
expect(delayedFn2).not.toHaveBeenCalled();
clock.tick();
expect(delayedFn2).toHaveBeenCalled();
});
it("calls the global clearTimeout correctly when not installed", function() {
var delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
global = jasmine.getGlobal(),
clock = new j$.Clock(global, delayedFunctionScheduler);
@@ -302,7 +352,7 @@ describe("Clock (acceptance)", function() {
}).not.toThrow();
});
it("calls the global clearTimeout correctly when not installed", function () {
it("calls the global clearTimeout correctly when not installed", function() {
var delayedFunctionScheduler = jasmine.createSpyObj('delayedFunctionScheduler', ['clearTimeout']),
global = jasmine.getGlobal(),
clock = new j$.Clock(global, delayedFunctionScheduler);

View File

@@ -8,9 +8,9 @@ describe("Env", function() {
describe('ids', function() {
it('nextSpecId should return consecutive integers, starting at 0', function() {
expect(env.nextSpecId()).toEqual(0);
expect(env.nextSpecId()).toEqual(1);
expect(env.nextSpecId()).toEqual(2);
expect(env.nextSpecId()).toEqual('spec0');
expect(env.nextSpecId()).toEqual('spec1');
expect(env.nextSpecId()).toEqual('spec2');
});
});
@@ -27,7 +27,7 @@ describe("Env", function() {
expect(fakeReporter.jasmineStarted).toHaveBeenCalled();
});
});
it('removes all spies when env is executed', function(done) {
originalFoo = function() {},
testObj = {
@@ -85,11 +85,11 @@ describe("Env", function() {
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
originalFunc = subject.spiedFunc;
var spy = env.spyOn(subject, 'spiedFunc');
expect(subject.spiedFunc).toEqual(spy);
expect(subject.spiedFunc.calls.any()).toEqual(false);
expect(subject.spiedFunc.calls.count()).toEqual(0);
@@ -236,6 +236,106 @@ describe("Env integration", function() {
env.execute();
});
it("calls associated befores/specs/afters with the same 'this'", function(done) {
var env = new j$.Env();
env.addReporter({jasmineDone: done});
env.describe("tests", function() {
var firstTimeThrough = true, firstSpecContext, secondSpecContext;
env.beforeEach(function() {
if (firstTimeThrough) {
firstSpecContext = this;
} else {
secondSpecContext = this;
}
expect(this).toEqual({});
});
env.it("sync spec", function() {
expect(this).toBe(firstSpecContext);
});
env.it("another sync spec", function() {
expect(this).toBe(secondSpecContext);
});
env.afterEach(function() {
if (firstTimeThrough) {
expect(this).toBe(firstSpecContext);
firstTimeThrough = false;
} else {
expect(this).toBe(secondSpecContext);
}
});
});
env.execute();
});
it("calls associated befores/its/afters with the same 'this' for an async spec", function(done) {
var env = new j$.Env();
env.addReporter({jasmineDone: done});
env.describe("with an async spec", function() {
var specContext;
env.beforeEach(function() {
specContext = this;
expect(this).toEqual({});
});
env.it("sync spec", function(underTestCallback) {
expect(this).toBe(specContext);
underTestCallback();
});
env.afterEach(function() {
expect(this).toBe(specContext);
});
});
env.execute();
});
it("Allows specifying which specs and suites to run", function(done) {
var env = new j$.Env(),
calls = [],
suiteCallback = jasmine.createSpy('suite callback'),
firstSpec,
secondSuite;
var assertions = function() {
expect(calls).toEqual([
'third spec',
'first spec'
]);
expect(suiteCallback).toHaveBeenCalled();
done();
};
env.addReporter({jasmineDone: assertions, suiteDone: suiteCallback});
env.describe("first suite", function() {
firstSpec = env.it("first spec", function() {
calls.push('first spec');
});
env.it("second spec", function() {
calls.push('second spec');
});
});
secondSuite = env.describe("second suite", function() {
env.it("third spec", function() {
calls.push('third spec');
});
});
env.execute([secondSuite.id, firstSpec.id]);
});
it("Mock clock can be installed and used in tests", function(done) {
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
@@ -293,52 +393,37 @@ describe("Env integration", function() {
});
describe("with a mock clock", function() {
beforeEach(function() {
jasmine.getEnv().clock.install();
var originalTimeout;
beforeEach(function() {
originalTimeout = j$.DEFAULT_TIMEOUT_INTERVAL;
jasmine.getEnv().clock.install();
});
afterEach(function() {
jasmine.getEnv().clock.uninstall();
j$.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
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.specDone.and.callFake(function() {
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'failed'}));
done();
});
afterEach(function() {
jasmine.getEnv().clock.uninstall();
env.addReporter(reporter);
j$.DEFAULT_TIMEOUT_INTERVAL = 8414;
env.it("async spec that doesn't call done", function(underTestCallback) {
env.expect(true).toBeTruthy();
jasmine.getEnv().clock.tick(8414);
});
it("should not hang on async specs that forget to call done()", function(done) {
var env = new j$.Env(),
reporter = jasmine.createSpyObj('fakeReporter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("tests", function() {
env.it("async spec that will hang", function(underTestCallback) {
env.expect(true).toBeTruthy();
});
env.it("after async spec", function() {
env.expect(true).toBeTruthy();
});
});
env.execute();
reporter.jasmineDone.and.callFake(function() {
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
totalSpecsDefined: 2
});
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'passed'}));
expect(reporter.specDone).toHaveBeenCalledWith(jasmine.objectContaining({status: 'failed'}));
done();
});
jasmine.getEnv().clock.tick(60001);
});
env.execute();
});
});
// TODO: something is wrong with this spec
@@ -400,9 +485,9 @@ describe("Env integration", function() {
});
});
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level.");
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level");
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested");
});
it("Custom equality testers should be per spec", function(done) {

View File

@@ -1,4 +1,4 @@
xdescribe('Exceptions:', function() {
describe('Exceptions:', function() {
var env;
beforeEach(function() {

View File

@@ -16,7 +16,7 @@ describe("buildExpectationResult", function() {
it("delegates message formatting to the provided formatter if there was an Error", function() {
var fakeError = {message: 'foo'},
messageFormatter = jasmine.createSpy("exception message formatter").and.callReturn(fakeError.message);
messageFormatter = jasmine.createSpy("exception message formatter").and.returnValue(fakeError.message);
var result = j$.buildExpectationResult(
{
@@ -31,7 +31,7 @@ describe("buildExpectationResult", function() {
it("delegates stack formatting to the provided formatter if there was an Error", function() {
var fakeError = {stack: 'foo'},
stackFormatter = jasmine.createSpy("stack formatter").and.callReturn(fakeError.stack);
stackFormatter = jasmine.createSpy("stack formatter").and.returnValue(fakeError.stack);
var result = j$.buildExpectationResult(
{

View File

@@ -56,7 +56,7 @@ describe("Expectation", function() {
it("wraps matchers's compare functions, passing in matcher dependencies", function() {
var fakeCompare = function() { return { pass: true }; },
matcherFactory = jasmine.createSpy("matcher").and.callReturn({ compare: fakeCompare }),
matcherFactory = jasmine.createSpy("matcher").and.returnValue({ compare: fakeCompare }),
matchers = {
toFoo: matcherFactory
},
@@ -80,7 +80,7 @@ describe("Expectation", function() {
});
it("wraps matchers's compare functions, passing the actual and expected", function() {
var fakeCompare = jasmine.createSpy('fake-compare').and.callReturn({pass: true}),
var fakeCompare = jasmine.createSpy('fake-compare').and.returnValue({pass: true}),
matchers = {
toFoo: function() {
return {

View File

@@ -196,7 +196,7 @@ describe("JsApiReporter", function() {
timer: timerSpy
});
timerSpy.elapsed.and.callReturn(1000);
timerSpy.elapsed.and.returnValue(1000);
reporter.jasmineDone();
expect(reporter.executionTime()).toEqual(1000);
});

View File

@@ -19,6 +19,23 @@ describe("QueueRunner", function() {
expect(calls).toEqual(['fn1', 'fn2']);
});
it("calls each function with a consistent 'this'-- an empty object", function() {
var fn1 = jasmine.createSpy('fn1'),
fn2 = jasmine.createSpy('fn2'),
fn3 = function(done) { asyncContext = this; done(); },
queueRunner = new j$.QueueRunner({
fns: [fn1, fn2, fn3]
}),
asyncContext;
queueRunner.execute();
var context = fn1.calls.first().object;
expect(context).toEqual({});
expect(fn2.calls.first().object).toBe(context);
expect(asyncContext).toBe(context);
});
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
//createSpy('asyncfn').and.callFake(function(done) {});

View File

@@ -25,11 +25,11 @@ describe("jasmine spec running", function () {
});
});
expect(it0.id).toEqual(0);
expect(it1.id).toEqual(1);
expect(it2.id).toEqual(2);
expect(it3.id).toEqual(3);
expect(it4.id).toEqual(4);
expect(it0.id).toEqual('spec0');
expect(it1.id).toEqual('spec1');
expect(it2.id).toEqual('spec2');
expect(it3.id).toEqual('spec3');
expect(it4.id).toEqual('spec4');
});
it('nested suites', function (done) {
@@ -305,4 +305,4 @@ describe("jasmine spec running", function () {
));
});
});
});

View File

@@ -36,7 +36,6 @@ describe("Spec", function() {
it("should call the start callback on execution", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
beforesWereCalled = false,
startCallback = jasmine.createSpy('startCallback'),
spec = new j$.Spec({
id: 123,
@@ -48,7 +47,12 @@ describe("Spec", function() {
spec.execute();
expect(startCallback).toHaveBeenCalledWith(spec);
// TODO: due to some issue with the Pretty Printer, this line fails, but the other two pass.
// This means toHaveBeenCalledWith on IE8 will always be broken.
// expect(startCallback).toHaveBeenCalledWith(spec);
expect(startCallback).toHaveBeenCalled();
expect(startCallback.calls.first().object).toEqual(spec);
});
it("should call the start callback on execution but before any befores are called", function() {

View File

@@ -22,7 +22,7 @@ describe("SpyStrategy", function() {
});
it("allows an original function to be called, passed through the params and returns it's value", function() {
var originalFn = jasmine.createSpy("original").and.callReturn(42),
var originalFn = jasmine.createSpy("original").and.returnValue(42),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
returnValue;
@@ -39,7 +39,7 @@ describe("SpyStrategy", function() {
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
returnValue;
spyStrategy.callReturn(17);
spyStrategy.returnValue(17);
returnValue = spyStrategy.exec();
expect(originalFn).not.toHaveBeenCalled();
@@ -50,15 +50,25 @@ describe("SpyStrategy", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy.callThrow("bar");
spyStrategy.throwError(new TypeError("bar"));
expect(function() { spyStrategy.exec(); }).toThrow("bar");
expect(function() { spyStrategy.exec(); }).toThrowError(TypeError, "bar");
expect(originalFn).not.toHaveBeenCalled();
});
it("allows a non-Error to be thrown, wrapping it into an exception when executed", function() {
var originalFn = jasmine.createSpy("original"),
spyStrategy = new j$.SpyStrategy({fn: originalFn});
spyStrategy.throwError("bar");
expect(function() { spyStrategy.exec(); }).toThrowError(Error, "bar");
expect(originalFn).not.toHaveBeenCalled();
});
it("allows a fake function to be called instead", function() {
var originalFn = jasmine.createSpy("original"),
fakeFn = jasmine.createSpy("fake").and.callReturn(67),
fakeFn = jasmine.createSpy("fake").and.returnValue(67),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
returnValue;
@@ -71,7 +81,7 @@ describe("SpyStrategy", function() {
it("allows a return to plan stubbing after another strategy", function() {
var originalFn = jasmine.createSpy("original"),
fakeFn = jasmine.createSpy("fake").and.callReturn(67),
fakeFn = jasmine.createSpy("fake").and.returnValue(67),
spyStrategy = new j$.SpyStrategy({fn: originalFn}),
returnValue;
@@ -89,12 +99,12 @@ describe("SpyStrategy", function() {
it("returns the spy after changing the strategy", function(){
var spy = {},
spyFn = jasmine.createSpy('spyFn').and.callReturn(spy),
spyFn = jasmine.createSpy('spyFn').and.returnValue(spy),
spyStrategy = new j$.SpyStrategy({getSpy: spyFn});
expect(spyStrategy.callThrough()).toBe(spy);
expect(spyStrategy.callReturn()).toBe(spy);
expect(spyStrategy.callThrow()).toBe(spy);
expect(spyStrategy.returnValue()).toBe(spy);
expect(spyStrategy.throwError()).toBe(spy);
expect(spyStrategy.callFake()).toBe(spy);
expect(spyStrategy.stub()).toBe(spy);
});

View File

@@ -3,10 +3,10 @@ describe("Timer", function() {
var fakeNow = jasmine.createSpy('fake Date.now'),
timer = new j$.Timer({now: fakeNow});
fakeNow.and.callReturn(100);
fakeNow.and.returnValue(100);
timer.start();
fakeNow.and.callReturn(200);
fakeNow.and.returnValue(200);
expect(timer.elapsed()).toEqual(100);
});

View File

@@ -1,7 +1,7 @@
describe("toContain", function() {
it("delegates to j$.matchersUtil.contains", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
matcher = j$.matchers.toContain(util);
@@ -12,7 +12,7 @@ describe("toContain", function() {
it("delegates to j$.matchersUtil.contains, passing in equality testers if present", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toContain(util, customEqualityTesters);

View File

@@ -1,7 +1,7 @@
describe("toEqual", function() {
it("delegates to equals function", function() {
var util = {
equals: jasmine.createSpy('delegated-equals').and.callReturn(true)
equals: jasmine.createSpy('delegated-equals').and.returnValue(true)
},
matcher = j$.matchers.toEqual(util),
result;
@@ -14,7 +14,7 @@ describe("toEqual", function() {
it("delegates custom equality testers, if present", function() {
var util = {
equals: jasmine.createSpy('delegated-equals').and.callReturn(true)
equals: jasmine.createSpy('delegated-equals').and.returnValue(true)
},
customEqualityTesters = ['a', 'b'],
matcher = j$.matchers.toEqual(util, customEqualityTesters),

View File

@@ -1,7 +1,7 @@
describe("toHaveBeenCalledWith", function() {
it("passes when the actual was called with matching parameters", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.callReturn(true)
contains: jasmine.createSpy('delegated-contains').and.returnValue(true)
},
matcher = j$.matchers.toHaveBeenCalledWith(util),
calledSpy = j$.createSpy('called-spy'),
@@ -11,11 +11,12 @@ 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.");
});
it("fails when the actual was not called", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.callReturn(false)
contains: jasmine.createSpy('delegated-contains').and.returnValue(false)
},
matcher = j$.matchers.toHaveBeenCalledWith(util),
uncalledSpy = j$.createSpy('uncalled spy'),
@@ -23,20 +24,23 @@ 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.");
});
it("fails when the actual was called with different parameters", function() {
var util = {
contains: jasmine.createSpy('delegated-contains').and.callReturn(false)
contains: jasmine.createSpy('delegated-contains').and.returnValue(false)
},
matcher = j$.matchers.toHaveBeenCalledWith(util),
calledSpy = j$.createSpy('called spy'),
result;
calledSpy('a');
calledSpy('c', 'd');
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' ].");
});
it("throws an exception when the actual is not a spy", function() {
@@ -45,13 +49,4 @@ describe("toHaveBeenCalledWith", function() {
expect(function() { matcher.compare(fn) }).toThrow(new Error("Expected a spy, but got Function."));
});
it("has a custom message on failure", function() {
var matcher = j$.matchers.toHaveBeenCalledWith(),
spy = j$.createSpy('sample-spy'),
messages = matcher.message(spy);
expect(messages.affirmative).toEqual("Expected spy sample-spy to have been called.")
expect(messages.negative).toEqual("Expected spy sample-spy not to have been called.")
});
});

View File

@@ -144,7 +144,7 @@ describe("toThrowError", function() {
it("passes if thrown is an Error and the expected the same Error", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {
@@ -160,7 +160,7 @@ describe("toThrowError", function() {
it("passes if thrown is a custom error that takes arguments and the expected is the same error", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrowError(util),
CustomError = function CustomError(arg) { arg.x },
@@ -180,7 +180,7 @@ describe("toThrowError", function() {
it("fails if thrown is an Error and the expected is a different Error", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {
@@ -196,7 +196,7 @@ describe("toThrowError", function() {
it("passes if thrown is a type of Error and it is equal to the expected Error and message", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {
@@ -212,7 +212,7 @@ describe("toThrowError", function() {
it("passes if thrown is a custom error that takes arguments and it is equal to the expected custom error and message", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrowError(util),
CustomError = function CustomError(arg) { this.message = arg.message },
@@ -232,7 +232,7 @@ describe("toThrowError", function() {
it("fails if thrown is a type of Error and the expected is a different Error", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {
@@ -248,7 +248,7 @@ describe("toThrowError", function() {
it("passes if thrown is a type of Error and has the same type as the expected Error and the message matches the exepcted message", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {
@@ -264,7 +264,7 @@ describe("toThrowError", function() {
it("fails if thrown is a type of Error and the expected is a different Error", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = j$.matchers.toThrowError(util),
fn = function() {

View File

@@ -22,7 +22,7 @@ describe("toThrow", function() {
it("passes if it throws but there is no expected", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrow(util),
fn = function() {
@@ -50,7 +50,7 @@ describe("toThrow", function() {
it("passes if what is thrown is equivalent to what is expected", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(true)
equals: jasmine.createSpy('delegated-equal').and.returnValue(true)
},
matcher = j$.matchers.toThrow(util),
fn = function() {
@@ -66,7 +66,7 @@ describe("toThrow", function() {
it("fails if what is thrown is not equivalent to what is expected", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = j$.matchers.toThrow(util),
fn = function() {
@@ -82,7 +82,7 @@ describe("toThrow", function() {
it("fails if what is thrown is not equivalent to undefined", function() {
var util = {
equals: jasmine.createSpy('delegated-equal').and.callReturn(false)
equals: jasmine.createSpy('delegated-equal').and.returnValue(false)
},
matcher = j$.matchers.toThrow(util),
fn = function() {

View File

@@ -1,19 +1,23 @@
(function(env) {
env.ieVersion = (function() {
function browserVersion(matchFn) {
var userAgent = jasmine.getGlobal().navigator.userAgent;
if (!userAgent) { return Number.MAX_VALUE; }
if (!userAgent) { return void 0; }
var match = /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
var match = matchFn(userAgent);
return match ? parseFloat(match[1]) : Number.MAX_VALUE;
})();
return match ? parseFloat(match[1]) : void 0;
}
env.safariVersion = (function() {
var userAgent = jasmine.getGlobal().navigator.userAgent;
if (!userAgent) { return Number.MAX_VALUE; }
env.ieVersion = browserVersion(function(userAgent) {
return /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(userAgent);
});
var match = /Safari/.exec(userAgent) && /Version\/([0-9]{0,})/.exec(userAgent);
env.safariVersion = browserVersion(function(userAgent) {
return /Safari/.exec(userAgent) && /Version\/([0-9]{0,})/.exec(userAgent);
});
env.firefoxVersion = browserVersion(function(userAgent) {
return /Firefox\/([0-9]{0,})/.exec(userAgent);
});
return match ? parseFloat(match[1]) : Number.MAX_VALUE;
})();
})(jasmine.getEnv());

View File

@@ -148,7 +148,7 @@ describe("New HtmlReporter", function() {
reporter.jasmineStarted({});
timer.elapsed.and.callReturn(100);
timer.elapsed.and.returnValue(100);
reporter.jasmineDone();
var duration = container.querySelector(".banner .duration");
@@ -461,8 +461,10 @@ describe("New HtmlReporter", function() {
expect(failure.getAttribute("class")).toMatch(/failed/);
expect(failure.getAttribute("class")).toMatch(/spec-detail/);
var specLink = failure.childNodes[0];
expect(specLink.getAttribute("class")).toEqual("description");
var specDiv = failure.childNodes[0];
expect(specDiv.getAttribute("class")).toEqual("description");
var specLink = specDiv.childNodes[0];
expect(specLink.getAttribute("title")).toEqual("a suite with a failing spec");
expect(specLink.getAttribute("href")).toEqual("?spec=a%20suite%20with%20a%20failing%20spec");

View File

@@ -5,4 +5,11 @@ describe("j$.pp (HTML Dependent)", function () {
expect(j$.pp(sampleNode)).toEqual("HTMLNode");
expect(j$.pp({foo: sampleNode})).toEqual("{ foo : HTMLNode }");
});
it("should print Firefox's wrapped native objects correctly", function() {
if(jasmine.getEnv().firefoxVersion) {
try { new CustomEvent(); } catch(e) { var err = e; };
expect(j$.pp(err)).toMatch(/Not enough arguments/);
}
});
});

View File

@@ -1,21 +0,0 @@
jasmine_dir:
- 'src'
jasmine_files:
- 'core/base.js'
- 'core/util.js'
- 'core/Reporter.js'
- 'html/HtmlReporterHelpers.js'
- 'core/ExpectationResult.js'
- '**/*.js'
jasmine_css_files:
- 'html/jasmine.css'
src_files:
stylesheets:
helpers:
spec_files:
- 'performance/performance_test.js'
src_dir:
spec_dir:
- 'spec'

View File

@@ -1,67 +0,0 @@
require 'rubygems'
require 'bundler/setup'
require 'jasmine'
Jasmine.load_configuration_from_yaml(File.join(Dir.pwd, 'spec', 'jasmine.yml'))
config = Jasmine.config
browser = ENV['JASMINE_BROWSER'] || 'firefox'
if ENV['USE_SAUCE'] == 'true'
require 'selenium-webdriver'
unless ENV['TRAVIS_BUILD_NUMBER']
require 'sauce/connect'
# we want Sauce Connect locally, not on Travis
Sauce::Connect.connect!
end
username = ENV['SAUCE_USERNAME']
key = ENV['SAUCE_ACCESS_KEY']
platform = ENV['SAUCE_PLATFORM']
version = ENV['SAUCE_VERSION']
url = "http://#{username}:#{key}@localhost:4445/wd/hub"
config.port = 5555
capabilities = {
:platform => platform,
:version => version,
:build => ENV['TRAVIS_BUILD_NUMBER'],
:tags => [ENV['TRAVIS_RUBY_VERSION'], 'CI'],
:browserName => browser
}
capabilities.merge!('tunnel-identifier' => ENV['TRAVIS_JOB_NUMBER']) if ENV['TRAVIS_JOB_NUMBER']
webdriver = Selenium::WebDriver.for :remote, :url => url, :desired_capabilities => capabilities
end
Jasmine.configure do |config|
config.webdriver = webdriver if webdriver
config.browser = browser if browser
end
server = Jasmine::Server.new(config.port, Jasmine::Application.app(config))
driver = Jasmine::SeleniumDriver.new(config.browser, "#{config.host}:#{config.port}/")
t = Thread.new do
begin
server.start
rescue ChildProcess::TimeoutError
end
# # ignore bad exits
end
t.abort_on_exception = true
Jasmine::wait_for_listener(config.port, "jasmine server")
puts "jasmine server started."
reporter = Jasmine::Reporters::ApiReporter.new(driver, config.result_batch_size)
raw_results = Jasmine::Runners::HTTP.new(driver, reporter).run
results = Jasmine::Results.new(raw_results)
formatter = Jasmine::Formatters::Console.new(results)
puts formatter.failures
puts formatter.summary
exit results.failures.size

View File

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

View File

@@ -141,7 +141,7 @@ var j$require = (function() {
}
}());
var j$ = j$require.core(j$require);
j$ = j$require.core(j$require);
j$require.console(j$require, j$);
// options from command line

View File

@@ -1,49 +0,0 @@
# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
# Require this file using `require "spec_helper.rb"` to ensure that it is only
# loaded once.
#
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.run_all_when_everything_filtered = true
config.filter_run :focus
end
require 'awesome_print'
require 'tmpdir'
require 'nokogiri'
def project_root
File.join(File.expand_path(File.dirname(__FILE__)), '..')
end
def capture_output(capture = true)
if capture
output = StringIO.new
$stdout = output
end
yield
if capture
output.string
end
ensure
$stdout = STDOUT
end
def reset_dir(dir)
FileUtils.rm_r dir if File.exists?(dir)
FileUtils.mkdir_p dir
end
def jasmine_version
version = jasmine_version_object
version_string = "#{version['major']}.#{version['minor']}.#{version['build']}"
version_string += ".rc#{version['release_candidate']}" if version['release_candidate']
version_string
end
def jasmine_version_object
@version_object ||= JSON.parse(File.read(File.join(JasmineDev.project_root, 'src', 'version.json')))
end

View File

@@ -48,11 +48,6 @@
},
clock: env.clock,
setTimeout: env.clock.setTimeout,
clearTimeout: env.clock.clearTimeout,
setInterval: env.clock.setInterval,
clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter({
timer: new jasmine.Timer()
})

View File

@@ -0,0 +1,14 @@
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

View File

@@ -22,7 +22,6 @@ helpers:
- 'helpers/**/*.js'
spec_files:
- '**/*[Ss]pec.js'
spec_dir:
- 'spec'
spec_dir: spec

View File

@@ -13,18 +13,19 @@ getJasmineRequireObj().Clock = function() {
setInterval: setInterval,
clearInterval: clearInterval
},
timer = realTimingFunctions,
installed = false;
self.install = function() {
installed = true;
replace(global, fakeTimingFunctions);
timer = fakeTimingFunctions;
installed = true;
};
self.uninstall = function() {
delayedFunctionScheduler.reset();
installed = false;
replace(global, realTimingFunctions);
timer = realTimingFunctions;
installed = false;
};
self.setTimeout = function(fn, delay, params) {
@@ -59,7 +60,7 @@ getJasmineRequireObj().Clock = function() {
if (installed) {
delayedFunctionScheduler.tick(millis);
} else {
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
throw new Error("Mock clock is not installed, use jasmine.getEnv().clock.install()");
}
};
@@ -69,7 +70,13 @@ getJasmineRequireObj().Clock = function() {
//if these methods are polyfilled, apply will be present
//TODO: it may be difficult to load the polyfill before jasmine loads
//(env should be new-ed inside of onload)
return !(global.setTimeout || global.setInterval).apply;
return !(realTimingFunctions.setTimeout || realTimingFunctions.setInterval).apply;
}
function replace(dest, source) {
for (var prop in source) {
dest[prop] = source[prop];
}
}
function setTimeout(fn, delay) {

View File

@@ -7,8 +7,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
self.tick = function(millis) {
millis = millis || 0;
runFunctionsWithinRange(currentTime, currentTime + millis);
currentTime = currentTime + millis;
runFunctionsWithinRange(currentTime - millis, currentTime);
};
self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {

View File

@@ -11,6 +11,8 @@ getJasmineRequireObj().Env = function(j$) {
var realClearTimeout = j$.getGlobal().clearTimeout;
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());
var runnableLookupTable = {};
var spies = [];
this.currentSpec = null;
@@ -79,7 +81,7 @@ getJasmineRequireObj().Env = function(j$) {
};
var getSpecName = function(spec, currentSuite) {
return currentSuite.getFullName() + ' ' + spec.description + '.';
return currentSuite.getFullName() + ' ' + spec.description;
};
// TODO: we may just be able to pass in the fn instead of wrapping here
@@ -148,6 +150,8 @@ getJasmineRequireObj().Env = function(j$) {
timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}
});
runnableLookupTable[spec.id] = spec;
if (!self.specFilter(spec)) {
spec.disable();
}
@@ -186,10 +190,11 @@ getJasmineRequireObj().Env = function(j$) {
completeCallback: function() {}, // TODO - hook this up
resultCallback: function() {} // TODO - hook this up
});
runnableLookupTable[this.topSuite.id] = this.topSuite;
this.currentSuite = this.topSuite;
this.suiteFactory = function(description) {
return new suiteConstructor({
var suite = new suiteConstructor({
env: self,
id: self.nextSuiteId(),
description: description,
@@ -200,13 +205,25 @@ getJasmineRequireObj().Env = function(j$) {
self.reporter.suiteDone(attrs);
}
});
runnableLookupTable[suite.id] = suite;
return suite;
};
this.execute = function() {
this.execute = function(runnablesToRun) {
runnablesToRun = runnablesToRun || [this.topSuite.id];
var allFns = [];
for(var i = 0; i < runnablesToRun.length; i++) {
var runnable = runnableLookupTable[runnablesToRun[i]];
allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
}
this.reporter.jasmineStarted({
totalSpecsDefined: totalSpecsDefined
});
this.topSuite.execute(self.reporter.jasmineDone);
queueRunnerFactory({fns: allFns, onComplete: this.reporter.jasmineDone});
};
this.spyOn = function(obj, methodName) {
@@ -259,12 +276,12 @@ getJasmineRequireObj().Env = function(j$) {
// TODO: move this to closure
Env.prototype.nextSpecId = function() {
return this.nextSpecId_++;
return 'spec' + this.nextSpecId_++;
};
// TODO: move this to closure
Env.prototype.nextSuiteId = function() {
return this.nextSuiteId_++;
return 'suite' + this.nextSuiteId_++;
};
// TODO: move this to closure

View File

@@ -29,7 +29,7 @@ getJasmineRequireObj().pp = function(j$) {
this.emitScalar('Date(' + value + ')');
} else if (value.__Jasmine_been_here_before__) {
this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
} else if (j$.isArray_(value) || typeof value == 'object') {
} else if (j$.isArray_(value) || j$.isA_('Object', value)) {
value.__Jasmine_been_here_before__ = true;
if (j$.isArray_(value)) {
this.emitArray(value);

View File

@@ -6,6 +6,7 @@ getJasmineRequireObj().QueueRunner = function() {
this.clearStack = attrs.clearStack || function(fn) {fn();};
this.onException = attrs.onException || function() {};
this.catchException = attrs.catchException || function() { return true; };
this.userContext = {};
}
QueueRunner.prototype.execute = function() {
@@ -34,7 +35,7 @@ getJasmineRequireObj().QueueRunner = function() {
function attemptSync(fn) {
try {
fn.call(self);
fn.call(self.userContext);
} catch (e) {
handleException(e);
}
@@ -44,7 +45,7 @@ getJasmineRequireObj().QueueRunner = function() {
var next = function () { self.run(fns, iterativeIndex + 1); };
try {
fn.call(self, next);
fn.call(self.userContext, next);
} catch (e) {
handleException(e);
next();

View File

@@ -1,4 +1,4 @@
getJasmineRequireObj().Spec = function() {
getJasmineRequireObj().Spec = function(j$) {
function Spec(attrs) {
this.encounteredExpectations = false;
this.expectationFactory = attrs.expectationFactory;
@@ -58,14 +58,14 @@ getJasmineRequireObj().Spec = function() {
var timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
onException(new Error('timeout'));
done();
}, 10000]]);
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
var callDone = function() {
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
done();
};
fn(callDone); //TODO: do we care about more than 1 arg?
fn.call(this, callDone); //TODO: do we care about more than 1 arg?
};
}

View File

@@ -21,16 +21,17 @@ getJasmineRequireObj().SpyStrategy = function() {
return getSpy();
};
this.callReturn = function(value) {
this.returnValue = function(value) {
plan = function() {
return value;
};
return getSpy();
};
this.callThrow = function(something) {
this.throwError = function(something) {
var error = (something instanceof Error) ? something : new Error(something);
plan = function() {
throw something;
throw error;
};
return getSpy();
};

View File

@@ -3,7 +3,6 @@ getJasmineRequireObj().base = function(j$) {
throw new Error("unimplemented method");
};
j$.DEFAULT_UPDATE_INTERVAL = 250;
j$.MAX_PRETTY_PRINT_DEPTH = 40;
j$.DEFAULT_TIMEOUT_INTERVAL = 5000;

View File

@@ -5,21 +5,26 @@ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
compare: function() {
var args = Array.prototype.slice.call(arguments, 0),
actual = args[0],
expectedArgs = args.slice(1);
expectedArgs = args.slice(1),
result = { pass: false };
if (!j$.isSpy(actual)) {
throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
}
return {
pass: util.contains(actual.calls.allArgs(), expectedArgs)
};
},
message: function(actual) {
return {
affirmative: "Expected spy " + actual.and.identity() + " to have been called.",
negative: "Expected spy " + actual.and.identity() + " not to have been called."
};
if (!actual.calls.any()) {
result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but it was never called.";
return result;
}
if (util.contains(actual.calls.allArgs(), expectedArgs)) {
result.pass = true;
result.message = "Expected spy " + actual.and.identity() + " not to have been called with " + j$.pp(expectedArgs) + " but it was.";
} else {
result.message = "Expected spy " + actual.and.identity() + " to have been called with " + j$.pp(expectedArgs) + " but actual calls were " + j$.pp(actual.calls.allArgs()).replace(/^\[ | \]$/g, '') + ".";
}
return result;
}
};
}

View File

@@ -8,7 +8,7 @@ function getJasmineRequireObj() {
}
getJasmineRequireObj().core = function(jRequire) {
j$ = {};
var j$ = {};
jRequire.base(j$);
j$.util = jRequire.util();
@@ -26,7 +26,7 @@ getJasmineRequireObj().core = function(jRequire) {
j$.pp = jRequire.pp(j$);
j$.QueueRunner = jRequire.QueueRunner();
j$.ReportDispatcher = jRequire.ReportDispatcher();
j$.Spec = jRequire.Spec();
j$.Spec = jRequire.Spec(j$);
j$.SpyStrategy = jRequire.SpyStrategy();
j$.Suite = jRequire.Suite();
j$.Timer = jRequire.Timer();

View File

@@ -81,7 +81,9 @@ jasmineRequire.HtmlReporter = function(j$) {
var failure =
createDom("div", {className: "spec-detail failed"},
createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
createDom("div", {className: "description"},
createDom("a", {title: result.fullName, href: specHref(result)}, result.fullName)
),
createDom("div", {className: "messages"})
);
var messages = failure.childNodes[1];

View File

@@ -93,11 +93,9 @@ body {
margin: $line-height 0;
li {
display: block;
float: left;
height: $line-height / 2;
display: inline-block;
height: ($line-height / 2) + 1;
width: $line-height;
margin-bottom: $line-height / 2;
font-size: 16px;
@@ -290,13 +288,11 @@ body {
margin-bottom: $line-height * 2;
.description {
//line-height: $line-height * 2;
display: block;
color: white;
background-color: $failing-color;
//font-size: $large-font-size;
a {
color: white;
}
}
}
}
@@ -305,7 +301,7 @@ body {
padding-top: $line-height;
color: $text-color;
white-space: pre;
}

View File

@@ -1,107 +0,0 @@
/* line 24, _HTMLReporter.scss */
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
/* line 31, _HTMLReporter.scss */
.html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
/* line 38, _HTMLReporter.scss */
.html-reporter a { text-decoration: none; }
/* line 41, _HTMLReporter.scss */
.html-reporter a:hover { text-decoration: underline; }
/* line 46, _HTMLReporter.scss */
.html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
/* line 58, _HTMLReporter.scss */
.html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
/* line 63, _HTMLReporter.scss */
.html-reporter .banner .version { margin-left: 14px; }
/* line 69, _HTMLReporter.scss */
.html-reporter #jasmine_content { position: fixed; right: 100%; }
/* line 74, _HTMLReporter.scss */
.html-reporter .version { color: #aaaaaa; }
/* line 80, _HTMLReporter.scss */
.html-reporter .banner { margin-top: 14px; }
/* line 84, _HTMLReporter.scss */
.html-reporter .duration { color: #aaaaaa; float: right; }
/* line 91, _HTMLReporter.scss */
.html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
/* line 95, _HTMLReporter.scss */
.html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
/* line 104, _HTMLReporter.scss */
.html-reporter .symbol-summary li.passed { font-size: 14px; }
/* line 107, _HTMLReporter.scss */
.html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
/* line 113, _HTMLReporter.scss */
.html-reporter .symbol-summary li.failed { line-height: 9px; }
/* line 116, _HTMLReporter.scss */
.html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
/* line 124, _HTMLReporter.scss */
.html-reporter .symbol-summary li.disabled { font-size: 14px; }
/* line 127, _HTMLReporter.scss */
.html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
/* line 133, _HTMLReporter.scss */
.html-reporter .symbol-summary li.pending { line-height: 17px; }
/* line 135, _HTMLReporter.scss */
.html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
/* line 143, _HTMLReporter.scss */
.html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
/* line 152, _HTMLReporter.scss */
.html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
/* line 159, _HTMLReporter.scss */
.html-reporter .bar.failed { background-color: #b03911; }
/* line 163, _HTMLReporter.scss */
.html-reporter .bar.passed { background-color: #a6b779; }
/* line 167, _HTMLReporter.scss */
.html-reporter .bar.skipped { background-color: #bababa; }
/* line 171, _HTMLReporter.scss */
.html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
/* line 175, _HTMLReporter.scss */
.html-reporter .bar.menu a { color: #333333; }
/* line 180, _HTMLReporter.scss */
.html-reporter .bar a { color: white; }
/* line 188, _HTMLReporter.scss */
.html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
/* line 195, _HTMLReporter.scss */
.html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
/* line 200, _HTMLReporter.scss */
.html-reporter .running-alert { background-color: #666666; }
/* line 206, _HTMLReporter.scss */
.html-reporter .results { margin-top: 14px; }
/* line 214, _HTMLReporter.scss */
.html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
/* line 218, _HTMLReporter.scss */
.html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
/* line 223, _HTMLReporter.scss */
.html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
/* line 228, _HTMLReporter.scss */
.html-reporter.showDetails .summary { display: none; }
/* line 232, _HTMLReporter.scss */
.html-reporter.showDetails #details { display: block; }
/* line 237, _HTMLReporter.scss */
.html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
/* line 244, _HTMLReporter.scss */
.html-reporter .summary { margin-top: 14px; }
/* line 247, _HTMLReporter.scss */
.html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
/* line 253, _HTMLReporter.scss */
.html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
/* line 260, _HTMLReporter.scss */
.html-reporter .summary li.passed a { color: #5e7d00; }
/* line 264, _HTMLReporter.scss */
.html-reporter .summary li.failed a { color: #b03911; }
/* line 268, _HTMLReporter.scss */
.html-reporter .summary li.pending a { color: #ba9d37; }
/* line 274, _HTMLReporter.scss */
.html-reporter .description + .suite { margin-top: 0; }
/* line 278, _HTMLReporter.scss */
.html-reporter .suite { margin-top: 14px; }
/* line 281, _HTMLReporter.scss */
.html-reporter .suite a { color: #333333; }
/* line 289, _HTMLReporter.scss */
.html-reporter .failures .spec-detail { margin-bottom: 28px; }
/* line 292, _HTMLReporter.scss */
.html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
/* line 304, _HTMLReporter.scss */
.html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
/* line 312, _HTMLReporter.scss */
.html-reporter .result-message span.result { display: block; }
/* line 316, _HTMLReporter.scss */
.html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }

View File

@@ -9,4 +9,4 @@ then
curl https://gist.github.com/santiycr/5139565/raw/sauce_connect_setup.sh | bash
fi
bundle exec rake core_spec
bundle exec rake jasmine:ci