Compare commits
84 Commits
v2.0.0.rc1
...
v1.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6f96bc121 | ||
|
|
feebfbba68 | ||
|
|
8e4bd86865 | ||
|
|
bb1a4428db | ||
|
|
079740ca2c | ||
|
|
fbbccf6ef7 | ||
|
|
7ad75c13d4 | ||
|
|
d46ca4f506 | ||
|
|
ee7af4496c | ||
|
|
e22c4492a5 | ||
|
|
d63836afb4 | ||
|
|
06f1edc197 | ||
|
|
3a6b233a2e | ||
|
|
d15964b7dc | ||
|
|
6e22754c10 | ||
|
|
bab4538404 | ||
|
|
06d191af74 | ||
|
|
ad78d0d0d8 | ||
|
|
733a6a4ae4 | ||
|
|
3e0cad41f5 | ||
|
|
885832e920 | ||
|
|
3a0ada034b | ||
|
|
674197aef8 | ||
|
|
626da5a112 | ||
|
|
4a1a2123a3 | ||
|
|
c87cf71f4f | ||
|
|
e4c557faae | ||
|
|
6559c5b43a | ||
|
|
912397120b | ||
|
|
551464b8d2 | ||
|
|
8a298e5c0e | ||
|
|
94a153ed15 | ||
|
|
b4439f74d5 | ||
|
|
d70e733f70 | ||
|
|
ac096f9911 | ||
|
|
08d72926ff | ||
|
|
67ec0af254 | ||
|
|
4f2fcff15a | ||
|
|
7158fc2426 | ||
|
|
992367dcbc | ||
|
|
ce886e20e4 | ||
|
|
86b0c80cc9 | ||
|
|
7dff84b1dc | ||
|
|
8c22b26d9c | ||
|
|
ad4f48dcd4 | ||
|
|
de9e2abad5 | ||
|
|
41f496001f | ||
|
|
6b5956724b | ||
|
|
ec24992250 | ||
|
|
83f232237d | ||
|
|
98d32bb4a4 | ||
|
|
c4f27ae377 | ||
|
|
a075c75bce | ||
|
|
a617b59e6a | ||
|
|
917b37481e | ||
|
|
67bbc98faa | ||
|
|
620f7b6e4c | ||
|
|
b722f416c7 | ||
|
|
634a7dc402 | ||
|
|
a4522e4dce | ||
|
|
e113c338d0 | ||
|
|
b81f690a25 | ||
|
|
c06e189699 | ||
|
|
67b6cfb828 | ||
|
|
57e622fb2a | ||
|
|
c0664dd6aa | ||
|
|
b640ce6fc0 | ||
|
|
e9af7834f5 | ||
|
|
0d43ae9c38 | ||
|
|
30431a3958 | ||
|
|
3775919c92 | ||
|
|
a692ff8c95 | ||
|
|
e4e9b51544 | ||
|
|
0b97951766 | ||
|
|
75dd391d57 | ||
|
|
ae24e00c0f | ||
|
|
6b2e45eab5 | ||
|
|
e59171935f | ||
|
|
2ba0aa371c | ||
|
|
c2ed71717f | ||
|
|
09e8822107 | ||
|
|
15763c2eb0 | ||
|
|
3f264cde34 | ||
|
|
f83cb7f766 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -5,3 +5,10 @@ site/
|
||||
.bundle/
|
||||
.pairs
|
||||
.rvmrc
|
||||
*.gem
|
||||
.bundle
|
||||
tags
|
||||
Gemfile.lock
|
||||
pkg/*
|
||||
.sass-cache/*
|
||||
src/html/.sass-cache/*
|
||||
45
Contribute.markdown
Normal file
45
Contribute.markdown
Normal file
@@ -0,0 +1,45 @@
|
||||
# Developing for Jasmine Core
|
||||
|
||||
## 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.
|
||||
|
||||
## How to write new Jasmine code
|
||||
|
||||
Or, How to make a successful pull request
|
||||
|
||||
* _Do not change the public interface_. Lots of projects depend on Jasmine and if you aren't careful you'll break them
|
||||
* _Be environment agnostic_ - server-side developers are just as important as browser developers
|
||||
* _Be browser agnostic_ - if you must rely on browser-specific functionality, please write it in a way that degrades gracefully
|
||||
* _Write specs_ - Jasmine's a testing framework; don't add functionality without test-driving it
|
||||
* _Ensure the *entire* test suite is green_ in all the big browsers, Node, and JSHint - your contribution shouldn't break Jasmine for other users
|
||||
|
||||
Follow these tips and your pull request, patch, or suggestion is much more likely to be integrated.
|
||||
|
||||
## Environment
|
||||
|
||||
Ruby, RubyGems and Rake are used in order to script the various file interactions. You will need to run on a system that supports Ruby in order to run Jasmine's specs.
|
||||
|
||||
Node.js is used to run most of the specs (the HTML-independent code) and should be present. Additionally, the JS Hint project scrubs the source code as part of the spec process.
|
||||
|
||||
## Development
|
||||
|
||||
All source code belongs in `src/`. The `core/` directory contains the bulk of Jasmine's functionality. This code should remain browser- and environment-agnostic. If your feature or fix cannot be, as mentioned above, please degrade gracefully. Any code that should only be in a non-browser environment should live in `src/console/`. Any code that depends on a browser (specifically, it expects `window` to be the global or `document` is present) should live in `src/html/`.
|
||||
|
||||
Please respect the code patterns as possible. For example, using `jasmine.getGlobal()` to get the global object so as to remain environment agnostic.
|
||||
|
||||
## Running Specs
|
||||
|
||||
As in all good projects, the `spec/` directory mirrors `src/` and follows the same rules. The browser runner will include and attempt to run all specs. The node runner will exclude any html-dependent specs (those in `spec/html/`).
|
||||
|
||||
You will notice that all specs are run against the built `jasmine.js` instead of the component source files. This is intentional as a way to ensure that the concatenation code is working correctly.
|
||||
|
||||
Please ensure all specs are green before committing or issuing a pull request.
|
||||
|
||||
There are Thor tasks to help with getting green - run `thor list` to see them all. Here are the key tasks:
|
||||
|
||||
* `thor jasmine_dev:execute_specs` outputs the expected number of specs that should be run and attempts to run in browser and Node
|
||||
* `thor jasmine_dev:execute_specs_in_browser` opens `spec/runner.html` in the default browser on MacOS. Please run this in at least Firefox and Chrome before committing
|
||||
* `thor jasmine_dev:execute_specs_in_node` runs all the Jasmine specs in Node.js - it will complain if Node is not installed
|
||||
* `thor jasmine_dev:js_hint` runs all the files through JSHint and will complain about potential viable issues with your code. Fix them.
|
||||
|
||||
7
Gemfile
7
Gemfile
@@ -1,6 +1,3 @@
|
||||
source :rubygems
|
||||
|
||||
gem "json_pure", "~>1.4.3"
|
||||
gem "frank"
|
||||
gem "ragaskar-jsdoc_helper"
|
||||
gem "rake", "0.8.7"
|
||||
gem "rake"
|
||||
gemspec
|
||||
|
||||
33
Gemfile.lock
33
Gemfile.lock
@@ -1,33 +0,0 @@
|
||||
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)
|
||||
@@ -1,49 +0,0 @@
|
||||
|
||||
|
||||
1. Ensure all specs are green in browsers & Node.js (via rake tasks)
|
||||
1. Ensure CI is green
|
||||
1.
|
||||
|
||||
|
||||
|
||||
|
||||
## 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`.
|
||||
@@ -6,40 +6,14 @@ Jasmine is a Behavior Driven Development testing framework for JavaScript. It do
|
||||
|
||||
Documentation & guides live here: [http://pivotal.github.com/jasmine/](http://pivotal.github.com/jasmine/)
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
* Search past discussions: [http://groups.google.com/group/jasmine-js](http://groups.google.com/group/jasmine-js)
|
||||
* Send an email to the list: [jasmine-js@googlegroups.com](jasmine-js@googlegroups.com)
|
||||
* Check the current build status: [ci.pivotallabs.com](http://ci.pivotallabs.com)
|
||||
* View the project backlog at Pivotal Tracker: [http://www.pivotaltracker.com/projects/10606](http://www.pivotaltracker.com/projects/10606)
|
||||
* Follow us on Twitter: [@JasmineBDD](http://twitter.com/JasmineBDD)
|
||||
|
||||
## 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
|
||||
|
||||
@@ -47,4 +21,4 @@ Do these things and we'll take a look.
|
||||
* [Rajan Agaskar](mailto:rajan@pivotallabs.com), Pivotal Labs
|
||||
* [Christian Williams](mailto:antixian666@gmail.com), Square
|
||||
|
||||
Copyright (c) 2008-2011 Pivotal Labs. This software is licensed under the MIT License.
|
||||
Copyright (c) 2008-2012 Pivotal Labs. This software is licensed under the MIT License.
|
||||
|
||||
192
Rakefile
192
Rakefile
@@ -1,170 +1,44 @@
|
||||
require 'json'
|
||||
require "bundler"
|
||||
Bundler::GemHelper.install_tasks
|
||||
require "json"
|
||||
require "tilt"
|
||||
|
||||
def jasmine_sources
|
||||
first_sources = JSON.parse(File.read('src/SourcesList.json')).collect {|f| "src/core/#{f}"}
|
||||
|
||||
sources = first_sources
|
||||
sources += Dir.glob('src/core/*.js').reject {|f| first_sources.include?(f)}.sort
|
||||
sources
|
||||
Dir["#{File.dirname(__FILE__)}/tasks/**/*.rb"].each do |file|
|
||||
require file
|
||||
end
|
||||
|
||||
def jasmine_html_sources
|
||||
["src/html/TrivialReporter.js"]
|
||||
desc "Run all Jasmine JS specs"
|
||||
task :jasmine_specs do
|
||||
jasmine_dev = JasmineDev.new
|
||||
|
||||
return unless jasmine_dev.node_installed?
|
||||
|
||||
system "thor jasmine_dev:execute_specs"
|
||||
|
||||
puts "\n\033[33m>>> DEPRECATED <<< Run Jasmine's JavaScript specs with 'thor jasmine_dev:execute_specs'\n\033[0m"
|
||||
end
|
||||
|
||||
def jasmine_version
|
||||
"#{version_hash['major']}.#{version_hash['minor']}.#{version_hash['build']}"
|
||||
desc "Run all Jasmine core tests (JavaScript and dev tasks)"
|
||||
task :spec => :require_pages_submodule do
|
||||
jasmine_dev = JasmineDev.new
|
||||
|
||||
return unless jasmine_dev.node_installed?
|
||||
|
||||
system "rspec"
|
||||
end
|
||||
|
||||
def version_hash
|
||||
require 'json'
|
||||
@version ||= JSON.parse(File.new("src/core/version.json").read);
|
||||
end
|
||||
task :require_pages_submodule do
|
||||
jasmine_dev = JasmineDev.new
|
||||
|
||||
|
||||
def substitute_jasmine_version(filename)
|
||||
contents = File.read(filename)
|
||||
contents = contents.gsub(/##JASMINE_VERSION##/, (jasmine_version))
|
||||
contents = contents.gsub(/[^\n]*REMOVE_THIS_LINE_FROM_BUILD[^\n]*/, '')
|
||||
File.open(filename, 'w') { |f| f.write(contents) }
|
||||
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")
|
||||
unless jasmine_dev.pages_submodule_installed?
|
||||
puts 'Installing the Github pages submodule:'
|
||||
system 'git submodule update --init'
|
||||
puts 'Now continuing...'
|
||||
end
|
||||
end
|
||||
|
||||
namespace :jasmine do
|
||||
|
||||
desc 'Prepares for distribution'
|
||||
task :dist => ['jasmine:build',
|
||||
'jasmine:doc',
|
||||
'jasmine:build_pages',
|
||||
'jasmine:build_example_project',
|
||||
'jasmine:fill_index_downloads']
|
||||
|
||||
desc 'Check jasmine sources for coding problems'
|
||||
task :lint do
|
||||
puts "Running JSHint via Node.js"
|
||||
system("node jshint/run.js") || exit(1)
|
||||
end
|
||||
|
||||
desc "Alias to JSHint"
|
||||
task :hint => :lint
|
||||
|
||||
desc 'Builds lib/jasmine from source'
|
||||
task :build => :lint do
|
||||
puts 'Building Jasmine from source'
|
||||
|
||||
sources = jasmine_sources
|
||||
version = version_hash
|
||||
|
||||
File.open("lib/jasmine.js", 'w') do |jasmine|
|
||||
sources.each do |source_filename|
|
||||
jasmine.puts(File.read(source_filename))
|
||||
end
|
||||
|
||||
jasmine.puts %{
|
||||
jasmine.version_= {
|
||||
"major": #{version['major'].to_json},
|
||||
"minor": #{version['minor'].to_json},
|
||||
"build": #{version['build'].to_json},
|
||||
"revision": #{Time.now.to_i}
|
||||
};
|
||||
}
|
||||
end
|
||||
|
||||
File.open("lib/jasmine-html.js", 'w') do |jasmine_html|
|
||||
jasmine_html_sources.each do |source_filename|
|
||||
jasmine_html.puts(File.read(source_filename))
|
||||
end
|
||||
end
|
||||
|
||||
FileUtils.cp("src/html/jasmine.css", "lib/jasmine.css")
|
||||
end
|
||||
|
||||
downloads_file = 'pages/download.html'
|
||||
task :need_pages_submodule do
|
||||
unless File.exist?(downloads_file)
|
||||
raise "Jasmine pages submodule isn't present. Run git submodule update --init"
|
||||
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"
|
||||
task :doc => :need_pages_submodule do
|
||||
puts 'Creating Jasmine Documentation'
|
||||
require 'rubygems'
|
||||
require 'jsdoc_helper'
|
||||
|
||||
FileUtils.rm_r "pages/jsdoc", :force => true
|
||||
|
||||
JsdocHelper::Rake::Task.new(:lambda_jsdoc) do |t|
|
||||
t[:files] = jasmine_sources << jasmine_html_sources
|
||||
t[:options] = "-a"
|
||||
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
|
||||
Rake::Task[:lambda_jsdoc].invoke
|
||||
end
|
||||
|
||||
desc "Build example project"
|
||||
task :build_example_project => :need_pages_submodule do
|
||||
require 'tmpdir'
|
||||
|
||||
temp_dir = File.join(Dir.tmpdir, 'jasmine-standalone-project')
|
||||
puts "Building Example Project in #{temp_dir}"
|
||||
FileUtils.rm_r temp_dir if File.exist?(temp_dir)
|
||||
Dir.mkdir(temp_dir)
|
||||
|
||||
root = File.expand_path(File.dirname(__FILE__))
|
||||
FileUtils.cp_r File.join(root, 'example/.'), File.join(temp_dir)
|
||||
substitute_jasmine_version(File.join(temp_dir, "SpecRunner.html"))
|
||||
|
||||
lib_dir = File.join(temp_dir, "lib/jasmine-#{jasmine_version}")
|
||||
FileUtils.mkdir_p(lib_dir)
|
||||
{
|
||||
"lib/jasmine.js" => "jasmine.js",
|
||||
"lib/jasmine-html.js" => "jasmine-html.js",
|
||||
"src/html/jasmine.css" => "jasmine.css",
|
||||
"MIT.LICENSE" => "MIT.LICENSE"
|
||||
}.each_pair do |src, dest|
|
||||
FileUtils.cp(File.join(root, src), File.join(lib_dir, dest))
|
||||
end
|
||||
|
||||
dist_dir = File.join(root, 'pages/downloads')
|
||||
zip_file_name = File.join(dist_dir, "jasmine-standalone-#{jasmine_version}.zip")
|
||||
puts "Zipping Example Project and moving to #{zip_file_name}"
|
||||
FileUtils.mkdir(dist_dir) unless File.exist?(dist_dir)
|
||||
if File.exist?(zip_file_name)
|
||||
puts "WARNING!!! #{zip_file_name} already exists!"
|
||||
FileUtils.rm(zip_file_name)
|
||||
end
|
||||
exec "cd #{temp_dir} && zip -r #{zip_file_name} . -x .[a-zA-Z0-9]*"
|
||||
end
|
||||
|
||||
end
|
||||
desc "View full development tasks"
|
||||
task :list_dev_tasks do
|
||||
puts "Jasmine uses Thor for command line tasks for development. Here is the command set:"
|
||||
system "thor list"
|
||||
end
|
||||
42
Release.markdown
Normal file
42
Release.markdown
Normal file
@@ -0,0 +1,42 @@
|
||||
# How to work on a Jasmine Release
|
||||
|
||||
## Development
|
||||
___Jasmine Core Maintainers Only___
|
||||
|
||||
Follow the instructions in `Contribute.markdown` during development.
|
||||
|
||||
### Git Rules
|
||||
|
||||
Please work on feature branches.
|
||||
|
||||
Please attempt to keep commits to `master` small, but cohesive. If a feature is contained in a bunch of small commits (e.g., it has several wip commits), please squash them when merging back to `master`.
|
||||
|
||||
### Version
|
||||
|
||||
We attempt to stick to [Semantic Versioning](). Most of the time, development should be against a new minor version - fixing bugs and adding new features that are backwards compatible.
|
||||
|
||||
The current version lives in the file `src/version.json`. This file should be set to the version that is _currently_ under development. That is, if version 1.0.0 is the current release then version should be incremented say, to 1.1.0.
|
||||
|
||||
This version is used by both `jasmine.js` and the `jasmine-core` Ruby gem.
|
||||
|
||||
Note that Jasmine should *not* use the "patch" version number. Let downstream projects rev their patch versions as needed, keeping their major and minor version numbers in sync with Jasmine core.
|
||||
|
||||
### Update the Github Pages (as needed)
|
||||
|
||||
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/pages_source` directory.
|
||||
|
||||
## Release
|
||||
|
||||
When ready to release - specs are all green and the stories are done:
|
||||
|
||||
1. Update the version in `version.json` to a release candidate - add a `release_candidate` property with a value of 1
|
||||
1. Update any comments on the public interfaces
|
||||
1. Update any links or top-level landing page for the Github Pages
|
||||
1. `thor jasmine_dev:release_prep` - updates the version, builds the `.js` files, builds the standalone release, and builds the Github pages
|
||||
1. `rake release` - tags the repo with the version, builds the `jasmine-core` gem, pushes the gem to Rubygems.org
|
||||
|
||||
There should be a post to Pivotal Labs blog and a tweet to that link.
|
||||
29
config.rb
Normal file
29
config.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Compass configuration file - for building Jasmine's 'final CSS files
|
||||
#
|
||||
|
||||
# Require any additional compass plugins here.
|
||||
|
||||
# Set this to the root of your project when deployed:
|
||||
http_path = "/"
|
||||
css_dir = "src/html"
|
||||
sass_dir = "src/html"
|
||||
images_dir = "images"
|
||||
javascripts_dir = "javascripts"
|
||||
|
||||
# You can select your preferred output style here (can be overridden via the command line):
|
||||
# output_style = :expanded or :nested or :compact or :compressed
|
||||
output_style = :compact
|
||||
|
||||
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||
# relative_assets = true
|
||||
|
||||
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||
line_comments = false
|
||||
|
||||
|
||||
# If you prefer the indented syntax, you might want to regenerate this
|
||||
# project again passing --syntax sass, or you can uncomment this:
|
||||
# preferred_syntax = :sass
|
||||
# and then run:
|
||||
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
||||
@@ -1,21 +0,0 @@
|
||||
# Project-specific configuration for CruiseControl.rb
|
||||
Project.configure do |project|
|
||||
|
||||
# Send email notifications about broken and fixed builds to email1@your.site, email2@your.site (default: send to nobody)
|
||||
# project.email_notifier.emails = ['email1@your.site', 'email2@your.site']
|
||||
|
||||
# Set email 'from' field to john@doe.com:
|
||||
# project.email_notifier.from = 'john@doe.com'
|
||||
|
||||
# Build the project by invoking rake task 'custom'
|
||||
project.rake_task = 'jasmine:test:ci:saucelabs'
|
||||
|
||||
# Build the project by invoking shell script "build_my_app.sh". Keep in mind that when the script is invoked,
|
||||
# current working directory is <em>[cruise data]</em>/projects/your_project/work, so if you do not keep build_my_app.sh
|
||||
# in version control, it should be '../build_my_app.sh' instead
|
||||
#project.build_command = 'cp ../saucelabs.yml .'
|
||||
|
||||
# Ping Subversion for new revisions every 5 minutes (default: 30 seconds)
|
||||
# project.scheduler.polling_interval = 5.minutes
|
||||
|
||||
end
|
||||
@@ -1,27 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Test Runner</title>
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-##JASMINE_VERSION##/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-##JASMINE_VERSION##/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-##JASMINE_VERSION##/jasmine-html.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="REMOVE_THIS_LINE_FROM_BUILD"><p>You must be trying to look at examples in the Jasmine source tree.</p><p>Please download a distribution version of Jasmine at <a href="http://pivotal.github.com/jasmine/">http://pivotal.github.com/jasmine/</a>.</p></div>
|
||||
<script type="text/javascript">
|
||||
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
||||
jasmine.getEnv().execute();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
29
jasmine-core.gemspec
Normal file
29
jasmine-core.gemspec
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
$:.push File.expand_path("../lib", __FILE__)
|
||||
require "jasmine-core/version"
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "jasmine-core"
|
||||
s.version = Jasmine::Core::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Rajan Agaskar", "Davis W. Frank", "Christian Williams"]
|
||||
s.summary = %q{JavaScript BDD framework}
|
||||
s.description = %q{Test your JavaScript without any framework dependencies, in any environment, and with a nice descriptive syntax.}
|
||||
s.email = %q{jasmine-js@googlegroups.com}
|
||||
s.homepage = "http://pivotal.github.com/jasmine"
|
||||
s.rubyforge_project = "jasmine-core"
|
||||
s.license = "MIT"
|
||||
|
||||
s.files = Dir.glob("./lib/**/*") + Dir.glob("./lib/jasmine-core/spec/**/*.js")
|
||||
s.require_paths = ["lib"]
|
||||
s.add_development_dependency "json_pure", ">= 1.4.3"
|
||||
s.add_development_dependency "frank"
|
||||
s.add_development_dependency "sass"
|
||||
s.add_development_dependency "compass"
|
||||
s.add_development_dependency "ragaskar-jsdoc_helper"
|
||||
s.add_development_dependency "rspec"
|
||||
s.add_development_dependency "fuubar"
|
||||
s.add_development_dependency "awesome_print"
|
||||
s.add_development_dependency "thor"
|
||||
s.add_development_dependency "nokogiri"
|
||||
end
|
||||
1
jasmine_dev.thor
Normal file
1
jasmine_dev.thor
Normal file
@@ -0,0 +1 @@
|
||||
require "#{File.expand_path(File.dirname(__FILE__))}/tasks/jasmine_dev"
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require("fs");
|
||||
var sys = require("sys");
|
||||
var util = require("util");
|
||||
var path = require("path");
|
||||
var JSHINT = require("./jshint").JSHINT;
|
||||
|
||||
|
||||
36
lib/jasmine-core.rb
Normal file
36
lib/jasmine-core.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
class << self
|
||||
def path
|
||||
File.join(File.dirname(__FILE__), "jasmine-core")
|
||||
end
|
||||
|
||||
def js_files
|
||||
(["jasmine.js"] + Dir.glob(File.join(path, "*.js"))).map { |f| File.basename(f) }.uniq
|
||||
end
|
||||
|
||||
SPEC_TYPES = ["core", "html", "node"]
|
||||
|
||||
def core_spec_files
|
||||
spec_files("core")
|
||||
end
|
||||
|
||||
def html_spec_files
|
||||
spec_files("html")
|
||||
end
|
||||
|
||||
def node_spec_files
|
||||
spec_files("node")
|
||||
end
|
||||
|
||||
def spec_files(type)
|
||||
raise ArgumentError.new("Unrecognized spec type") unless SPEC_TYPES.include?(type)
|
||||
(Dir.glob(File.join(path, "spec", type, "*.js"))).map { |f| File.join("spec", type, File.basename(f)) }.uniq
|
||||
end
|
||||
|
||||
def css_files
|
||||
Dir.glob(File.join(path, "*.css")).map { |f| File.basename(f) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
54
lib/jasmine-core/example/SpecRunner.html
Normal file
54
lib/jasmine-core/example/SpecRunner.html
Normal file
@@ -0,0 +1,54 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Spec Runner</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="lib/jasmine-1.1.0.rc1/jasmine_favicon.png">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0.rc1/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-1.1.0.rc1/jasmine-html.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src="spec/SpecHelper.js"></script>
|
||||
<script type="text/javascript" src="spec/PlayerSpec.js"></script>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src="src/Player.js"></script>
|
||||
<script type="text/javascript" src="src/Song.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
616
lib/jasmine-core/jasmine-html.js
Normal file
616
lib/jasmine-core/jasmine-html.js
Normal file
@@ -0,0 +1,616 @@
|
||||
jasmine.HtmlReporterHelpers = {};
|
||||
|
||||
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
|
||||
var results = child.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
|
||||
var parentDiv = this.dom.summary;
|
||||
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
|
||||
var parent = child[parentSuite];
|
||||
|
||||
if (parent) {
|
||||
if (typeof this.views.suites[parent.id] == 'undefined') {
|
||||
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
|
||||
}
|
||||
parentDiv = this.views.suites[parent.id].element;
|
||||
}
|
||||
|
||||
parentDiv.appendChild(childElement);
|
||||
};
|
||||
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
|
||||
for(var fn in jasmine.HtmlReporterHelpers) {
|
||||
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter = function(_doc) {
|
||||
var self = this;
|
||||
var doc = _doc || window.document;
|
||||
|
||||
var reporterView;
|
||||
|
||||
var dom = {};
|
||||
|
||||
// Jasmine Reporter Public Interface
|
||||
self.logRunningSpecs = false;
|
||||
|
||||
self.reportRunnerStarting = function(runner) {
|
||||
var specs = runner.specs() || [];
|
||||
|
||||
if (specs.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReporterDom(runner.env.versionString());
|
||||
doc.body.appendChild(dom.reporter);
|
||||
|
||||
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
|
||||
reporterView.addSpecs(specs, self.specFilter);
|
||||
};
|
||||
|
||||
self.reportRunnerResults = function(runner) {
|
||||
reporterView && reporterView.complete();
|
||||
};
|
||||
|
||||
self.reportSuiteResults = function(suite) {
|
||||
reporterView.suiteComplete(suite);
|
||||
};
|
||||
|
||||
self.reportSpecStarting = function(spec) {
|
||||
if (self.logRunningSpecs) {
|
||||
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
self.reportSpecResults = function(spec) {
|
||||
reporterView.specComplete(spec);
|
||||
};
|
||||
|
||||
self.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.specFilter = function(spec) {
|
||||
if (!focusedSpecName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return spec.getFullName().indexOf(focusedSpecName()) === 0;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function focusedSpecName() {
|
||||
var specName;
|
||||
|
||||
(function memoizeFocusedSpec() {
|
||||
if (specName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var paramMap = [];
|
||||
var params = doc.location.search.substring(1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
specName = paramMap.spec;
|
||||
})();
|
||||
|
||||
return specName;
|
||||
}
|
||||
|
||||
function createReporterDom(version) {
|
||||
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
|
||||
dom.banner = self.createDom('div', { className: 'banner' },
|
||||
self.createDom('span', { className: 'title' }, "Jasmine "),
|
||||
self.createDom('span', { className: 'version' }, version)),
|
||||
|
||||
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
|
||||
dom.alert = self.createDom('div', {className: 'alert'}),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
};
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporter.ReporterView = function(dom) {
|
||||
this.startedAt = new Date();
|
||||
this.runningSpecCount = 0;
|
||||
this.completeSpecCount = 0;
|
||||
this.passedCount = 0;
|
||||
this.failedCount = 0;
|
||||
this.skippedCount = 0;
|
||||
|
||||
this.createResultsMenu = function() {
|
||||
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
|
||||
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
|
||||
' | ',
|
||||
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
|
||||
|
||||
this.summaryMenuItem.onclick = function() {
|
||||
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
|
||||
};
|
||||
|
||||
this.detailsMenuItem.onclick = function() {
|
||||
showDetails();
|
||||
};
|
||||
};
|
||||
|
||||
this.addSpecs = function(specs, specFilter) {
|
||||
this.totalSpecCount = specs.length;
|
||||
|
||||
this.views = {
|
||||
specs: {},
|
||||
suites: {}
|
||||
};
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var spec = specs[i];
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
|
||||
if (specFilter(spec)) {
|
||||
this.runningSpecCount++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.specComplete = function(spec) {
|
||||
this.completeSpecCount++;
|
||||
|
||||
if (isUndefined(this.views.specs[spec.id])) {
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
|
||||
}
|
||||
|
||||
var specView = this.views.specs[spec.id];
|
||||
|
||||
switch (specView.status()) {
|
||||
case 'passed':
|
||||
this.passedCount++;
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.failedCount++;
|
||||
break;
|
||||
|
||||
case 'skipped':
|
||||
this.skippedCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
specView.refresh();
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
this.suiteComplete = function(suite) {
|
||||
var suiteView = this.views.suites[suite.id];
|
||||
if (isUndefined(suiteView)) {
|
||||
return;
|
||||
}
|
||||
suiteView.refresh();
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
|
||||
if (isUndefined(this.resultsMenu)) {
|
||||
this.createResultsMenu();
|
||||
}
|
||||
|
||||
// currently running UI
|
||||
if (isUndefined(this.runningAlert)) {
|
||||
this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
|
||||
dom.alert.appendChild(this.runningAlert);
|
||||
}
|
||||
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
|
||||
|
||||
// skipped specs UI
|
||||
if (isUndefined(this.skippedAlert)) {
|
||||
this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
|
||||
}
|
||||
|
||||
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.skippedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.skippedAlert);
|
||||
}
|
||||
|
||||
// passing specs UI
|
||||
if (isUndefined(this.passedAlert)) {
|
||||
this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
|
||||
}
|
||||
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
|
||||
|
||||
// failing specs UI
|
||||
if (isUndefined(this.failedAlert)) {
|
||||
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
|
||||
}
|
||||
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
|
||||
|
||||
if (this.failedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.failedAlert);
|
||||
dom.alert.appendChild(this.resultsMenu);
|
||||
}
|
||||
|
||||
// summary info
|
||||
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
|
||||
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
|
||||
};
|
||||
|
||||
this.complete = function() {
|
||||
dom.alert.removeChild(this.runningAlert);
|
||||
|
||||
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.failedCount === 0) {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
|
||||
} else {
|
||||
showDetails();
|
||||
}
|
||||
|
||||
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function showDetails() {
|
||||
if (dom.reporter.className.search(/showDetails/) === -1) {
|
||||
dom.reporter.className += " showDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefined(obj) {
|
||||
return typeof obj === 'undefined';
|
||||
}
|
||||
|
||||
function isDefined(obj) {
|
||||
return !isUndefined(obj);
|
||||
}
|
||||
|
||||
function specPluralizedFor(count) {
|
||||
var str = count + " spec";
|
||||
if (count > 1) {
|
||||
str += "s"
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
|
||||
|
||||
|
||||
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
|
||||
this.spec = spec;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.symbol = this.createDom('li', { className: 'pending' });
|
||||
this.dom.symbolSummary.appendChild(this.symbol);
|
||||
|
||||
this.summary = this.createDom('div', { className: 'specSummary' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.description)
|
||||
);
|
||||
|
||||
this.detail = this.createDom('div', { className: 'specDetail' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.getFullName())
|
||||
);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.spec);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
|
||||
this.symbol.className = this.status();
|
||||
|
||||
switch (this.status()) {
|
||||
case 'skipped':
|
||||
break;
|
||||
|
||||
case 'passed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
this.appendFailureDetail();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
|
||||
this.summary.className += ' ' + this.status();
|
||||
this.appendToSummary(this.spec, this.summary);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
|
||||
this.detail.className += ' ' + this.status();
|
||||
|
||||
var resultItems = this.spec.results().getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
this.detail.appendChild(messagesDiv);
|
||||
this.dom.details.appendChild(this.detail);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
|
||||
this.suite = suite;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.element = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
|
||||
);
|
||||
|
||||
this.appendToSummary(this.suite, this.element);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.suite);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
|
||||
this.element.className += " " + this.status();
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
|
||||
|
||||
/* @deprecated Use jasmine.HtmlReporter instead
|
||||
*/
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
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() {
|
||||
return this.document.location;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
81
lib/jasmine-core/jasmine.css
Normal file
81
lib/jasmine-core/jasmine.css
Normal file
@@ -0,0 +1,81 @@
|
||||
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
|
||||
|
||||
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
#HTMLReporter a { text-decoration: none; }
|
||||
#HTMLReporter a:hover { text-decoration: underline; }
|
||||
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
|
||||
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
|
||||
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#HTMLReporter .version { color: #aaaaaa; }
|
||||
#HTMLReporter .banner { margin-top: 14px; }
|
||||
#HTMLReporter .duration { color: #aaaaaa; float: right; }
|
||||
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
|
||||
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
|
||||
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
|
||||
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
#HTMLReporter .runningAlert { background-color: #666666; }
|
||||
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
|
||||
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
|
||||
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
|
||||
#HTMLReporter .passingAlert { background-color: #a6b779; }
|
||||
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
|
||||
#HTMLReporter .failingAlert { background-color: #cf867e; }
|
||||
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
|
||||
#HTMLReporter .results { margin-top: 14px; }
|
||||
#HTMLReporter #details { display: none; }
|
||||
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .summary { display: none; }
|
||||
#HTMLReporter.showDetails #details { display: block; }
|
||||
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter .summary { margin-top: 14px; }
|
||||
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
|
||||
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
|
||||
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
|
||||
#HTMLReporter .description + .suite { margin-top: 0; }
|
||||
#HTMLReporter .suite { margin-top: 14px; }
|
||||
#HTMLReporter .suite a { color: #333333; }
|
||||
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
|
||||
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
|
||||
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
|
||||
#HTMLReporter .resultMessage span.result { display: block; }
|
||||
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
|
||||
|
||||
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
|
||||
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
|
||||
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
|
||||
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
|
||||
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
|
||||
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
|
||||
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
|
||||
#TrivialReporter .runner.running { background-color: yellow; }
|
||||
#TrivialReporter .options { text-align: right; font-size: .8em; }
|
||||
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
|
||||
#TrivialReporter .suite .suite { margin: 5px; }
|
||||
#TrivialReporter .suite.passed { background-color: #dfd; }
|
||||
#TrivialReporter .suite.failed { background-color: #fdd; }
|
||||
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
|
||||
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
|
||||
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
|
||||
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
|
||||
#TrivialReporter .spec.skipped { background-color: #bbb; }
|
||||
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
|
||||
#TrivialReporter .passed { background-color: #cfc; display: none; }
|
||||
#TrivialReporter .failed { background-color: #fbb; }
|
||||
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
|
||||
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
|
||||
#TrivialReporter .resultMessage .mismatch { color: black; }
|
||||
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
|
||||
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
|
||||
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
|
||||
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
|
||||
@@ -196,6 +196,21 @@ jasmine.any = function(clazz) {
|
||||
return new jasmine.Matchers.Any(clazz);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
|
||||
* attributes on the object.
|
||||
*
|
||||
* @example
|
||||
* // don't care about any other attributes than foo.
|
||||
* expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
|
||||
*
|
||||
* @param sample {Object} sample
|
||||
* @returns matchable object for the sample
|
||||
*/
|
||||
jasmine.objectContaining = function (sample) {
|
||||
return new jasmine.Matchers.ObjectContaining(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
|
||||
*
|
||||
@@ -735,12 +750,17 @@ jasmine.Env.prototype.version = function () {
|
||||
* @returns string containing jasmine version build info, if set.
|
||||
*/
|
||||
jasmine.Env.prototype.versionString = function() {
|
||||
if (jasmine.version_) {
|
||||
var version = this.version();
|
||||
return version.major + "." + version.minor + "." + version.build + " revision " + version.revision;
|
||||
} else {
|
||||
if (!jasmine.version_) {
|
||||
return "version unknown";
|
||||
}
|
||||
|
||||
var version = this.version();
|
||||
var versionString = version.major + "." + version.minor + "." + version.build;
|
||||
if (version.release_candidate) {
|
||||
versionString += ".rc" + version.release_candidate;
|
||||
}
|
||||
versionString += " revision " + version.revision;
|
||||
return versionString;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -909,11 +929,19 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
return a.getTime() == b.getTime();
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.Any) {
|
||||
if (a.jasmineMatches) {
|
||||
return a.jasmineMatches(b);
|
||||
}
|
||||
|
||||
if (b.jasmineMatches) {
|
||||
return b.jasmineMatches(a);
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return a.matches(b);
|
||||
}
|
||||
|
||||
if (b instanceof jasmine.Matchers.Any) {
|
||||
if (b instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return b.matches(a);
|
||||
}
|
||||
|
||||
@@ -1207,7 +1235,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
|
||||
/**
|
||||
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toNotEqual() instead.
|
||||
* @deprecated as of 1.0. Use not.toEqual() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotEqual = function(expected) {
|
||||
return !this.env.equals_(this.actual, expected);
|
||||
@@ -1380,7 +1408,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
|
||||
* Matcher that checks that the expected item is NOT an element in the actual Array.
|
||||
*
|
||||
* @param {Object} expected
|
||||
* @deprecated as of 1.0. Use not.toNotContain() instead.
|
||||
* @deprecated as of 1.0. Use not.toContain() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotContain = function(expected) {
|
||||
return !this.env.contains_(this.actual, expected);
|
||||
@@ -1448,7 +1476,7 @@ jasmine.Matchers.Any = function(expectedClass) {
|
||||
this.expectedClass = expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
|
||||
if (this.expectedClass == String) {
|
||||
return typeof other == 'string' || other instanceof String;
|
||||
}
|
||||
@@ -1468,10 +1496,222 @@ jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
return other instanceof this.expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.toString = function() {
|
||||
jasmine.Matchers.Any.prototype.jasmineToString = function() {
|
||||
return '<jasmine.any(' + this.expectedClass + ')>';
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining = function (sample) {
|
||||
this.sample = sample;
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
|
||||
mismatchKeys = mismatchKeys || [];
|
||||
mismatchValues = mismatchValues || [];
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj != null && obj[keyName] !== jasmine.undefined;
|
||||
};
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasKey(other, property) && hasKey(this.sample, property)) {
|
||||
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
|
||||
}
|
||||
else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
|
||||
mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
|
||||
}
|
||||
}
|
||||
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
|
||||
return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
|
||||
};
|
||||
// Mock setTimeout, clearTimeout
|
||||
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
|
||||
|
||||
jasmine.FakeTimer = function() {
|
||||
this.reset();
|
||||
|
||||
var self = this;
|
||||
self.setTimeout = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.setInterval = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.clearTimeout = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
self.clearInterval = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.reset = function() {
|
||||
this.timeoutsMade = 0;
|
||||
this.scheduledFunctions = {};
|
||||
this.nowMillis = 0;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.tick = function(millis) {
|
||||
var oldMillis = this.nowMillis;
|
||||
var newMillis = oldMillis + millis;
|
||||
this.runFunctionsWithinRange(oldMillis, newMillis);
|
||||
this.nowMillis = newMillis;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
|
||||
var scheduledFunc;
|
||||
var funcsToRun = [];
|
||||
for (var timeoutKey in this.scheduledFunctions) {
|
||||
scheduledFunc = this.scheduledFunctions[timeoutKey];
|
||||
if (scheduledFunc != jasmine.undefined &&
|
||||
scheduledFunc.runAtMillis >= oldMillis &&
|
||||
scheduledFunc.runAtMillis <= nowMillis) {
|
||||
funcsToRun.push(scheduledFunc);
|
||||
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (funcsToRun.length > 0) {
|
||||
funcsToRun.sort(function(a, b) {
|
||||
return a.runAtMillis - b.runAtMillis;
|
||||
});
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
try {
|
||||
var funcToRun = funcsToRun[i];
|
||||
this.nowMillis = funcToRun.runAtMillis;
|
||||
funcToRun.funcToCall();
|
||||
if (funcToRun.recurring) {
|
||||
this.scheduleFunction(funcToRun.timeoutKey,
|
||||
funcToRun.funcToCall,
|
||||
funcToRun.millis,
|
||||
true);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
this.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
|
||||
this.scheduledFunctions[timeoutKey] = {
|
||||
runAtMillis: this.nowMillis + millis,
|
||||
funcToCall: funcToCall,
|
||||
recurring: recurring,
|
||||
timeoutKey: timeoutKey,
|
||||
millis: millis
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
jasmine.Clock = {
|
||||
defaultFakeTimer: new jasmine.FakeTimer(),
|
||||
|
||||
reset: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.reset();
|
||||
},
|
||||
|
||||
tick: function(millis) {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.tick(millis);
|
||||
},
|
||||
|
||||
runFunctionsWithinRange: function(oldMillis, nowMillis) {
|
||||
jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
},
|
||||
|
||||
scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
|
||||
jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
|
||||
},
|
||||
|
||||
useMock: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
var spec = jasmine.getEnv().currentSpec;
|
||||
spec.after(jasmine.Clock.uninstallMock);
|
||||
|
||||
jasmine.Clock.installMock();
|
||||
}
|
||||
},
|
||||
|
||||
installMock: function() {
|
||||
jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
uninstallMock: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
},
|
||||
|
||||
real: {
|
||||
setTimeout: jasmine.getGlobal().setTimeout,
|
||||
clearTimeout: jasmine.getGlobal().clearTimeout,
|
||||
setInterval: jasmine.getGlobal().setInterval,
|
||||
clearInterval: jasmine.getGlobal().clearInterval
|
||||
},
|
||||
|
||||
assertInstalled: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
|
||||
}
|
||||
},
|
||||
|
||||
isInstalled: function() {
|
||||
return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
installed: null
|
||||
};
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
|
||||
//else for IE support
|
||||
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setTimeout.apply) {
|
||||
return jasmine.Clock.installed.setTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setTimeout(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setInterval.apply) {
|
||||
return jasmine.Clock.installed.setInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setInterval(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearTimeout(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearInterval = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearInterval(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
@@ -1612,8 +1852,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === jasmine.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value instanceof jasmine.Matchers.Any) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString());
|
||||
} else if (typeof value === 'string') {
|
||||
this.emitString(value);
|
||||
} else if (jasmine.isSpy(value)) {
|
||||
@@ -2280,193 +2520,10 @@ jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
|
||||
}, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
|
||||
}
|
||||
};
|
||||
// Mock setTimeout, clearTimeout
|
||||
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
|
||||
|
||||
jasmine.FakeTimer = function() {
|
||||
this.reset();
|
||||
|
||||
var self = this;
|
||||
self.setTimeout = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.setInterval = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.clearTimeout = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
self.clearInterval = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.reset = function() {
|
||||
this.timeoutsMade = 0;
|
||||
this.scheduledFunctions = {};
|
||||
this.nowMillis = 0;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.tick = function(millis) {
|
||||
var oldMillis = this.nowMillis;
|
||||
var newMillis = oldMillis + millis;
|
||||
this.runFunctionsWithinRange(oldMillis, newMillis);
|
||||
this.nowMillis = newMillis;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
|
||||
var scheduledFunc;
|
||||
var funcsToRun = [];
|
||||
for (var timeoutKey in this.scheduledFunctions) {
|
||||
scheduledFunc = this.scheduledFunctions[timeoutKey];
|
||||
if (scheduledFunc != jasmine.undefined &&
|
||||
scheduledFunc.runAtMillis >= oldMillis &&
|
||||
scheduledFunc.runAtMillis <= nowMillis) {
|
||||
funcsToRun.push(scheduledFunc);
|
||||
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (funcsToRun.length > 0) {
|
||||
funcsToRun.sort(function(a, b) {
|
||||
return a.runAtMillis - b.runAtMillis;
|
||||
});
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
try {
|
||||
var funcToRun = funcsToRun[i];
|
||||
this.nowMillis = funcToRun.runAtMillis;
|
||||
funcToRun.funcToCall();
|
||||
if (funcToRun.recurring) {
|
||||
this.scheduleFunction(funcToRun.timeoutKey,
|
||||
funcToRun.funcToCall,
|
||||
funcToRun.millis,
|
||||
true);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
this.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
|
||||
this.scheduledFunctions[timeoutKey] = {
|
||||
runAtMillis: this.nowMillis + millis,
|
||||
funcToCall: funcToCall,
|
||||
recurring: recurring,
|
||||
timeoutKey: timeoutKey,
|
||||
millis: millis
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
jasmine.Clock = {
|
||||
defaultFakeTimer: new jasmine.FakeTimer(),
|
||||
|
||||
reset: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.reset();
|
||||
},
|
||||
|
||||
tick: function(millis) {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.tick(millis);
|
||||
},
|
||||
|
||||
runFunctionsWithinRange: function(oldMillis, nowMillis) {
|
||||
jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
},
|
||||
|
||||
scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
|
||||
jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
|
||||
},
|
||||
|
||||
useMock: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
var spec = jasmine.getEnv().currentSpec;
|
||||
spec.after(jasmine.Clock.uninstallMock);
|
||||
|
||||
jasmine.Clock.installMock();
|
||||
}
|
||||
},
|
||||
|
||||
installMock: function() {
|
||||
jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
uninstallMock: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
},
|
||||
|
||||
real: {
|
||||
setTimeout: jasmine.getGlobal().setTimeout,
|
||||
clearTimeout: jasmine.getGlobal().clearTimeout,
|
||||
setInterval: jasmine.getGlobal().setInterval,
|
||||
clearInterval: jasmine.getGlobal().clearInterval
|
||||
},
|
||||
|
||||
assertInstalled: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
|
||||
}
|
||||
},
|
||||
|
||||
isInstalled: function() {
|
||||
return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
installed: null
|
||||
};
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
|
||||
//else for IE support
|
||||
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setTimeout.apply) {
|
||||
return jasmine.Clock.installed.setTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setTimeout(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setInterval.apply) {
|
||||
return jasmine.Clock.installed.setInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setInterval(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearTimeout(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearInterval = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearInterval(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
jasmine.version_= {
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"minor": 2,
|
||||
"build": 0,
|
||||
"revision": 1307546962
|
||||
"revision": 1337005947
|
||||
};
|
||||
1
lib/jasmine-core/spec
Symbolic link
1
lib/jasmine-core/spec
Symbolic link
@@ -0,0 +1 @@
|
||||
../../spec
|
||||
6
lib/jasmine-core/version.rb
Normal file
6
lib/jasmine-core/version.rb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "1.2.0"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
|
||||
|
||||
var resultItems = results.getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
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() {
|
||||
return this.document.location;
|
||||
};
|
||||
|
||||
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
};
|
||||
166
lib/jasmine.css
166
lib/jasmine.css
@@ -1,166 +0,0 @@
|
||||
body {
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
}
|
||||
|
||||
|
||||
.jasmine_reporter a:visited, .jasmine_reporter a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
.jasmine_reporter a:hover, .jasmine_reporter a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jasmine_reporter {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
.show-passed .passed,
|
||||
.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
2
pages
2
pages
Submodule pages updated: d08ce2de24...b928db73fc
@@ -1,4 +1,4 @@
|
||||
describe("TrivialConsoleReporter", function() {
|
||||
describe("ConsoleReporter", function() {
|
||||
//keep these literal. otherwise the test loses value as a test.
|
||||
function green(str) {
|
||||
return '\033[32m' + str + '\033[0m';
|
||||
@@ -107,14 +107,14 @@ describe("TrivialConsoleReporter", function() {
|
||||
})();
|
||||
|
||||
done = false;
|
||||
reporter = new jasmine.TrivialConsoleReporter(out.print, function(runner) {
|
||||
reporter = new jasmine.ConsoleReporter(out.print, function(runner) {
|
||||
done = true
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Integration', function() {
|
||||
it("prints the proper output under a pass scenario. small numbers.", function() {
|
||||
it("prints the proper output under a pass scenario - small numbers.", function() {
|
||||
simulateRun(reporter,
|
||||
repeat(passingSpec, 3),
|
||||
[],
|
||||
@@ -134,16 +134,10 @@ describe("TrivialConsoleReporter", function() {
|
||||
1777
|
||||
);
|
||||
|
||||
expect(out.getOutput()).toEqual(
|
||||
[
|
||||
"Started",
|
||||
green(".") + green(".") + green("."),
|
||||
"",
|
||||
"Finished in 0.777 seconds",
|
||||
green("3 specs, 0 failures"),
|
||||
""
|
||||
].join("\n") + "\n"
|
||||
);
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
});
|
||||
|
||||
it("prints the proper output under a pass scenario. large numbers.", function() {
|
||||
@@ -165,33 +159,12 @@ describe("TrivialConsoleReporter", function() {
|
||||
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, 0 failures"),
|
||||
""
|
||||
].join("\n") + "\n"
|
||||
);
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./);
|
||||
expect(output).toMatch(/3 specs, 0 failures/);
|
||||
});
|
||||
|
||||
|
||||
it("prints the proper output under a failure scenario.", function() {
|
||||
simulateRun(reporter,
|
||||
[failingSpec, passingSpec, failingSpec],
|
||||
@@ -237,24 +210,12 @@ describe("TrivialConsoleReporter", function() {
|
||||
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, 2 failures"),
|
||||
""
|
||||
].join("\n") + "\n"
|
||||
);
|
||||
var output = out.getOutput();
|
||||
expect(output).toMatch(/^Started/);
|
||||
expect(output).toMatch(/F\.F/);
|
||||
expect(output).toMatch(/The oven heats up\n stack trace one\n second line\n stack trace two/);
|
||||
expect(output).toMatch(/The washing machine washes clothes\n stack trace one/);
|
||||
expect(output).toMatch(/3 specs, 2 failures/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -275,19 +236,19 @@ describe("TrivialConsoleReporter", function() {
|
||||
it("prints a green dot if the spec passes", function() {
|
||||
reporter.reportSpecResults(passingSpec);
|
||||
|
||||
expect(out.getOutput()).toEqual(green("."));
|
||||
expect(out.getOutput()).toMatch(/\./);
|
||||
});
|
||||
|
||||
it("prints a red dot if the spec fails", function() {
|
||||
reporter.reportSpecResults(failingSpec);
|
||||
|
||||
expect(out.getOutput()).toEqual(red("F"));
|
||||
expect(out.getOutput()).toMatch(/F/);
|
||||
});
|
||||
|
||||
it("prints a yellow star if the spec was skipped", function() {
|
||||
reporter.reportSpecResults(skippedSpec);
|
||||
|
||||
expect(out.getOutput()).toEqual(yellow("*"));
|
||||
expect(out.getOutput()).toMatch(/\*/);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -64,9 +64,10 @@ describe("jasmine.Env", function() {
|
||||
"major": 1,
|
||||
"minor": 9,
|
||||
"build": 7,
|
||||
"release_candidate": "1",
|
||||
"revision": 8
|
||||
};
|
||||
expect(env.versionString()).toEqual("1.9.7 revision 8");
|
||||
expect(env.versionString()).toEqual("1.9.7.rc1 revision 8");
|
||||
});
|
||||
|
||||
it("should return a nice string when version is unknown", function() {
|
||||
|
||||
@@ -352,6 +352,33 @@ describe("jasmine.Matchers", function() {
|
||||
}]).toEqual(["a", jasmine.any(Function)])).toPass();
|
||||
});
|
||||
|
||||
describe("toEqual with an object implementing jasmineMatches", function () {
|
||||
var matcher;
|
||||
beforeEach(function () {
|
||||
matcher = {
|
||||
jasmineMatches: jasmine.createSpy("jasmineMatches")
|
||||
};
|
||||
});
|
||||
|
||||
describe("on the left side", function () {
|
||||
it("uses the jasmineMatches function", function () {
|
||||
matcher.jasmineMatches.andReturn(false);
|
||||
expect(match(matcher).toEqual("foo")).toFail();
|
||||
matcher.jasmineMatches.andReturn(true);
|
||||
expect(match(matcher).toEqual("foo")).toPass();
|
||||
});
|
||||
});
|
||||
|
||||
describe("on the right side", function () {
|
||||
it("uses the jasmineMatches function", function () {
|
||||
matcher.jasmineMatches.andReturn(false);
|
||||
expect(match("foo").toEqual(matcher)).toFail();
|
||||
matcher.jasmineMatches.andReturn(true);
|
||||
expect(match("foo").toEqual(matcher)).toPass();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("toEqual handles circular objects ok", function() {
|
||||
expect(match({foo: "bar", baz: jasmine.undefined}).toEqual({foo: "bar", baz: jasmine.undefined})).toPass();
|
||||
expect(match({foo:['bar','baz','quux']}).toEqual({foo:['bar','baz','quux']})).toPass();
|
||||
@@ -830,6 +857,252 @@ describe("jasmine.Matchers", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("ObjectContaining", function () {
|
||||
describe("with an empty object", function () {
|
||||
var containing;
|
||||
beforeEach(function () {
|
||||
containing = new jasmine.Matchers.ObjectContaining({});
|
||||
});
|
||||
it("matches everything", function () {
|
||||
expect(containing.jasmineMatches("foo", [], [])).toBe(true);
|
||||
});
|
||||
|
||||
it("says it didn't expect to contain anything", function () {
|
||||
expect(containing.jasmineToString()).toEqual("<jasmine.objectContaining({ })>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("with an object with items in it", function () {
|
||||
var containing, mismatchKeys, mismatchValues;
|
||||
beforeEach(function () {
|
||||
mismatchKeys = [];
|
||||
mismatchValues = [];
|
||||
containing = new jasmine.Matchers.ObjectContaining({foo: "fooVal", bar: "barVal"});
|
||||
});
|
||||
|
||||
it("doesn't match an empty object", function () {
|
||||
expect(containing.jasmineMatches({}, mismatchKeys, mismatchValues)).toBe(false);
|
||||
});
|
||||
|
||||
it("doesn't match an object with none of the specified options", function () {
|
||||
expect(containing.jasmineMatches({baz:"stuff"}, mismatchKeys, mismatchValues)).toBe(false);
|
||||
});
|
||||
|
||||
it("adds a message for each missing key", function () {
|
||||
containing.jasmineMatches({foo: "fooVal"}, mismatchKeys, mismatchValues);
|
||||
expect(mismatchKeys.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("doesn't match an object when the values are different", function () {
|
||||
expect(containing.jasmineMatches({foo:"notFoo", bar:"notBar"}, mismatchKeys, mismatchValues)).toBe(false);
|
||||
});
|
||||
|
||||
it("adds a message when values don't match", function () {
|
||||
containing.jasmineMatches({foo: "fooVal", bar: "notBar"}, mismatchKeys, mismatchValues);
|
||||
expect(mismatchValues.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("doesn't match an object with only one of the values matching", function () {
|
||||
expect(containing.jasmineMatches({foo:"notFoo", bar:"barVal"}, mismatchKeys, mismatchValues)).toBe(false);
|
||||
});
|
||||
|
||||
it("matches when all the values are the same", function () {
|
||||
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues)).toBe(true);
|
||||
});
|
||||
|
||||
it("matches when there are additional values", function () {
|
||||
expect(containing.jasmineMatches({foo: "fooVal", bar: "barVal", baz: "bazVal"}, mismatchKeys, mismatchValues)).toBe(true);
|
||||
});
|
||||
|
||||
it("doesn't modify missingKeys or missingValues when match is successful", function () {
|
||||
containing.jasmineMatches({foo: "fooVal", bar: "barVal"}, mismatchKeys, mismatchValues);
|
||||
expect(mismatchKeys.length).toEqual(0);
|
||||
expect(mismatchValues.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("says what it expects to contain", function () {
|
||||
expect(containing.jasmineToString()).toEqual("<jasmine.objectContaining(" + jasmine.pp({foo:"fooVal", bar:"barVal"}) + ")>");
|
||||
});
|
||||
});
|
||||
|
||||
describe("in real life", function () {
|
||||
var method;
|
||||
beforeEach(function () {
|
||||
method = jasmine.createSpy("method");
|
||||
method({a:"b", c:"d"});
|
||||
});
|
||||
it("works correctly for positive matches", function () {
|
||||
expect(method).toHaveBeenCalledWith(jasmine.objectContaining({a:"b"}));
|
||||
});
|
||||
|
||||
it("works correctly for negative matches", function () {
|
||||
expect(method).not.toHaveBeenCalledWith(jasmine.objectContaining({z:"x"}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Matchers.Any", function () {
|
||||
var any;
|
||||
describe(".jasmineToString", function () {
|
||||
describe("with Object", function () {
|
||||
it("says it's looking for an object", function () {
|
||||
any = jasmine.any(Object);
|
||||
expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Object.*\)>/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with Function", function () {
|
||||
it("says it's looking for a function", function () {
|
||||
any = jasmine.any(Function);
|
||||
expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Function.*\)>/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with String", function () {
|
||||
it("says it's looking for a string", function () {
|
||||
any = jasmine.any(String);
|
||||
expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function String.*\)>/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with Number", function () {
|
||||
it("says it's looking for a number", function () {
|
||||
any = jasmine.any(Number);
|
||||
expect(any.jasmineToString().replace(/\n/g, "")).toMatch(/<jasmine\.any\(function Number.*\)>/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with some other defined 'class'", function () {
|
||||
it("says it's looking for an object", function () {
|
||||
function MyClass () {}
|
||||
any = jasmine.any(MyClass);
|
||||
expect(any.jasmineToString().replace("\n", "")).toMatch(/<jasmine\.any\(function MyClass.*\)>/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(".jasmineMatches", function () {
|
||||
describe("with Object", function () {
|
||||
beforeEach(function () {
|
||||
any = jasmine.any(Object);
|
||||
});
|
||||
|
||||
it("matches an empty object", function () {
|
||||
expect(any.jasmineMatches({})).toEqual(true);
|
||||
});
|
||||
|
||||
it("matches a newed up object", function () {
|
||||
expect(any.jasmineMatches(new Object())).toEqual(true);
|
||||
});
|
||||
|
||||
it("doesn't match a string", function () {
|
||||
expect(any.jasmineMatches("")).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a number", function () {
|
||||
expect(any.jasmineMatches(123)).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a function", function () {
|
||||
expect(any.jasmineMatches(function () {})).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with Function", function () {
|
||||
beforeEach(function () {
|
||||
any = jasmine.any(Function);
|
||||
});
|
||||
|
||||
it("doesn't match an object", function () {
|
||||
expect(any.jasmineMatches({})).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a string", function () {
|
||||
expect(any.jasmineMatches("")).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a number", function () {
|
||||
expect(any.jasmineMatches(123)).toEqual(false);
|
||||
});
|
||||
|
||||
it("matches a function", function () {
|
||||
expect(any.jasmineMatches(function () {})).toEqual(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with Number", function () {
|
||||
beforeEach(function () {
|
||||
any = jasmine.any(Number);
|
||||
});
|
||||
|
||||
it("doesn't match an object", function () {
|
||||
expect(any.jasmineMatches({})).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a string", function () {
|
||||
expect(any.jasmineMatches("")).toEqual(false);
|
||||
});
|
||||
|
||||
it("matches a number", function () {
|
||||
expect(any.jasmineMatches(123)).toEqual(true);
|
||||
});
|
||||
|
||||
it("doesn't match a function", function () {
|
||||
expect(any.jasmineMatches(function () {})).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with String", function () {
|
||||
beforeEach(function () {
|
||||
any = jasmine.any(String);
|
||||
});
|
||||
|
||||
it("doesn't match an object", function () {
|
||||
expect(any.jasmineMatches({})).toEqual(false);
|
||||
});
|
||||
|
||||
it("matches a string", function () {
|
||||
expect(any.jasmineMatches("")).toEqual(true);
|
||||
});
|
||||
|
||||
it("doesn't match a number", function () {
|
||||
expect(any.jasmineMatches(123)).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a function", function () {
|
||||
expect(any.jasmineMatches(function () {})).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with some defined 'class'", function () {
|
||||
function MyClass () {}
|
||||
beforeEach(function () {
|
||||
any = jasmine.any(MyClass);
|
||||
});
|
||||
|
||||
it("doesn't match an object", function () {
|
||||
expect(any.jasmineMatches({})).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a string", function () {
|
||||
expect(any.jasmineMatches("")).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a number", function () {
|
||||
expect(any.jasmineMatches(123)).toEqual(false);
|
||||
});
|
||||
|
||||
it("doesn't match a function", function () {
|
||||
expect(any.jasmineMatches(function () {})).toEqual(false);
|
||||
});
|
||||
|
||||
it("matches an instance of the defined class", function () {
|
||||
expect(any.jasmineMatches(new MyClass())).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("all matchers", function() {
|
||||
it("should return null, for future-proofing, since we might eventually allow matcher chaining", function() {
|
||||
expect(match(true).toBe(true)).toBeUndefined();
|
||||
|
||||
@@ -83,5 +83,12 @@ describe("jasmine.pp", function () {
|
||||
expect(jasmine.pp(jasmine.createSpy("something"))).toEqual("spy on something");
|
||||
});
|
||||
|
||||
it("should stringify objects that implement jasmineToString", function () {
|
||||
var obj = {
|
||||
jasmineToString: function () { return "strung"; }
|
||||
};
|
||||
|
||||
expect(jasmine.pp(obj)).toEqual("strung");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
209
spec/html/HTMLReporterSpec.js
Normal file
209
spec/html/HTMLReporterSpec.js
Normal file
@@ -0,0 +1,209 @@
|
||||
describe("HtmlReporter", function() {
|
||||
var env;
|
||||
var htmlReporter;
|
||||
var body;
|
||||
var fakeDocument;
|
||||
|
||||
beforeEach(function() {
|
||||
env = new jasmine.Env();
|
||||
env.updateInterval = 0;
|
||||
|
||||
body = document.createElement("body");
|
||||
fakeDocument = { body: body, location: { search: "" } };
|
||||
htmlReporter = new jasmine.HtmlReporter(fakeDocument);
|
||||
});
|
||||
|
||||
function fakeSpec(name) {
|
||||
return {
|
||||
getFullName: function() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function findElements(divs, withClass) {
|
||||
var els = [];
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
if (divs[i].className == withClass) els.push(divs[i]);
|
||||
}
|
||||
return els;
|
||||
}
|
||||
|
||||
function findElement(divs, withClass) {
|
||||
var els = findElements(divs, withClass);
|
||||
if (els.length > 0) {
|
||||
return els[0];
|
||||
}
|
||||
throw new Error("couldn't find div with class " + withClass);
|
||||
}
|
||||
|
||||
it("should run only specs beginning with spec parameter", function() {
|
||||
fakeDocument.location.search = "?spec=run%20this";
|
||||
expect(htmlReporter.specFilter(fakeSpec("run this"))).toBeTruthy();
|
||||
expect(htmlReporter.specFilter(fakeSpec("not the right spec"))).toBeFalsy();
|
||||
expect(htmlReporter.specFilter(fakeSpec("not run this"))).toBeFalsy();
|
||||
});
|
||||
|
||||
describe("running without any specs", function() {
|
||||
var runner;
|
||||
beforeEach(function() {
|
||||
runner = env.currentRunner();
|
||||
env.addReporter(htmlReporter);
|
||||
});
|
||||
|
||||
it("should not error", function() {
|
||||
var exec = function() {
|
||||
runner.execute();
|
||||
};
|
||||
expect(exec).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Matcher reporting', function() {
|
||||
var getResultMessageDiv = function(body) {
|
||||
var divs = body.getElementsByTagName("div");
|
||||
for (var i = 0; i < divs.length; i++) {
|
||||
if (divs[i].className.match(/resultMessage/)) {
|
||||
return divs[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var runner, spec, fakeTimer;
|
||||
beforeEach(function() {
|
||||
fakeTimer = new jasmine.FakeTimer();
|
||||
env.setTimeout = fakeTimer.setTimeout;
|
||||
env.clearTimeout = fakeTimer.clearTimeout;
|
||||
env.setInterval = fakeTimer.setInterval;
|
||||
env.clearInterval = fakeTimer.clearInterval;
|
||||
runner = env.currentRunner();
|
||||
var suite = new jasmine.Suite(env, 'some suite');
|
||||
runner.add(suite);
|
||||
spec = new jasmine.Spec(env, suite, 'some spec');
|
||||
suite.add(spec);
|
||||
fakeDocument.location.search = "?";
|
||||
env.addReporter(htmlReporter);
|
||||
});
|
||||
|
||||
describe('toContain', function() {
|
||||
it('should show actual and expected', function() {
|
||||
spec.runs(function() {
|
||||
this.expect('foo').toContain('bar');
|
||||
});
|
||||
runner.execute();
|
||||
fakeTimer.tick(0);
|
||||
|
||||
var resultEl = getResultMessageDiv(body);
|
||||
expect(resultEl.innerHTML).toMatch(/foo/);
|
||||
expect(resultEl.innerHTML).toMatch(/bar/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("failure messages (integration)", function() {
|
||||
var spec, results, expectationResult;
|
||||
|
||||
it("should add the failure message to the DOM (non-toEquals matchers)", function() {
|
||||
env.describe("suite", function() {
|
||||
env.it("will have log messages", function() {
|
||||
this.expect('a').toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
var divs = body.getElementsByTagName("div");
|
||||
var errorDiv = findElement(divs, 'resultMessage fail');
|
||||
expect(errorDiv.innerHTML).toMatch(/Expected 'a' to be null/);
|
||||
});
|
||||
|
||||
it("should add the failure message to the DOM (non-toEquals matchers) html escaping", function() {
|
||||
env.describe("suite", function() {
|
||||
env.it("will have log messages", function() {
|
||||
this.expect('1 < 2').toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
var divs = body.getElementsByTagName("div");
|
||||
var errorDiv = findElement(divs, 'resultMessage fail');
|
||||
expect(errorDiv.innerHTML).toMatch(/Expected '1 < 2' to be null/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("log messages", function() {
|
||||
it("should appear in the report of a failed spec", function() {
|
||||
env.describe("suite", function() {
|
||||
env.it("will have log messages", function() {
|
||||
this.log("this is a", "multipart log message");
|
||||
this.expect(true).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
var divs = body.getElementsByTagName("div");
|
||||
var errorDiv = findElement(divs, 'specDetail failed');
|
||||
expect(errorDiv.innerHTML).toMatch("this is a multipart log message");
|
||||
});
|
||||
|
||||
xit("should work on IE without console.log.apply", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("duplicate example names", function() {
|
||||
it("should report failures correctly", function() {
|
||||
var suite1 = env.describe("suite", function() {
|
||||
env.it("will have log messages", function() {
|
||||
this.log("this one fails!");
|
||||
this.expect(true).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
var suite2 = env.describe("suite", function() {
|
||||
env.it("will have log messages", function() {
|
||||
this.log("this one passes!");
|
||||
this.expect(true).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
var divs = body.getElementsByTagName("div");
|
||||
var failedSpecDiv = findElement(divs, 'specDetail failed');
|
||||
expect(failedSpecDiv.className).toEqual('specDetail failed');
|
||||
expect(failedSpecDiv.innerHTML).toContain("this one fails!");
|
||||
expect(failedSpecDiv.innerHTML).not.toContain("this one passes!");
|
||||
});
|
||||
});
|
||||
|
||||
describe('#reportSpecStarting', function() {
|
||||
beforeEach(function() {
|
||||
env.describe("suite 1", function() {
|
||||
env.it("spec 1", function() {
|
||||
});
|
||||
});
|
||||
spyOn(htmlReporter, 'log').andCallThrough();
|
||||
});
|
||||
|
||||
it('DOES NOT log running specs by default', function() {
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
expect(htmlReporter.log).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('logs running specs when log_running_specs is true', function() {
|
||||
htmlReporter.logRunningSpecs = true;
|
||||
env.addReporter(htmlReporter);
|
||||
env.execute();
|
||||
|
||||
expect(htmlReporter.log).toHaveBeenCalledWith('>> Jasmine Running suite 1 spec 1...');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,16 +1,16 @@
|
||||
var fs = require('fs');
|
||||
var sys = require('sys');
|
||||
var util = require('util');
|
||||
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');
|
||||
var jasmineGlobals = require('../lib/jasmine-core/jasmine.js');
|
||||
for (var k in jasmineGlobals) {
|
||||
global[k] = jasmineGlobals[k];
|
||||
}
|
||||
require('../src/console/TrivialConsoleReporter.js');
|
||||
require('../src/console/ConsoleReporter.js');
|
||||
|
||||
/*
|
||||
Pulling in code from jasmine-node.
|
||||
@@ -30,14 +30,14 @@ delete global.window;
|
||||
function noop() {
|
||||
}
|
||||
|
||||
jasmine.executeSpecs = function(specs, done) {
|
||||
jasmine.executeSpecs = function(specs, done, isVerbose, showColors) {
|
||||
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);
|
||||
var consoleReporter = new jasmine.ConsoleReporter(util.print, done, showColors);
|
||||
|
||||
jasmineEnv.addReporter(consoleReporter);
|
||||
jasmineEnv.execute();
|
||||
@@ -124,4 +124,4 @@ jasmine.executeSpecs(domIndependentSpecs, function(runner, log) {
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
}, isVerbose, showColors);
|
||||
}, isVerbose, showColors);
|
||||
|
||||
@@ -2,62 +2,83 @@
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Jasmine Test Runner</title>
|
||||
<title>Jasmine Spec Runner: Jasmine Core</title>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="../images/jasmine_favicon.png">
|
||||
|
||||
<link href="../lib/jasmine-core/jasmine.css" rel="stylesheet"/>
|
||||
<script type="text/javascript" src="../lib/jasmine-core/jasmine.js"></script>
|
||||
<script type="text/javascript">
|
||||
// yes, really keep this here to keep us honest, but only for jasmine's own runner! [xw]
|
||||
undefined = "diz be undefined yo";
|
||||
</script>
|
||||
<link rel="shortcut icon" type="image/png" href="../images/jasmine_favicon.png">
|
||||
<script type="text/javascript" src="../lib/jasmine.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../src/html/TrivialReporter.js"></script>
|
||||
<script type="text/javascript" src="../src/console/TrivialConsoleReporter.js"></script>
|
||||
|
||||
<script type="text/javascript" src="core/BaseSpec.js"></script>
|
||||
<script type="text/javascript" src="core/CustomMatchersSpec.js"></script>
|
||||
<script type="text/javascript" src="core/EnvSpec.js"></script>
|
||||
<script type="text/javascript" src="core/ExceptionsSpec.js"></script>
|
||||
<script type="text/javascript" src="core/JsApiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="core/MatchersSpec.js"></script>
|
||||
<script type="text/javascript" src="core/MockClockSpec.js"></script>
|
||||
<script type="text/javascript" src="core/MultiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="core/NestedResultsSpec.js"></script>
|
||||
<script type="text/javascript" src="core/PrettyPrintSpec.js"></script>
|
||||
<script type="text/javascript" src="core/ReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="core/RunnerSpec.js"></script>
|
||||
<script type="text/javascript" src="core/QueueSpec.js"></script>
|
||||
<script type="text/javascript" src="core/SpecSpec.js"></script>
|
||||
<script type="text/javascript" src="core/SpecRunningSpec.js"></script>
|
||||
<script type="text/javascript" src="core/SpySpec.js"></script>
|
||||
<script type="text/javascript" src="core/SuiteSpec.js"></script>
|
||||
<script type="text/javascript" src="core/UtilSpec.js"></script>
|
||||
<script type="text/javascript" src="core/WaitsForBlockSpec.js"></script>
|
||||
<script type="text/javascript" src="console/TrivialConsoleReporterSpec.js"></script>
|
||||
<script type="text/javascript" src="html/MatchersHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src="html/PrettyPrintHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src="html/TrivialReporterSpec.js"></script>
|
||||
<!-- include source files here... -->
|
||||
<script type="text/javascript" src=".././src/html/HtmlReporterHelpers.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/HtmlReporter.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/HtmlReporterHelpers.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/ReporterView.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/SpecView.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/SuiteView.js"></script>
|
||||
<script type="text/javascript" src=".././src/html/TrivialReporter.js"></script>
|
||||
<script type="text/javascript" src=".././src/console/ConsoleReporter.js"></script>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<script type="text/javascript" src=".././spec/core/BaseSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/CustomMatchersSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/EnvSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/ExceptionsSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/JsApiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MatchersSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MockClockSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/MultiReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/NestedResultsSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/PrettyPrintSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/QueueSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/ReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/RunnerSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpecRunningSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpecSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SpySpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/SuiteSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/UtilSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/core/WaitsForBlockSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/HTMLReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/MatchersHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/PrettyPrintHtmlSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/html/TrivialReporterSpec.js"></script>
|
||||
<script type="text/javascript" src=".././spec/console/ConsoleReporterSpec.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var trivialReporter = new jasmine.TrivialReporter();
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
|
||||
jasmineEnv.addReporter(trivialReporter);
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return trivialReporter.specFilter(spec);
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
jasmineEnv.execute();
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
<link href="../src/html/jasmine.css" rel="stylesheet"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
51
spec/spec_helper.rb
Normal file
51
spec/spec_helper.rb
Normal file
@@ -0,0 +1,51 @@
|
||||
# This file was generated by the `rspec --init` command. Conventionally, all
|
||||
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
||||
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
||||
# loaded once.
|
||||
#
|
||||
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
||||
RSpec.configure do |config|
|
||||
config.treat_symbols_as_metadata_keys_with_true_values = true
|
||||
config.run_all_when_everything_filtered = true
|
||||
config.filter_run :focus
|
||||
end
|
||||
|
||||
require 'awesome_print'
|
||||
require 'tmpdir'
|
||||
require 'nokogiri'
|
||||
|
||||
def project_root
|
||||
File.join(File.expand_path(File.dirname(__FILE__)), '..')
|
||||
end
|
||||
|
||||
require "#{project_root}/tasks/jasmine_dev"
|
||||
|
||||
def capture_output(capture = true)
|
||||
if capture
|
||||
output = StringIO.new
|
||||
$stdout = output
|
||||
end
|
||||
yield
|
||||
if capture
|
||||
output.string
|
||||
end
|
||||
ensure
|
||||
$stdout = STDOUT
|
||||
end
|
||||
|
||||
def reset_dir(dir)
|
||||
FileUtils.rm_r dir if File.exists?(dir)
|
||||
FileUtils.mkdir_p dir
|
||||
end
|
||||
|
||||
def jasmine_version
|
||||
version = jasmine_version_object
|
||||
|
||||
version_string = "#{version['major']}.#{version['minor']}.#{version['build']}"
|
||||
version_string += ".rc#{version['release_candidate']}" if version['release_candidate']
|
||||
version_string
|
||||
end
|
||||
|
||||
def jasmine_version_object
|
||||
@version_object ||= JSON.parse(File.read(File.join(JasmineDev.project_root, 'src', 'version.json')))
|
||||
end
|
||||
33
spec/tasks/build_distribution_spec.rb
Normal file
33
spec/tasks/build_distribution_spec.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Build Jasmine task" do
|
||||
|
||||
let(:jasmine_core_dir) { "#{Dir.tmpdir}/jasmine-core" }
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
before do
|
||||
reset_dir jasmine_core_dir
|
||||
@output = capture_output { jasmine_dev.build_distribution jasmine_core_dir }
|
||||
end
|
||||
|
||||
it "should say that JSHint is running" do
|
||||
@output.should match(/Running JSHint/)
|
||||
@output.should match(/Jasmine JSHint PASSED/)
|
||||
end
|
||||
|
||||
it "should tell the developer it is building the distribution" do
|
||||
@output.should match(/Building Jasmine distribution/)
|
||||
end
|
||||
|
||||
it "should build jasmine.js in the destination directory" do
|
||||
File.exist?("#{jasmine_core_dir}/jasmine.js").should be_true
|
||||
end
|
||||
|
||||
it "should build jasmine-html.js in the destination directory" do
|
||||
File.exist?("#{jasmine_core_dir}/jasmine-html.js").should be_true
|
||||
end
|
||||
|
||||
it "should build jasmine.css" do
|
||||
File.exist?("#{jasmine_core_dir}/jasmine.css").should be_true
|
||||
end
|
||||
end
|
||||
69
spec/tasks/build_github_pages_spec.rb
Normal file
69
spec/tasks/build_github_pages_spec.rb
Normal file
@@ -0,0 +1,69 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Build Github Pages task" do
|
||||
|
||||
let(:pages_dir) { File.join(Dir.tmpdir, 'pages') }
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
before do
|
||||
reset_dir pages_dir
|
||||
end
|
||||
|
||||
describe "when the Github pages submodule is not present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_pages_submodule?).and_return(false)
|
||||
|
||||
@output = capture_output { jasmine_dev.build_github_pages pages_dir }
|
||||
end
|
||||
|
||||
it "should tell the user the task is running" do
|
||||
@output.should match(/Building Github Pages/)
|
||||
end
|
||||
|
||||
it "should prompt the user to install the submodule" do
|
||||
@output.should match(/Submodule for Github Pages isn't present/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the Github pages submodule is present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_pages_submodule?).and_return(true)
|
||||
|
||||
@output = capture_output { jasmine_dev.build_github_pages pages_dir }
|
||||
end
|
||||
|
||||
it "should tell the user the task is running" do
|
||||
@output.should match(/Building Github Pages/)
|
||||
end
|
||||
|
||||
it "should tell the user the pages are built" do
|
||||
@output.should match(/Congratulations, project dumped to/)
|
||||
end
|
||||
|
||||
it "should build the pages output to the requested diretory" do
|
||||
Dir.chdir File.join(pages_dir, 'pages_output') do
|
||||
pages = Dir.glob(File.join('**', '*'))
|
||||
|
||||
pages.should include('download.html')
|
||||
pages.should include('index.html')
|
||||
pages.should include(File.join('images', 'jasmine_logo.png'))
|
||||
pages.should include(File.join('images', 'pivotal_logo.gif'))
|
||||
pages.should include(File.join('css', 'pygments.css'))
|
||||
pages.should include(File.join('css', 'screen.css'))
|
||||
end
|
||||
end
|
||||
|
||||
it "should copy the generated page files to the destination directory" do
|
||||
Dir.chdir pages_dir do
|
||||
pages = Dir.glob(File.join('**', '*'))
|
||||
|
||||
pages.should include('download.html')
|
||||
pages.should include('index.html')
|
||||
pages.should include(File.join('images', 'jasmine_logo.png'))
|
||||
pages.should include(File.join('images', 'pivotal_logo.gif'))
|
||||
pages.should include(File.join('css', 'pygments.css'))
|
||||
pages.should include(File.join('css', 'screen.css'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
109
spec/tasks/build_standalone_distribution_spec.rb
Normal file
109
spec/tasks/build_standalone_distribution_spec.rb
Normal file
@@ -0,0 +1,109 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Standalone Distribution tasks" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
let(:standalone_temp_dir) { File.join(Dir.tmpdir, 'jasmine_test') }
|
||||
let(:download_dir) { File.join(standalone_temp_dir, 'download')}
|
||||
|
||||
describe "build_standalone_distribution" do
|
||||
before do
|
||||
reset_dir standalone_temp_dir
|
||||
reset_dir download_dir
|
||||
|
||||
Dir.should_receive(:tmpdir).any_number_of_times.and_return(standalone_temp_dir)
|
||||
|
||||
@standalone_staging_dir = File.join(standalone_temp_dir, 'jasmine_standalone')
|
||||
|
||||
@version_dir = File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}")
|
||||
@lib_dir = File.join(@version_dir, 'lib')
|
||||
@source_dir = File.join(@version_dir, 'src')
|
||||
@spec_dir = File.join(@version_dir, 'spec')
|
||||
|
||||
@output = capture_output { jasmine_dev.build_standalone_distribution download_dir }
|
||||
end
|
||||
|
||||
it "should build the distribution" do
|
||||
@output.should match(/Building Jasmine distribution/)
|
||||
end
|
||||
|
||||
it "should tell the developer the task has started" do
|
||||
@output.should match(/Building standalone distribution/)
|
||||
end
|
||||
|
||||
it "should copy the lib directory to the staging directory, under a versioned directory" do
|
||||
lib_dir_files = Dir.glob(File.join(standalone_temp_dir, 'jasmine_standalone', '**', '*'))
|
||||
|
||||
staged_lib_files = %w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE }
|
||||
staged_lib_files.each do |filename|
|
||||
lib_dir_files.should include(File.join(@lib_dir, "jasmine-#{jasmine_version}", filename))
|
||||
end
|
||||
end
|
||||
|
||||
it "should copy the sample project source to the staging directory" do
|
||||
File.exist?(File.join(@source_dir, 'Player.js')).should be_true
|
||||
File.exist?(File.join(@source_dir, 'Song.js')).should be_true
|
||||
end
|
||||
|
||||
it "should copy the sample project specs to the staging directory" do
|
||||
File.exist?(File.join(@spec_dir, 'PlayerSpec.js')).should be_true
|
||||
File.exist?(File.join(@spec_dir, 'SpecHelper.js')).should be_true
|
||||
end
|
||||
|
||||
it "should copy a build SpecRunner.html to the staging directory" do
|
||||
File.exist?(File.join(@version_dir, 'SpecRunner.html')).should be_true
|
||||
end
|
||||
|
||||
it "should zip up the contents of the staging directory" do
|
||||
File.exist?(File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}.zip")).should be_true
|
||||
end
|
||||
|
||||
it "should copy the zip file to the pages sub directory" do
|
||||
File.exist?(File.join(download_dir, "jasmine-standalone-#{jasmine_version}.zip")).should be_true
|
||||
end
|
||||
|
||||
describe "when the zip file is unzipped" do
|
||||
before do
|
||||
@out_directory = File.join(standalone_temp_dir, 'unzip')
|
||||
reset_dir @out_directory
|
||||
|
||||
FileUtils.cp File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}.zip"),
|
||||
@out_directory
|
||||
|
||||
Dir.chdir @out_directory do
|
||||
system("unzip -qq jasmine-standalone-#{jasmine_version}.zip")
|
||||
end
|
||||
end
|
||||
|
||||
describe "the distirbution" do
|
||||
before do
|
||||
Dir.chdir @out_directory do
|
||||
@files = Dir.glob(File.join('**', '*'))
|
||||
end
|
||||
end
|
||||
|
||||
it "should include the correct root files" do
|
||||
@files.should include('SpecRunner.html')
|
||||
end
|
||||
|
||||
it "should include the correct lib files" do
|
||||
%w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE }.each do |file|
|
||||
@files.should include(File.join('lib', "jasmine-#{jasmine_version}", file))
|
||||
end
|
||||
end
|
||||
|
||||
it "should include the correct src files" do
|
||||
%w{Player.js Song.js}.each do |file|
|
||||
@files.should include(File.join('src', file))
|
||||
end
|
||||
end
|
||||
|
||||
it "should include the correct spec files" do
|
||||
%w{PlayerSpec.js SpecHelper.js}.each do |file|
|
||||
@files.should include(File.join('spec', file))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
63
spec/tasks/build_standalone_runner_spec.rb
Normal file
63
spec/tasks/build_standalone_runner_spec.rb
Normal file
@@ -0,0 +1,63 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Build Standalone runner HTML task" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
let(:standalone_temp_dir) { "#{Dir.tmpdir}/jasmine_test" }
|
||||
|
||||
describe "build_standalone_runner" do
|
||||
before do
|
||||
reset_dir standalone_temp_dir
|
||||
Dir.should_receive(:tmpdir).any_number_of_times.and_return(standalone_temp_dir)
|
||||
|
||||
@standalone_staging_dir = File.join(standalone_temp_dir, 'jasmine_standalone')
|
||||
|
||||
@version_dir = File.join(@standalone_staging_dir, "jasmine-standalone-#{jasmine_version}")
|
||||
|
||||
@output = capture_output { jasmine_dev.build_standalone_runner }
|
||||
end
|
||||
|
||||
it "should tell the developer the task has started" do
|
||||
@output.should match(/Building standalone runner HTML/)
|
||||
end
|
||||
|
||||
it "should copy a build SpecRunner.html to the staging directory" do
|
||||
File.exist?(File.join(@version_dir, 'SpecRunner.html')).should be_true
|
||||
end
|
||||
|
||||
describe "should build the file that has HTML that" do
|
||||
before do
|
||||
html = File.read(File.join(@version_dir, 'SpecRunner.html'))
|
||||
@runner = Nokogiri(html)
|
||||
end
|
||||
|
||||
it "should have the favicon tag" do
|
||||
favicon_tag = @runner.css('link')[0]
|
||||
favicon_tag['href'].should match("lib/jasmine-#{jasmine_version}/jasmine_favicon.png")
|
||||
end
|
||||
|
||||
it "should have the stylesheet" do
|
||||
css_tag = @runner.css('link')[1]
|
||||
css_tag['href'].should match("lib/jasmine-#{jasmine_version}/jasmine.css")
|
||||
end
|
||||
|
||||
it "should have the jasmine script tags" do
|
||||
script_sources = @runner.css('script').collect {|tag| tag['src']}
|
||||
script_sources.should include("lib/jasmine-#{jasmine_version}/jasmine.js")
|
||||
script_sources.should include("lib/jasmine-#{jasmine_version}/jasmine-html.js")
|
||||
end
|
||||
|
||||
it "should have the example source files" do
|
||||
script_sources = @runner.css('script').collect {|tag| tag['src']}
|
||||
script_sources.should include('src/Player.js')
|
||||
script_sources.should include('src/Song.js')
|
||||
end
|
||||
|
||||
it "should have the example source files" do
|
||||
script_sources = @runner.css('script').collect {|tag| tag['src']}
|
||||
script_sources.should include('spec/SpecHelper.js')
|
||||
script_sources.should include('spec/PlayerSpec.js')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
26
spec/tasks/count_specs_spec.rb
Normal file
26
spec/tasks/count_specs_spec.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Spec counting task" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
before do
|
||||
@output = capture_output { jasmine_dev.count_specs }
|
||||
end
|
||||
|
||||
it "should tell the developer that the specs are being counted" do
|
||||
@output.should match(/Counting specs/)
|
||||
end
|
||||
|
||||
it "should report the number of specs that will run in node" do
|
||||
@output.should match(/\d+ \e\[0mspecs for Node.js/)
|
||||
end
|
||||
|
||||
it "should report the number of specs that will run in the browser" do
|
||||
@output.should match(/\d+ \e\[0mspecs for Browser/)
|
||||
end
|
||||
|
||||
it "should remind the developer to check the count" do
|
||||
@output.should match(/Please verify/)
|
||||
end
|
||||
end
|
||||
81
spec/tasks/execute_specs_spec.rb
Normal file
81
spec/tasks/execute_specs_spec.rb
Normal file
@@ -0,0 +1,81 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Spec tasks" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
describe "execute_specs_in_node" do
|
||||
describe "when Node.js is not present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_node?).and_return(false)
|
||||
@output = capture_output { jasmine_dev.execute_specs_in_node }
|
||||
end
|
||||
|
||||
it "should prompt the user to install Node" do
|
||||
@output.should match(/Node\.js is required/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when Node.js is present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_node?).and_return(true)
|
||||
@output = capture_output { jasmine_dev.execute_specs_in_node }
|
||||
end
|
||||
|
||||
it "should build the distribution" do
|
||||
@output.should match(/Building Jasmine distribution/)
|
||||
end
|
||||
|
||||
it "should tell the developer that the specs are being counted" do
|
||||
@output.should match(/Counting specs/)
|
||||
end
|
||||
|
||||
it "should tell the user that the specs are running in Node.js" do
|
||||
@output.should match(/specs via Node/)
|
||||
@output.should match(/Started/)
|
||||
@output.should match(/\d+ specs, 0 failures/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "execute_specs_in_browser" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:run)
|
||||
@output = capture_output { jasmine_dev.execute_specs_in_browser }
|
||||
end
|
||||
|
||||
it "should build the distribution" do
|
||||
@output.should match(/Building Jasmine distribution/)
|
||||
end
|
||||
|
||||
it "should tell the developer that the specs are being counted" do
|
||||
@output.should match(/Counting specs/)
|
||||
end
|
||||
|
||||
it "should tell the user that the specs are running in the broswer" do
|
||||
@output.should match(/specs via the default web browser/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "execute_specs" do
|
||||
before do
|
||||
@output = capture_output { jasmine_dev.execute_specs }
|
||||
end
|
||||
|
||||
it "should build the distribution" do
|
||||
@output.should match(/Building Jasmine distribution/)
|
||||
end
|
||||
|
||||
it "should tell the developer that the specs are being counted" do
|
||||
@output.should match(/Counting specs/)
|
||||
end
|
||||
|
||||
it "should tell the user that the specs are running in Node.js" do
|
||||
@output.should match(/specs via Node/)
|
||||
end
|
||||
|
||||
it "should tell the user that the specs are running in the broswer" do
|
||||
@output.should match(/specs via the default web browser/)
|
||||
end
|
||||
end
|
||||
end
|
||||
39
spec/tasks/jshint_spec.rb
Normal file
39
spec/tasks/jshint_spec.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "JSHint task" do
|
||||
|
||||
let(:tmp_dir) { "#{Dir.tmpdir}/jasmine_tasks_test" }
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
before do
|
||||
reset_dir tmp_dir
|
||||
end
|
||||
|
||||
describe "when Node is not present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_node?).and_return(false)
|
||||
@output = capture_output { jasmine_dev.js_hint }
|
||||
end
|
||||
|
||||
it "should not tell the user that lint is running" do
|
||||
@output.should_not match(/Running JSHint/)
|
||||
end
|
||||
|
||||
it "should prompt the user to install Node" do
|
||||
@output.should match(/Node\.js is required/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when Node is present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_node?).and_return(true)
|
||||
|
||||
@output = capture_output { jasmine_dev.js_hint }
|
||||
end
|
||||
|
||||
it "should tell the user that lint is running" do
|
||||
@output.should match(/Running JSHint/)
|
||||
@output.should match(/Jasmine JSHint PASSED/)
|
||||
end
|
||||
end
|
||||
end
|
||||
39
spec/tasks/release_spec.rb
Normal file
39
spec/tasks/release_spec.rb
Normal file
@@ -0,0 +1,39 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Release task" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
describe "when the pages submodule is not present" do
|
||||
before do
|
||||
jasmine_dev.should_receive(:has_pages_submodule?).and_return(false)
|
||||
|
||||
@output = capture_output { jasmine_dev.release_prep }
|
||||
end
|
||||
|
||||
it "should tell the user the task is running" do
|
||||
@output.should match(/Building Release/)
|
||||
end
|
||||
|
||||
it "should prompt the user to install the submodule" do
|
||||
@output.should match(/Submodule for Github Pages isn't present/)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the pages submodule is present" do
|
||||
before do
|
||||
JasmineDev.any_instance.should_receive(:write_version_files)
|
||||
JasmineDev.any_instance.should_receive(:build_distribution)
|
||||
JasmineDev.any_instance.should_receive(:build_standalone_distribution)
|
||||
JasmineDev.any_instance.should_receive(:build_github_pages)
|
||||
|
||||
jasmine_dev.should_receive(:has_pages_submodule?).and_return(true)
|
||||
|
||||
@output = capture_output { jasmine_dev.release_prep }
|
||||
end
|
||||
|
||||
it "should tell the user the task is running" do
|
||||
@output.should match(/Building Release/)
|
||||
end
|
||||
end
|
||||
end
|
||||
55
spec/tasks/version_spec.rb
Normal file
55
spec/tasks/version_spec.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
require 'spec_helper.rb'
|
||||
|
||||
describe "Version tasks" do
|
||||
|
||||
let(:jasmine_dev) { JasmineDev.new }
|
||||
|
||||
describe "write_version_files" do
|
||||
|
||||
before do
|
||||
@output = capture_output { jasmine_dev.write_version_files }
|
||||
end
|
||||
|
||||
it "should tell the user that the task has started" do
|
||||
@output.should match(/Building version files/)
|
||||
end
|
||||
|
||||
it "should build the version.js file" do
|
||||
js_version = File.read(File.join(project_root, 'src', 'version.js'))
|
||||
js_version.should match(%Q{"build": #{jasmine_version_object["build"]}})
|
||||
js_version.should match(%Q{"minor": #{jasmine_version_object["minor"]}})
|
||||
js_version.should match(%Q{"build": #{jasmine_version_object["build"]}})
|
||||
|
||||
if jasmine_version_object["release_candidate"]
|
||||
js_version.should match(%Q{"release_candidate": #{jasmine_version_object["release_candidate"]}})
|
||||
end
|
||||
|
||||
js_version.should match(/"revision": \d+/)
|
||||
end
|
||||
|
||||
it "should build the jasmine-core ruby gem version" do
|
||||
ruby_version = File.read(File.join(project_root, 'lib', 'jasmine-core', 'version.rb'))
|
||||
ruby_version.should match(%Q{VERSION = "#{jasmine_version}"})
|
||||
end
|
||||
end
|
||||
|
||||
describe "display_version" do
|
||||
describe "when Node.js is not present" do
|
||||
before do
|
||||
@output = capture_output { jasmine_dev.display_version }
|
||||
end
|
||||
|
||||
it "should display a version header" do
|
||||
@output.should match(/Current version/)
|
||||
end
|
||||
|
||||
it "should display the current version Object" do
|
||||
@output.should match(/Display version: \e\[33m\d+\.\d+\.\d+/)
|
||||
end
|
||||
|
||||
it "should display the current version string" do
|
||||
@output.should match(/\{ "major": \d+, "minor": \d+, "build": \d+/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
spec/templates/runner.html.erb
Normal file
49
spec/templates/runner.html.erb
Normal file
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title><%= title %></title>
|
||||
|
||||
<%= favicon %>
|
||||
<%= jasmine_tags %>
|
||||
|
||||
<!-- include source files here... -->
|
||||
<%= source_tags %>
|
||||
|
||||
<!-- include spec files here... -->
|
||||
<%= spec_file_tags %>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
var jasmineEnv = jasmine.getEnv();
|
||||
jasmineEnv.updateInterval = 1000;
|
||||
|
||||
var htmlReporter = new jasmine.HtmlReporter();
|
||||
|
||||
jasmineEnv.addReporter(htmlReporter);
|
||||
|
||||
jasmineEnv.specFilter = function(spec) {
|
||||
return htmlReporter.specFilter(spec);
|
||||
};
|
||||
|
||||
var currentWindowOnload = window.onload;
|
||||
|
||||
window.onload = function() {
|
||||
if (currentWindowOnload) {
|
||||
currentWindowOnload();
|
||||
}
|
||||
execJasmine();
|
||||
};
|
||||
|
||||
function execJasmine() {
|
||||
jasmineEnv.execute();
|
||||
}
|
||||
|
||||
})();
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
1
spec/templates/script_tag.html.erb
Normal file
1
spec/templates/script_tag.html.erb
Normal file
@@ -0,0 +1 @@
|
||||
<script type="text/javascript" src="<%= file %>"></script>
|
||||
@@ -1,7 +0,0 @@
|
||||
[
|
||||
"base.js",
|
||||
"util.js",
|
||||
"Env.js",
|
||||
"Reporter.js",
|
||||
"Block.js"
|
||||
]
|
||||
@@ -1,4 +1,4 @@
|
||||
jasmine.TrivialConsoleReporter = function(print, doneCallback) {
|
||||
jasmine.ConsoleReporter = function(print, doneCallback, showColors) {
|
||||
//inspired by mhevery's jasmine-node reporter
|
||||
//https://github.com/mhevery/jasmine-node
|
||||
|
||||
@@ -16,7 +16,7 @@ jasmine.TrivialConsoleReporter = function(print, doneCallback) {
|
||||
};
|
||||
|
||||
function coloredStr(color, str) {
|
||||
return ansi[color] + str + ansi.none;
|
||||
return showColors ? (ansi[color] + str + ansi.none) : str;
|
||||
}
|
||||
|
||||
function greenStr(str) {
|
||||
@@ -19,4 +19,4 @@ jasmine.Block.prototype.execute = function(onComplete) {
|
||||
this.spec.fail(e);
|
||||
}
|
||||
onComplete();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -51,12 +51,17 @@ jasmine.Env.prototype.version = function () {
|
||||
* @returns string containing jasmine version build info, if set.
|
||||
*/
|
||||
jasmine.Env.prototype.versionString = function() {
|
||||
if (jasmine.version_) {
|
||||
var version = this.version();
|
||||
return version.major + "." + version.minor + "." + version.build + " revision " + version.revision;
|
||||
} else {
|
||||
if (!jasmine.version_) {
|
||||
return "version unknown";
|
||||
}
|
||||
|
||||
var version = this.version();
|
||||
var versionString = version.major + "." + version.minor + "." + version.build;
|
||||
if (version.release_candidate) {
|
||||
versionString += ".rc" + version.release_candidate;
|
||||
}
|
||||
versionString += " revision " + version.revision;
|
||||
return versionString;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -225,11 +230,19 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
return a.getTime() == b.getTime();
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.Any) {
|
||||
if (a.jasmineMatches) {
|
||||
return a.jasmineMatches(b);
|
||||
}
|
||||
|
||||
if (b.jasmineMatches) {
|
||||
return b.jasmineMatches(a);
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return a.matches(b);
|
||||
}
|
||||
|
||||
if (b instanceof jasmine.Matchers.Any) {
|
||||
if (b instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return b.matches(a);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
|
||||
/**
|
||||
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toNotEqual() instead.
|
||||
* @deprecated as of 1.0. Use not.toEqual() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotEqual = function(expected) {
|
||||
return !this.env.equals_(this.actual, expected);
|
||||
@@ -277,7 +277,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
|
||||
* Matcher that checks that the expected item is NOT an element in the actual Array.
|
||||
*
|
||||
* @param {Object} expected
|
||||
* @deprecated as of 1.0. Use not.toNotContain() instead.
|
||||
* @deprecated as of 1.0. Use not.toContain() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotContain = function(expected) {
|
||||
return !this.env.contains_(this.actual, expected);
|
||||
@@ -345,7 +345,7 @@ jasmine.Matchers.Any = function(expectedClass) {
|
||||
this.expectedClass = expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
|
||||
if (this.expectedClass == String) {
|
||||
return typeof other == 'string' || other instanceof String;
|
||||
}
|
||||
@@ -365,7 +365,36 @@ jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
return other instanceof this.expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.toString = function() {
|
||||
jasmine.Matchers.Any.prototype.jasmineToString = function() {
|
||||
return '<jasmine.any(' + this.expectedClass + ')>';
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining = function (sample) {
|
||||
this.sample = sample;
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
|
||||
mismatchKeys = mismatchKeys || [];
|
||||
mismatchValues = mismatchValues || [];
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj != null && obj[keyName] !== jasmine.undefined;
|
||||
};
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasKey(other, property) && hasKey(this.sample, property)) {
|
||||
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
|
||||
}
|
||||
else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
|
||||
mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
|
||||
}
|
||||
}
|
||||
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
|
||||
return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
|
||||
};
|
||||
|
||||
@@ -23,8 +23,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === jasmine.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value instanceof jasmine.Matchers.Any) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString());
|
||||
} else if (typeof value === 'string') {
|
||||
this.emitString(value);
|
||||
} else if (jasmine.isSpy(value)) {
|
||||
|
||||
@@ -74,4 +74,4 @@ jasmine.Runner.prototype.topLevelSuites = function() {
|
||||
|
||||
jasmine.Runner.prototype.results = function() {
|
||||
return this.queue.results();
|
||||
};
|
||||
};
|
||||
|
||||
@@ -79,4 +79,4 @@ jasmine.Suite.prototype.execute = function(onComplete) {
|
||||
this.queue.start(function () {
|
||||
self.finish(onComplete);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
15
src/core/base.js
Executable file → Normal file
15
src/core/base.js
Executable file → Normal file
@@ -196,6 +196,21 @@ jasmine.any = function(clazz) {
|
||||
return new jasmine.Matchers.Any(clazz);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
|
||||
* attributes on the object.
|
||||
*
|
||||
* @example
|
||||
* // don't care about any other attributes than foo.
|
||||
* expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
|
||||
*
|
||||
* @param sample {Object} sample
|
||||
* @returns matchable object for the sample
|
||||
*/
|
||||
jasmine.objectContaining = function (sample) {
|
||||
return new jasmine.Matchers.ObjectContaining(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
|
||||
*
|
||||
|
||||
0
src/core/mock-timeout.js
Executable file → Normal file
0
src/core/mock-timeout.js
Executable file → Normal file
101
src/html/HtmlReporter.js
Normal file
101
src/html/HtmlReporter.js
Normal file
@@ -0,0 +1,101 @@
|
||||
jasmine.HtmlReporter = function(_doc) {
|
||||
var self = this;
|
||||
var doc = _doc || window.document;
|
||||
|
||||
var reporterView;
|
||||
|
||||
var dom = {};
|
||||
|
||||
// Jasmine Reporter Public Interface
|
||||
self.logRunningSpecs = false;
|
||||
|
||||
self.reportRunnerStarting = function(runner) {
|
||||
var specs = runner.specs() || [];
|
||||
|
||||
if (specs.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReporterDom(runner.env.versionString());
|
||||
doc.body.appendChild(dom.reporter);
|
||||
|
||||
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
|
||||
reporterView.addSpecs(specs, self.specFilter);
|
||||
};
|
||||
|
||||
self.reportRunnerResults = function(runner) {
|
||||
reporterView && reporterView.complete();
|
||||
};
|
||||
|
||||
self.reportSuiteResults = function(suite) {
|
||||
reporterView.suiteComplete(suite);
|
||||
};
|
||||
|
||||
self.reportSpecStarting = function(spec) {
|
||||
if (self.logRunningSpecs) {
|
||||
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
self.reportSpecResults = function(spec) {
|
||||
reporterView.specComplete(spec);
|
||||
};
|
||||
|
||||
self.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
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
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.specFilter = function(spec) {
|
||||
if (!focusedSpecName()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return spec.getFullName().indexOf(focusedSpecName()) === 0;
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function focusedSpecName() {
|
||||
var specName;
|
||||
|
||||
(function memoizeFocusedSpec() {
|
||||
if (specName) {
|
||||
return;
|
||||
}
|
||||
|
||||
var paramMap = [];
|
||||
var params = doc.location.search.substring(1).split('&');
|
||||
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
specName = paramMap.spec;
|
||||
})();
|
||||
|
||||
return specName;
|
||||
}
|
||||
|
||||
function createReporterDom(version) {
|
||||
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
|
||||
dom.banner = self.createDom('div', { className: 'banner' },
|
||||
self.createDom('span', { className: 'title' }, "Jasmine "),
|
||||
self.createDom('span', { className: 'version' }, version)),
|
||||
|
||||
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
|
||||
dom.alert = self.createDom('div', {className: 'alert'}),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
};
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
|
||||
60
src/html/HtmlReporterHelpers.js
Normal file
60
src/html/HtmlReporterHelpers.js
Normal file
@@ -0,0 +1,60 @@
|
||||
jasmine.HtmlReporterHelpers = {};
|
||||
|
||||
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
var child = arguments[i];
|
||||
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var attr in attrs) {
|
||||
if (attr == "className") {
|
||||
el[attr] = attrs[attr];
|
||||
} else {
|
||||
el.setAttribute(attr, attrs[attr]);
|
||||
}
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
|
||||
var results = child.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
|
||||
var parentDiv = this.dom.summary;
|
||||
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
|
||||
var parent = child[parentSuite];
|
||||
|
||||
if (parent) {
|
||||
if (typeof this.views.suites[parent.id] == 'undefined') {
|
||||
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
|
||||
}
|
||||
parentDiv = this.views.suites[parent.id].element;
|
||||
}
|
||||
|
||||
parentDiv.appendChild(childElement);
|
||||
};
|
||||
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
|
||||
for(var fn in jasmine.HtmlReporterHelpers) {
|
||||
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
|
||||
}
|
||||
};
|
||||
|
||||
164
src/html/ReporterView.js
Normal file
164
src/html/ReporterView.js
Normal file
@@ -0,0 +1,164 @@
|
||||
jasmine.HtmlReporter.ReporterView = function(dom) {
|
||||
this.startedAt = new Date();
|
||||
this.runningSpecCount = 0;
|
||||
this.completeSpecCount = 0;
|
||||
this.passedCount = 0;
|
||||
this.failedCount = 0;
|
||||
this.skippedCount = 0;
|
||||
|
||||
this.createResultsMenu = function() {
|
||||
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
|
||||
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
|
||||
' | ',
|
||||
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
|
||||
|
||||
this.summaryMenuItem.onclick = function() {
|
||||
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
|
||||
};
|
||||
|
||||
this.detailsMenuItem.onclick = function() {
|
||||
showDetails();
|
||||
};
|
||||
};
|
||||
|
||||
this.addSpecs = function(specs, specFilter) {
|
||||
this.totalSpecCount = specs.length;
|
||||
|
||||
this.views = {
|
||||
specs: {},
|
||||
suites: {}
|
||||
};
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var spec = specs[i];
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
|
||||
if (specFilter(spec)) {
|
||||
this.runningSpecCount++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.specComplete = function(spec) {
|
||||
this.completeSpecCount++;
|
||||
|
||||
if (isUndefined(this.views.specs[spec.id])) {
|
||||
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
|
||||
}
|
||||
|
||||
var specView = this.views.specs[spec.id];
|
||||
|
||||
switch (specView.status()) {
|
||||
case 'passed':
|
||||
this.passedCount++;
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.failedCount++;
|
||||
break;
|
||||
|
||||
case 'skipped':
|
||||
this.skippedCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
specView.refresh();
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
this.suiteComplete = function(suite) {
|
||||
var suiteView = this.views.suites[suite.id];
|
||||
if (isUndefined(suiteView)) {
|
||||
return;
|
||||
}
|
||||
suiteView.refresh();
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
|
||||
if (isUndefined(this.resultsMenu)) {
|
||||
this.createResultsMenu();
|
||||
}
|
||||
|
||||
// currently running UI
|
||||
if (isUndefined(this.runningAlert)) {
|
||||
this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
|
||||
dom.alert.appendChild(this.runningAlert);
|
||||
}
|
||||
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
|
||||
|
||||
// skipped specs UI
|
||||
if (isUndefined(this.skippedAlert)) {
|
||||
this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
|
||||
}
|
||||
|
||||
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.skippedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.skippedAlert);
|
||||
}
|
||||
|
||||
// passing specs UI
|
||||
if (isUndefined(this.passedAlert)) {
|
||||
this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
|
||||
}
|
||||
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
|
||||
|
||||
// failing specs UI
|
||||
if (isUndefined(this.failedAlert)) {
|
||||
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
|
||||
}
|
||||
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
|
||||
|
||||
if (this.failedCount === 1 && isDefined(dom.alert)) {
|
||||
dom.alert.appendChild(this.failedAlert);
|
||||
dom.alert.appendChild(this.resultsMenu);
|
||||
}
|
||||
|
||||
// summary info
|
||||
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
|
||||
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
|
||||
};
|
||||
|
||||
this.complete = function() {
|
||||
dom.alert.removeChild(this.runningAlert);
|
||||
|
||||
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
|
||||
|
||||
if (this.failedCount === 0) {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
|
||||
} else {
|
||||
showDetails();
|
||||
}
|
||||
|
||||
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function showDetails() {
|
||||
if (dom.reporter.className.search(/showDetails/) === -1) {
|
||||
dom.reporter.className += " showDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefined(obj) {
|
||||
return typeof obj === 'undefined';
|
||||
}
|
||||
|
||||
function isDefined(obj) {
|
||||
return !isUndefined(obj);
|
||||
}
|
||||
|
||||
function specPluralizedFor(count) {
|
||||
var str = count + " spec";
|
||||
if (count > 1) {
|
||||
str += "s"
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
|
||||
|
||||
|
||||
79
src/html/SpecView.js
Normal file
79
src/html/SpecView.js
Normal file
@@ -0,0 +1,79 @@
|
||||
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
|
||||
this.spec = spec;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.symbol = this.createDom('li', { className: 'pending' });
|
||||
this.dom.symbolSummary.appendChild(this.symbol);
|
||||
|
||||
this.summary = this.createDom('div', { className: 'specSummary' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.description)
|
||||
);
|
||||
|
||||
this.detail = this.createDom('div', { className: 'specDetail' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.getFullName())
|
||||
);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.spec);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
|
||||
this.symbol.className = this.status();
|
||||
|
||||
switch (this.status()) {
|
||||
case 'skipped':
|
||||
break;
|
||||
|
||||
case 'passed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
this.appendFailureDetail();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
|
||||
this.summary.className += ' ' + this.status();
|
||||
this.appendToSummary(this.spec, this.summary);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
|
||||
this.detail.className += ' ' + this.status();
|
||||
|
||||
var resultItems = this.spec.results().getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
if (result.type == 'log') {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
|
||||
} else if (result.type == 'expect' && result.passed && !result.passed()) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
|
||||
|
||||
if (result.trace.stack) {
|
||||
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
this.detail.appendChild(messagesDiv);
|
||||
this.dom.details.appendChild(this.detail);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);
|
||||
22
src/html/SuiteView.js
Normal file
22
src/html/SuiteView.js
Normal file
@@ -0,0 +1,22 @@
|
||||
jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
|
||||
this.suite = suite;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.element = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
|
||||
);
|
||||
|
||||
this.appendToSummary(this.suite, this.element);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.suite);
|
||||
};
|
||||
|
||||
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
|
||||
this.element.className += " " + this.status();
|
||||
};
|
||||
|
||||
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* @deprecated Use jasmine.HtmlReporter instead
|
||||
*/
|
||||
jasmine.TrivialReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
@@ -31,10 +33,10 @@ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarA
|
||||
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"),
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
|
||||
302
src/html/_HTMLReporter.scss
Normal file
302
src/html/_HTMLReporter.scss
Normal file
@@ -0,0 +1,302 @@
|
||||
@import "compass";
|
||||
|
||||
$line-height: 14px;
|
||||
$margin-unit: 14px;
|
||||
|
||||
$feint-text-color: #aaa;
|
||||
$light-text-color: #666;
|
||||
$text-color: #333;
|
||||
|
||||
$page-background-color: #eee;
|
||||
|
||||
$light-passing-color: #a6b779;
|
||||
$passing-color: #5e7d00;
|
||||
|
||||
$light-failing-color: #cf867e;
|
||||
$failing-color: #b03911;
|
||||
|
||||
$neutral-color: #bababa;
|
||||
|
||||
$font-size: 11px;
|
||||
$large-font-size: 14px;
|
||||
|
||||
body {
|
||||
background-color: $page-background-color;
|
||||
padding: 0;
|
||||
margin: 5px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#HTMLReporter {
|
||||
|
||||
font-size: $font-size;
|
||||
font-family: Monaco, "Lucida Console", monospace;
|
||||
line-height: $line-height;
|
||||
color: $text-color;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
p, h1, h2, h3, h4, h5, h6 {
|
||||
margin: 0;
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
.banner,
|
||||
.symbolSummary,
|
||||
.summary,
|
||||
.resultMessage,
|
||||
.specDetail .description,
|
||||
.alert .bar,
|
||||
.stackTrace {
|
||||
padding-left: $margin-unit - 5px;
|
||||
padding-right: $margin-unit - 5px;
|
||||
}
|
||||
|
||||
// This div is available for testing elements that must be added to the DOM.
|
||||
// We position it out of view, so it doesn't obstruct the runner.
|
||||
#jasmine_content {
|
||||
position: fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.version {
|
||||
color: $feint-text-color;
|
||||
}
|
||||
|
||||
//--- Banner ---//
|
||||
|
||||
.banner {
|
||||
margin-top: $line-height;
|
||||
}
|
||||
|
||||
.duration {
|
||||
color: $feint-text-color;
|
||||
float: right;
|
||||
}
|
||||
|
||||
//--- Symbol summary ---//
|
||||
|
||||
.symbolSummary {
|
||||
@include clearfix;
|
||||
margin: $line-height 0;
|
||||
|
||||
li {
|
||||
display: block;
|
||||
float: left;
|
||||
height: $line-height / 2;
|
||||
width: $line-height;
|
||||
margin-bottom: $line-height / 2;
|
||||
|
||||
//opacity: .9;
|
||||
|
||||
font-size: 16px;
|
||||
|
||||
&.passed {
|
||||
font-size: 14px;
|
||||
|
||||
&:before{
|
||||
color: $passing-color;
|
||||
content: "\02022";
|
||||
}
|
||||
}
|
||||
|
||||
&.failed {
|
||||
line-height: ($line-height / 2) + 2;
|
||||
|
||||
&:before{
|
||||
color: $failing-color;
|
||||
content: "x";
|
||||
font-weight: bold;
|
||||
margin-left: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
&.skipped {
|
||||
font-size: 14px;
|
||||
|
||||
&:before{
|
||||
color: $neutral-color;
|
||||
content: "\02022";
|
||||
}
|
||||
}
|
||||
|
||||
&.pending{
|
||||
line-height: ($line-height / 2) + 4;
|
||||
|
||||
&:before {
|
||||
color: $feint-text-color;
|
||||
content: "-";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- Alert ---//
|
||||
|
||||
.bar {
|
||||
line-height: $line-height * 2;
|
||||
font-size: $large-font-size;
|
||||
|
||||
display: block;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.runningAlert {
|
||||
background-color: $light-text-color;
|
||||
}
|
||||
|
||||
.skippedAlert {
|
||||
background-color: $feint-text-color;
|
||||
|
||||
&:first-child {
|
||||
background-color: $text-color;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.passingAlert {
|
||||
background-color: $light-passing-color;
|
||||
|
||||
&:first-child {
|
||||
background-color: $passing-color;
|
||||
}
|
||||
}
|
||||
|
||||
.failingAlert {
|
||||
background-color: $light-failing-color;
|
||||
|
||||
&:first-child {
|
||||
background-color: $failing-color
|
||||
}
|
||||
}
|
||||
|
||||
//--- Results ---//
|
||||
|
||||
.results {
|
||||
margin-top: $line-height;
|
||||
}
|
||||
|
||||
//--- Results menu ---//
|
||||
|
||||
#details {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.resultsMenu,
|
||||
.resultsMenu a {
|
||||
background-color: #fff;
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
&.showDetails {
|
||||
|
||||
.summaryMenuItem {
|
||||
font-weight: normal;
|
||||
text-decoration: inherit;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.detailsMenuItem {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.summary {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#details {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.summaryMenuItem {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
//--- Results summary ---//
|
||||
|
||||
.summary {
|
||||
margin-top: $margin-unit;
|
||||
|
||||
.suite .suite, .specSummary {
|
||||
margin-left: $margin-unit;
|
||||
}
|
||||
|
||||
.specSummary {
|
||||
&.passed a {
|
||||
color: $passing-color;
|
||||
}
|
||||
&.failed a {
|
||||
color: $failing-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.description+.suite {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.suite {
|
||||
margin-top: $margin-unit;
|
||||
|
||||
a {
|
||||
color: $text-color;
|
||||
}
|
||||
}
|
||||
|
||||
//--- Results details ---//
|
||||
|
||||
#details {
|
||||
.specDetail {
|
||||
margin-bottom: $line-height * 2;
|
||||
|
||||
.description {
|
||||
//line-height: $line-height * 2;
|
||||
display: block;
|
||||
|
||||
color: white;
|
||||
background-color: $failing-color;
|
||||
|
||||
//font-size: $large-font-size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.resultMessage {
|
||||
padding-top: $line-height;
|
||||
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
margin: 5px 0 0 0;
|
||||
max-height: $line-height * 16;
|
||||
overflow: auto;
|
||||
line-height: 18px;
|
||||
|
||||
color: $light-text-color;
|
||||
border: 1px solid #ddd;
|
||||
background: white;
|
||||
white-space: pre;
|
||||
}
|
||||
}
|
||||
169
src/html/_TrivialReporter.scss
Normal file
169
src/html/_TrivialReporter.scss
Normal file
@@ -0,0 +1,169 @@
|
||||
#TrivialReporter {
|
||||
padding: 8px 13px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow-y: scroll;
|
||||
|
||||
background-color: white;
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
|
||||
a:visited, a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
a:hover, a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
&.show-passed .passed,
|
||||
&.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
}
|
||||
@@ -1,166 +1,81 @@
|
||||
body {
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
}
|
||||
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
|
||||
|
||||
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
#HTMLReporter a { text-decoration: none; }
|
||||
#HTMLReporter a:hover { text-decoration: underline; }
|
||||
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
|
||||
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
|
||||
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#HTMLReporter .version { color: #aaaaaa; }
|
||||
#HTMLReporter .banner { margin-top: 14px; }
|
||||
#HTMLReporter .duration { color: #aaaaaa; float: right; }
|
||||
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
|
||||
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
|
||||
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
|
||||
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
#HTMLReporter .runningAlert { background-color: #666666; }
|
||||
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
|
||||
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
|
||||
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
|
||||
#HTMLReporter .passingAlert { background-color: #a6b779; }
|
||||
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
|
||||
#HTMLReporter .failingAlert { background-color: #cf867e; }
|
||||
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
|
||||
#HTMLReporter .results { margin-top: 14px; }
|
||||
#HTMLReporter #details { display: none; }
|
||||
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter.showDetails .summary { display: none; }
|
||||
#HTMLReporter.showDetails #details { display: block; }
|
||||
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
|
||||
#HTMLReporter .summary { margin-top: 14px; }
|
||||
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
|
||||
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
|
||||
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
|
||||
#HTMLReporter .description + .suite { margin-top: 0; }
|
||||
#HTMLReporter .suite { margin-top: 14px; }
|
||||
#HTMLReporter .suite a { color: #333333; }
|
||||
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
|
||||
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
|
||||
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
|
||||
#HTMLReporter .resultMessage span.result { display: block; }
|
||||
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
|
||||
|
||||
.jasmine_reporter a:visited, .jasmine_reporter a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
.jasmine_reporter a:hover, .jasmine_reporter a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jasmine_reporter {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
.show-passed .passed,
|
||||
.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
|
||||
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
|
||||
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
|
||||
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
|
||||
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
|
||||
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
|
||||
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
|
||||
#TrivialReporter .runner.running { background-color: yellow; }
|
||||
#TrivialReporter .options { text-align: right; font-size: .8em; }
|
||||
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
|
||||
#TrivialReporter .suite .suite { margin: 5px; }
|
||||
#TrivialReporter .suite.passed { background-color: #dfd; }
|
||||
#TrivialReporter .suite.failed { background-color: #fdd; }
|
||||
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
|
||||
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
|
||||
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
|
||||
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
|
||||
#TrivialReporter .spec.skipped { background-color: #bbb; }
|
||||
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
|
||||
#TrivialReporter .passed { background-color: #cfc; display: none; }
|
||||
#TrivialReporter .failed { background-color: #fbb; }
|
||||
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
|
||||
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
|
||||
#TrivialReporter .resultMessage .mismatch { color: black; }
|
||||
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
|
||||
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
|
||||
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
|
||||
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
|
||||
|
||||
2
src/html/jasmine.scss
Normal file
2
src/html/jasmine.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "HTMLReporter";
|
||||
@import "TrivialReporter";
|
||||
3
src/templates/example_project_jasmine_tags.html.erb
Normal file
3
src/templates/example_project_jasmine_tags.html.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
<link rel="stylesheet" type="text/css" href="lib/jasmine-<%= jasmine_version %>/jasmine.css">
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmine_version %>/jasmine.js"></script>
|
||||
<script type="text/javascript" src="lib/jasmine-<%= jasmine_version %>/jasmine-html.js"></script>
|
||||
7
src/templates/version.js.erb
Normal file
7
src/templates/version.js.erb
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
jasmine.version_= {
|
||||
"major": <%= major %>,
|
||||
"minor": <%= minor %>,
|
||||
"build": <%= build %>,
|
||||
"revision": <%= revision %><%= %Q{,\n "release_candidate": #{release_candidate}} if release_candidate %>
|
||||
};
|
||||
6
src/templates/version.rb.erb
Normal file
6
src/templates/version.rb.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
module Jasmine
|
||||
module Core
|
||||
VERSION = "<%= "#{major}.#{minor}.#{build}" %><%= ".rc#{release_candidate}" if release_candidate %>"
|
||||
end
|
||||
end
|
||||
|
||||
7
src/version.js
Normal file
7
src/version.js
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
jasmine.version_= {
|
||||
"major": 1,
|
||||
"minor": 2,
|
||||
"build": 0,
|
||||
"revision": 1337006083
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"minor": 2,
|
||||
"build": 0
|
||||
}
|
||||
17
tasks/docs.rb
Normal file
17
tasks/docs.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
desc "Build jasmine documentation"
|
||||
task :doc => :require_pages_submodule do
|
||||
puts 'Creating Jasmine Documentation'
|
||||
require 'rubygems'
|
||||
require 'jsdoc_helper'
|
||||
|
||||
FileUtils.rm_r "pages/jsdoc", :force => true
|
||||
|
||||
JsdocHelper::Rake::Task.new(:lambda_jsdoc) do |t|
|
||||
t[:files] = core_sources + html_sources + console_sources
|
||||
t[:options] = "-a"
|
||||
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
|
||||
Rake::Task[:lambda_jsdoc].invoke
|
||||
end
|
||||
18
tasks/jasmine_dev.rb
Normal file
18
tasks/jasmine_dev.rb
Normal file
@@ -0,0 +1,18 @@
|
||||
require 'thor'
|
||||
require 'json'
|
||||
require 'tilt'
|
||||
require 'ostruct'
|
||||
|
||||
$:.unshift(File.join(File.dirname(__FILE__), "jasmine_dev"))
|
||||
|
||||
require "base"
|
||||
require "sources"
|
||||
require "js_hint"
|
||||
require "build_distribution"
|
||||
require "build_github_pages"
|
||||
require "build_standalone_distribution"
|
||||
require "build_standalone_runner"
|
||||
require "count_specs"
|
||||
require "execute_specs"
|
||||
require "release"
|
||||
require "version"
|
||||
54
tasks/jasmine_dev/base.rb
Normal file
54
tasks/jasmine_dev/base.rb
Normal file
@@ -0,0 +1,54 @@
|
||||
class JasmineDev < Thor
|
||||
include Thor::Actions
|
||||
|
||||
def self.source_root
|
||||
File.dirname(__FILE__)
|
||||
end
|
||||
|
||||
def self.source_paths
|
||||
[
|
||||
File.join(JasmineDev.project_root, 'lib', 'jasmine-core'),
|
||||
JasmineDev.project_root
|
||||
]
|
||||
end
|
||||
|
||||
def self.project_root
|
||||
File.join(JasmineDev.source_root, '..', '..')
|
||||
end
|
||||
|
||||
def self.spacer
|
||||
"\n--------------------"
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
# allows merged stdout in test with low-harassment
|
||||
def run_with_output(*run_args)
|
||||
say run *run_args
|
||||
end
|
||||
|
||||
def node_installed?
|
||||
return true if has_node?
|
||||
|
||||
say "Node.js is required to develop Jasmine. Please visit http://nodejs.org to install.",
|
||||
:red
|
||||
false
|
||||
end
|
||||
|
||||
def has_node?
|
||||
run "which node", :verbose => false, :capture => true
|
||||
$?.exitstatus == 0
|
||||
end
|
||||
|
||||
def pages_submodule_installed?
|
||||
return true if has_pages_submodule?
|
||||
|
||||
say "Submodule for Github Pages isn't present. Run git submodule update --init",
|
||||
:red
|
||||
false
|
||||
end
|
||||
|
||||
def has_pages_submodule?
|
||||
File.exist?(File.join(JasmineDev.project_root, 'pages', 'index.html'))
|
||||
end
|
||||
end
|
||||
end
|
||||
53
tasks/jasmine_dev/build_distribution.rb
Normal file
53
tasks/jasmine_dev/build_distribution.rb
Normal file
@@ -0,0 +1,53 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "build_distribution", "Build Jasmine js & css files"
|
||||
def build_distribution(directory = "./lib/jasmine-core")
|
||||
invoke :js_hint
|
||||
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building Jasmine distribution from source into #{directory}", :cyan
|
||||
|
||||
say 'Building JavaScript...', :yellow
|
||||
|
||||
inside directory do
|
||||
create_file "jasmine.js",
|
||||
concat_contents_of(jasmine_js_paths),
|
||||
:force => true
|
||||
create_file "jasmine-html.js",
|
||||
concat_contents_of(jasmine_html_js_paths),
|
||||
:force => true
|
||||
end
|
||||
|
||||
say 'Building CSS...', :yellow
|
||||
|
||||
run "compass compile", :capture => true
|
||||
|
||||
copy_file File.join("#{JasmineDev.project_root}", 'src', 'html', 'jasmine.css'),
|
||||
File.join(directory, 'jasmine.css')
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def jasmine_js_paths
|
||||
paths = JasmineDev::JASMINE_SOURCES[:core].collect do |f|
|
||||
File.join(JasmineDev.project_root, 'src', 'core', f)
|
||||
end
|
||||
|
||||
paths << File.join(JasmineDev.project_root, 'src', 'version.js')
|
||||
paths
|
||||
end
|
||||
|
||||
def jasmine_html_js_paths
|
||||
JasmineDev::JASMINE_SOURCES[:html].collect do |f|
|
||||
File.join(JasmineDev.project_root, 'src', 'html', f)
|
||||
end
|
||||
end
|
||||
|
||||
def concat_contents_of(paths)
|
||||
paths.inject("") do |string, path|
|
||||
string << File.read(path)
|
||||
string
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
31
tasks/jasmine_dev/build_github_pages.rb
Normal file
31
tasks/jasmine_dev/build_github_pages.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "build_github_pages", "Build static pages for pivotal.github.com/jasmine"
|
||||
def build_github_pages(pages_dir = File.expand_path(File.join('.', 'pages')))
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building Github Pages...", :cyan
|
||||
|
||||
return unless pages_submodule_installed?
|
||||
|
||||
pages_output = File.join(pages_dir, 'pages_output')
|
||||
FileUtils.rm_r(pages_output) if File.exist?(pages_output)
|
||||
|
||||
inside File.join('pages', 'pages_source') do
|
||||
run_with_output "frank export #{pages_output}", :capture => true
|
||||
end
|
||||
|
||||
pages_files = Dir.chdir(pages_output) { Dir.glob('*') }
|
||||
|
||||
pages_files.each do |file|
|
||||
source_path = File.join(pages_output, file)
|
||||
destination_path = File.join(pages_dir, file)
|
||||
|
||||
if File.directory?(source_path)
|
||||
directory source_path, destination_path
|
||||
else
|
||||
copy_file source_path, destination_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
49
tasks/jasmine_dev/build_standalone_distribution.rb
Normal file
49
tasks/jasmine_dev/build_standalone_distribution.rb
Normal file
@@ -0,0 +1,49 @@
|
||||
class JasmineDev < Thor
|
||||
include Thor::Actions
|
||||
|
||||
desc "build_standalone_distribution", "Build Jasmine standalone distribution"
|
||||
def build_standalone_distribution(download_dir = File.expand_path(File.join('.', 'pages', 'downloads')))
|
||||
invoke :build_distribution
|
||||
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building standalone distribution...", :cyan
|
||||
|
||||
say "Staging files...", :yellow
|
||||
|
||||
lib_files.each do |f|
|
||||
copy_file f, File.join(standalone_temp_dir, 'lib', "jasmine-#{version_string}", f)
|
||||
end
|
||||
|
||||
['src', 'spec'].each do |dir|
|
||||
directory File.join('lib', 'jasmine-core', 'example', dir),
|
||||
File.join(standalone_temp_dir, dir)
|
||||
end
|
||||
|
||||
invoke :build_standalone_runner
|
||||
|
||||
say "Zipping distribution...", :yellow
|
||||
|
||||
inside standalone_temp_dir do
|
||||
run_with_output "zip -rq ../jasmine-standalone-#{version_string}.zip ."
|
||||
|
||||
say "Copying Zip file to downloads directory", :yellow
|
||||
run "cp ../jasmine-standalone-#{version_string}.zip #{download_dir}"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def standalone_temp_dir
|
||||
@standalone_temp_dir ||= File.join(Dir.tmpdir, 'jasmine_standalone', "jasmine-standalone-#{version_string}")
|
||||
end
|
||||
|
||||
def lib_files
|
||||
%w{ jasmine.js jasmine-html.js jasmine.css MIT.LICENSE }
|
||||
end
|
||||
|
||||
def example_path
|
||||
File.join('lib', "jasmine-#{version_string}")
|
||||
end
|
||||
end
|
||||
end
|
||||
59
tasks/jasmine_dev/build_standalone_runner.rb
Normal file
59
tasks/jasmine_dev/build_standalone_runner.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
class JasmineDev < Thor
|
||||
include Thor::Actions
|
||||
|
||||
desc "build_standalone_runner", "Build HTML spec runner for Jasmine standalone distribution"
|
||||
|
||||
def build_standalone_runner
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building standalone runner HTML...", :cyan
|
||||
|
||||
create_file File.join(standalone_temp_dir, 'SpecRunner.html') do
|
||||
template = Tilt.new(File.join('spec', 'templates','runner.html.erb'))
|
||||
|
||||
scope = OpenStruct.new(:title => "Jasmine Spec Runner",
|
||||
:favicon => example_favicon,
|
||||
:jasmine_tags => example_jasmine_tags,
|
||||
:source_tags => example_source_tags,
|
||||
:spec_file_tags => example_spec_tags)
|
||||
template.render(scope)
|
||||
end
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def standalone_temp_dir
|
||||
@standalone_temp_dir ||= File.join(Dir.tmpdir, 'jasmine_standalone', "jasmine-standalone-#{version_string}")
|
||||
end
|
||||
|
||||
def example_path
|
||||
File.join('lib', "jasmine-#{version_string}")
|
||||
end
|
||||
|
||||
def example_favicon
|
||||
%Q{<link rel="shortcut icon" type="image/png" href="#{example_path}/jasmine_favicon.png">}
|
||||
end
|
||||
|
||||
def script_tags_for(files)
|
||||
srcs = (files.is_a?(String) ? [files] : files)
|
||||
srcs.inject([]) do |tags, file|
|
||||
tags << %Q{<script type="text/javascript" src="#{file}"></script>}
|
||||
tags
|
||||
end.join("\n ")
|
||||
end
|
||||
|
||||
def example_jasmine_tags
|
||||
tags = %Q{<link rel="stylesheet" type="text/css" href="#{example_path}/jasmine.css">}
|
||||
tags << "\n "
|
||||
tags << script_tags_for(["#{example_path}/jasmine.js", "#{example_path}/jasmine-html.js"])
|
||||
tags
|
||||
end
|
||||
|
||||
def example_source_tags
|
||||
script_tags_for ['spec/SpecHelper.js', 'spec/PlayerSpec.js']
|
||||
end
|
||||
|
||||
def example_spec_tags
|
||||
script_tags_for ['src/Player.js', 'src/Song.js']
|
||||
end
|
||||
end
|
||||
end
|
||||
29
tasks/jasmine_dev/count_specs.rb
Normal file
29
tasks/jasmine_dev/count_specs.rb
Normal file
@@ -0,0 +1,29 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "count_specs", "Count the number of specs for each test runner"
|
||||
def count_specs
|
||||
say JasmineDev.spacer
|
||||
say "Counting specs...", :cyan
|
||||
|
||||
core_spec_count = count_specs_in(File.join('spec', 'core'))
|
||||
console_spec_count = count_specs_in(File.join('spec', 'console'))
|
||||
html_spec_count = count_specs_in(File.join('spec', 'html'))
|
||||
|
||||
say "#{(core_spec_count + console_spec_count).to_s} ", :yellow
|
||||
say "specs for Node.js runner (exclude DOM-related specs)"
|
||||
say "#{(core_spec_count + console_spec_count + html_spec_count).to_s} ", :yellow
|
||||
say "specs for Browser runner (all specs)"
|
||||
say "\n"
|
||||
say "Please verify that these numbers match the runner output."
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def count_specs_in(relative_path)
|
||||
files = Dir.glob(File.join(JasmineDev.project_root, relative_path, '*.js'))
|
||||
files.inject(0) do |count, file|
|
||||
File.read(file).scan(/\sit\s*\(/) { |s| count += 1 }
|
||||
count
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
52
tasks/jasmine_dev/execute_specs.rb
Normal file
52
tasks/jasmine_dev/execute_specs.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "execute_specs_in_node", "Run all relevant specs in Node.js"
|
||||
|
||||
def execute_specs_in_node
|
||||
return unless node_installed?
|
||||
|
||||
invoke :build_distribution
|
||||
invoke :count_specs
|
||||
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Running all appropriate specs via Node.js...", :cyan
|
||||
|
||||
with_color_option = STDOUT.isatty ? "--color" : "--noColor"
|
||||
|
||||
run_with_output "node spec/node_suite.js #{with_color_option}", :capture => true
|
||||
end
|
||||
|
||||
desc "execute_specs_in_browser", "Run all relevent specs in your default browser"
|
||||
|
||||
def execute_specs_in_browser
|
||||
invoke :build_distribution
|
||||
invoke :count_specs
|
||||
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Running all appropriate specs via the default web browser...", :cyan
|
||||
|
||||
open_specs_in_browser
|
||||
end
|
||||
|
||||
desc "execute_specs", "Run all of Jasmine's JavaScript specs"
|
||||
|
||||
def execute_specs
|
||||
invoke :execute_specs_in_node
|
||||
invoke :execute_specs_in_browser
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def open_specs_in_browser
|
||||
require 'rbconfig'
|
||||
|
||||
case Object.const_get(defined?(RbConfig) ? :RbConfig : :Config)::CONFIG['host_os']
|
||||
when /linux/
|
||||
run "xdg-open spec/runner.html"
|
||||
else
|
||||
run "open spec/runner.html"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
13
tasks/jasmine_dev/js_hint.rb
Normal file
13
tasks/jasmine_dev/js_hint.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "js_hint", "Run Jasmine source through JSHint"
|
||||
def js_hint
|
||||
say JasmineDev.spacer
|
||||
|
||||
return unless node_installed?
|
||||
|
||||
say "Running JSHint on Jasmine source and specs...", :cyan
|
||||
|
||||
run_with_output "node jshint/run.js", :capture => true
|
||||
end
|
||||
end
|
||||
16
tasks/jasmine_dev/release.rb
Normal file
16
tasks/jasmine_dev/release.rb
Normal file
@@ -0,0 +1,16 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc 'release_prep', "Update version and build distributions"
|
||||
def release_prep
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building Release...", :cyan
|
||||
|
||||
return unless pages_submodule_installed?
|
||||
|
||||
invoke :write_version_files
|
||||
invoke :build_distribution
|
||||
invoke :build_standalone_distribution
|
||||
invoke :build_github_pages
|
||||
end
|
||||
end
|
||||
32
tasks/jasmine_dev/sources.rb
Normal file
32
tasks/jasmine_dev/sources.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
class JasmineDev < Thor
|
||||
JASMINE_SOURCES = {
|
||||
:core => [
|
||||
"base.js",
|
||||
"util.js",
|
||||
"Env.js",
|
||||
"Reporter.js",
|
||||
"Block.js",
|
||||
"JsApiReporter.js",
|
||||
"Matchers.js",
|
||||
"mock-timeout.js",
|
||||
"MultiReporter.js",
|
||||
"NestedResults.js",
|
||||
"PrettyPrinter.js",
|
||||
"Queue.js",
|
||||
"Runner.js",
|
||||
"Spec.js",
|
||||
"Suite.js",
|
||||
"WaitsBlock.js",
|
||||
"WaitsForBlock.js"
|
||||
],
|
||||
|
||||
:html => [
|
||||
"HtmlReporterHelpers.js",
|
||||
"HtmlReporter.js",
|
||||
"ReporterView.js",
|
||||
"SpecView.js",
|
||||
"SuiteView.js",
|
||||
"TrivialReporter.js"
|
||||
]
|
||||
}
|
||||
end
|
||||
62
tasks/jasmine_dev/version.rb
Normal file
62
tasks/jasmine_dev/version.rb
Normal file
@@ -0,0 +1,62 @@
|
||||
class JasmineDev < Thor
|
||||
|
||||
desc "write_version_files", "Write out version files"
|
||||
|
||||
def write_version_files
|
||||
say JasmineDev.spacer
|
||||
|
||||
say "Building version files", :cyan
|
||||
|
||||
scope = OpenStruct.new(:major => version_object["major"],
|
||||
:minor => version_object["minor"],
|
||||
:build => version_object["build"],
|
||||
:release_candidate => version_object["release_candidate"],
|
||||
:revision => Time.now.to_i)
|
||||
|
||||
js_template = Tilt.new(File.join(JasmineDev.project_root, 'src', 'templates', 'version.js.erb'))
|
||||
create_file File.join(JasmineDev.project_root, 'src', 'version.js'), :force => true do
|
||||
js_template.render(scope)
|
||||
end
|
||||
|
||||
rb_template = Tilt.new(File.join(JasmineDev.project_root, 'src', 'templates', 'version.rb.erb'))
|
||||
|
||||
create_file File.join(JasmineDev.project_root, 'lib', 'jasmine-core', 'version.rb'), :force => true do
|
||||
rb_template.render(scope)
|
||||
end
|
||||
end
|
||||
|
||||
desc "display_version", "Display version currently stored in source"
|
||||
|
||||
def display_version
|
||||
|
||||
say "Current version information from src/version.json", :cyan
|
||||
|
||||
say "Display version: "
|
||||
say "#{version_string}", :yellow
|
||||
|
||||
say "Version object: "
|
||||
say "#{version_object_old}", :yellow
|
||||
end
|
||||
|
||||
no_tasks do
|
||||
def version
|
||||
@version ||= File.read(File.join(JasmineDev.project_root, 'src', 'version.json'))
|
||||
end
|
||||
|
||||
def version_string
|
||||
display = "#{version_object['major']}.#{version_object['minor']}.#{version_object['build']}"
|
||||
display += ".rc#{version_object['release_candidate']}" if version_object['release_candidate']
|
||||
display
|
||||
end
|
||||
|
||||
def version_object
|
||||
@version_object ||= JSON.parse(version)
|
||||
end
|
||||
|
||||
def version_object_old
|
||||
version.gsub("\n", " ").
|
||||
gsub(/\s+/, " ").
|
||||
gsub(/\}\s+$/, "}")
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user