Compare commits

...

77 Commits

Author SHA1 Message Date
John Bintz 825a9a1278 leftover file removed 2011-06-07 10:10:54 -04:00
John Bintz 793470b65f suites also support descriptions from classnames 2011-06-07 10:01:48 -04:00
John Bintz 222dda4e06 if a spec description is given a function as the description, use its name as the displayed description 2011-06-07 09:50:05 -04:00
Davis W. Frank af7f1818b0 Revert back to the old jasmine.css 2011-06-05 21:55:51 -07:00
Davis W. Frank 12f56787b0 Move building single-file JS to use a JSON file with initial priority files 2011-06-05 21:55:32 -07:00
Davis W. Frank e88d88e427 Move all core files into src/core.
Move Browser & Node specs to test against lib/jasmine.js instead of the separate source. Yes, this makes development a little harder but it's better to test that jasmine.js was built correctly.
2011-06-05 21:28:26 -07:00
Davis W. Frank ba10d178b2 Better stack trace on exception. Better results if exception is due to true exception 2011-06-01 21:14:59 -07:00
Davis W. Frank da297d0f56 And what I meant was *this* commit was pulling in the fixes to TrivialConsoleReporter 2011-05-25 08:28:16 -07:00
Davis W. Frank 7ead5388c2 merge in fixes to TrivialConsoleReporter: correct # of specs, no longer limited by column length 2011-05-25 08:14:18 -07:00
Davis W. Frank a445a62e7c TrivialConsoleReporter now reports the correct number of specs that were executed. TCR is still very heavily mocked instead of using testing an actual Jasmine environment. But now at least the numbers are correct. 2011-05-16 18:28:46 -07:00
Davis W. Frank 1d65d56a92 TrivialConsoleReporter refactor & fixes. No longer limitied to 50 columns of dots. 2011-05-16 08:08:12 -07:00
ragaskar d875d1d997 Don't run TrivialConsoleReporter specs if TrivialConsoleReporter is not loaded 2011-05-06 23:18:57 -04:00
ragaskar 1fae8f0a31 Rebuild main jasmine lib 2011-05-06 23:08:49 -04:00
ragaskar c1f8151bcb Add png suitable for favicon 2011-05-06 22:40:53 -04:00
ragaskar bd8a3baed1 Remove unused image files 2011-05-06 22:30:48 -04:00
ragaskar 118324b451 Don't show 'Jasmine waiting for...' console messages unless jasmine.VERBOSE is set to true 2011-05-06 19:07:00 -04:00
ragaskar c30f7d1aa7 Fail with an error if node is not installed when running rake spec 2011-05-06 18:34:42 -04:00
ragaskar de7be4b316 ignore rvmrc 2011-05-06 18:32:58 -04:00
Davis W. Frank b02aa9840a fixed bad merge of gvanhove's describe exception fix 2011-04-17 21:44:41 -07:00
Davis W. Frank 61de2268fe toBeCloseTo matcher merged in 2011-04-17 21:18:41 -07:00
gvanhove dd32048383 Failure messages for toHaveBeenCalledWith print out the name of the spy 2011-04-17 20:55:32 -07:00
gvanhove 32e736aa47 commit updated version into jasmine.js 2011-04-17 20:55:32 -07:00
Steve Conover 38e9af8f68 integrating TrivialConsoleReporter into node_suite.js, deleting some code pulled over from jasmine-node 2011-04-17 20:50:57 -07:00
Carl Jackson & Davis W. Frank e826fbb170 More README edits for the Contributor guide 2011-03-09 13:31:03 -08:00
Carl Jackson & Davis W. Frank 0c77662c5b One more README tweak 2011-03-09 13:15:33 -08:00
Davis W. Frank 75fb19bc49 README changes 2011-03-09 08:16:47 -08:00
Davis W. Frank 6ec825f62d Updating docs. Version goes to 1.1.0 2011-03-08 18:39:13 -08:00
Davis W. Frank fc994108db Update Rakefile a bit. Added more rake tasks to run specs. 2011-03-08 18:38:46 -08:00
Davis W. Frank 70aed2d900 move all "assertion" to "expectation" 2011-03-08 18:37:44 -08:00
Davis W. Frank ccfa17499f Merge remote branch 'sconover/trivial_console_reporter' into work 2011-03-07 22:35:25 -08:00
Davis W. Frank ab087ef5f8 Pendantic terminology 2011-03-07 22:34:58 -08:00
Davis W. Frank 0ef6582f73 Merging in sconover/jshint 2011-03-07 22:30:43 -08:00
Steve Conover a1ba43c864 call back when done 2011-02-28 23:58:06 -08:00
Steve Conover 88ee377662 integrated trivial console into a real-world situation and dicovered a couple mistakes/misses 2011-02-28 23:18:53 -08:00
Steve Conover f5afe18a6b semicolon fixes subsequent to jshint run 2011-02-28 22:56:04 -08:00
Steve Conover 2731716ccb making this consistent 2011-02-28 22:39:16 -08:00
Steve Conover 4e5083d570 style rf 2011-02-28 22:36:31 -08:00
Steve Conover b9cbd3c5a0 integration test - failure scenario 2011-02-28 22:30:03 -08:00
Steve Conover e42026ee84 rename *node to *console 2011-02-28 21:15:57 -08:00
Steve Conover a1f58f8be4 rf 2011-02-28 21:15:57 -08:00
Steve Conover ac00d765d2 integration tests - passing scenarios 2011-02-28 21:15:57 -08:00
Steve Conover b1dceeacd4 stack traces 2011-02-28 21:15:57 -08:00
Steve Conover 5018f0d1c2 spec failure - description 2011-02-28 21:15:57 -08:00
Steve Conover 9704550b33 rf 2011-02-28 21:15:56 -08:00
Steve Conover 882c287191 specs/assertions/failures 2011-02-28 21:15:56 -08:00
Steve Conover 7d2b900b48 remember suite results as suites finish 2011-02-28 21:15:56 -08:00
Steve Conover f701fdc132 needful 2011-02-28 21:15:56 -08:00
Steve Conover eb49fab652 print elapsed time in summary 2011-02-28 21:15:56 -08:00
Steve Conover e8c8a0bdfd run result - passed green, failed red 2011-02-28 21:15:56 -08:00
Steve Conover e6a080039f print started when the test run starts 2011-02-28 21:15:56 -08:00
Steve Conover c485c33a3c skipped specs mean yellow star 2011-02-28 21:15:56 -08:00
Steve Conover 8fbf3ba859 newline at 50 characters 2011-02-28 21:15:56 -08:00
Steve Conover dccafe33b0 style reform 2011-02-28 21:15:56 -08:00
Steve Conover c1d2718bea red F, duh 2011-02-28 21:15:55 -08:00
Steve Conover 945a9ba638 failing spec makes a red dot 2011-02-28 21:15:55 -08:00
Steve Conover 528b5abeda beginning of trivial node reporter, based on jasmine-node. jshint rules exclude bad escapements WRT ansi colors, beacuse that's ok. 2011-02-28 21:15:55 -08:00
Davis W. Frank d7cced2e7c How to for release 2011-02-27 14:22:53 -08:00
Davis W. Frank 3be0610572 adding latest pages 2011-02-27 14:00:45 -08:00
Davis W. Frank 5e90115eaf removing incorrectlt added submodule 2011-02-27 12:33:47 -08:00
Davis W. Frank 148317eb90 1.0.2, finishing to Frank for static pages 2011-02-27 12:26:38 -08:00
Davis W. Frank 45b4e1316c updating for new pages 2011-02-27 10:36:13 -08:00
Davis W. Frank aee4c5926c .gitmodules 2011-02-27 09:48:17 -08:00
Steve Conover f41af6c2d0 jshint passes - run 'node jshint/run.js'. running jshint with a couple jshint options and workarounds to allow certain jasmine-specific styles. many actual style problems are fixed. the jshint run is integrated into rake jasmine:lint. 2011-02-26 15:07:59 -08:00
Steve Conover 9f90c4eca5 initial jshint commit. including the library, made a runner for jasmine. 2011-02-26 11:23:25 -08:00
Steve Conover 545752ae20 semicolons 2011-02-26 11:01:33 -08:00
Steve Conover c04f1b1fa8 node spec/node_suite.js runs all dom-independent jasmine specs. basic commonjs support for jasmine along the way. node_suite.js and runner.html are both green. 2011-02-26 10:53:55 -08:00
Davis W. Frank fa9741dbda removed old ghpages dir 2011-02-25 08:14:48 -08:00
Davis W. Frank 560cb2edcb wip 2011-02-25 08:10:34 -08:00
Davis W. Frank 9a12b32a3a swapping ignore from Jekyll to staticmatic 2011-01-25 13:23:01 -08:00
Christian Williams bd15ed6a45 Really? "File.exist?", not "File.exists?"? Whatever. 2010-11-09 13:10:40 -05:00
Christian Williams fa74051071 Don't commit Gemfile.lock. 2010-11-09 09:48:30 -05:00
Christian Williams 127fe049d9 Build for 1.0.1. 2010-10-05 13:51:29 -07:00
Christian Williams 550e378dc0 Fix download page regen after redesign. 2010-10-05 13:50:55 -07:00
Christian Williams 377703745f Making the checkboxes work fine on IE. onchange doesnt work very well with checkboxes there. The target is not set too.
Original author: Fabio M. Costa <fabiomcosta@gmail.com>
2010-10-05 13:27:50 -07:00
Fabio M. Costa 8ecfd26325 Making the checkboxes work fine on IE. onchange doesnt work very well with checkboxes there. The target is not set too. 2010-10-05 13:25:24 -07:00
Christian Williams 2d10cc1404 IE doesn't have console.log.apply(); fall back to console.log() in that case. 2010-10-05 13:11:27 -07:00
Christian Williams & Ryan Richard 63df354e78 Drop in jsdoc template (from jsdoc-toolkit 2.1.0). 2010-10-05 13:11:04 -07:00
68 changed files with 8617 additions and 271 deletions

3
.gitignore vendored
View File

@ -1,6 +1,7 @@
.idea/ .idea/
.svn/ .svn/
.DS_Store .DS_Store
_site/ site/
.bundle/ .bundle/
.pairs .pairs
.rvmrc

View File

@ -1,6 +1,6 @@
source :gemcutter source :rubygems
gem "jekyll", "0.6.2"
gem "json_pure", "~>1.4.3" gem "json_pure", "~>1.4.3"
gem "frank"
gem "ragaskar-jsdoc_helper" gem "ragaskar-jsdoc_helper"
gem "rake", "0.8.7" gem "rake", "0.8.7"

33
Gemfile.lock Normal file
View File

@ -0,0 +1,33 @@
GEM
remote: http://rubygems.org/
specs:
daemons (1.0.10)
frank (1.0.8)
haml (>= 3.0)
mongrel (>= 1.2.0.pre2)
net-scp (>= 1.0)
net-ssh (>= 2.0)
rack (>= 1.0)
tilt (= 0.9)
gem_plugin (0.2.3)
haml (3.0.25)
json_pure (1.4.6)
mongrel (1.2.0.pre2)
daemons (~> 1.0.10)
gem_plugin (~> 0.2.3)
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-ssh (2.1.0)
rack (1.2.1)
ragaskar-jsdoc_helper (0.0.2.1)
rake (0.8.7)
tilt (0.9)
PLATFORMS
ruby
DEPENDENCIES
frank
json_pure (~> 1.4.3)
ragaskar-jsdoc_helper
rake (= 0.8.7)

42
HowToRelease.markdown Normal file
View File

@ -0,0 +1,42 @@
## Development
## Release
# Making a Release of Jasmine Core
'Jasmine' is the Github repo for Jasmine Core and contains all the JavaScript code for the Jasmine BDD framework.
It also contains two HTML pages for the Github Pages at http://pivotal.github.com/jasmine.
## The Repo
All of the JS for Jasmine is in the src directory. The specs for each file are in the specs directory. There are rake tasks to build the various files for distribution.
## Running Specs
There are rake tasks to help with getting green:
* `rake spec:browser` opens `spec/runner.html` in the default browser. Please run this in at least Firefox and Chrome before comitting
* `rake spec:node` runs all the Jasmine specs in Node.js
* `rake jasmine:lint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
## The Pages
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.
The pages are built with [Frank](https://github.com/blahed/frank). All the source for these pages live in the pages_source directory.
## Releasing
Once all specs are green and you've updated the version in `version.json`, you need to run the rake task to make a distribution: `rake jasmine:dist`.

View File

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

View File

@ -2,27 +2,49 @@
======= =======
**A JavaScript Testing Framework** **A JavaScript Testing Framework**
Want to use Jasmine in a project? Go HERE: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/) 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.
Want to contribute to Jasmine? Read on... Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
<i>(More developer docs to come...)</i>
## Support ## Support
We now have a Google Group for support & discussion.
* Discussion: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) * Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
* Group email: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com) * Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
* Current build status of Jasmine is visible at [ci.pivotallabs.com](http://ci.pivotallabs.com) * Check the current build status: [ci.pivotallabs.com](http://ci.pivotallabs.com)
* Pivotal Tracker project: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606) * View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
* Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD) * Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
## How to Contribute
We welcome your contributions - Thanks for helping make Jasmine a better project for everyone. Please review the backlog and discussion lists (the main group - [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js) and the developer's list - [http://groups.google.com/group/jasmine-js-dev](http://groups.google.com/group/jasmine-js-dev)) before starting work - what you're looking for may already have been done. If it hasn't, the community can help make your contribution better.
### Development Environment
Jasmine Core relies on Ruby for executing the test suite and building the project for release. The spec suite runs in any major, modern browser (Firefox, Safari, Chrome, and yes various IE's) and in [Node.js](http://nodejs.org). While you probably have browsers installed, you want to make sure that Ruby and Node are present.
### How to Develop for Jasmine Core
* Write specs
* Make them pass in a browser (or three):
* open `spec/runner.html` in your browsers
* `rake spec:browser` will run in the default browser on MacOS
* Make them pass in Node: `rake spec:node`
* Fix any warnings or errors from JSHint: `rake jasmine:lint`
Running `rake spec` will run the browser tests, then run specs in Node, then run JSHint. But this will only run in the default browser and only on MacOS (for now).
### Making a Successful Pull Request
* __Include specs for your work__ - it helps us understand your intent and makes sure that future development doesn't break your work
* __Ensure the full test suite is green__ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
Do these things and we'll take a look.
## Maintainers ## Maintainers
* [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs * [Davis W. Frank](mailto:dwfrank@pivotallabs.com), Pivotal Labs
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs * [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
* [Christian Williams](mailto:xian@pivotallabs.com), Pivotal Labs * [Christian Williams](mailto:antixian666@gmail.com), Square
## Developers Copyright (c) 2008-2011 Pivotal Labs. This software is licensed under the MIT License.
We welcome your contributions! Jasmine is currently maintained by Davis Frank ([infews](http://github.com/infews)), Rajan Agaskar ([ragaskar](http://github.com/ragaskar)), and Christian Williams ([Xian](http://github.com/Xian)). You can help us by removing all other recipients from your pull request.
Copyright (c) 2008-2010 Pivotal Labs. This software is licensed under the MIT License.

110
Rakefile
View File

@ -1,6 +1,10 @@
require 'json'
def jasmine_sources def jasmine_sources
sources = ["src/base.js", "src/util.js", "src/Env.js", "src/Reporter.js", "src/Block.js"] first_sources = JSON.parse(File.read('src/SourcesList.json')).collect {|f| "src/core/#{f}"}
sources += Dir.glob('src/*.js').reject { |f| f == 'src/base.js' || sources.include?(f) }.sort
sources = first_sources
sources += Dir.glob('src/core/*.js').reject {|f| first_sources.include?(f)}.sort
sources sources
end end
@ -14,10 +18,9 @@ end
def version_hash def version_hash
require 'json' require 'json'
@version ||= JSON.parse(File.new("src/version.json").read); @version ||= JSON.parse(File.new("src/core/version.json").read);
end end
task :default => 'jasmine:dist'
def substitute_jasmine_version(filename) def substitute_jasmine_version(filename)
contents = File.read(filename) contents = File.read(filename)
@ -26,36 +29,40 @@ def substitute_jasmine_version(filename)
File.open(filename, 'w') { |f| f.write(contents) } File.open(filename, 'w') { |f| f.write(contents) }
end end
task :default => :spec
desc "Run spec suite: Browser, Node, JSHint"
task :spec => ["jasmine:build", "spec:node", "spec:browser"]
namespace :spec do
desc 'Run specs in Node.js'
task :node do
raise "Node is required to run all jasmine specs" unless system("node spec/node_suite.js")
end
desc "Run specs in the default browser (MacOS only)"
task :browser do
system("open spec/runner.html")
end
end
namespace :jasmine do namespace :jasmine do
desc 'Prepares for distribution' desc 'Prepares for distribution'
task :dist => ['jasmine:build', 'jasmine:doc', 'jasmine:build_example_project', 'jasmine:fill_index_downloads'] task :dist => ['jasmine:build',
'jasmine:doc',
'jasmine:build_pages',
'jasmine:build_example_project',
'jasmine:fill_index_downloads']
desc 'Check jasmine sources for coding problems' desc 'Check jasmine sources for coding problems'
task :lint do task :lint do
passed = true puts "Running JSHint via Node.js"
jasmine_sources.each do |src| system("node jshint/run.js") || exit(1)
lines = File.read(src).split(/\n/)
lines.each_index do |i|
line = lines[i]
undefineds = line.scan(/.?undefined/)
if undefineds.include?(" undefined") || undefineds.include?("\tundefined")
puts "Dangerous undefined at #{src}:#{i}:\n > #{line}"
passed = false
end end
if line.scan(/window/).length > 0 desc "Alias to JSHint"
puts "Dangerous window at #{src}:#{i}:\n > #{line}" task :hint => :lint
passed = false
end
end
end
unless passed
puts "Lint failed!"
exit 1
end
end
desc 'Builds lib/jasmine from source' desc 'Builds lib/jasmine from source'
task :build => :lint do task :build => :lint do
@ -64,9 +71,6 @@ namespace :jasmine do
sources = jasmine_sources sources = jasmine_sources
version = version_hash version = version_hash
old_jasmine_files = Dir.glob('lib/jasmine*.js')
old_jasmine_files.each { |file| File.delete(file) }
File.open("lib/jasmine.js", 'w') do |jasmine| File.open("lib/jasmine.js", 'w') do |jasmine|
sources.each do |source_filename| sources.each do |source_filename|
jasmine.puts(File.read(source_filename)) jasmine.puts(File.read(source_filename))
@ -91,12 +95,25 @@ jasmine.version_= {
FileUtils.cp("src/html/jasmine.css", "lib/jasmine.css") FileUtils.cp("src/html/jasmine.css", "lib/jasmine.css")
end end
downloads_file = 'pages/download.html'
task :need_pages_submodule do task :need_pages_submodule do
unless File.exists?('pages/index.html') unless File.exist?(downloads_file)
raise "Jasmine pages submodule isn't present. Run git submodule update --init" raise "Jasmine pages submodule isn't present. Run git submodule update --init"
end end
end end
desc "Build the Github pages HTML"
task :build_pages => :need_pages_submodule do
Dir.chdir("pages") do
FileUtils.rm_r('pages_output') if File.exist?('pages_output')
Dir.chdir('pages_source') do
system("frank export ../pages_output")
end
puts "\nCopying Frank output to the root of the gh-pages branch\n\n"
system("cp -r pages_output/* .")
end
end
desc "Build jasmine documentation" desc "Build jasmine documentation"
task :doc => :need_pages_submodule do task :doc => :need_pages_submodule do
puts 'Creating Jasmine Documentation' puts 'Creating Jasmine Documentation'
@ -109,6 +126,8 @@ jasmine.version_= {
t[:files] = jasmine_sources << jasmine_html_sources t[:files] = jasmine_sources << jasmine_html_sources
t[:options] = "-a" t[:options] = "-a"
t[:out] = "pages/jsdoc" t[:out] = "pages/jsdoc"
# JsdocHelper bug: template must be relative to the JsdocHelper gem, ick
t[:template] = File.join("../".*(100), Dir::getwd, "jsdoc-template")
end end
Rake::Task[:lambda_jsdoc].invoke Rake::Task[:lambda_jsdoc].invoke
end end
@ -119,7 +138,7 @@ jasmine.version_= {
temp_dir = File.join(Dir.tmpdir, 'jasmine-standalone-project') temp_dir = File.join(Dir.tmpdir, 'jasmine-standalone-project')
puts "Building Example Project in #{temp_dir}" puts "Building Example Project in #{temp_dir}"
FileUtils.rm_r temp_dir if File.exists?(temp_dir) FileUtils.rm_r temp_dir if File.exist?(temp_dir)
Dir.mkdir(temp_dir) Dir.mkdir(temp_dir)
root = File.expand_path(File.dirname(__FILE__)) root = File.expand_path(File.dirname(__FILE__))
@ -148,33 +167,4 @@ jasmine.version_= {
exec "cd #{temp_dir} && zip -r #{zip_file_name} . -x .[a-zA-Z0-9]*" exec "cd #{temp_dir} && zip -r #{zip_file_name} . -x .[a-zA-Z0-9]*"
end end
task :fill_index_downloads do
require 'digest/sha1'
download_html = "<!-- START_DOWNLOADS -->\n"
download_html += "<table id=\"standalone-downloads\">\n<tr><th></th><th>Version</th><th>Size</th><th>Date</th><th>SHA1</th></tr>\n"
Dir.glob('pages/downloads/*.zip').sort.reverse.each do |f|
sha1 = Digest::SHA1.hexdigest File.read(f)
fn = f.sub(/^pages\//, '')
version = /jasmine-standalone-(.*).zip/.match(f)[1]
prerelease = /\.rc/.match(f)
download_html += prerelease ? "<tr class=\"rc\">\n" : "<tr>\n"
download_html += "<td class=\"link\"><a href='#{fn}'>#{fn.sub(/downloads\//, '')}</a></td>\n"
download_html += "<td class=\"version\">#{version}</td>\n"
download_html += "<td class=\"size\">#{File.size(f) / 1024}k</td>\n"
download_html += "<td class=\"date\">#{File.mtime(f).strftime("%Y/%m/%d %H:%M:%S %Z")}</td>\n"
download_html += "<td class=\"sha\">#{sha1}</td>\n"
download_html += "</tr>\n"
end
download_html += "</table>\n<!-- END_DOWNLOADS -->"
index_page = File.read('pages/index.html')
matcher = /<!-- START_DOWNLOADS -->.*<!-- END_DOWNLOADS -->/m
index_page = index_page.sub(matcher, download_html)
File.open('pages/index.html', 'w') {|f| f.write(index_page)}
puts "rewrote that file"
end
end end
task :jasmine => ['jasmine:dist']

View File

@ -2,8 +2,8 @@ beforeEach(function() {
this.addMatchers({ this.addMatchers({
toBePlaying: function(expectedSong) { toBePlaying: function(expectedSong) {
var player = this.actual; var player = this.actual;
return player.currentlyPlayingSong === expectedSong return player.currentlyPlayingSong === expectedSong &&
&& player.isPlaying; player.isPlaying;
} }
}) });
}); });

Binary file not shown.

Before

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
images/jasmine_favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 802 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,17 @@
<div align="center">{+new Link().toFile("index.html").withText("Class Index")+}
| {+new Link().toFile("files.html").withText("File Index")+}</div>
<hr />
<h2>Classes</h2>
<ul class="classList">
<for each="thisClass" in="data">
<li>{!
if (thisClass.alias == "_global_") {
output += "<i>"+new Link().toClass(thisClass.alias)+"</i>";
}
else {
output += new Link().toClass(thisClass.alias);
}
!}</li>
</for>
</ul>
<hr />

View File

@ -0,0 +1,56 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
{! Link.base = ""; /* all generated links will be relative to this */ !}
<title>JsDoc Reference - File Index</title>
<meta name="generator" content="JsDoc Toolkit" />
<style type="text/css">
{+include("static/default.css")+}
</style>
</head>
<body>
{+include("static/header.html")+}
<div id="index">
{+publish.classesIndex+}
</div>
<div id="content">
<h1 class="classTitle">File Index</h1>
<for each="item" in="data">
<div>
<h2>{+new Link().toSrc(item.alias).withText(item.name)+}</h2>
<if test="item.desc">{+resolveLinks(summarize(item.desc))+}</if>
<dl>
<if test="item.author">
<dt class="heading">Author:</dt>
<dd>{+item.author+}</dd>
</if>
<if test="item.version">
<dt class="heading">Version:</dt>
<dd>{+item.version+}</dd>
</if>
{! var locations = item.comment.getTag('location').map(function($){return $.toString().replace(/(^\$ ?| ?\$$)/g, '').replace(/^HeadURL: https:/g, 'http:');}) !}
<if test="locations.length">
<dt class="heading">Location:</dt>
<for each="location" in="locations">
<dd><a href="{+location+}">{+location+}</a></dd>
</for>
</if>
</dl>
</div>
<hr />
</for>
</div>
<div class="fineprint" style="clear:both">
<if test="JSDOC.opt.D.copyright">&copy;{+JSDOC.opt.D.copyright+}<br /></if>
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
</div>
</body>
</html>

646
jsdoc-template/class.tmpl Normal file
View File

@ -0,0 +1,646 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}" />
<meta name="generator" content="JsDoc Toolkit" />
{! Link.base = "../"; /* all generated links will be relative to this */ !}
<title>JsDoc Reference - {+data.alias+}</title>
<style type="text/css">
{+include("static/default.css")+}
</style>
</head>
<body>
<!-- ============================== header ================================= -->
<!-- begin static/header.html -->
{+include("static/header.html")+}
<!-- end static/header.html -->
<!-- ============================== classes index ============================ -->
<div id="index">
<!-- begin publish.classesIndex -->
{+publish.classesIndex+}
<!-- end publish.classesIndex -->
</div>
<div id="content">
<!-- ============================== class title ============================ -->
<h1 class="classTitle">
{!
var classType = "";
if (data.isBuiltin()) {
classType += "Built-In ";
}
if (data.isNamespace) {
if (data.is('FUNCTION')) {
classType += "Function ";
}
classType += "Namespace ";
}
else {
classType += "Class ";
}
!}
{+classType+}{+data.alias+}
</h1>
<!-- ============================== class summary ========================== -->
<p class="description">
<if test="data.augments.length"><br />Extends
{+
data.augments
.sort()
.map(
function($) { return new Link().toSymbol($); }
)
.join(", ")
+}.<br />
</if>
{+resolveLinks(data.classDesc)+}
<if test="!data.isBuiltin()">{# isn't defined in any file #}
<br /><i>Defined in: </i> {+new Link().toSrc(data.srcFile)+}.
</if>
</p>
<!-- ============================== constructor summary ==================== -->
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
<table class="summaryTable" cellspacing="0" summary="A summary of the constructor documented in the class {+data.alias+}.">
<caption>{+classType+}Summary</caption>
<thead>
<tr>
<th scope="col">Constructor Attributes</th>
<th scope="col">Constructor Name and Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="attributes">{!
if (data.isPrivate) output += "&lt;private&gt; ";
if (data.isInner) output += "&lt;inner&gt; ";
!}&nbsp;</td>
<td class="nameDescription" {!if (data.comment.getTag("hilited").length){output += 'style="color: red"'}!}>
<div class="fixedFont">
<b>{+ new Link().toSymbol(data.alias).inner('constructor')+}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
</div>
<div class="description">{+resolveLinks(summarize(data.desc))+}</div>
</td>
</tr>
</tbody>
</table>
</if>
<!-- ============================== properties summary ===================== -->
<if test="data.properties.length">
{! var ownProperties = data.properties.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
<if test="ownProperties.length">
<table class="summaryTable" cellspacing="0" summary="A summary of the fields documented in the class {+data.alias+}.">
<caption>Field Summary</caption>
<thead>
<tr>
<th scope="col">Field Attributes</th>
<th scope="col">Field Name and Description</th>
</tr>
</thead>
<tbody>
<for each="member" in="ownProperties">
<tr>
<td class="attributes">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
if (member.isConstant) output += "&lt;constant&gt; ";
!}&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont">
<if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>
</div>
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
</td>
</tr>
</for>
</tbody>
</table>
</if>
<if test="data.inheritsFrom.length">
<dl class="inheritsList">
{!
var borrowedMembers = data.properties.filter(function($) {return $.memberOf != data.alias});
var contributers = [];
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
for (var i = 0, l = contributers.length; i < l; i++) {
output +=
"<dt>Fields borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
+
"<dd>" +
borrowedMembers
.filter(
function($) { return $.memberOf == contributers[i] }
)
.sort(makeSortby("name"))
.map(
function($) { return new Link().toSymbol($.alias).withText($.name) }
)
.join(", ")
+
"</dd>";
}
!}
</dl>
</if>
</if>
<!-- ============================== methods summary ======================== -->
<if test="data.methods.length">
{! var ownMethods = data.methods.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
<if test="ownMethods.length">
<table class="summaryTable" cellspacing="0" summary="A summary of the methods documented in the class {+data.alias+}.">
<caption>Method Summary</caption>
<thead>
<tr>
<th scope="col">Method Attributes</th>
<th scope="col">Method Name and Description</th>
</tr>
</thead>
<tbody>
<for each="member" in="ownMethods">
<tr>
<td class="attributes">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
!}&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
</div>
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
</td>
</tr>
</for>
</tbody>
</table>
</if>
<if test="data.inheritsFrom.length">
<dl class="inheritsList">
{!
var borrowedMembers = data.methods.filter(function($) {return $.memberOf != data.alias});
var contributers = [];
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
for (var i = 0, l = contributers.length; i < l; i++) {
output +=
"<dt>Methods borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
+
"<dd>" +
borrowedMembers
.filter(
function($) { return $.memberOf == contributers[i] }
)
.sort(makeSortby("name"))
.map(
function($) { return new Link().toSymbol($.alias).withText($.name) }
)
.join(", ")
+
"</dd>";
}
!}
</dl>
</if>
</if>
<!-- ============================== events summary ======================== -->
<if test="data.events.length">
{! var ownEvents = data.events.filter(function($){return $.memberOf == data.alias && !$.isNamespace}).sort(makeSortby("name")); !}
<if test="ownEvents.length">
<table class="summaryTable" cellspacing="0" summary="A summary of the events documented in the class {+data.alias+}.">
<caption>Event Summary</caption>
<thead>
<tr>
<th scope="col">Event Attributes</th>
<th scope="col">Event Name and Description</th>
</tr>
</thead>
<tbody>
<for each="member" in="ownEvents">
<tr>
<td class="attributes">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
!}&nbsp;</td>
<td class="nameDescription">
<div class="fixedFont"><if test="member.isStatic && member.memberOf != '_global_'">{+member.memberOf+}.</if><b>{+new Link().toSymbol(member.alias).withText(member.name)+}</b>{+makeSignature(member.params)+}
</div>
<div class="description">{+resolveLinks(summarize(member.desc))+}</div>
</td>
</tr>
</for>
</tbody>
</table>
</if>
<if test="data.inheritsFrom.length">
<dl class="inheritsList">
{!
var borrowedMembers = data.events.filter(function($) {return $.memberOf != data.alias});
var contributers = [];
borrowedMembers.map(function($) {if (contributers.indexOf($.memberOf) < 0) contributers.push($.memberOf)});
for (var i = 0, l = contributers.length; i < l; i++) {
output +=
"<dt>Events borrowed from class "+new Link().toSymbol(contributers[i])+": </dt>"
+
"<dd>" +
borrowedMembers
.filter(
function($) { return $.memberOf == contributers[i] }
)
.sort(makeSortby("name"))
.map(
function($) { return new Link().toSymbol($.alias).withText($.name) }
)
.join(", ")
+
"</dd>";
}
!}
</dl>
</if>
</if>
<!-- ============================== constructor details ==================== -->
<if test="!data.isBuiltin() && (data.isNamespace || data.is('CONSTRUCTOR'))">
<div class="details"><a name="constructor"> </a>
<div class="sectionTitle">
{+classType+}Detail
</div>
<div class="fixedFont">{!
if (data.isPrivate) output += "&lt;private&gt; ";
if (data.isInner) output += "&lt;inner&gt; ";
!}
<b>{+ data.alias +}</b><if test="classType != 'Namespace '">{+ makeSignature(data.params) +}</if>
</div>
<div class="description">
{+resolveLinks(data.desc)+}
<if test="data.author"><br /><i>Author: </i>{+data.author+}.</if>
</div>
<if test="data.example.length">
<for each="example" in="data.example">
<pre class="code">{+example+}</pre>
</for>
</if>
<if test="data.params.length">
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<for each="item" in="data.params">
<dt>
{+((item.type)?""+("<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type)+"}</span> ")) : "")+} <b>{+item.name+}</b>
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="data.deprecated">
<dl class="detailList">
<dt class="heading">Deprecated:</dt>
<dt>
{+resolveLinks(data.deprecated)+}
</dt>
</dl>
</if>
<if test="data.since">
<dl class="detailList">
<dt class="heading">Since:</dt>
<dd>{+ data.since +}</dd>
</dl>
</if>
<if test="data.exceptions.length">
<dl class="detailList">
<dt class="heading">Throws:</dt>
<for each="item" in="data.exceptions">
<dt>
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="data.returns.length">
<dl class="detailList">
<dt class="heading">Returns:</dt>
<for each="item" in="data.returns">
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="data.requires.length">
<dl class="detailList">
<dt class="heading">Requires:</dt>
<for each="item" in="data.requires">
<dd>{+ resolveLinks(item) +}</dd>
</for>
</dl>
</if>
<if test="data.see.length">
<dl class="detailList">
<dt class="heading">See:</dt>
<for each="item" in="data.see">
<dd>{+ new Link().toSymbol(item) +}</dd>
</for>
</dl>
</if>
</div>
</if>
<!-- ============================== field details ========================== -->
<if test="defined(ownProperties) && ownProperties.length">
<div class="sectionTitle">
Field Detail
</div>
<for each="member" in="ownProperties">
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
<div class="fixedFont">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
if (member.isConstant) output += "&lt;constant&gt; ";
!}
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>
</div>
<div class="description">
{+resolveLinks(member.desc)+}
<if test="member.srcFile != data.srcFile">
<br />
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
</if>
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
</div>
<if test="member.example.length">
<for each="example" in="member.example">
<pre class="code">{+example+}</pre>
</for>
</if>
<if test="member.deprecated">
<dl class="detailList">
<dt class="heading">Deprecated:</dt>
<dt>
{+ member.deprecated +}
</dt>
</dl>
</if>
<if test="member.since">
<dl class="detailList">
<dt class="heading">Since:</dt>
<dd>{+ member.since +}</dd>
</dl>
</if>
<if test="member.see.length">
<dl class="detailList">
<dt class="heading">See:</dt>
<for each="item" in="member.see">
<dd>{+ new Link().toSymbol(item) +}</dd>
</for>
</dl>
</if>
<if test="member.defaultValue">
<dl class="detailList">
<dt class="heading">Default Value:</dt>
<dd>
{+resolveLinks(member.defaultValue)+}
</dd>
</dl>
</if>
<if test="!$member_last"><hr /></if>
</for>
</if>
<!-- ============================== method details ========================= -->
<if test="defined(ownMethods) && ownMethods.length">
<div class="sectionTitle">
Method Detail
</div>
<for each="member" in="ownMethods">
<a name="{+Link.symbolNameToLinkName(member)+}"> </a>
<div class="fixedFont">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
!}
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
</div>
<div class="description">
{+resolveLinks(member.desc)+}
<if test="member.srcFile != data.srcFile">
<br />
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
</if>
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
</div>
<if test="member.example.length">
<for each="example" in="member.example">
<pre class="code">{+example+}</pre>
</for>
</if>
<if test="member.params.length">
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<for each="item" in="member.params">
<dt>
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.deprecated">
<dl class="detailList">
<dt class="heading">Deprecated:</dt>
<dt>
{+member.deprecated+}
</dt>
</dl>
</if>
<if test="member.since">
<dl class="detailList">
<dt class="heading">Since:</dt>
<dd>{+ member.since +}</dd>
</dl>
</dl>
</if>
<if test="member.exceptions.length">
<dl class="detailList">
<dt class="heading">Throws:</dt>
<for each="item" in="member.exceptions">
<dt>
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.returns.length">
<dl class="detailList">
<dt class="heading">Returns:</dt>
<for each="item" in="member.returns">
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.requires.length">
<dl class="detailList">
<dt class="heading">Requires:</dt>
<for each="item" in="member.requires">
<dd>{+ resolveLinks(item) +}</dd>
</for>
</dl>
</if>
<if test="member.see.length">
<dl class="detailList">
<dt class="heading">See:</dt>
<for each="item" in="member.see">
<dd>{+ new Link().toSymbol(item) +}</dd>
</for>
</dl>
</if>
<if test="!$member_last"><hr /></if>
</for>
</if>
<!-- ============================== event details ========================= -->
<if test="defined(ownEvents) && ownEvents.length">
<div class="sectionTitle">
Event Detail
</div>
<for each="member" in="ownEvents">
<a name="event:{+Link.symbolNameToLinkName(member)+}"> </a>
<div class="fixedFont">{!
if (member.isPrivate) output += "&lt;private&gt; ";
if (member.isInner) output += "&lt;inner&gt; ";
if (member.isStatic) output += "&lt;static&gt; ";
!}
<if test="member.type"><span class="light">{{+new Link().toSymbol(member.type)+}}</span></if>
<if test="member.isStatic && member.memberOf != '_global_'"><span class="light">{+member.memberOf+}.</span></if><b>{+member.name+}</b>{+makeSignature(member.params)+}
</div>
<div class="description">
{+resolveLinks(member.desc)+}
<if test="member.srcFile != data.srcFile">
<br />
<i>Defined in: </i> {+new Link().toSrc(member.srcFile)+}.
</if>
<if test="member.author"><br /><i>Author: </i>{+member.author+}.</if>
</div>
<if test="member.example.length">
<for each="example" in="member.example">
<pre class="code">{+example+}</pre>
</for>
</if>
<if test="member.params.length">
<dl class="detailList">
<dt class="heading">Parameters:</dt>
<for each="item" in="member.params">
<dt>
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}<b>{+item.name+}</b>
<if test="item.isOptional"><i>Optional<if test="item.defaultValue">, Default: {+item.defaultValue+}</if></i></if>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.deprecated">
<dl class="detailList">
<dt class="heading">Deprecated:</dt>
<dt>
{+member.deprecated+}
</dt>
</dl>
</if>
<if test="member.since">
<dl class="detailList">
<dt class="heading">Since:</dt>
<dd>{+ member.since +}</dd>
</dl>
</dl>
</if>
<if test="member.exceptions.length">
<dl class="detailList">
<dt class="heading">Throws:</dt>
<for each="item" in="member.exceptions">
<dt>
{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+} <b>{+item.name+}</b>
</dt>
<dd>{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.returns.length">
<dl class="detailList">
<dt class="heading">Returns:</dt>
<for each="item" in="member.returns">
<dd>{+((item.type)?"<span class=\"light fixedFont\">{"+(new Link().toSymbol(item.type))+"}</span> " : "")+}{+resolveLinks(item.desc)+}</dd>
</for>
</dl>
</if>
<if test="member.requires.length">
<dl class="detailList">
<dt class="heading">Requires:</dt>
<for each="item" in="member.requires">
<dd>{+ resolveLinks(item) +}</dd>
</for>
</dl>
</if>
<if test="member.see.length">
<dl class="detailList">
<dt class="heading">See:</dt>
<for each="item" in="member.see">
<dd>{+ new Link().toSymbol(item) +}</dd>
</for>
</dl>
</if>
<if test="!$member_last"><hr /></if>
</for>
</if>
<hr />
</div>
<!-- ============================== footer ================================= -->
<div class="fineprint" style="clear:both">
<if test="JSDOC.opt.D.copyright">&copy;{+JSDOC.opt.D.copyright+}<br /></if>
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blank">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
</div>
</body>
</html>

39
jsdoc-template/index.tmpl Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset={+IO.encoding+}"" />
<title>JsDoc Reference - Index</title>
<meta name="generator" content="JsDoc Toolkit" />
<style type="text/css">
{+include("static/default.css")+}
</style>
</head>
<body>
{+include("static/header.html")+}
<div id="index">
{+publish.classesIndex+}
</div>
<div id="content">
<h1 class="classTitle">Class Index</h1>
<for each="thisClass" in="data">
<div>
<h2>{+(new Link().toSymbol(thisClass.alias))+}</h2>
{+resolveLinks(summarize(thisClass.classDesc))+}
</div>
<hr />
</for>
</div>
<div class="fineprint" style="clear:both">
<if test="JSDOC.opt.D.copyright">&copy;{+JSDOC.opt.D.copyright+}<br /></if>
Documentation generated by <a href="http://www.jsdoctoolkit.org/" target="_blankt">JsDoc Toolkit</a> {+JSDOC.VERSION+} on {+new Date()+}
</div>
</body>
</html>

184
jsdoc-template/publish.js Normal file
View File

@ -0,0 +1,184 @@
/** Called automatically by JsDoc Toolkit. */
function publish(symbolSet) {
publish.conf = { // trailing slash expected for dirs
ext: ".html",
outDir: JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
symbolsDir: "symbols/",
srcDir: "symbols/src/"
};
// is source output is suppressed, just display the links to the source file
if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
Link.prototype._makeSrcLink = function(srcFilePath) {
return "&lt;"+srcFilePath+"&gt;";
}
}
// create the folders and subfolders to hold the output
IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));
// used to allow Link to check the details of things being linked to
Link.symbolSet = symbolSet;
// create the required templates
try {
var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
var classesTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
}
catch(e) {
print("Couldn't create the required templates: "+e);
quit();
}
// some ustility filters
function hasNoParent($) {return ($.memberOf == "")}
function isaFile($) {return ($.is("FILE"))}
function isaClass($) {return ($.is("CONSTRUCTOR") || $.isNamespace)}
// get an array version of the symbolset, useful for filtering
var symbols = symbolSet.toArray();
// create the hilited source code files
var files = JSDOC.opt.srcFiles;
for (var i = 0, l = files.length; i < l; i++) {
var file = files[i];
var srcDir = publish.conf.outDir + "symbols/src/";
makeSrcFile(file, srcDir);
}
// get a list of all the classes in the symbolset
var classes = symbols.filter(isaClass).sort(makeSortby("alias"));
// create a class index, displayed in the left-hand column of every class page
Link.base = "../";
publish.classesIndex = classesTemplate.process(classes); // kept in memory
// create each of the class pages
for (var i = 0, l = classes.length; i < l; i++) {
var symbol = classes[i];
symbol.events = symbol.getEvents(); // 1 order matters
symbol.methods = symbol.getMethods(); // 2
var output = "";
output = classTemplate.process(symbol);
IO.saveFile(publish.conf.outDir+"symbols/", symbol.alias+publish.conf.ext, output);
}
// regenerate the index with different relative links, used in the index pages
Link.base = "";
publish.classesIndex = classesTemplate.process(classes);
// create the class index page
try {
var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"index.tmpl");
}
catch(e) { print(e.message); quit(); }
var classesIndex = classesindexTemplate.process(classes);
IO.saveFile(publish.conf.outDir, "index"+publish.conf.ext, classesIndex);
classesindexTemplate = classesIndex = classes = null;
// create the file index page
try {
var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
}
catch(e) { print(e.message); quit(); }
var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
var allFiles = []; // not all files have file-level docs, but we need to list every one
for (var i = 0; i < files.length; i++) {
allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
}
for (var i = 0; i < documentedFiles.length; i++) {
var offset = files.indexOf(documentedFiles[i].alias);
allFiles[offset] = documentedFiles[i];
}
allFiles = allFiles.sort(makeSortby("name"));
// output the file index page
var filesIndex = fileindexTemplate.process(allFiles);
IO.saveFile(publish.conf.outDir, "files"+publish.conf.ext, filesIndex);
fileindexTemplate = filesIndex = files = null;
}
/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
function summarize(desc) {
if (typeof desc != "undefined")
return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
}
/** Make a symbol sorter by some attribute. */
function makeSortby(attribute) {
return function(a, b) {
if (a[attribute] != undefined && b[attribute] != undefined) {
a = a[attribute].toLowerCase();
b = b[attribute].toLowerCase();
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
}
}
/** Pull in the contents of an external file at the given path. */
function include(path) {
var path = publish.conf.templatesDir+path;
return IO.readFile(path);
}
/** Turn a raw source file into a code-hilited page in the docs. */
function makeSrcFile(path, srcDir, name) {
if (JSDOC.opt.s) return;
if (!name) {
name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
name = name.replace(/\:/g, "_");
}
var src = {path: path, name:name, charset: IO.encoding, hilited: ""};
if (defined(JSDOC.PluginManager)) {
JSDOC.PluginManager.run("onPublishSrc", src);
}
if (src.hilited) {
IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
}
}
/** Build output for displaying function parameters. */
function makeSignature(params) {
if (!params) return "()";
var signature = "("
+
params.filter(
function($) {
return $.name.indexOf(".") == -1; // don't show config params in signature
}
).map(
function($) {
return $.name;
}
).join(", ")
+
")";
return signature;
}
/** Find symbol {@link ...} strings in text and turn into html links */
function resolveLinks(str, from) {
str = str.replace(/\{@link ([^} ]+) ?\}/gi,
function(match, symbolName) {
return new Link().toSymbol(symbolName);
}
);
return str;
}

View File

@ -0,0 +1,162 @@
/* default.css */
body
{
font: 12px "Lucida Grande", Tahoma, Arial, Helvetica, sans-serif;
width: 800px;
}
.header
{
clear: both;
background-color: #ccc;
padding: 8px;
}
h1
{
font-size: 150%;
font-weight: bold;
padding: 0;
margin: 1em 0 0 .3em;
}
hr
{
border: none 0;
border-top: 1px solid #7F8FB1;
height: 1px;
}
pre.code
{
display: block;
padding: 8px;
border: 1px dashed #ccc;
}
#index
{
margin-top: 24px;
float: left;
width: 160px;
position: absolute;
left: 8px;
background-color: #F3F3F3;
padding: 8px;
}
#content
{
margin-left: 190px;
width: 600px;
}
.classList
{
list-style-type: none;
padding: 0;
margin: 0 0 0 8px;
font-family: arial, sans-serif;
font-size: 1em;
overflow: auto;
}
.classList li
{
padding: 0;
margin: 0 0 8px 0;
}
.summaryTable { width: 100%; }
h1.classTitle
{
font-size:170%;
line-height:130%;
}
h2 { font-size: 110%; }
caption, div.sectionTitle
{
background-color: #7F8FB1;
color: #fff;
font-size:130%;
text-align: left;
padding: 2px 6px 2px 6px;
border: 1px #7F8FB1 solid;
}
div.sectionTitle { margin-bottom: 8px; }
.summaryTable thead { display: none; }
.summaryTable td
{
vertical-align: top;
padding: 4px;
border-bottom: 1px #7F8FB1 solid;
border-right: 1px #7F8FB1 solid;
}
/*col#summaryAttributes {}*/
.summaryTable td.attributes
{
border-left: 1px #7F8FB1 solid;
width: 140px;
text-align: right;
}
td.attributes, .fixedFont
{
line-height: 15px;
color: #002EBE;
font-family: "Courier New",Courier,monospace;
font-size: 13px;
}
.summaryTable td.nameDescription
{
text-align: left;
font-size: 13px;
line-height: 15px;
}
.summaryTable td.nameDescription, .description
{
line-height: 15px;
padding: 4px;
padding-left: 4px;
}
.summaryTable { margin-bottom: 8px; }
ul.inheritsList
{
list-style: square;
margin-left: 20px;
padding-left: 0;
}
.detailList {
margin-left: 20px;
line-height: 15px;
}
.detailList dt { margin-left: 20px; }
.detailList .heading
{
font-weight: bold;
padding-bottom: 6px;
margin-left: 0;
}
.light, td.attributes, .light a:link, .light a:visited
{
color: #777;
font-style: italic;
}
.fineprint
{
text-align: right;
font-size: 10px;
}

View File

@ -0,0 +1,2 @@
<div id="header">
</div>

View File

@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Generated Javascript Documentation</title>
</head>
<frameset cols="20%,80%">
<frame src="allclasses-frame.html" name="packageFrame" />
<frame src="splash.html" name="classFrame" />
<noframes>
<body>
<p>
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
</p>
</body>
</noframes>
</frameset>
</html>

View File

@ -0,0 +1,35 @@
<symbol alias="{+data.alias+}">
<name>{+data.name+}</name>
<memberOf>{+data.memberOf+}</memberOf>
<isStatic>{+data.isStatic+}</isStatic>
<isa>{+data.isa+}</isa>
<desc>{+data.desc+}</desc>
<classDesc>{+data.classDesc+}</classDesc>
<methods><for each="method" in="data.methods">
<method>
<name>{+method.name+}</name>
<memberOf>{+method.memberOf+}</memberOf>
<isStatic>{+method.isStatic+}</isStatic>
<desc>{+method.desc+}</desc>
<params><for each="param" in="method.params">
<param>
<type>{+param.type+}</type>
<name>{+param.name+}</name>
<desc>{+param.desc+}</desc>
<defaultValue>{+param.defaultValue+}</defaultValue>
</param></for>
</params>
</method></for>
</methods>
<properties><for each="property" in="data.properties">
<property>
<name>{+property.name+}</name>
<memberOf>{+property.memberOf+}</memberOf>
<isStatic>{+property.isStatic+}</isStatic>
<desc>{+property.desc+}</desc>
<type>{+property.type+}</type>
</property></for>
</properties>
</symbol>

5919
jshint/jshint.js Executable file

File diff suppressed because it is too large Load Diff

99
jshint/run.js Normal file
View File

@ -0,0 +1,99 @@
var fs = require("fs");
var sys = require("sys");
var path = require("path");
var JSHINT = require("./jshint").JSHINT;
// DWF TODO: Standardize this?
function isExcluded(fullPath) {
var fileName = path.basename(fullPath);
var excludeFiles = ["json2.js", "jshint.js", "publish.js", "node_suite.js", "jasmine.js", "jasmine-html.js"];
for (var i = 0; i < excludeFiles.length; i++) {
if (fileName == excludeFiles[i]) {
return true;
}
}
return false;
}
// DWF TODO: This function could/should be re-written
function allJasmineJsFiles(rootDir) {
var files = [];
fs.readdirSync(rootDir).filter(function(filename) {
var fullPath = rootDir + "/" + filename;
if (fs.statSync(fullPath).isDirectory() && !fullPath.match(/pages/)) {
var subDirFiles = allJasmineJsFiles(fullPath);
if (subDirFiles.length > 0) {
files = files.concat();
return true;
}
} else {
if (fullPath.match(/\.js$/) && !isExcluded(fullPath)) {
files.push(fullPath);
return true;
}
}
return false;
});
return files;
}
var jasmineJsFiles = allJasmineJsFiles(".");
jasmineJsFiles.reverse(); //cheap way to do the stuff in src stuff first
var jasmineJsHintConfig = {
forin:true, //while it's possible that we could be
//considering unwanted prototype methods, mostly
//we're doing this because the jsobjects are being
//used as maps.
loopfunc:true //we're fine with functions defined inside loops (setTimeout functions, etc)
};
var jasmineGlobals = {};
//jasmine.undefined is a jasmine-ism, let's let it go...
function removeJasmineUndefinedErrors(errors) {
var keepErrors = [];
for (var i = 0; i < errors.length; i++) {
if (!(errors[i] &&
errors[i].raw &&
errors[i].evidence &&
( errors[i].evidence.match(/jasmine\.undefined/) ||
errors[i].evidence.match(/diz be undefined yo/) )
)) {
keepErrors.push(errors[i]);
}
}
return keepErrors;
}
(function() {
var ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
};
for (var i = 0; i < jasmineJsFiles.length; i++) {
var file = jasmineJsFiles[i];
JSHINT(fs.readFileSync(file, "utf8"), jasmineJsHintConfig);
var errors = JSHINT.data().errors || [];
errors = removeJasmineUndefinedErrors(errors);
if (errors.length >= 1) {
console.log(ansi.red + "Jasmine JSHint failure: " + ansi.none);
console.log(file);
console.log(errors);
process.exit(1);
}
}
console.log(ansi.green + "Jasmine JSHint PASSED." + ansi.none);
})();

View File

@ -70,16 +70,16 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
this.startedAt = new Date(); this.startedAt = new Date();
var self = this; var self = this;
showPassed.onchange = function(evt) { showPassed.onclick = function(evt) {
if (evt.target.checked) { if (showPassed.checked) {
self.outerDiv.className += ' show-passed'; self.outerDiv.className += ' show-passed';
} else { } else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
} }
}; };
showSkipped.onchange = function(evt) { showSkipped.onclick = function(evt) {
if (evt.target.checked) { if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped'; self.outerDiv.className += ' show-skipped';
} else { } else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
@ -110,7 +110,7 @@ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results(); var results = suite.results();
var status = results.passed() ? 'passed' : 'failed'; var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount == 0) { // todo: change this to check results.skipped if (results.totalCount === 0) { // todo: change this to check results.skipped
status = 'skipped'; status = 'skipped';
} }
this.suiteDivs[suite.id].className += " " + status; this.suiteDivs[suite.id].className += " " + status;
@ -162,7 +162,13 @@ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
jasmine.TrivialReporter.prototype.log = function() { jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console; var console = jasmine.getGlobal().console;
if (console && console.log) console.log.apply(console, arguments); if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
}; };
jasmine.TrivialReporter.prototype.getLocation = function() { jasmine.TrivialReporter.prototype.getLocation = function() {
@ -177,6 +183,8 @@ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
} }
if (!paramMap["spec"]) return true; if (!paramMap.spec) {
return spec.getFullName().indexOf(paramMap["spec"]) == 0; return true;
}
return spec.getFullName().indexOf(paramMap.spec) === 0;
}; };

View File

@ -1,10 +1,12 @@
var isCommonJS = typeof window == "undefined";
/** /**
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
* *
* @namespace * @namespace
*/ */
var jasmine = {}; var jasmine = {};
if (isCommonJS) exports.jasmine = jasmine;
/** /**
* @private * @private
*/ */
@ -20,6 +22,12 @@ jasmine.unimplementedMethod_ = function() {
*/ */
jasmine.undefined = jasmine.___undefined___; jasmine.undefined = jasmine.___undefined___;
/**
* Show diagnostic messages in the console if set to true
*
*/
jasmine.VERBOSE = false;
/** /**
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
* *
@ -72,7 +80,7 @@ jasmine.MessageResult = function(values) {
jasmine.MessageResult.prototype.toString = function() { jasmine.MessageResult.prototype.toString = function() {
var text = ""; var text = "";
for(var i = 0; i < this.values.length; i++) { for (var i = 0; i < this.values.length; i++) {
if (i > 0) text += " "; if (i > 0) text += " ";
if (jasmine.isString_(this.values[i])) { if (jasmine.isString_(this.values[i])) {
text += this.values[i]; text += this.values[i];
@ -89,9 +97,10 @@ jasmine.ExpectationResult = function(params) {
this.passed_ = params.passed; this.passed_ = params.passed;
this.expected = params.expected; this.expected = params.expected;
this.actual = params.actual; this.actual = params.actual;
this.message = this.passed_ ? 'Passed.' : params.message; this.message = this.passed_ ? 'Passed.' : params.message;
this.trace = this.passed_ ? '' : new Error(this.message);
var trace = (params.trace || new Error(this.message));
this.trace = this.passed_ ? '' : trace;
}; };
jasmine.ExpectationResult.prototype.toString = function () { jasmine.ExpectationResult.prototype.toString = function () {
@ -106,7 +115,8 @@ jasmine.ExpectationResult.prototype.passed = function () {
* Getter for the Jasmine environment. Ensures one gets created * Getter for the Jasmine environment. Ensures one gets created
*/ */
jasmine.getEnv = function() { jasmine.getEnv = function() {
return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
return env;
}; };
/** /**
@ -169,7 +179,7 @@ jasmine.pp = function(value) {
* @returns {Boolean} * @returns {Boolean}
*/ */
jasmine.isDomNode = function(obj) { jasmine.isDomNode = function(obj) {
return obj['nodeType'] > 0; return obj.nodeType > 0;
}; };
/** /**
@ -405,7 +415,7 @@ jasmine.isSpy = function(putativeSpy) {
* @param {Array} methodNames array of names of methods to make spies * @param {Array} methodNames array of names of methods to make spies
*/ */
jasmine.createSpyObj = function(baseName, methodNames) { jasmine.createSpyObj = function(baseName, methodNames) {
if (!jasmine.isArray_(methodNames) || methodNames.length == 0) { if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
} }
var obj = {}; var obj = {};
@ -443,6 +453,7 @@ jasmine.log = function() {
var spyOn = function(obj, methodName) { var spyOn = function(obj, methodName) {
return jasmine.getEnv().currentSpec.spyOn(obj, methodName); return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
}; };
if (isCommonJS) exports.spyOn = spyOn;
/** /**
* Creates a Jasmine spec that will be added to the current suite. * Creates a Jasmine spec that will be added to the current suite.
@ -460,6 +471,7 @@ var spyOn = function(obj, methodName) {
var it = function(desc, func) { var it = function(desc, func) {
return jasmine.getEnv().it(desc, func); return jasmine.getEnv().it(desc, func);
}; };
if (isCommonJS) exports.it = it;
/** /**
* Creates a <em>disabled</em> Jasmine spec. * Creates a <em>disabled</em> Jasmine spec.
@ -472,6 +484,7 @@ var it = function(desc, func) {
var xit = function(desc, func) { var xit = function(desc, func) {
return jasmine.getEnv().xit(desc, func); return jasmine.getEnv().xit(desc, func);
}; };
if (isCommonJS) exports.xit = xit;
/** /**
* Starts a chain for a Jasmine expectation. * Starts a chain for a Jasmine expectation.
@ -484,6 +497,7 @@ var xit = function(desc, func) {
var expect = function(actual) { var expect = function(actual) {
return jasmine.getEnv().currentSpec.expect(actual); return jasmine.getEnv().currentSpec.expect(actual);
}; };
if (isCommonJS) exports.expect = expect;
/** /**
* Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
@ -493,6 +507,7 @@ var expect = function(actual) {
var runs = function(func) { var runs = function(func) {
jasmine.getEnv().currentSpec.runs(func); jasmine.getEnv().currentSpec.runs(func);
}; };
if (isCommonJS) exports.runs = runs;
/** /**
* Waits a fixed time period before moving to the next block. * Waits a fixed time period before moving to the next block.
@ -503,6 +518,7 @@ var runs = function(func) {
var waits = function(timeout) { var waits = function(timeout) {
jasmine.getEnv().currentSpec.waits(timeout); jasmine.getEnv().currentSpec.waits(timeout);
}; };
if (isCommonJS) exports.waits = waits;
/** /**
* Waits for the latchFunction to return true before proceeding to the next block. * Waits for the latchFunction to return true before proceeding to the next block.
@ -514,6 +530,7 @@ var waits = function(timeout) {
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
}; };
if (isCommonJS) exports.waitsFor = waitsFor;
/** /**
* A function that is called before each spec in a suite. * A function that is called before each spec in a suite.
@ -525,6 +542,7 @@ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout
var beforeEach = function(beforeEachFunction) { var beforeEach = function(beforeEachFunction) {
jasmine.getEnv().beforeEach(beforeEachFunction); jasmine.getEnv().beforeEach(beforeEachFunction);
}; };
if (isCommonJS) exports.beforeEach = beforeEach;
/** /**
* A function that is called after each spec in a suite. * A function that is called after each spec in a suite.
@ -536,6 +554,7 @@ var beforeEach = function(beforeEachFunction) {
var afterEach = function(afterEachFunction) { var afterEach = function(afterEachFunction) {
jasmine.getEnv().afterEach(afterEachFunction); jasmine.getEnv().afterEach(afterEachFunction);
}; };
if (isCommonJS) exports.afterEach = afterEach;
/** /**
* Defines a suite of specifications. * Defines a suite of specifications.
@ -555,6 +574,7 @@ var afterEach = function(afterEachFunction) {
var describe = function(description, specDefinitions) { var describe = function(description, specDefinitions) {
return jasmine.getEnv().describe(description, specDefinitions); return jasmine.getEnv().describe(description, specDefinitions);
}; };
if (isCommonJS) exports.describe = describe;
/** /**
* Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
@ -565,27 +585,35 @@ var describe = function(description, specDefinitions) {
var xdescribe = function(description, specDefinitions) { var xdescribe = function(description, specDefinitions) {
return jasmine.getEnv().xdescribe(description, specDefinitions); return jasmine.getEnv().xdescribe(description, specDefinitions);
}; };
if (isCommonJS) exports.xdescribe = xdescribe;
// Provide the XMLHttpRequest class for IE 5.x-6.x: // Provide the XMLHttpRequest class for IE 5.x-6.x:
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
function tryIt(f) {
try { try {
return f();
} catch(e) {
}
return null;
}
var xhr = tryIt(function() {
return new ActiveXObject("Msxml2.XMLHTTP.6.0"); return new ActiveXObject("Msxml2.XMLHTTP.6.0");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0"); return new ActiveXObject("Msxml2.XMLHTTP.3.0");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP"); return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Microsoft.XMLHTTP"); return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) { });
}
throw new Error("This browser does not support XMLHttpRequest."); if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
return xhr;
} : XMLHttpRequest; } : XMLHttpRequest;
/** /**
* @namespace * @namespace
@ -606,7 +634,7 @@ jasmine.util.inherit = function(childClass, parentClass) {
var subclass = function() { var subclass = function() {
}; };
subclass.prototype = parentClass.prototype; subclass.prototype = parentClass.prototype;
childClass.prototype = new subclass; childClass.prototype = new subclass();
}; };
jasmine.util.formatException = function(e) { jasmine.util.formatException = function(e) {
@ -760,14 +788,14 @@ jasmine.Env.prototype.describe = function(description, specDefinitions) {
declarationError = e; declarationError = e;
} }
this.currentSuite = parentSuite;
if (declarationError) { if (declarationError) {
this.it("encountered a declaration exception", function() { this.it("encountered a declaration exception", function() {
throw declarationError; throw declarationError;
}); });
} }
this.currentSuite = parentSuite;
return suite; return suite;
}; };
@ -828,7 +856,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
b.__Jasmine_been_here_before__ = a; b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== jasmine.undefined; return obj !== null && obj[keyName] !== jasmine.undefined;
}; };
for (var property in b) { for (var property in b) {
@ -854,7 +882,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
delete a.__Jasmine_been_here_before__; delete a.__Jasmine_been_here_before__;
delete b.__Jasmine_been_here_before__; delete b.__Jasmine_been_here_before__;
return (mismatchKeys.length == 0 && mismatchValues.length == 0); return (mismatchKeys.length === 0 && mismatchValues.length === 0);
}; };
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
@ -1302,16 +1330,16 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
} }
this.message = function() { this.message = function() {
if (this.actual.callCount == 0) { if (this.actual.callCount === 0) {
// todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
return [ return [
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was." "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
]; ];
} else { } else {
return [ return [
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
]; ];
} }
}; };
@ -1333,7 +1361,7 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() {
return [ return [
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
] ];
}; };
return !this.env.contains_(this.actual.argsForCall, expectedArgs); return !this.env.contains_(this.actual.argsForCall, expectedArgs);
@ -1366,6 +1394,23 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.actual > expected; return this.actual > expected;
}; };
/**
* Matcher that checks that the expected item is equal to the actual item
* up to a given level of decimal precision (default 2).
*
* @param {Number} expected
* @param {Number} precision
*/
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
if (!(precision === 0)) {
precision = precision || 2;
}
var multiplier = Math.pow(10, precision);
var actual = Math.round(this.actual * multiplier);
expected = Math.round(expected * multiplier);
return expected == actual;
};
/** /**
* Matcher that checks that the expected exception was thrown by the actual. * Matcher that checks that the expected exception was thrown by the actual.
* *
@ -1390,7 +1435,7 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
this.message = function() { this.message = function() {
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' '); return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
} else { } else {
return "Expected function to throw an exception."; return "Expected function to throw an exception.";
} }
@ -1602,7 +1647,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) { for (var property in obj) {
if (property == '__Jasmine_been_here_before__') continue; if (property == '__Jasmine_been_here_before__') continue;
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false); fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
obj.__lookupGetter__(property) !== null) : false);
} }
}; };
@ -1871,7 +1917,8 @@ jasmine.Spec = function(env, suite, description) {
}; };
jasmine.Spec.prototype.getFullName = function() { jasmine.Spec.prototype.getFullName = function() {
return this.suite.getFullName() + ' ' + this.description + '.'; var description = (this.description.apply ? this.description.name : this.description);
return this.suite.getFullName() + ' ' + description + '.';
}; };
@ -1962,7 +2009,8 @@ jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessag
jasmine.Spec.prototype.fail = function (e) { jasmine.Spec.prototype.fail = function (e) {
var expectationResult = new jasmine.ExpectationResult({ var expectationResult = new jasmine.ExpectationResult({
passed: false, passed: false,
message: e ? jasmine.util.formatException(e) : 'Exception' message: e ? jasmine.util.formatException(e) : 'Exception',
trace: { stack: e.stack }
}); });
this.results_.addResult(expectationResult); this.results_.addResult(expectationResult);
}; };
@ -2106,7 +2154,7 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
}; };
jasmine.Suite.prototype.getFullName = function() { jasmine.Suite.prototype.getFullName = function() {
var fullName = this.description; var fullName = (this.description.apply ? this.description.name : this.description);
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
fullName = parentSuite.description + ' ' + fullName; fullName = parentSuite.description + ' ' + fullName;
} }
@ -2172,7 +2220,9 @@ jasmine.WaitsBlock = function(env, timeout, spec) {
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
jasmine.WaitsBlock.prototype.execute = function (onComplete) { jasmine.WaitsBlock.prototype.execute = function (onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
}
this.env.setTimeout(function () { this.env.setTimeout(function () {
onComplete(); onComplete();
}, this.timeout); }, this.timeout);
@ -2200,7 +2250,9 @@ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
jasmine.WaitsForBlock.prototype.execute = function(onComplete) { jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
}
var latchFunctionResult; var latchFunctionResult;
try { try {
latchFunctionResult = this.latchFunction.apply(this.spec); latchFunctionResult = this.latchFunction.apply(this.spec);
@ -2415,7 +2467,7 @@ jasmine.getGlobal().clearInterval = function(timeoutKey) {
jasmine.version_= { jasmine.version_= {
"major": 1, "major": 1,
"minor": 0, "minor": 1,
"build": 0, "build": 0,
"revision": 1284494074 "revision": 1307455841
}; };

2
pages

@ -1 +1 @@
Subproject commit 9ef772465fe1af3d1a75a7bd30558594686f02cc Subproject commit d08ce2de245d6782c09c652045a12e93af0dc7ec

127
spec/node_suite.js Normal file
View File

@ -0,0 +1,127 @@
var fs = require('fs');
var sys = require('sys');
var path = require('path');
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
// undefined = "diz be undefined yo";
var jasmineGlobals = require('../lib/jasmine.js');
for (var k in jasmineGlobals) {
global[k] = jasmineGlobals[k];
}
require('../src/console/TrivialConsoleReporter.js');
/*
Pulling in code from jasmine-node.
We can't just depend on jasmine-node because it has its own jasmine that it uses.
*/
global.window = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setInterval: setInterval,
clearInterval: clearInterval
};
delete global.window;
function noop() {
}
jasmine.executeSpecs = function(specs, done) {
for (var i = 0, len = specs.length; i < len; ++i) {
var filename = specs[i];
require(filename.replace(/\.\w+$/, ""));
}
var jasmineEnv = jasmine.getEnv();
var consoleReporter = new jasmine.TrivialConsoleReporter(sys.print, done);
jasmineEnv.addReporter(consoleReporter);
jasmineEnv.execute();
};
jasmine.getAllSpecFiles = function(dir, matcher) {
var specs = [];
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
specs.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)) {
specs.push(filename);
} else if (fs.statSync(filename).isDirectory()) {
var subfiles = this.getAllSpecFiles(filename, matcher);
subfiles.forEach(function(result) {
specs.push(result);
});
}
}
}
return specs;
};
function now() {
return new Date().getTime();
}
jasmine.asyncSpecWait = function() {
var wait = jasmine.asyncSpecWait;
wait.start = now();
wait.done = false;
(function innerWait() {
waits(10);
runs(function() {
if (wait.start + wait.timeout < now()) {
expect('timeout waiting for spec').toBeNull();
} else if (wait.done) {
wait.done = false;
} else {
innerWait();
}
});
})();
};
jasmine.asyncSpecWait.timeout = 4 * 1000;
jasmine.asyncSpecDone = function() {
jasmine.asyncSpecWait.done = true;
};
for (var key in jasmine) {
exports[key] = jasmine[key];
}
/*
End jasmine-node runner
*/
var isVerbose = false;
var showColors = true;
process.argv.forEach(function(arg) {
switch (arg) {
case '--color': showColors = true; break;
case '--noColor': showColors = false; break;
case '--verbose': isVerbose = true; break;
}
});
var specs = jasmine.getAllSpecFiles(__dirname + '/suites', new RegExp(".js$"));
var domIndependentSpecs = [];
for (var i = 0; i < specs.length; i++) {
if (fs.readFileSync(specs[i], "utf8").indexOf("document.createElement") < 0) {
domIndependentSpecs.push(specs[i]);
}
}
jasmine.executeSpecs(domIndependentSpecs, function(runner, log) {
if (runner.results().failedCount === 0) {
process.exit(0);
} else {
process.exit(1);
}
}, isVerbose, showColors);

View File

@ -8,27 +8,11 @@
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw] // yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
undefined = "diz be undefined yo"; undefined = "diz be undefined yo";
</script> </script>
<link rel="shortcut icon" type="image/png" href="../images/jasmine_favicon.png">
<script type="text/javascript" src="../src/base.js"></script> <script type="text/javascript" src="../lib/jasmine.js"></script>
<script type="text/javascript" src="../src/util.js"></script>
<script type="text/javascript" src="../src/Env.js"></script>
<script type="text/javascript" src="../src/Reporter.js"></script>
<script type="text/javascript" src="../src/Block.js"></script>
<script type="text/javascript" src="../src/JsApiReporter.js"></script>
<script type="text/javascript" src="../src/Matchers.js"></script>
<script type="text/javascript" src="../src/mock-timeout.js"></script>
<script type="text/javascript" src="../src/MultiReporter.js"></script>
<script type="text/javascript" src="../src/NestedResults.js"></script>
<script type="text/javascript" src="../src/PrettyPrinter.js"></script>
<script type="text/javascript" src="../src/Queue.js"></script>
<script type="text/javascript" src="../src/Runner.js"></script>
<script type="text/javascript" src="../src/Spec.js"></script>
<script type="text/javascript" src="../src/Suite.js"></script>
<script type="text/javascript" src="../src/WaitsBlock.js"></script>
<script type="text/javascript" src="../src/WaitsForBlock.js"></script>
<script type="text/javascript" src="../src/html/TrivialReporter.js"></script> <script type="text/javascript" src="../src/html/TrivialReporter.js"></script>
<script type="text/javascript" src="../src/console/TrivialConsoleReporter.js"></script>
@ -50,6 +34,7 @@
<script type="text/javascript" src="suites/SpySpec.js"></script> <script type="text/javascript" src="suites/SpySpec.js"></script>
<script type="text/javascript" src="suites/SuiteSpec.js"></script> <script type="text/javascript" src="suites/SuiteSpec.js"></script>
<script type="text/javascript" src="suites/TrivialReporterSpec.js"></script> <script type="text/javascript" src="suites/TrivialReporterSpec.js"></script>
<script type="text/javascript" src="suites/TrivialConsoleReporterSpec.js"></script>
<script type="text/javascript" src="suites/WaitsForBlockSpec.js"></script> <script type="text/javascript" src="suites/WaitsForBlockSpec.js"></script>

View File

@ -108,7 +108,7 @@ describe("jasmine.Env", function() {
it("should give custom equality testers precedence", function() { it("should give custom equality testers precedence", function() {
expect(env.equals_('abc', 'abc')).toBeFalsy(); expect(env.equals_('abc', 'abc')).toBeFalsy();
var o = new Object(); var o = {};
expect(env.equals_(o, o)).toBeFalsy(); expect(env.equals_(o, o)).toBeFalsy();
}); });
}); });

View File

@ -89,9 +89,9 @@ describe('Exceptions:', function() {
expect(blockResults[0].message).toMatch(/fake error 1/); expect(blockResults[0].message).toMatch(/fake error 1/);
expect(specResults[1].passed()).toEqual(false); expect(specResults[1].passed()).toEqual(false);
var blockResults = specResults[1].getItems(); blockResults = specResults[1].getItems();
expect(blockResults[0].passed()).toEqual(false); expect(blockResults[0].passed()).toEqual(false);
expect(blockResults[0].message).toMatch(/fake error 2/), expect(blockResults[0].message).toMatch(/fake error 2/);
expect(blockResults[1].passed()).toEqual(true); expect(blockResults[1].passed()).toEqual(true);
expect(specResults[2].passed()).toEqual(true); expect(specResults[2].passed()).toEqual(true);
@ -101,7 +101,49 @@ describe('Exceptions:', function() {
expect(blockResults[0].message).toMatch(/fake error 3/); expect(blockResults[0].message).toMatch(/fake error 3/);
expect(specResults[4].passed()).toEqual(true); expect(specResults[4].passed()).toEqual(true);
}); });
it("should handle exceptions thrown directly in top-level describe blocks and continue", function () {
var suite = env.describe("a top level describe block that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
throw new Error("top level error");
});
suite.execute();
var suiteResults = suite.results();
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
expect(specResults.length).toEqual(2);
expect(specResults[1].description).toMatch(/encountered a declaration exception/);
});
it("should handle exceptions thrown directly in nested describe blocks and continue", function () {
var suite = env.describe("a top level describe", function () {
env.describe("a mid-level describe that throws an exception", function () {
env.it("is a test that should pass", function () {
this.expect(true).toEqual(true);
});
throw new Error("a mid-level error");
});
});
suite.execute();
var suiteResults = suite.results();
var specResults = suiteResults.getItems();
expect(suiteResults.passed()).toEqual(false);
expect(specResults.length).toEqual(1);
var nestedSpecResults = specResults[0].getItems();
expect(nestedSpecResults.length).toEqual(2);
expect(nestedSpecResults[1].description).toMatch(/encountered a declaration exception/);
});
}); });

View File

@ -21,7 +21,7 @@ describe('jasmine.jsApiReporter', function() {
nestedSuite = env.describe("nested suite", function() { nestedSuite = env.describe("nested suite", function() {
nestedSpec = env.it("nested spec", function() { nestedSpec = env.it("nested spec", function() {
expect(true).toEqual(true); expect(true).toEqual(true);
}) });
}); });
spec3 = env.it("spec 3", function() { spec3 = env.it("spec 3", function() {

View File

@ -18,7 +18,7 @@ describe("jasmine.Matchers", function() {
toFail: function() { toFail: function() {
return !lastResult().passed(); return !lastResult().passed();
} }
}) });
}); });
function match(value) { function match(value) {
@ -68,13 +68,13 @@ describe("jasmine.Matchers", function() {
expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toFail(); expect((match(['a', 'b']).toEqual(['a', jasmine.undefined]))).toFail();
expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toFail(); expect((match(['a', 'b']).toEqual(['a', 'b', jasmine.undefined]))).toFail();
expect((match(new String("cat")).toEqual("cat"))).toPass(); expect((match("cat").toEqual("cat"))).toPass();
expect((match(new String("cat")).toNotEqual("cat"))).toFail(); expect((match("cat").toNotEqual("cat"))).toFail();
expect((match(new Number(5)).toEqual(5))).toPass(); expect((match(5).toEqual(5))).toPass();
expect((match(new Number('5')).toEqual(5))).toPass(); expect((match(parseInt('5', 10)).toEqual(5))).toPass();
expect((match(new Number(5)).toNotEqual(5))).toFail(); expect((match(5).toNotEqual(5))).toFail();
expect((match(new Number('5')).toNotEqual(5))).toFail(); expect((match(parseInt('5', 10)).toNotEqual(5))).toFail();
}); });
it("toEqual with DOM nodes", function() { it("toEqual with DOM nodes", function() {
@ -348,10 +348,12 @@ describe("jasmine.Matchers", function() {
expect(match("foo").toEqual(jasmine.any(Object))).toFail(); expect(match("foo").toEqual(jasmine.any(Object))).toFail();
expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toPass(); expect(match({someObj:'foo'}).toEqual(jasmine.any(Object))).toPass();
expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail(); expect(match({someObj:'foo'}).toEqual(jasmine.any(Function))).toFail();
expect(match(function() { expect(match(
function() {
}).toEqual(jasmine.any(Object))).toFail(); }).toEqual(jasmine.any(Object))).toFail();
expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass(); expect(match(["foo", "goo"]).toEqual(["foo", jasmine.any(String)])).toPass();
expect(match(function() { expect(match(
function() {
}).toEqual(jasmine.any(Function))).toPass(); }).toEqual(jasmine.any(Function))).toPass();
expect(match(["a", function() { expect(match(["a", function() {
}]).toEqual(["a", jasmine.any(Function)])).toPass(); }]).toEqual(["a", jasmine.any(Function)])).toPass();
@ -471,6 +473,47 @@ describe("jasmine.Matchers", function() {
expect(result.expected).toEqual(expected); expect(result.expected).toEqual(expected);
}); });
describe("toBeCloseTo", function() {
it("returns 'true' iff actual and expected are equal within 2 decimal points of precision", function() {
expect(0).toBeCloseTo(0);
expect(1).toBeCloseTo(1);
expect(1).not.toBeCloseTo(1.1);
expect(1).not.toBeCloseTo(1.01);
expect(1).toBeCloseTo(1.001);
expect(1.23).toBeCloseTo(1.234);
expect(1.23).toBeCloseTo(1.233);
expect(1.23).toBeCloseTo(1.232);
expect(1.23).not.toBeCloseTo(1.24);
expect(-1.23).toBeCloseTo(-1.234);
expect(-1.23).not.toBeCloseTo(-1.24);
});
it("accepts an optional precision argument", function() {
expect(1).toBeCloseTo(1.1, 0);
expect(1.2).toBeCloseTo(1.23, 1);
expect(1.234).toBeCloseTo(1.2343, 3);
expect(1.234).not.toBeCloseTo(1.233, 3);
});
it("rounds", function() {
expect(1.23).toBeCloseTo(1.229);
expect(1.23).toBeCloseTo(1.226);
expect(1.23).toBeCloseTo(1.225);
expect(1.23).not.toBeCloseTo(1.2249999);
expect(1.23).toBeCloseTo(1.234);
expect(1.23).toBeCloseTo(1.2349999);
expect(1.23).not.toBeCloseTo(1.235);
expect(-1.23).toBeCloseTo(-1.234);
expect(-1.23).not.toBeCloseTo(-1.235);
expect(-1.23).not.toBeCloseTo(-1.236);
});
});
describe("toThrow", function() { describe("toThrow", function() {
describe("when code block throws an exception", function() { describe("when code block throws an exception", function() {
var throwingFn; var throwingFn;
@ -540,7 +583,8 @@ describe("jasmine.Matchers", function() {
describe("when code block does not throw an exception", function() { describe("when code block does not throw an exception", function() {
it("should fail (or pass when inverted with .not)", function() { it("should fail (or pass when inverted with .not)", function() {
expect(match(function() { expect(match(
function() {
}).toThrow()).toFail(); }).toThrow()).toFail();
expect(lastResult().message).toEqual('Expected function to throw an exception.'); expect(lastResult().message).toEqual('Expected function to throw an exception.');
}); });
@ -596,19 +640,23 @@ describe("jasmine.Matchers", function() {
function shouldThrowAnExceptionWhenInvokedOnANonSpy(methodName) { function shouldThrowAnExceptionWhenInvokedOnANonSpy(methodName) {
return function() { return function() {
expect(function() { expect(
function() {
match(TestClass.normalFunction)[methodName](); match(TestClass.normalFunction)[methodName]();
}).toThrow('Expected a spy, but got Function.'); }).toThrow('Expected a spy, but got Function.');
expect(function() { expect(
function() {
match(jasmine.undefined)[methodName](); match(jasmine.undefined)[methodName]();
}).toThrow('Expected a spy, but got undefined.'); }).toThrow('Expected a spy, but got undefined.');
expect(function() { expect(
function() {
match({some:'object'})[methodName](); match({some:'object'})[methodName]();
}).toThrow('Expected a spy, but got { some : \'object\' }.'); }).toThrow('Expected a spy, but got { some : \'object\' }.');
expect(function() { expect(
function() {
match("<b>")[methodName](); match("<b>")[methodName]();
}).toThrow('Expected a spy, but got \'<b>\'.'); }).toThrow('Expected a spy, but got \'<b>\'.');
}; };
@ -623,7 +671,8 @@ describe("jasmine.Matchers", function() {
}); });
it("should throw an exception when invoked with any arguments", function() { it("should throw an exception when invoked with any arguments", function() {
expect(function() { expect(
function() {
match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument"); match(TestClass.normalFunction).toHaveBeenCalled("unwanted argument");
}).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); }).toThrow('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
}); });
@ -651,7 +700,8 @@ describe("jasmine.Matchers", function() {
}); });
it("should throw an exception when invoked with any arguments", function() { it("should throw an exception when invoked with any arguments", function() {
expect(function() { expect(
function() {
match(TestClass.normalFunction).wasNotCalled("unwanted argument"); match(TestClass.normalFunction).wasNotCalled("unwanted argument");
}).toThrow('wasNotCalled does not take arguments'); }).toThrow('wasNotCalled does not take arguments');
}); });
@ -701,7 +751,7 @@ describe("jasmine.Matchers", function() {
TestClass.spyFunction('d', 'e', 'f'); TestClass.spyFunction('d', 'e', 'f');
var expected = match(TestClass.spyFunction); var expected = match(TestClass.spyFunction);
expect(expected.toHaveBeenCalledWith('a', 'b')).toFail(); expect(expected.toHaveBeenCalledWith('a', 'b')).toFail();
expect(lastResult().message).toEqual("Expected spy to have been called with [ 'a', 'b' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]"); expect(lastResult().message).toEqual("Expected spy My spy to have been called with [ 'a', 'b' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
}); });
it("should return a decent message when inverted", function() { it("should return a decent message when inverted", function() {
@ -709,7 +759,7 @@ describe("jasmine.Matchers", function() {
TestClass.spyFunction('d', 'e', 'f'); TestClass.spyFunction('d', 'e', 'f');
var expected = match(TestClass.spyFunction); var expected = match(TestClass.spyFunction);
expect(expected.not.toHaveBeenCalledWith('a', 'b', 'c')).toFail(); expect(expected.not.toHaveBeenCalledWith('a', 'b', 'c')).toFail();
expect(lastResult().message).toEqual("Expected spy not to have been called with [ 'a', 'b', 'c' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]"); expect(lastResult().message).toEqual("Expected spy My spy not to have been called with [ 'a', 'b', 'c' ] but was called with [ [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] ]");
}); });
it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalledWith')); it('should throw an exception when invoked on a non-spy', shouldThrowAnExceptionWhenInvokedOnANonSpy('toHaveBeenCalledWith'));

View File

@ -18,9 +18,9 @@ describe("jasmine.MultiReporter", function() {
delegate[methodName] = jasmine.createSpy(methodName); delegate[methodName] = jasmine.createSpy(methodName);
this.actual[methodName]("whatever argument"); this.actual[methodName]("whatever argument");
return delegate[methodName].wasCalled return delegate[methodName].wasCalled &&
&& delegate[methodName].mostRecentCall.args.length == 1 delegate[methodName].mostRecentCall.args.length == 1 &&
&& delegate[methodName].mostRecentCall.args[0] == "whatever argument"; delegate[methodName].mostRecentCall.args[0] == "whatever argument";
} }
}); });

View File

@ -107,7 +107,6 @@ describe('RunnerTest', function() {
}); });
}); });
it('should run child suites and specs and generate results when execute is called', function() { it('should run child suites and specs and generate results when execute is called', function() {
env.describe('one suite description', function () { env.describe('one suite description', function () {
env.it('should be a test', function() { env.it('should be a test', function() {

View File

@ -54,7 +54,7 @@ describe("jasmine spec running", function () {
this.expect(foo).toEqual('baz'); this.expect(foo).toEqual('baz');
}); });
specWithMultipleExpectations = env.it('spec with multiple assertions').runs(function () { specWithMultipleExpectations = env.it('spec with multiple expectations').runs(function () {
var foo = 'bar'; var foo = 'bar';
var baz = 'quux'; var baz = 'quux';
@ -1225,6 +1225,9 @@ describe("jasmine spec running", function () {
this.expect(true).toEqual(true); this.expect(true).toEqual(true);
}); });
}); });
throw new Error("fake error");
}); });
} catch(e) { } catch(e) {
} }
@ -1241,10 +1244,12 @@ describe("jasmine spec running", function () {
expect(specs.join('')).toMatch(new RegExp( expect(specs.join('')).toMatch(new RegExp(
'Spec: outer1 inner1 should thingy.' + 'Spec: outer1 inner1 should thingy.' +
'Result: Passed.' + 'Result: Passed.' +
'Spec: outer1 encountered a declaration exception.' + 'Spec: outer1 inner1 encountered a declaration exception.' +
'Result: Error: fake error.*' + 'Result: Error: fake error.*' +
'Spec: outer1 inner2 should other thingy.' + 'Spec: outer1 inner2 should other thingy.' +
'Result: Passed.' + 'Result: Passed.' +
'Spec: outer1 encountered a declaration exception.' +
'Result: Error: fake error.*' +
'Spec: outer2 should xxx.' + 'Spec: outer2 should xxx.' +
'Result: Passed.' 'Result: Passed.'
)); ));

View File

@ -36,9 +36,22 @@ describe('Spec', function () {
}); });
}); });
describe('full name', function() {
describe('with string', function() {
it('getFullName returns suite & spec description', function () { it('getFullName returns suite & spec description', function () {
var spec = new jasmine.Spec(env, suite, 'spec 1'); var spec = new jasmine.Spec(env, suite, 'spec 1');
expect(spec.getFullName()).toEqual('suite 1 spec 1.') expect(spec.getFullName()).toEqual('suite 1 spec 1.');
});
});
describe('with class name', function () {
function MyClass() {}
it('getFullName returns suite & spec description', function () {
var spec = new jasmine.Spec(env, suite, MyClass);
expect(spec.getFullName()).toEqual('suite 1 MyClass.');
});
});
}); });
describe('results', function () { describe('results', function () {

View File

@ -67,6 +67,22 @@ describe('Suite', function() {
}); });
}); });
describe('getFullName', function() {
describe('with class', function() {
function MyClass() {}
it('should use the name of the class if provided as the description', function() {
suite = env.describe(MyClass, function() {
env.it('should be something', function() {
});
});
expect(suite.getFullName()).toEqual("MyClass");
expect(suite.children()[0].getFullName()).toEqual("MyClass should be something.");
});
});
});
describe('SpecCount', function () { describe('SpecCount', function () {
it('should keep a count of the number of specs that are run', function() { it('should keep a count of the number of specs that are run', function() {

View File

@ -0,0 +1,490 @@
describe("TrivialConsoleReporter", function() {
//keep these literal. otherwise the test loses value as a test.
function green(str) {
return '\033[32m' + str + '\033[0m';
}
function red(str) {
return '\033[31m' + str + '\033[0m';
}
function yellow(str) {
return '\033[33m' + str + '\033[0m';
}
function prefixGreen(str) {
return '\033[32m' + str;
}
function prefixRed(str) {
return '\033[31m' + str;
}
var newline = "\n";
var passingSpec = {
results: function() {
return {
passed: function() {
return true;
}
};
}
},
failingSpec = {
results: function() {
return {
passed: function() {
return false;
}
};
}
},
skippedSpec = {
results: function() {
return {skipped: true};
}
},
passingRun = {
specs: function() {
return [null, null, null];
},
results: function() {
return {failedCount: 0, items_: [null, null, null]};
}
},
failingRun = {
specs: function() {
return [null, null, null];
},
results: function() {
return {
failedCount: 7, items_: [null, null, null]};
}
};
function repeatedlyInvoke(f, times) {
for (var i = 0; i < times; i++) f(times + 1);
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) arr.push(thing);
return arr;
}
function simulateRun(reporter, specResults, suiteResults, finalRunner, startTime, endTime) {
reporter.reportRunnerStarting();
for (var i = 0; i < specResults.length; i++) {
reporter.reportSpecResults(specResults[i]);
}
for (i = 0; i < suiteResults.length; i++) {
reporter.reportSuiteResults(suiteResults[i]);
}
reporter.runnerStartTime = startTime;
reporter.now = function() {
return endTime;
};
reporter.reportRunnerResults(finalRunner);
}
var reporter, out, done;
beforeEach(function() {
out = (function() {
var output = "";
return {
print:function(str) {
output += str;
},
getOutput:function() {
return output;
},
clear: function() {
output = "";
}
};
})();
done = false;
reporter = new jasmine.TrivialConsoleReporter(out.print, function(runner) {
done = true
});
});
describe('Integration', function() {
it("prints the proper output under a pass scenario. small numbers.", function() {
simulateRun(reporter,
repeat(passingSpec, 3),
[],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 0
};
}
},
1000,
1777
);
expect(out.getOutput()).toEqual(
[
"Started",
green(".") + green(".") + green("."),
"",
"Finished in 0.777 seconds",
green("3 specs, 7 expectations, 0 failures"),
""
].join("\n") + "\n"
);
});
it("prints the proper output under a pass scenario. large numbers.", function() {
simulateRun(reporter,
repeat(passingSpec, 57),
[],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 0
};
}
},
1000,
1777);
expect(out.getOutput()).toEqual(
[
"Started",
green(".") + green(".") + green(".") + green(".") + green(".") + //50 green dots
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") +
green(".") + green(".") + green(".") + green(".") + green(".") + //7 green dots
green(".") + green("."),
"",
"Finished in 0.777 seconds",
green("3 specs, 7 expectations, 0 failures"),
""
].join("\n") + "\n"
);
});
it("prints the proper output under a failure scenario.", function() {
simulateRun(reporter,
[failingSpec, passingSpec, failingSpec],
[
{description:"The oven",
results:function() {
return {
items_:[
{failedCount:2,
description:"heats up",
items_:[
{trace:{stack:"stack trace one\n second line"}},
{trace:{stack:"stack trace two"}}
]}
]
};
}},
{description:"The washing machine",
results:function() {
return {
items_:[
{failedCount:2,
description:"washes clothes",
items_:[
{trace:{stack:"stack trace one"}}
]}
]
};
}}
],
{
specs: function() {
return [null, null, null];
},
results:function() {
return {
items_: [null, null, null],
totalCount: 7,
failedCount: 2
};
}
},
1000,
1777);
expect(out.getOutput()).toEqual(
[
"Started",
red("F") + green(".") + red("F"),
"",
"The oven heats up",
" stack trace one",
" second line",
" stack trace two",
"",
"The washing machine washes clothes",
" stack trace one",
"",
"Finished in 0.777 seconds",
red("3 specs, 7 expectations, 2 failures"),
""
].join("\n") + "\n"
);
});
});
describe('When a Jasmine environment executes', function() {
beforeEach(function() {
reporter.reportRunnerStarting();
});
it("should print 'Started' to the console", function() {
expect(out.getOutput()).toEqual("Started" + newline);
});
describe('when a spec reports', function() {
beforeEach(function() {
out.clear();
});
it("prints a green dot if the spec passes", function() {
reporter.reportSpecResults(passingSpec);
expect(out.getOutput()).toEqual(green("."));
});
it("prints a red dot if the spec fails", function() {
reporter.reportSpecResults(failingSpec);
expect(out.getOutput()).toEqual(red("F"));
});
it("prints a yellow star if the spec was skipped", function() {
reporter.reportSpecResults(skippedSpec);
expect(out.getOutput()).toEqual(yellow("*"));
});
});
describe('when a suite reports', function() {
var emptyResults;
beforeEach(function() {
emptyResults = function() {
return {
items_:[]
};
};
});
it("remembers suite results", function() {
reporter.reportSuiteResults({description: "Oven", results: emptyResults});
reporter.reportSuiteResults({description: "Mixer", results: emptyResults});
expect(reporter.suiteResults[0].description).toEqual('Oven');
expect(reporter.suiteResults[1].description).toEqual('Mixer');
});
it("creates a description out of the current suite and any parent suites", function() {
var grandparentSuite = {
description: "My house",
results: emptyResults
};
var parentSuite = {
description: "kitchen",
parentSuite: grandparentSuite,
results: emptyResults
};
reporter.reportSuiteResults({ description: "oven", parentSuite: parentSuite, results: emptyResults });
expect(reporter.suiteResults[0].description).toEqual("My house kitchen oven");
});
it("gathers failing spec results from the suite - the spec must have a description.", function() {
reporter.reportSuiteResults({description:"Oven",
results: function() {
return {
items_:[
{ failedCount: 0, description: "specOne" },
{ failedCount: 99, description: "specTwo" },
{ failedCount: 0, description: "specThree" },
{ failedCount: 88, description: "specFour" },
{ failedCount: 3 }
]
};
}});
expect(reporter.suiteResults[0].failedSpecResults).
toEqual([
{ failedCount: 99, description: "specTwo" },
{ failedCount: 88, description: "specFour" }
]);
});
});
describe('and finishes', function() {
describe('when reporting spec failure information', function() {
it("prints suite and spec descriptions together as a sentence", function() {
reporter.suiteResults = [
{description:"The oven", failedSpecResults:[
{description:"heats up", items_:[]},
{description:"cleans itself", items_:[]}
]},
{description:"The mixer", failedSpecResults:[
{description:"blends things together", items_:[]}
]}
];
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("The oven heats up");
expect(out.getOutput()).toContain("The oven cleans itself");
expect(out.getOutput()).toContain("The mixer blends things together");
});
it("prints stack trace of spec failure", function() {
reporter.suiteResults = [
{description:"The oven", failedSpecResults:[
{description:"heats up",
items_:[
{trace:{stack:"stack trace one"}},
{trace:{stack:"stack trace two"}}
]}
]}
];
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("The oven heats up");
expect(out.getOutput()).toContain("stack trace one");
expect(out.getOutput()).toContain("stack trace two");
});
});
describe('when reporting the execution time', function() {
it("prints the full finished message", function() {
reporter.now = function() {
return 1000;
};
reporter.reportRunnerStarting();
reporter.now = function() {
return 1777;
};
reporter.reportRunnerResults(failingRun);
expect(out.getOutput()).toContain("Finished in 0.777 seconds");
});
it("prints round time numbers correctly", function() {
function run(startTime, endTime) {
out.clear();
reporter.runnerStartTime = startTime;
reporter.now = function() {
return endTime;
};
reporter.reportRunnerResults(passingRun);
}
run(1000, 11000);
expect(out.getOutput()).toContain("10 seconds");
run(1000, 2000);
expect(out.getOutput()).toContain("1 seconds");
run(1000, 1100);
expect(out.getOutput()).toContain("0.1 seconds");
run(1000, 1010);
expect(out.getOutput()).toContain("0.01 seconds");
run(1000, 1001);
expect(out.getOutput()).toContain("0.001 seconds");
});
});
describe("when reporting the results summary", function() {
it("prints statistics in green if there were no failures", function() {
reporter.reportRunnerResults({
specs: function() {
return [null, null, null];
},
results:function() {
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
}
});
expect(out.getOutput()).
toContain("3 specs, 7 expectations, 0 failures");
});
it("prints statistics in red if there was a failure", function() {
reporter.reportRunnerResults({
specs: function() {
return [null, null, null];
},
results:function() {
return {items_: [null, null, null], totalCount: 7, failedCount: 3};
}
});
expect(out.getOutput()).
toContain("3 specs, 7 expectations, 3 failures");
});
it("handles pluralization with 1's ones appropriately", function() {
reporter.reportRunnerResults({
specs: function() {
return [null];
},
results:function() {
return {items_: [null], totalCount: 1, failedCount: 1};
}
});
expect(out.getOutput()).
toContain("1 spec, 1 expectation, 1 failure");
});
});
describe("done callback", function() {
it("calls back when done", function() {
expect(done).toBeFalsy();
reporter.reportRunnerResults({
specs: function() {
return [null, null, null];
},
results:function() {
return {items_: [null, null, null], totalCount: 7, failedCount: 0};
}
});
expect(done).toBeTruthy();
});
});
});
});
});

View File

@ -172,6 +172,9 @@ describe("TrivialReporter", function() {
var errorDiv = findElement(divs, 'resultMessage log'); var errorDiv = findElement(divs, 'resultMessage log');
expect(errorDiv.innerHTML).toEqual("this is a multipart log message"); expect(errorDiv.innerHTML).toEqual("this is a multipart log message");
}); });
xit("should work on IE without console.log.apply", function() {
});
}); });
describe("duplicate example names", function() { describe("duplicate example names", function() {

View File

@ -25,7 +25,6 @@ describe("jasmine.util", function() {
it("should return true if the argument is an array", function() { it("should return true if the argument is an array", function() {
expect(jasmine.isArray_([])).toBe(true); expect(jasmine.isArray_([])).toBe(true);
expect(jasmine.isArray_(['a'])).toBe(true); expect(jasmine.isArray_(['a'])).toBe(true);
expect(jasmine.isArray_(new Array())).toBe(true);
}); });
it("should return false if the argument is not an array", function() { it("should return false if the argument is not an array", function() {

View File

@ -10,6 +10,37 @@ describe('WaitsForBlock', function () {
onComplete = jasmine.createSpy("onComplete"); onComplete = jasmine.createSpy("onComplete");
}); });
describe("jasmine.VERBOSE", function() {
var jasmineVerboseOriginal;
beforeEach(function() {
jasmineVerboseOriginal = jasmine.VERBOSE;
spyOn(env.reporter, 'log');
});
it('do not show information if jasmine.VERBOSE is set to false', function () {
jasmine.VERBOSE = false;
var latchFunction = function() {
return true;
};
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(env.reporter.log).not.toHaveBeenCalled();
block.execute(onComplete);
expect(env.reporter.log).not.toHaveBeenCalled();
jasmine.VERBOSE = jasmineVerboseOriginal;
});
it('show information if jasmine.VERBOSE is set to true', function () {
jasmine.VERBOSE = true;
var latchFunction = function() {
return true;
};
var block = new jasmine.WaitsForBlock(env, timeout, latchFunction, message, spec);
expect(env.reporter.log).not.toHaveBeenCalled();
block.execute(onComplete);
expect(env.reporter.log).toHaveBeenCalled();
jasmine.VERBOSE = jasmineVerboseOriginal;
});
});
it('onComplete should be called if the latchFunction returns true', function () { it('onComplete should be called if the latchFunction returns true', function () {
var latchFunction = function() { var latchFunction = function() {
return true; return true;

7
src/SourcesList.json Normal file
View File

@ -0,0 +1,7 @@
[
"base.js",
"util.js",
"Env.js",
"Reporter.js",
"Block.js"
]

View File

@ -0,0 +1,193 @@
jasmine.TrivialConsoleReporter = function(print, doneCallback) {
//inspired by mhevery's jasmine-node reporter
//https://github.com/mhevery/jasmine-node
doneCallback = doneCallback || function() {
};
var defaultColumnsPerLine = 50,
ansi = {
green: '\033[32m',
red: '\033[31m',
yellow: '\033[33m',
none: '\033[0m'
},
language = {
spec: "spec",
expectation: "expectation",
failure: "failure"
};
function coloredStr(color, str) {
return ansi[color] + str + ansi.none;
}
function greenStr(str) {
return coloredStr("green", str);
}
function redStr(str) {
return coloredStr("red", str);
}
function yellowStr(str) {
return coloredStr("yellow", str);
}
function newline() {
print("\n");
}
function started() {
print("Started");
newline();
}
function greenDot() {
print(greenStr("."));
}
function redF() {
print(redStr("F"));
}
function yellowStar() {
print(yellowStr("*"));
}
function plural(str, count) {
return count == 1 ? str : str + "s";
}
function repeat(thing, times) {
var arr = [];
for (var i = 0; i < times; i++) arr.push(thing);
return arr;
}
function indent(str, spaces) {
var lines = (str || '').split("\n");
var newArr = [];
for (var i = 0; i < lines.length; i++) {
newArr.push(repeat(" ", spaces).join("") + lines[i]);
}
return newArr.join("\n");
}
function specFailureDetails(suiteDescription, specDescription, stackTraces) {
newline();
print(suiteDescription + " " + specDescription);
newline();
for (var i = 0; i < stackTraces.length; i++) {
print(indent(stackTraces[i], 2));
newline();
}
}
function finished(elapsed) {
newline();
print("Finished in " + elapsed / 1000 + " seconds");
}
function summary(colorF, specs, expectations, failed) {
newline();
print(colorF(specs + " " + plural(language.spec, specs) + ", " +
expectations + " " + plural(language.expectation, expectations) + ", " +
failed + " " + plural(language.failure, failed)));
newline();
newline();
}
function greenSummary(specs, expectations, failed) {
summary(greenStr, specs, expectations, failed);
}
function redSummary(specs, expectations, failed) {
summary(redStr, specs, expectations, failed);
}
function lineEnder(columnsPerLine) {
var columnsSoFar = 0;
return function() {
columnsSoFar += 1;
if (columnsSoFar == columnsPerLine) {
newline();
columnsSoFar = 0;
}
};
}
function fullSuiteDescription(suite) {
var fullDescription = suite.description;
if (suite.parentSuite) fullDescription = fullSuiteDescription(suite.parentSuite) + " " + fullDescription;
return fullDescription;
}
var startNewLineIfNecessary = lineEnder(defaultColumnsPerLine);
this.now = function() {
return new Date().getTime();
};
this.reportRunnerStarting = function() {
this.runnerStartTime = this.now();
started();
};
this.reportSpecStarting = function() { /* do nothing */
};
this.reportSpecResults = function(spec) {
var results = spec.results();
if (results.skipped) {
yellowStar();
} else if (results.passed()) {
greenDot();
} else {
redF();
}
// startNewLineIfNecessary();
};
this.suiteResults = [];
this.reportSuiteResults = function(suite) {
var suiteResult = {
description: fullSuiteDescription(suite),
failedSpecResults: []
};
suite.results().items_.forEach(function(spec) {
if (spec.failedCount > 0 && spec.description) suiteResult.failedSpecResults.push(spec);
});
this.suiteResults.push(suiteResult);
};
function eachSpecFailure(suiteResults, callback) {
for (var i = 0; i < suiteResults.length; i++) {
var suiteResult = suiteResults[i];
for (var j = 0; j < suiteResult.failedSpecResults.length; j++) {
var failedSpecResult = suiteResult.failedSpecResults[j];
var stackTraces = [];
for (var k = 0; k < failedSpecResult.items_.length; k++) stackTraces.push(failedSpecResult.items_[k].trace.stack);
callback(suiteResult.description, failedSpecResult.description, stackTraces);
}
}
}
this.reportRunnerResults = function(runner) {
newline();
eachSpecFailure(this.suiteResults, function(suiteDescription, specDescription, stackTraces) {
specFailureDetails(suiteDescription, specDescription, stackTraces);
});
finished(this.now() - this.runnerStartTime);
var results = runner.results();
var summaryFunction = results.failedCount === 0 ? greenSummary : redSummary;
summaryFunction(runner.specs().length, results.totalCount, results.failedCount);
doneCallback(runner);
};
};

View File

@ -104,14 +104,14 @@ jasmine.Env.prototype.describe = function(description, specDefinitions) {
declarationError = e; declarationError = e;
} }
this.currentSuite = parentSuite;
if (declarationError) { if (declarationError) {
this.it("encountered a declaration exception", function() { this.it("encountered a declaration exception", function() {
throw declarationError; throw declarationError;
}); });
} }
this.currentSuite = parentSuite;
return suite; return suite;
}; };
@ -172,7 +172,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
b.__Jasmine_been_here_before__ = a; b.__Jasmine_been_here_before__ = a;
var hasKey = function(obj, keyName) { var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== jasmine.undefined; return obj !== null && obj[keyName] !== jasmine.undefined;
}; };
for (var property in b) { for (var property in b) {
@ -198,7 +198,7 @@ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchVal
delete a.__Jasmine_been_here_before__; delete a.__Jasmine_been_here_before__;
delete b.__Jasmine_been_here_before__; delete b.__Jasmine_been_here_before__;
return (mismatchKeys.length == 0 && mismatchValues.length == 0); return (mismatchKeys.length === 0 && mismatchValues.length === 0);
}; };
jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {

View File

@ -227,16 +227,16 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
} }
this.message = function() { this.message = function() {
if (this.actual.callCount == 0) { if (this.actual.callCount === 0) {
// todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
return [ return [
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was." "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
]; ];
} else { } else {
return [ return [
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
]; ];
} }
}; };
@ -258,7 +258,7 @@ jasmine.Matchers.prototype.wasNotCalledWith = function() {
return [ return [
"Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
"Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
] ];
}; };
return !this.env.contains_(this.actual.argsForCall, expectedArgs); return !this.env.contains_(this.actual.argsForCall, expectedArgs);
@ -291,6 +291,23 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
return this.actual > expected; return this.actual > expected;
}; };
/**
* Matcher that checks that the expected item is equal to the actual item
* up to a given level of decimal precision (default 2).
*
* @param {Number} expected
* @param {Number} precision
*/
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
if (!(precision === 0)) {
precision = precision || 2;
}
var multiplier = Math.pow(10, precision);
var actual = Math.round(this.actual * multiplier);
expected = Math.round(expected * multiplier);
return expected == actual;
};
/** /**
* Matcher that checks that the expected exception was thrown by the actual. * Matcher that checks that the expected exception was thrown by the actual.
* *
@ -315,7 +332,7 @@ jasmine.Matchers.prototype.toThrow = function(expected) {
this.message = function() { this.message = function() {
if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' '); return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
} else { } else {
return "Expected function to throw an exception."; return "Expected function to throw an exception.";
} }

View File

@ -58,7 +58,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
for (var property in obj) { for (var property in obj) {
if (property == '__Jasmine_been_here_before__') continue; if (property == '__Jasmine_been_here_before__') continue;
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false); fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
obj.__lookupGetter__(property) !== null) : false);
} }
}; };

View File

@ -29,7 +29,8 @@ jasmine.Spec = function(env, suite, description) {
}; };
jasmine.Spec.prototype.getFullName = function() { jasmine.Spec.prototype.getFullName = function() {
return this.suite.getFullName() + ' ' + this.description + '.'; var description = (this.description.apply ? this.description.name : this.description);
return this.suite.getFullName() + ' ' + description + '.';
}; };
@ -120,7 +121,8 @@ jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessag
jasmine.Spec.prototype.fail = function (e) { jasmine.Spec.prototype.fail = function (e) {
var expectationResult = new jasmine.ExpectationResult({ var expectationResult = new jasmine.ExpectationResult({
passed: false, passed: false,
message: e ? jasmine.util.formatException(e) : 'Exception' message: e ? jasmine.util.formatException(e) : 'Exception',
trace: { stack: e.stack }
}); });
this.results_.addResult(expectationResult); this.results_.addResult(expectationResult);
}; };

View File

@ -22,7 +22,7 @@ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
}; };
jasmine.Suite.prototype.getFullName = function() { jasmine.Suite.prototype.getFullName = function() {
var fullName = this.description; var fullName = (this.description.apply ? this.description.name : this.description);
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
fullName = parentSuite.description + ' ' + fullName; fullName = parentSuite.description + ' ' + fullName;
} }

View File

@ -6,7 +6,9 @@ jasmine.WaitsBlock = function(env, timeout, spec) {
jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
jasmine.WaitsBlock.prototype.execute = function (onComplete) { jasmine.WaitsBlock.prototype.execute = function (onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
}
this.env.setTimeout(function () { this.env.setTimeout(function () {
onComplete(); onComplete();
}, this.timeout); }, this.timeout);

View File

@ -21,7 +21,9 @@ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
jasmine.WaitsForBlock.prototype.execute = function(onComplete) { jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
if (jasmine.VERBOSE) {
this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
}
var latchFunctionResult; var latchFunctionResult;
try { try {
latchFunctionResult = this.latchFunction.apply(this.spec); latchFunctionResult = this.latchFunction.apply(this.spec);

View File

@ -1,10 +1,12 @@
var isCommonJS = typeof window == "undefined";
/** /**
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
* *
* @namespace * @namespace
*/ */
var jasmine = {}; var jasmine = {};
if (isCommonJS) exports.jasmine = jasmine;
/** /**
* @private * @private
*/ */
@ -20,6 +22,12 @@ jasmine.unimplementedMethod_ = function() {
*/ */
jasmine.undefined = jasmine.___undefined___; jasmine.undefined = jasmine.___undefined___;
/**
* Show diagnostic messages in the console if set to true
*
*/
jasmine.VERBOSE = false;
/** /**
* Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
* *
@ -72,7 +80,7 @@ jasmine.MessageResult = function(values) {
jasmine.MessageResult.prototype.toString = function() { jasmine.MessageResult.prototype.toString = function() {
var text = ""; var text = "";
for(var i = 0; i < this.values.length; i++) { for (var i = 0; i < this.values.length; i++) {
if (i > 0) text += " "; if (i > 0) text += " ";
if (jasmine.isString_(this.values[i])) { if (jasmine.isString_(this.values[i])) {
text += this.values[i]; text += this.values[i];
@ -89,9 +97,10 @@ jasmine.ExpectationResult = function(params) {
this.passed_ = params.passed; this.passed_ = params.passed;
this.expected = params.expected; this.expected = params.expected;
this.actual = params.actual; this.actual = params.actual;
this.message = this.passed_ ? 'Passed.' : params.message; this.message = this.passed_ ? 'Passed.' : params.message;
this.trace = this.passed_ ? '' : new Error(this.message);
var trace = (params.trace || new Error(this.message));
this.trace = this.passed_ ? '' : trace;
}; };
jasmine.ExpectationResult.prototype.toString = function () { jasmine.ExpectationResult.prototype.toString = function () {
@ -106,7 +115,8 @@ jasmine.ExpectationResult.prototype.passed = function () {
* Getter for the Jasmine environment. Ensures one gets created * Getter for the Jasmine environment. Ensures one gets created
*/ */
jasmine.getEnv = function() { jasmine.getEnv = function() {
return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
return env;
}; };
/** /**
@ -169,7 +179,7 @@ jasmine.pp = function(value) {
* @returns {Boolean} * @returns {Boolean}
*/ */
jasmine.isDomNode = function(obj) { jasmine.isDomNode = function(obj) {
return obj['nodeType'] > 0; return obj.nodeType > 0;
}; };
/** /**
@ -405,7 +415,7 @@ jasmine.isSpy = function(putativeSpy) {
* @param {Array} methodNames array of names of methods to make spies * @param {Array} methodNames array of names of methods to make spies
*/ */
jasmine.createSpyObj = function(baseName, methodNames) { jasmine.createSpyObj = function(baseName, methodNames) {
if (!jasmine.isArray_(methodNames) || methodNames.length == 0) { if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
} }
var obj = {}; var obj = {};
@ -443,6 +453,7 @@ jasmine.log = function() {
var spyOn = function(obj, methodName) { var spyOn = function(obj, methodName) {
return jasmine.getEnv().currentSpec.spyOn(obj, methodName); return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
}; };
if (isCommonJS) exports.spyOn = spyOn;
/** /**
* Creates a Jasmine spec that will be added to the current suite. * Creates a Jasmine spec that will be added to the current suite.
@ -460,6 +471,7 @@ var spyOn = function(obj, methodName) {
var it = function(desc, func) { var it = function(desc, func) {
return jasmine.getEnv().it(desc, func); return jasmine.getEnv().it(desc, func);
}; };
if (isCommonJS) exports.it = it;
/** /**
* Creates a <em>disabled</em> Jasmine spec. * Creates a <em>disabled</em> Jasmine spec.
@ -472,6 +484,7 @@ var it = function(desc, func) {
var xit = function(desc, func) { var xit = function(desc, func) {
return jasmine.getEnv().xit(desc, func); return jasmine.getEnv().xit(desc, func);
}; };
if (isCommonJS) exports.xit = xit;
/** /**
* Starts a chain for a Jasmine expectation. * Starts a chain for a Jasmine expectation.
@ -484,6 +497,7 @@ var xit = function(desc, func) {
var expect = function(actual) { var expect = function(actual) {
return jasmine.getEnv().currentSpec.expect(actual); return jasmine.getEnv().currentSpec.expect(actual);
}; };
if (isCommonJS) exports.expect = expect;
/** /**
* Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
@ -493,6 +507,7 @@ var expect = function(actual) {
var runs = function(func) { var runs = function(func) {
jasmine.getEnv().currentSpec.runs(func); jasmine.getEnv().currentSpec.runs(func);
}; };
if (isCommonJS) exports.runs = runs;
/** /**
* Waits a fixed time period before moving to the next block. * Waits a fixed time period before moving to the next block.
@ -503,6 +518,7 @@ var runs = function(func) {
var waits = function(timeout) { var waits = function(timeout) {
jasmine.getEnv().currentSpec.waits(timeout); jasmine.getEnv().currentSpec.waits(timeout);
}; };
if (isCommonJS) exports.waits = waits;
/** /**
* Waits for the latchFunction to return true before proceeding to the next block. * Waits for the latchFunction to return true before proceeding to the next block.
@ -514,6 +530,7 @@ var waits = function(timeout) {
var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
}; };
if (isCommonJS) exports.waitsFor = waitsFor;
/** /**
* A function that is called before each spec in a suite. * A function that is called before each spec in a suite.
@ -525,6 +542,7 @@ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout
var beforeEach = function(beforeEachFunction) { var beforeEach = function(beforeEachFunction) {
jasmine.getEnv().beforeEach(beforeEachFunction); jasmine.getEnv().beforeEach(beforeEachFunction);
}; };
if (isCommonJS) exports.beforeEach = beforeEach;
/** /**
* A function that is called after each spec in a suite. * A function that is called after each spec in a suite.
@ -536,6 +554,7 @@ var beforeEach = function(beforeEachFunction) {
var afterEach = function(afterEachFunction) { var afterEach = function(afterEachFunction) {
jasmine.getEnv().afterEach(afterEachFunction); jasmine.getEnv().afterEach(afterEachFunction);
}; };
if (isCommonJS) exports.afterEach = afterEach;
/** /**
* Defines a suite of specifications. * Defines a suite of specifications.
@ -555,6 +574,7 @@ var afterEach = function(afterEachFunction) {
var describe = function(description, specDefinitions) { var describe = function(description, specDefinitions) {
return jasmine.getEnv().describe(description, specDefinitions); return jasmine.getEnv().describe(description, specDefinitions);
}; };
if (isCommonJS) exports.describe = describe;
/** /**
* Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
@ -565,25 +585,33 @@ var describe = function(description, specDefinitions) {
var xdescribe = function(description, specDefinitions) { var xdescribe = function(description, specDefinitions) {
return jasmine.getEnv().xdescribe(description, specDefinitions); return jasmine.getEnv().xdescribe(description, specDefinitions);
}; };
if (isCommonJS) exports.xdescribe = xdescribe;
// Provide the XMLHttpRequest class for IE 5.x-6.x: // Provide the XMLHttpRequest class for IE 5.x-6.x:
jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
function tryIt(f) {
try { try {
return f();
} catch(e) {
}
return null;
}
var xhr = tryIt(function() {
return new ActiveXObject("Msxml2.XMLHTTP.6.0"); return new ActiveXObject("Msxml2.XMLHTTP.6.0");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0"); return new ActiveXObject("Msxml2.XMLHTTP.3.0");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP"); return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) { }) ||
} tryIt(function() {
try {
return new ActiveXObject("Microsoft.XMLHTTP"); return new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) { });
}
throw new Error("This browser does not support XMLHttpRequest."); if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
return xhr;
} : XMLHttpRequest; } : XMLHttpRequest;

View File

@ -17,7 +17,7 @@ jasmine.util.inherit = function(childClass, parentClass) {
var subclass = function() { var subclass = function() {
}; };
subclass.prototype = parentClass.prototype; subclass.prototype = parentClass.prototype;
childClass.prototype = new subclass; childClass.prototype = new subclass();
}; };
jasmine.util.formatException = function(e) { jasmine.util.formatException = function(e) {

View File

@ -1,5 +1,5 @@
{ {
"major": 1, "major": 1,
"minor": 0, "minor": 1,
"build": 0 "build": 0
} }

View File

@ -70,16 +70,16 @@ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
this.startedAt = new Date(); this.startedAt = new Date();
var self = this; var self = this;
showPassed.onchange = function(evt) { showPassed.onclick = function(evt) {
if (evt.target.checked) { if (showPassed.checked) {
self.outerDiv.className += ' show-passed'; self.outerDiv.className += ' show-passed';
} else { } else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
} }
}; };
showSkipped.onchange = function(evt) { showSkipped.onclick = function(evt) {
if (evt.target.checked) { if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped'; self.outerDiv.className += ' show-skipped';
} else { } else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
@ -110,7 +110,7 @@ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results(); var results = suite.results();
var status = results.passed() ? 'passed' : 'failed'; var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount == 0) { // todo: change this to check results.skipped if (results.totalCount === 0) { // todo: change this to check results.skipped
status = 'skipped'; status = 'skipped';
} }
this.suiteDivs[suite.id].className += " " + status; this.suiteDivs[suite.id].className += " " + status;
@ -162,7 +162,13 @@ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
jasmine.TrivialReporter.prototype.log = function() { jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console; var console = jasmine.getGlobal().console;
if (console && console.log) console.log.apply(console, arguments); if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
}; };
jasmine.TrivialReporter.prototype.getLocation = function() { jasmine.TrivialReporter.prototype.getLocation = function() {
@ -177,6 +183,8 @@ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
} }
if (!paramMap["spec"]) return true; if (!paramMap.spec) {
return spec.getFullName().indexOf(paramMap["spec"]) == 0; return true;
}
return spec.getFullName().indexOf(paramMap.spec) === 0;
}; };