diff --git a/.rspec b/.rspec
new file mode 100644
index 00000000..4e1e0d2f
--- /dev/null
+++ b/.rspec
@@ -0,0 +1 @@
+--color
diff --git a/.travis.yml b/.travis.yml
index 57e2e9e8..6ae02e7a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,3 +55,4 @@ matrix:
env: RAILS_VERSION=pojs-rspec2
allow_failures:
- rvm: rbx
+ - rvm: jruby
diff --git a/Gemfile b/Gemfile
index b36c6989..1afd28ab 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,13 +3,6 @@ gemspec
unless ENV["TRAVIS"]
group :debug do
- # curl -OL http://rubyforge.org/frs/download.php/75414/linecache19-0.5.13.gem
- # curl -OL http://rubyforge.org/frs/download.php/75415/ruby-debug-base19-0.11.26.gem
- # # Replace with your ruby path if necessary
- # gem install linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem -- --with-ruby-include=$rvm_path/src/ruby-1.9.3-p125/
- # rm linecache19-0.5.13.gem ruby-debug-base19-0.11.26.gem
- gem 'linecache19', '0.5.13'
- gem 'ruby-debug-base19', '0.11.26'
- gem 'ruby-debug19', :require => 'ruby-debug'
+ gem 'debugger'
end
end
diff --git a/MIT.LICENSE b/MIT.LICENSE
index 1eb9b49e..dd16e1ac 100644
--- a/MIT.LICENSE
+++ b/MIT.LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2008-2010 Pivotal Labs
+Copyright (c) 2008-2012 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/README.markdown b/README.markdown
index f3c466fa..8b8e17b8 100644
--- a/README.markdown
+++ b/README.markdown
@@ -11,6 +11,12 @@ This gem contains:
You can get all of this by: `gem install jasmine` or by adding Jasmine to your `Gemfile`.
+```ruby
+group :development, :test do
+ gem 'jasmine'
+end
+```
+
## Init A Project
To initialize a project for Jasmine, it depends on your web framework
@@ -46,15 +52,13 @@ For Continuous Integration environments, add this task to the project build step
`rake jasmine:ci`
-This uses Selenium to launch a browser and run the Jasmine suite. Then it uses RSpec to extract the results from the Jasmine reporter and write them to your build log.
+This uses Selenium to launch a browser and run the Jasmine suite. Then it uses RSpec to extract the results from the Jasmine reporter and write them to your build log. The browser used by selenium can be changed by setting the JASMINE_BROWSER environment variable (this might require additional webdriver dependencies).
## Configuration
Customize `spec/javascripts/support/jasmine.yml` to enumerate the source files, stylesheets, and spec files you would like the Jasmine runner to include.
You may use dir glob strings.
-For more complex configuration (e.g., port number), edit `spec/javascripts/support/jasmine_config.rb` file directly.
-
## Note about the CI task and RSpec
This gem requires RSpec for the `jasmine:ci` rake task to work. But this gem does not explicitly *depend* on any version of the RSpec gem.
diff --git a/Rakefile b/Rakefile
index 0f5a67d5..ed9cd9fb 100644
--- a/Rakefile
+++ b/Rakefile
@@ -29,10 +29,19 @@ task :default => :spec
namespace :jasmine do
require "jasmine-core"
- require './spec/jasmine_self_test_config'
task :server do
port = ENV['JASMINE_PORT'] || 8888
- JasmineSelfTestConfig.new.start_server(port)
+ Jasmine.configure do |config|
+ root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
+ config.src_dir = File.join(root, 'src')
+ config.spec_dir = Jasmine::Core.path
+ config.spec_files = lambda { (Jasmine::Core.html_spec_files + Jasmine::Core.core_spec_files).map {|f| File.join(config.spec_dir, f) } }
+ end
+
+ config = Jasmine.config
+
+ server = Jasmine::Server.new(8888, Jasmine::Application.app(config))
+ server.start
puts "your tests are here:"
puts " http://localhost:#{port}/"
diff --git a/generators/jasmine/jasmine_generator.rb b/generators/jasmine/jasmine_generator.rb
index 157f0282..e79de77a 100644
--- a/generators/jasmine/jasmine_generator.rb
+++ b/generators/jasmine/jasmine_generator.rb
@@ -14,6 +14,7 @@ def manifest
m.directory "spec/javascripts/support"
m.file "spec/javascripts/support/jasmine-rails.yml", "spec/javascripts/support/jasmine.yml"
+ m.file "spec/javascripts/support/jasmine_helper.rb", "spec/javascripts/support/jasmine_helper.rb"
m.readme "INSTALL"
m.directory "lib/tasks"
diff --git a/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml b/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml
index 6c844008..337259a5 100644
--- a/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml
+++ b/generators/jasmine/templates/spec/javascripts/support/jasmine-rails.yml
@@ -43,7 +43,7 @@ stylesheets:
# - helpers/**/*.js
#
helpers:
- - helpers/**/*.js
+ - 'helpers/**/*.js'
# spec_files
#
@@ -53,7 +53,7 @@ helpers:
# EXAMPLE:
#
# spec_files:
-# - **/*[sS]pec.js
+# - '**/*[sS]pec.js'
#
spec_files:
- '**/*[sS]pec.js'
diff --git a/generators/jasmine/templates/spec/javascripts/support/jasmine.yml b/generators/jasmine/templates/spec/javascripts/support/jasmine.yml
index 7cce692d..1e773424 100644
--- a/generators/jasmine/templates/spec/javascripts/support/jasmine.yml
+++ b/generators/jasmine/templates/spec/javascripts/support/jasmine.yml
@@ -37,7 +37,7 @@ stylesheets:
# - helpers/**/*.js
#
helpers:
-
+ - 'helpers/**/*.js'
# spec_files
#
# Return an array of filepaths relative to spec_dir to include.
@@ -49,6 +49,7 @@ helpers:
# - **/*[sS]pec.js
#
spec_files:
+ - '**/*[sS]pec.js'
# src_dir
#
@@ -71,3 +72,17 @@ src_dir:
# spec_dir: spec/javascripts
#
spec_dir:
+
+# spec_helper
+#
+# Ruby file that Jasmine server will require before starting.
+# Returned relative to your root path
+# Default spec/support/jasmine_helper.rb
+#
+# EXAMPLE:
+#
+# spec_helper: spec/support/jasmine_helper.rb
+#
+spec_helper: spec/support/jasmine_helper.rb
+
+
diff --git a/generators/jasmine/templates/spec/javascripts/support/jasmine_helper.rb b/generators/jasmine/templates/spec/javascripts/support/jasmine_helper.rb
new file mode 100644
index 00000000..b4919802
--- /dev/null
+++ b/generators/jasmine/templates/spec/javascripts/support/jasmine_helper.rb
@@ -0,0 +1,11 @@
+#Use this file to set/override Jasmine configuration options
+#You can remove it if you don't need it.
+#This file is loaded *after* jasmine.yml is interpreted.
+#
+#Example: using a different boot file.
+#Jasmine.configure do |config|
+# config.boot_dir = '/absolute/path/to/boot_dir'
+# config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
+#end
+#
+
diff --git a/jasmine.gemspec b/jasmine.gemspec
index 361296f0..3a0c2560 100644
--- a/jasmine.gemspec
+++ b/jasmine.gemspec
@@ -11,7 +11,8 @@ Gem::Specification.new do |s|
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.homepage = "http://pivotal.github.com/jasmine/"
+ s.license = "MIT"
s.files = `git ls-files`.split("\n") | Dir.glob('jasmine/**/*')
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -66,7 +67,9 @@ Gem::Specification.new do |s|
s.add_development_dependency 'json_pure'
s.add_development_dependency 'nokogiri'
- s.add_dependency 'jasmine-core', ">= 1.2.0"
+ s.add_development_dependency 'anchorman'
+
+ s.add_dependency 'jasmine-core', "~> 1.3.1"
s.add_dependency 'rack', '~> 1.0'
s.add_dependency 'rspec', '>= 1.3.1'
s.add_dependency 'selenium-webdriver', '>= 0.1.3'
diff --git a/lib/generators/jasmine/install/USAGE b/lib/generators/jasmine/install/USAGE
index 03147927..b0c9fe16 100644
--- a/lib/generators/jasmine/install/USAGE
+++ b/lib/generators/jasmine/install/USAGE
@@ -6,6 +6,4 @@ Example:
This will create:
spec/javascripts/support/jasmine.yml
- spec/javascripts/support/jasmine_config.rb
- spec/javascripts/support/jasmine_runner.rb
spec/javascripts/helpers/.gitkeep
diff --git a/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine_helper.rb b/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine_helper.rb
new file mode 100644
index 00000000..986a4c16
--- /dev/null
+++ b/lib/generators/jasmine/install/templates/spec/javascripts/support/jasmine_helper.rb
@@ -0,0 +1,11 @@
+#Use this file to set/override Jasmine configuration options
+#You can remove it if you don't need it.
+#This file is loaded *after* jasmine.yml is interpreted.
+#
+#Example: using a different boot file.
+#Jasmine.configure do |config|
+# @config.boot_dir = '/absolute/path/to/boot_dir'
+# @config.boot_files = lambda { ['/absolute/path/to/boot_dir/file.js'] }
+#end
+#
+
diff --git a/lib/jasmine.rb b/lib/jasmine.rb
index acf7b902..f35d2353 100644
--- a/lib/jasmine.rb
+++ b/lib/jasmine.rb
@@ -1,15 +1,30 @@
jasmine_files = ['base',
'dependencies',
+ 'core_configuration',
+ 'configuration',
'config',
+ 'application',
'server',
'selenium_driver',
- 'spec_builder',
+ 'rspec_formatter',
'command_line_tool',
- 'page']
+ 'page',
+ 'path_mapper',
+ 'asset_pipeline_utility',
+ 'asset_pipeline_mapper',
+ 'asset_expander',
+ 'results_processor',
+ 'results',
+ 'path_expander',
+ 'yaml_config_parser',
+ File.join('runners', 'http')]
jasmine_files.each do |file|
require File.join('jasmine', file)
end
+# jasmine_rack_files.each do |file|
+ # require File.join('rack', 'jasmine', file)
+# end
require File.join('jasmine', "railtie") if Jasmine::Dependencies.rails3?
diff --git a/lib/jasmine/application.rb b/lib/jasmine/application.rb
new file mode 100644
index 00000000..bf64cd33
--- /dev/null
+++ b/lib/jasmine/application.rb
@@ -0,0 +1,21 @@
+require 'rack'
+require 'rack/utils'
+require 'jasmine-core'
+require 'rack/jasmine/runner'
+require 'rack/jasmine/focused_suite'
+require 'rack/jasmine/cache_control'
+require 'ostruct'
+
+module Jasmine
+ class Application
+ def self.app(config, builder = Rack::Builder.new)
+ config.rack_apps.each do |(app, config_block)|
+ builder.use(app, &config_block)
+ end
+ config.rack_path_map.each do |path, handler|
+ builder.map(path) { run handler.call }
+ end
+ builder
+ end
+ end
+end
diff --git a/lib/jasmine/asset_expander.rb b/lib/jasmine/asset_expander.rb
new file mode 100644
index 00000000..7f0f287b
--- /dev/null
+++ b/lib/jasmine/asset_expander.rb
@@ -0,0 +1,18 @@
+module Jasmine
+ class AssetExpander
+ def initialize(bundled_asset_factory, asset_path_for)
+ @bundled_asset_factory = bundled_asset_factory
+ @asset_path_for = asset_path_for
+ end
+
+ def expand(src_dir, src_path)
+ pathname = src_path.gsub(/^\/?assets\//, '').gsub(/\.js$/, '')
+ bundled_asset = @bundled_asset_factory.call(pathname, 'js')
+ return nil unless bundled_asset
+
+ bundled_asset.to_a.map do |asset|
+ "/#{@asset_path_for.call(asset).gsub(/^\//, '')}?body=true"
+ end.flatten
+ end
+ end
+end
diff --git a/lib/jasmine/asset_pipeline_mapper.rb b/lib/jasmine/asset_pipeline_mapper.rb
new file mode 100644
index 00000000..3afaf739
--- /dev/null
+++ b/lib/jasmine/asset_pipeline_mapper.rb
@@ -0,0 +1,16 @@
+module Jasmine
+ class AssetPipelineMapper
+
+ def initialize(config, asset_expander)
+ @config = config
+ @asset_expander = asset_expander
+ end
+
+ def map_src_paths(src_paths)
+ src_paths.map do |src_path|
+ @asset_expander.call(@config.src_dir, src_path) || src_path
+ end.flatten.uniq
+ end
+
+ end
+end
diff --git a/lib/jasmine/asset_pipeline_utility.rb b/lib/jasmine/asset_pipeline_utility.rb
new file mode 100644
index 00000000..1b8efb31
--- /dev/null
+++ b/lib/jasmine/asset_pipeline_utility.rb
@@ -0,0 +1,19 @@
+module Jasmine
+ class AssetPipelineUtility
+ def self.bundled_asset_factory(pathname, ext)
+ context.asset_paths.asset_for(pathname, 'js')
+ end
+
+ def self.asset_path_for(filepath)
+ context.asset_path(filepath)
+ end
+
+ def self.context
+ return @context if @context
+ @context = ::Rails.application.assets.context_class
+ @context.extend(::Sprockets::Helpers::IsolatedHelper)
+ @context.extend(::Sprockets::Helpers::RailsHelper)
+ end
+
+ end
+end
diff --git a/lib/jasmine/base.rb b/lib/jasmine/base.rb
index 13d5a179..a0ce77fe 100644
--- a/lib/jasmine/base.rb
+++ b/lib/jasmine/base.rb
@@ -40,11 +40,15 @@ def self.wait_for_listener(port, name = "required process", seconds_to_wait = 20
end
def self.runner_filepath
- File.expand_path(File.join(File.dirname(__FILE__), "runner.rb"))
+ File.expand_path(File.join(File.dirname(__FILE__), "run_specs.rb"))
end
def self.runner_template
File.read(File.join(File.dirname(__FILE__), "run.html.erb"))
end
+ def self.root(*paths)
+ File.expand_path(File.join(File.dirname(__FILE__), *paths))
+ end
+
end
diff --git a/lib/jasmine/command_line_tool.rb b/lib/jasmine/command_line_tool.rb
index 7bb7ac1b..447d8a00 100644
--- a/lib/jasmine/command_line_tool.rb
+++ b/lib/jasmine/command_line_tool.rb
@@ -36,23 +36,18 @@ def process(argv)
copy_unless_exists('jasmine-example/spec/PlayerSpec.js', 'spec/javascripts/PlayerSpec.js')
copy_unless_exists('jasmine-example/spec/SpecHelper.js', 'spec/javascripts/helpers/SpecHelper.js')
- rails_tasks_dir = dest_path('lib/tasks')
- if File.exist?(rails_tasks_dir)
- copy_unless_exists('lib/tasks/jasmine.rake')
- copy_unless_exists('spec/javascripts/support/jasmine-rails.yml', 'spec/javascripts/support/jasmine.yml')
- else
- copy_unless_exists('spec/javascripts/support/jasmine.yml')
- require 'rake'
- write_mode = 'w'
- if File.exist?(dest_path('Rakefile'))
- load dest_path('Rakefile')
- write_mode = 'a'
- end
+ copy_unless_exists('spec/javascripts/support/jasmine.yml')
+ copy_unless_exists('spec/javascripts/support/jasmine_helper.rb')
+ require 'rake'
+ write_mode = 'w'
+ if File.exist?(dest_path('Rakefile'))
+ load dest_path('Rakefile')
+ write_mode = 'a'
+ end
- unless Rake::Task.task_defined?('jasmine')
- File.open(dest_path('Rakefile'), write_mode) do |f|
- f.write("\n" + File.read(template_path('lib/tasks/jasmine.rake')))
- end
+ unless Rake::Task.task_defined?('jasmine')
+ File.open(dest_path('Rakefile'), write_mode) do |f|
+ f.write("\n" + File.read(template_path('lib/tasks/jasmine.rake')))
end
end
File.open(template_path('INSTALL'), 'r').each_line do |line|
diff --git a/lib/jasmine/config.rb b/lib/jasmine/config.rb
index cf209b75..21d683e3 100644
--- a/lib/jasmine/config.rb
+++ b/lib/jasmine/config.rb
@@ -1,176 +1,85 @@
module Jasmine
- class Config
- require 'yaml'
- require 'erb'
-
- def browser
- ENV["JASMINE_BROWSER"] || 'firefox'
- end
-
- def jasmine_host
- ENV["JASMINE_HOST"] || 'http://localhost'
- end
-
- def jasmine_port
- ENV["JASMINE_PORT"] || Jasmine::find_unused_port
- end
-
- def start_server(port = 8888)
- if defined? Rack::Server # Rack ~>1.0 compatibility
- server = Rack::Server.new(:Port => port, :AccessLog => [])
- server.instance_variable_set(:@app, Jasmine.app(self)) # workaround for Rack bug, when Rack > 1.2.1 is released Rack::Server.start(:app => Jasmine.app(self)) will work
- server.start
- else
- handler = Rack::Handler.get('webrick')
- handler.run(Jasmine.app(self), :Port => port, :AccessLog => [])
- end
- end
-
- def start
- start_jasmine_server
- @client = Jasmine::SeleniumDriver.new(browser, "#{jasmine_host}:#{@jasmine_server_port}/")
- @client.connect
- end
-
- def stop
- @client.disconnect
- end
-
- def start_jasmine_server
- require 'json'
- @jasmine_server_port = jasmine_port
- t = Thread.new do
- begin
- start_server(@jasmine_server_port)
- rescue ChildProcess::TimeoutError; end
- #ignore bad exits
- end
- t.abort_on_exception = true
- Jasmine::wait_for_listener(@jasmine_server_port, "jasmine server")
- puts "jasmine server started."
- end
-
- def windows?
- require 'rbconfig'
- ::RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
- end
-
- def run
- begin
- start
- puts "servers are listening on their ports -- running the test script..."
- tests_passed = @client.run
- ensure
- stop
- end
- return tests_passed
- end
-
- def eval_js(script)
- @client.eval_js(script)
- end
-
- def json_generate(obj)
- @client.json_generate(obj)
- end
-
- def match_files(dir, patterns)
- dir = File.expand_path(dir)
- negative, positive = patterns.partition {|pattern| /^!/ =~ pattern}
- chosen, negated = [positive, negative].collect do |patterns|
- patterns.collect do |pattern|
- matches = Dir.glob(File.join(dir, pattern.gsub(/^!/,'')))
- matches.empty? && !(pattern =~ /\*|^\!/) ? pattern : matches.collect {|f| f.sub("#{dir}/", "")}.sort
- end.flatten.uniq
- end
- chosen - negated
- end
-
- def simple_config
- config = File.exist?(simple_config_file) ? YAML::load(ERB.new(File.read(simple_config_file)).result(binding)) : false
- config || {}
- end
-
-
- def spec_path
- "/__spec__"
- end
-
- def root_path
- "/__root__"
- end
-
- def js_files(spec_filter = nil)
- spec_files_to_include = spec_filter.nil? ? spec_files : match_files(spec_dir, [spec_filter])
- src_files.collect {|f| "/" + f } + helpers.collect {|f| File.join(spec_path, f) } + spec_files_to_include.collect {|f| File.join(spec_path, f) }
- end
-
- def css_files
- stylesheets.collect {|f| "/" + f }
- end
-
- def assets_files
- assets.collect {|f| "/" + f }
- end
-
- def spec_files_full_paths
- spec_files.collect {|spec_file| File.join(spec_dir, spec_file) }
- end
-
- def project_root
- Dir.pwd
- end
+ require 'yaml'
+ require 'erb'
+ def self.configure(&block)
+ block.call(self.config)
+ end
- def simple_config_file
- File.join(project_root, 'spec/javascripts/support/jasmine.yml')
+ def self.initialize_config
+ return if @config
+ @config = Jasmine::Configuration.new
+ core_config = Jasmine::CoreConfiguration.new
+
+ @config.add_path_mapper(Jasmine::PathMapper.method(:new))
+
+ @config.jasmine_path = jasmine_path = "/__jasmine__"
+ @config.src_path = src_path = "/"
+ @config.spec_path = spec_path = "/__spec__"
+ @config.boot_path = boot_path = "/__boot__"
+
+ @config.jasmine_dir = core_config.path
+ @config.boot_dir = core_config.boot_path
+ @config.boot_files = lambda { core_config.boot_files }
+ @config.jasmine_files = lambda { core_config.js_files }
+ @config.jasmine_css_files = lambda { core_config.css_files }
+ @config.add_rack_path(jasmine_path, lambda { Rack::File.new(config.jasmine_dir) })
+ @config.add_rack_path(boot_path, lambda { Rack::File.new(config.boot_dir) })
+ @config.add_rack_path(spec_path, lambda { Rack::File.new(config.spec_dir) })
+ @config.add_rack_path(src_path, lambda {
+ Rack::Cascade.new([
+ Rack::URLMap.new('/' => Rack::File.new(config.src_dir)),
+ Rack::Jasmine::Runner.new(Jasmine::Page.new(config))
+ ])
+ })
+
+ @config.add_rack_app(Rack::Head)
+ @config.add_rack_app(Rack::Jasmine::CacheControl)
+
+ if Jasmine::Dependencies.rails_3_asset_pipeline?
+ @config.add_path_mapper(lambda { |config|
+ asset_expander = Jasmine::AssetExpander.new(
+ Jasmine::AssetPipelineUtility.method(:bundled_asset_factory),
+ Jasmine::AssetPipelineUtility.method(:asset_path_for)
+ )
+ Jasmine::AssetPipelineMapper.new(config, asset_expander.method(:expand))
+ })
+ @config.add_rack_path('/assets', lambda {
+ # In order to have asset helpers like asset_path and image_path, we need to require 'action_view/base'. This
+ # triggers run_load_hooks on action_view which, in turn, causes sprockets/railtie to load the Sprockets asset
+ # helpers. Alternatively, you can include the helpers yourself without loading action_view/base:
+ Rails.application.assets.context_class.instance_eval do
+ include ::Sprockets::Helpers::IsolatedHelper
+ include ::Sprockets::Helpers::RailsHelper
+ end
+ Rails.application.assets
+ })
end
- def src_dir
- if simple_config['src_dir']
- File.join(project_root, simple_config['src_dir'])
- else
- project_root
- end
- end
-
- def spec_dir
- if simple_config['spec_dir']
- File.join(project_root, simple_config['spec_dir'])
- else
- File.join(project_root, 'spec/javascripts')
- end
- end
-
- def helpers
- if simple_config['helpers']
- match_files(spec_dir, simple_config['helpers'])
- else
- match_files(spec_dir, ["helpers/**/*.js"])
- end
- end
+ end
- def src_files
- if simple_config['src_files']
- match_files(src_dir, simple_config['src_files'])
- else
- []
- end
- end
+ def self.config
+ initialize_config
+ @config
+ end
- def spec_files
- if simple_config['spec_files']
- match_files(spec_dir, simple_config['spec_files'])
- else
- match_files(spec_dir, ["**/*[sS]pec.js"])
+ def self.load_configuration_from_yaml(path = nil)
+ path ||= File.join(Dir.pwd, 'spec', 'javascripts', 'support', 'jasmine.yml')
+ if File.exist?(path)
+ yaml_loader = lambda do |filepath|
+ YAML::load(ERB.new(File.read(filepath)).result(binding)) if File.exist?(filepath)
end
- end
-
- def stylesheets
- if simple_config['stylesheets']
- match_files(src_dir, simple_config['stylesheets'])
- else
- []
+ yaml_config = Jasmine::YamlConfigParser.new(path, Dir.pwd, Jasmine::PathExpander.method(:expand), yaml_loader)
+ Jasmine.configure do |config|
+ config.jasmine_dir = yaml_config.jasmine_dir if yaml_config.jasmine_dir
+ config.jasmine_files = lambda { yaml_config.jasmine_files } if yaml_config.jasmine_files.any?
+ config.jasmine_css_files = lambda { yaml_config.jasmine_css_files } if yaml_config.jasmine_css_files.any?
+ config.src_files = lambda { yaml_config.src_files }
+ config.spec_files = lambda { yaml_config.helpers + yaml_config.spec_files }
+ config.css_files = lambda { yaml_config.css_files }
+ config.src_dir = yaml_config.src_dir
+ config.spec_dir = yaml_config.spec_dir
end
+ require yaml_config.spec_helper if File.exist?(yaml_config.spec_helper)
end
def asssets
@@ -181,4 +90,5 @@ def asssets
end
end
end
+
end
diff --git a/lib/jasmine/configuration.rb b/lib/jasmine/configuration.rb
new file mode 100644
index 00000000..92c4e5bd
--- /dev/null
+++ b/lib/jasmine/configuration.rb
@@ -0,0 +1,83 @@
+module Jasmine
+ class Configuration
+ attr_writer :jasmine_css_files, :css_files
+ attr_writer :jasmine_files, :boot_files, :src_files, :spec_files
+ attr_accessor :jasmine_path, :spec_path, :boot_path, :src_path
+ attr_accessor :jasmine_dir, :spec_dir, :boot_dir, :src_dir
+ #TODO: these are largely client concerns, move them.
+ attr_accessor :port, :browser, :host, :result_batch_size
+
+ def initialize()
+ @rack_paths = {}
+ @apps = []
+ @path_mappers = []
+ @jasmine_css_files = lambda { [] }
+ @css_files = lambda { [] }
+ @jasmine_files = lambda { [] }
+ @boot_files = lambda { [] }
+ @src_files = lambda { [] }
+ @spec_files = lambda { [] }
+ end
+
+ def css_files
+ map(@jasmine_css_files, :jasmine) +
+ map(@css_files, :src)
+ end
+
+ def js_files
+ map(@jasmine_files, :jasmine) +
+ map(@src_files, :src) +
+ map(@spec_files, :spec) +
+ map(@boot_files, :boot)
+ end
+
+ def rack_path_map
+ {}.merge(@rack_paths)
+ end
+
+ def add_rack_path(path, rack_app_lambda)
+ @rack_paths[path] = rack_app_lambda
+ end
+
+ def rack_apps
+ [] + @apps
+ end
+
+ def add_rack_app(app, &block)
+ @apps << [app, block]
+ end
+
+ def add_path_mapper(mapper)
+ @path_mappers << mapper.call(self)
+ end
+
+ def port
+ @port ||= Jasmine.find_unused_port
+ end
+
+ def browser
+ @browser || 'firefox'
+ end
+
+ def host
+ @host || 'http://localhost'
+ end
+
+ def result_batch_size
+ @result_batch_size || 50
+ end
+
+ private
+
+ def map(paths, type)
+ @path_mappers.inject(paths.call) do |paths, mapper|
+ if mapper.respond_to?("map_#{type}_paths")
+ mapper.send("map_#{type}_paths", paths)
+ else
+ paths
+ end
+ end
+ end
+
+ end
+end
diff --git a/lib/jasmine/core_configuration.rb b/lib/jasmine/core_configuration.rb
new file mode 100644
index 00000000..28519c7f
--- /dev/null
+++ b/lib/jasmine/core_configuration.rb
@@ -0,0 +1,28 @@
+module Jasmine
+ class CoreConfiguration
+ def initialize(core = Jasmine::Core)
+ @core = core
+ end
+
+ def path
+ @core.path
+ end
+
+ #TODO: maybe this doesn't belong in CoreConfig
+ def boot_path
+ Jasmine.root('javascripts')
+ end
+
+ def boot_files
+ Dir.glob(File.join(boot_path, "**"))
+ end
+
+ def js_files
+ @core.js_files
+ end
+
+ def css_files
+ @core.css_files
+ end
+ end
+end
diff --git a/lib/jasmine/dependencies.rb b/lib/jasmine/dependencies.rb
index b7617457..608e888e 100644
--- a/lib/jasmine/dependencies.rb
+++ b/lib/jasmine/dependencies.rb
@@ -7,15 +7,19 @@ def rspec2?
end
def rails2?
- safe_gem_check("rails", "~> 2.3")
+ safe_gem_check("rails", "~> 2.3") && running_rails2?
end
def legacy_rails?
- safe_gem_check("rails", "< 2.3.11")
+ safe_gem_check("rails", "< 2.3.11") && running_legacy_rails?
end
def rails3?
- safe_gem_check("rails", ">= 3.0")
+ safe_gem_check("rails", ">= 3.0") && running_rails3?
+ end
+
+ def legacy_rack?
+ !defined?(Rack::Server)
end
def rails_3_asset_pipeline?
@@ -23,6 +27,23 @@ def rails_3_asset_pipeline?
end
private
+
+ def running_legacy_rails?
+ running_rails? && (Gem::Version.new(Rails.version) < Gem::Version.new("2.3.11"))
+ end
+
+ def running_rails2?
+ running_rails? && Rails.version.to_i == 2
+ end
+
+ def running_rails3?
+ running_rails? && Rails.version.to_i == 3
+ end
+
+ def running_rails?
+ defined?(Rails) && Rails.respond_to?(:version)
+ end
+
def safe_gem_check(gem_name, version_string)
if Gem::Specification.respond_to?(:find_by_name)
Gem::Specification.find_by_name(gem_name, version_string)
diff --git a/lib/jasmine/javascripts/boot.js b/lib/jasmine/javascripts/boot.js
new file mode 100644
index 00000000..a0a2d325
--- /dev/null
+++ b/lib/jasmine/javascripts/boot.js
@@ -0,0 +1,28 @@
+var jsApiReporter;
+(function() {
+ var jasmineEnv = jasmine.getEnv();
+
+ jsApiReporter = new jasmine.JsApiReporter();
+ var htmlReporter = new jasmine.HtmlReporter();
+
+ jasmineEnv.addReporter(jsApiReporter);
+ 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();
+ }
+
+})();
diff --git a/lib/jasmine/page.rb b/lib/jasmine/page.rb
index 0d8c2325..b18c7219 100644
--- a/lib/jasmine/page.rb
+++ b/lib/jasmine/page.rb
@@ -5,7 +5,7 @@ def initialize(context)
end
def render
- ERB.new(::Jasmine.runner_template).result(@context)
+ ERB.new(::Jasmine.runner_template).result(@context.instance_eval { binding })
end
end
end
diff --git a/lib/jasmine/path_expander.rb b/lib/jasmine/path_expander.rb
new file mode 100644
index 00000000..64f2e85d
--- /dev/null
+++ b/lib/jasmine/path_expander.rb
@@ -0,0 +1,18 @@
+module Jasmine
+ class PathExpander
+
+ def self.expand(base_directory, patterns, globber = Dir.method(:glob))
+ negative, positive = patterns.partition {|pattern| /^!/ =~ pattern}
+ chosen, negated = [positive, negative].collect do |patterns|
+ patterns.map do |path|
+ files = globber.call(File.join(base_directory, path.gsub(/^!/, '')))
+ if files.empty? && !(path =~ /\*|^\!/)
+ files = [File.join(base_directory, path)]
+ end
+ files
+ end.flatten.uniq
+ end
+ chosen - negated
+ end
+ end
+end
diff --git a/lib/jasmine/path_mapper.rb b/lib/jasmine/path_mapper.rb
new file mode 100644
index 00000000..ed641334
--- /dev/null
+++ b/lib/jasmine/path_mapper.rb
@@ -0,0 +1,29 @@
+module Jasmine
+ class PathMapper
+ def initialize(config)
+ @config = config
+ end
+
+ def map_src_paths(paths)
+ map(paths, @config.src_dir, @config.src_path)
+ end
+
+ def map_spec_paths(paths)
+ map(paths, @config.spec_dir, @config.spec_path)
+ end
+
+ def map_boot_paths(paths)
+ map(paths, @config.boot_dir, @config.boot_path)
+ end
+
+ def map_jasmine_paths(paths)
+ map(paths, @config.jasmine_dir, @config.jasmine_path)
+ end
+
+ private
+ def map(paths, remove_path, add_path)
+ paths.map { |path| File.join(add_path, (path.gsub(remove_path, ''))) }
+ end
+
+ end
+end
diff --git a/lib/jasmine/results.rb b/lib/jasmine/results.rb
new file mode 100644
index 00000000..208df047
--- /dev/null
+++ b/lib/jasmine/results.rb
@@ -0,0 +1,19 @@
+module Jasmine
+ class Results
+
+ attr_reader :suites
+ def initialize(result_hash, suite_hash, example_locations)
+ @suites = suite_hash
+ @results = result_hash
+ @example_locations = example_locations
+ end
+
+ def for_spec_id(id)
+ @results[id]
+ end
+
+ def example_location_for(spec_description)
+ @example_locations[spec_description]
+ end
+ end
+end
diff --git a/lib/jasmine/results_processor.rb b/lib/jasmine/results_processor.rb
new file mode 100644
index 00000000..0725eaf6
--- /dev/null
+++ b/lib/jasmine/results_processor.rb
@@ -0,0 +1,38 @@
+module Jasmine
+ class ResultsProcessor
+
+ def initialize(config)
+ @config = config
+ end
+
+ def process(results_hash, suites_hash)
+ return Jasmine::Results.new(results_hash, suites_hash, example_locations)
+ end
+
+ def example_locations
+ # example_locations = {}
+ # example_name_parts = []
+ # previous_indent_level = 0
+ # @config.spec_files_full_paths.each do |filename|
+ # line_number = 1
+ # File.open(filename, "r") do |file|
+ # file.readlines.each do |line|
+ # match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
+ # if (match)
+ # indent_level = match[1].length / 2
+ # example_name = match[3]
+ # example_name_parts[indent_level] = example_name
+
+ # full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
+ # example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
+ # end
+ # line_number += 1
+ # end
+ # end
+ # end
+ # example_locations
+ {}
+ end
+
+ end
+end
diff --git a/lib/jasmine/rspec_formatter.rb b/lib/jasmine/rspec_formatter.rb
new file mode 100644
index 00000000..72510390
--- /dev/null
+++ b/lib/jasmine/rspec_formatter.rb
@@ -0,0 +1,92 @@
+require 'enumerator'
+
+module Jasmine
+ class RspecFormatter
+
+ def format_results(results)
+ @results = results
+ declare_suites(@results.suites)
+ end
+
+ def declare_suites(suites)
+ suites.each do |suite|
+ #empty block for rspec 1
+ group = example_group(suite["name"]) {}
+ process_children(group, suite["children"])
+ end
+ end
+
+ def process_children(parent, children)
+ children.each do |suite_or_spec|
+ type = suite_or_spec["type"]
+ if type == "suite"
+ process_children(parent.describe(suite_or_spec["name"]), suite_or_spec["children"])
+ elsif type == "spec"
+ declare_spec(parent, suite_or_spec)
+ else
+ raise "unknown type #{type} for #{suite_or_spec.inspect}"
+ end
+ end
+ end
+
+ def declare_spec(parent, spec)
+ me = self
+ example_name = spec["name"]
+ backtrace = @results.example_location_for(parent.description + " " + example_name)
+ if Jasmine::Dependencies.rspec2?
+ parent.it example_name, {} do
+ me.report_spec(spec["id"])
+ end
+ else
+ parent.it example_name, {}, backtrace do
+ me.report_spec(spec["id"])
+ end
+ end
+ end
+
+ def report_spec(spec_id)
+ spec_results = results_for(spec_id)
+ out = ""
+ messages = spec_results['messages'].each do |message|
+ case
+ when message["type"] == "log"
+ puts message["text"]
+ puts "\n"
+ else
+ unless message["message"] =~ /^Passed.$/
+ STDERR << message["message"]
+ STDERR << "\n"
+
+ out << message["message"]
+ out << "\n"
+ end
+
+ if !message["passed"] && message["trace"]["stack"]
+ stack_trace = message["trace"]["stack"].gsub(/
/, "\n").gsub(/<\/?b>/, " ")
+ STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
+ STDERR << "\n"
+ end
+ end
+
+ end
+ fail out unless spec_results['result'] == 'passed'
+ puts out unless out.empty?
+ end
+
+ private
+
+ def example_group(*args, &block)
+ if Jasmine::Dependencies.rspec2?
+ RSpec::Core::ExampleGroup.describe(*args, &block).register
+ else
+ Spec::Example::ExampleGroupFactory.create_example_group(*args, &block)
+ end
+ end
+
+ def results_for(spec_id)
+ @results.for_spec_id(spec_id.to_s)
+ end
+
+
+ end
+end
diff --git a/lib/jasmine/run.html.erb b/lib/jasmine/run.html.erb
index 00436d49..9c9124e0 100644
--- a/lib/jasmine/run.html.erb
+++ b/lib/jasmine/run.html.erb
@@ -7,42 +7,6 @@
<% css_files.each do |css_file| %>
<% end %>
-
- <% jasmine_files.each do |jasmine_file| %>
-
- <% end %>
-
-
-
<% js_files.each do |js_file| %>
<% end %>
diff --git a/lib/jasmine/run_specs.rb b/lib/jasmine/run_specs.rb
new file mode 100644
index 00000000..5df89f95
--- /dev/null
+++ b/lib/jasmine/run_specs.rb
@@ -0,0 +1,36 @@
+$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
+
+require 'rubygems'
+require 'jasmine'
+if Jasmine::Dependencies.rspec2?
+ require 'rspec'
+else
+ require 'spec'
+end
+
+jasmine_yml = File.join(Dir.pwd, 'spec', 'javascripts', 'support', 'jasmine.yml')
+if File.exist?(jasmine_yml)
+end
+
+Jasmine.load_configuration_from_yaml
+
+config = Jasmine.config
+
+server = Jasmine::Server.new(config.port, Jasmine::Application.app(config))
+driver = Jasmine::SeleniumDriver.new(config.browser, "#{config.host}:#{config.port}/")
+t = Thread.new do
+ begin
+ server.start
+ rescue ChildProcess::TimeoutError
+ end
+ # # ignore bad exits
+end
+t.abort_on_exception = true
+Jasmine::wait_for_listener(config.port, "jasmine server")
+puts "jasmine server started."
+
+results_processor = Jasmine::ResultsProcessor.new(config)
+results = Jasmine::Runners::HTTP.new(driver, results_processor, config.result_batch_size).run
+formatter = Jasmine::RspecFormatter.new
+formatter.format_results(results)
+
diff --git a/lib/jasmine/runner.rb b/lib/jasmine/runner.rb
deleted file mode 100644
index 7fbd1f90..00000000
--- a/lib/jasmine/runner.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-$:.unshift(ENV['JASMINE_GEM_PATH']) if ENV['JASMINE_GEM_PATH'] # for gem testing purposes
-
-require 'rubygems'
-require 'jasmine'
-jasmine_config_overrides = File.expand_path(File.join(Dir.pwd, 'spec', 'javascripts', 'support', 'jasmine_config.rb'))
-require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
-if Jasmine::Dependencies.rspec2?
- require 'rspec'
-else
- require 'spec'
-end
-
-jasmine_config = Jasmine::Config.new
-spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
-
-should_stop = false
-
-if Jasmine::Dependencies.rspec2?
- RSpec.configuration.after(:suite) do
- spec_builder.stop if should_stop
- end
-else
- Spec::Runner.configure do |config|
- config.after(:suite) do
- spec_builder.stop if should_stop
- end
- end
-end
-
-spec_builder.start
-should_stop = true
-spec_builder.declare_suites
diff --git a/lib/jasmine/runners/http.rb b/lib/jasmine/runners/http.rb
new file mode 100644
index 00000000..3d613432
--- /dev/null
+++ b/lib/jasmine/runners/http.rb
@@ -0,0 +1,71 @@
+module Jasmine
+ module Runners
+ class HTTP
+ attr_accessor :suites
+
+ def initialize(client, results_processor, result_batch_size)
+ @client = client
+ @results_processor = results_processor
+ @result_batch_size = result_batch_size
+ end
+
+ def run
+ @client.connect
+ load_suite_info
+ wait_for_suites_to_finish_running
+ results = @results_processor.process(results_hash, suites)
+ @client.disconnect
+ results
+ end
+
+ private
+
+ def load_suite_info
+ started = Time.now
+ while !eval_js('return jsApiReporter && jsApiReporter.started') do
+ raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
+ sleep 0.1
+ end
+
+ @suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }")
+ end
+
+ def results_hash
+ spec_results = {}
+ spec_ids.each_slice(@result_batch_size) do |slice|
+ spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{json_generate(slice)}); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }"))
+ end
+ spec_results
+ end
+
+ def spec_ids
+ map_spec_ids = lambda do |suites|
+ suites.map do |suite_or_spec|
+ if suite_or_spec['type'] == 'spec'
+ suite_or_spec['id']
+ else
+ map_spec_ids.call(suite_or_spec['children'])
+ end
+ end
+ end
+ map_spec_ids.call(@suites).compact.flatten
+ end
+
+ def wait_for_suites_to_finish_running
+ puts "Waiting for suite to finish in browser ..."
+ while !eval_js('return jsApiReporter.finished') do
+ sleep 0.1
+ end
+ end
+
+ def eval_js(script)
+ @client.eval_js(script)
+ end
+
+ def json_generate(obj)
+ @client.json_generate(obj)
+ end
+
+ end
+ end
+end
diff --git a/lib/jasmine/selenium_driver.rb b/lib/jasmine/selenium_driver.rb
index a80e4996..85f03ad3 100644
--- a/lib/jasmine/selenium_driver.rb
+++ b/lib/jasmine/selenium_driver.rb
@@ -1,4 +1,5 @@
module Jasmine
+ require 'json'
class SeleniumDriver
def initialize(browser, http_address)
require 'selenium-webdriver'
@@ -21,10 +22,6 @@ def initialize(browser, http_address)
@http_address = http_address
end
- def tests_have_finished?
- @driver.execute_script("return window.jasmine.getEnv().currentRunner.finished") == "true"
- end
-
def connect
@driver.navigate.to @http_address
end
@@ -33,16 +30,6 @@ def disconnect
@driver.quit
end
- def run
- until tests_have_finished? do
- sleep 0.1
- end
-
- puts @driver.execute_script("return window.results()")
- failed_count = @driver.execute_script("return window.jasmine.getEnv().currentRunner.results().failedCount").to_i
- failed_count == 0
- end
-
def eval_js(script)
result = @driver.execute_script(script)
JSON.parse("{\"result\":#{result}}", :max_nesting => false)["result"]
diff --git a/lib/jasmine/server.rb b/lib/jasmine/server.rb
index 53a7dd41..ac12bb42 100644
--- a/lib/jasmine/server.rb
+++ b/lib/jasmine/server.rb
@@ -1,45 +1,19 @@
-require 'rack'
-require 'rack/utils'
-require 'jasmine-core'
-require 'rack/jasmine/runner'
-require 'rack/jasmine/focused_suite'
-require 'rack/jasmine/redirect'
-require 'rack/jasmine/blank_asset'
-require 'rack/jasmine/cache_control'
-require 'ostruct'
-
module Jasmine
- def self.app(config)
- jasmine_stylesheets = ::Jasmine::Core.css_files.map {|f| "/__JASMINE_ROOT__/#{f}"}
- config_shim = OpenStruct.new({:jasmine_files => ::Jasmine::Core.js_files.map {|f| "/__JASMINE_ROOT__/#{f}"},
- :js_files => config.js_files,
- :css_files => jasmine_stylesheets + (config.css_files || [])})
- page = Jasmine::Page.new(config_shim.instance_eval { binding })
- Rack::Builder.app do
- use Rack::Head
- use Rack::Jasmine::CacheControl
- if Jasmine::Dependencies.rails_3_asset_pipeline?
- map('/assets') do
- run Rails.application.assets
- end
- end
-
- map('/images') do
- run Rack::Jasmine::BlankAsset.new
- end
-
- map('/run.html') { run Rack::Jasmine::Redirect.new('/') }
- map('/__suite__') { run Rack::Jasmine::FocusedSuite.new(config) }
-
- map('/__JASMINE_ROOT__') { run Rack::File.new(Jasmine::Core.path) }
- map(config.spec_path) { run Rack::File.new(config.spec_dir) }
- map(config.root_path) { run Rack::File.new(config.project_root) }
+ class Server
+ def initialize(port = 8888, application = nil)
+ @port = port
+ @application = application
+ end
- map('/') do
- run Rack::Cascade.new([
- Rack::URLMap.new('/' => Rack::File.new(config.src_dir)),
- Rack::Jasmine::Runner.new(page)
- ])
+ def start
+ if Jasmine::Dependencies.legacy_rack?
+ handler = Rack::Handler.get('webrick')
+ handler.run(@application, :Port => @port, :AccessLog => [])
+ else
+ server = Rack::Server.new(:Port => @port, :AccessLog => [])
+ # workaround for Rack bug, when Rack > 1.2.1 is released Rack::Server.start(:app => Jasmine.app(self)) will work
+ server.instance_variable_set(:@app, @application)
+ server.start
end
end
end
diff --git a/lib/jasmine/spec_builder.rb b/lib/jasmine/spec_builder.rb
deleted file mode 100644
index 49c16baa..00000000
--- a/lib/jasmine/spec_builder.rb
+++ /dev/null
@@ -1,162 +0,0 @@
-require 'enumerator'
-
-module Jasmine
- class SpecBuilder
- attr_accessor :suites
-
- def initialize(config)
- @config = config
- @spec_files = config.spec_files
- @runner = config
- @spec_ids = []
- end
-
- def start
- guess_example_locations
-
- @runner.start
- load_suite_info
- wait_for_suites_to_finish_running
- end
-
- def stop
- @runner.stop
- end
-
- def script_path
- File.expand_path(__FILE__)
- end
-
- def guess_example_locations
- @example_locations = {}
-
- example_name_parts = []
- previous_indent_level = 0
- @config.spec_files_full_paths.each do |filename|
- line_number = 1
- File.open(filename, "r") do |file|
- file.readlines.each do |line|
- match = /^(\s*)(describe|it)\s*\(\s*["'](.*)["']\s*,\s*function/.match(line)
- if (match)
- indent_level = match[1].length / 2
- example_name = match[3]
- example_name_parts[indent_level] = example_name
-
- full_example_name = example_name_parts.slice(0, indent_level + 1).join(" ")
- @example_locations[full_example_name] = "#{filename}:#{line_number}: in `it'"
- end
- line_number += 1
- end
- end
- end
- end
-
- def load_suite_info
- started = Time.now
- while !eval_js('return jsApiReporter && jsApiReporter.started') do
- raise "couldn't connect to Jasmine after 60 seconds" if (started + 60 < Time.now)
- sleep 0.1
- end
-
- @suites = eval_js("var result = jsApiReporter.suites(); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }")
- end
-
- def results_for(spec_id)
- @spec_results ||= load_results
- @spec_results[spec_id.to_s]
- end
-
- def load_results
- @spec_results = {}
- @spec_ids.each_slice(50) do |slice|
- @spec_results.merge!(eval_js("var result = jsApiReporter.resultsForSpecs(#{json_generate(slice)}); if (window.Prototype && Object.toJSON) { return Object.toJSON(result) } else { return JSON.stringify(result) }"))
- end
- @spec_results
- end
-
- def wait_for_suites_to_finish_running
- puts "Waiting for suite to finish in browser ..."
- while !eval_js('return jsApiReporter.finished') do
- sleep 0.1
- end
- end
-
- def declare_suites
- me = self
- suites.each do |suite|
- declare_suite(self, suite)
- end
- end
-
- def declare_suite(parent, suite)
- me = self
- parent.describe suite["name"] do
- suite["children"].each do |suite_or_spec|
- type = suite_or_spec["type"]
- if type == "suite"
- me.declare_suite(self, suite_or_spec)
- elsif type == "spec"
- me.declare_spec(self, suite_or_spec)
- else
- raise "unknown type #{type} for #{suite_or_spec.inspect}"
- end
- end
- end
- end
-
- def declare_spec(parent, spec)
- me = self
- example_name = spec["name"]
- @spec_ids << spec["id"]
- backtrace = @example_locations[parent.description + " " + example_name]
- if Jasmine::Dependencies.rspec2?
- parent.it example_name, {} do
- me.report_spec(spec["id"])
- end
- else
- parent.it example_name, {}, backtrace do
- me.report_spec(spec["id"])
- end
- end
- end
-
- def report_spec(spec_id)
- spec_results = results_for(spec_id)
- out = ""
- messages = spec_results['messages'].each do |message|
- case
- when message["type"] == "log"
- puts message["text"]
- puts "\n"
- else
- unless message["message"] =~ /^Passed.$/
- STDERR << message["message"]
- STDERR << "\n"
-
- out << message["message"]
- out << "\n"
- end
-
- if !message["passed"] && message["trace"]["stack"]
- stack_trace = message["trace"]["stack"].gsub(/
/, "\n").gsub(/<\/?b>/, " ")
- STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/")
- STDERR << "\n"
- end
- end
-
- end
- fail out unless spec_results['result'] == 'passed'
- puts out unless out.empty?
- end
-
- private
-
- def eval_js(js)
- @runner.eval_js(js)
- end
-
- def json_generate(obj)
- @runner.json_generate(obj)
- end
- end
-end
diff --git a/lib/jasmine/tasks/jasmine.rake b/lib/jasmine/tasks/jasmine.rake
index 5093369e..76a121fc 100644
--- a/lib/jasmine/tasks/jasmine.rake
+++ b/lib/jasmine/tasks/jasmine.rake
@@ -27,7 +27,7 @@ namespace :jasmine do
t.rspec_opts = ["--colour", "--format", ENV['JASMINE_SPEC_FORMAT'] || "progress"]
t.verbose = true
if Jasmine::Dependencies.rails_3_asset_pipeline?
- t.ruby_opts = ["-r #{File.expand_path(File.join(::Rails.root, 'config', 'environment'))}"]
+ t.rspec_opts += ["-r #{File.expand_path(File.join(::Rails.root, 'config', 'environment'))}"]
end
t.pattern = [Jasmine.runner_filepath]
end
@@ -42,13 +42,12 @@ namespace :jasmine do
end
task :server => "jasmine:require" do
- jasmine_config_overrides = File.join(Jasmine::Config.new.project_root, 'spec', 'javascripts' ,'support' ,'jasmine_config.rb')
- require jasmine_config_overrides if File.exist?(jasmine_config_overrides)
-
port = ENV['JASMINE_PORT'] || 8888
puts "your tests are here:"
puts " http://localhost:#{port}/"
- Jasmine::Config.new.start_server(port)
+ Jasmine.load_configuration_from_yaml
+ app = Jasmine::Application.app(Jasmine.config)
+ Jasmine::Server.new(port, app).start
end
end
diff --git a/lib/jasmine/version.rb b/lib/jasmine/version.rb
index 5cf2e90f..c0547fae 100644
--- a/lib/jasmine/version.rb
+++ b/lib/jasmine/version.rb
@@ -1,3 +1,3 @@
module Jasmine
- VERSION = "1.2.0"
+ VERSION = "1.3.2"
end
diff --git a/lib/jasmine/yaml_config_parser.rb b/lib/jasmine/yaml_config_parser.rb
new file mode 100644
index 00000000..e6cc3054
--- /dev/null
+++ b/lib/jasmine/yaml_config_parser.rb
@@ -0,0 +1,58 @@
+module Jasmine
+ class YamlConfigParser
+ def initialize(path, pwd, path_expander = lambda {}, yaml_loader = lambda {})
+ @path = path
+ @path_expander = path_expander
+ @pwd = pwd
+ @yaml_loader = yaml_loader
+ end
+
+ def src_dir
+ return @pwd unless loaded_yaml['src_dir']
+ File.join(@pwd, loaded_yaml['src_dir'])
+ end
+
+ def spec_dir
+ return File.join(@pwd, 'spec', 'javascripts') unless loaded_yaml['spec_dir']
+ File.join(@pwd, loaded_yaml['spec_dir'])
+ end
+
+ def jasmine_dir
+ return nil unless loaded_yaml['jasmine_dir']
+ File.join(@pwd, loaded_yaml['jasmine_dir'])
+ end
+
+ def src_files
+ @path_expander.call(src_dir, loaded_yaml['src_files'] || [])
+ end
+
+ def jasmine_files
+ @path_expander.call(jasmine_dir, loaded_yaml['jasmine_files'] || [])
+ end
+
+ def jasmine_css_files
+ @path_expander.call(jasmine_dir, loaded_yaml['jasmine_css_files'] || [])
+ end
+
+ def spec_files
+ @path_expander.call(spec_dir, loaded_yaml['spec_files'] || [])
+ end
+
+ def helpers
+ @path_expander.call(spec_dir, loaded_yaml['helpers'] || [])
+ end
+
+ def css_files
+ @path_expander.call(src_dir, loaded_yaml['stylesheets'] || [])
+ end
+
+ def spec_helper
+ File.join(@pwd, loaded_yaml['spec_helper'] || File.join('spec', 'javascripts', 'support', 'jasmine_helper.rb'))
+ end
+
+ private
+ def loaded_yaml
+ @yaml_loader.call(@path)
+ end
+ end
+end
diff --git a/lib/rack/jasmine/focused_suite.rb b/lib/rack/jasmine/focused_suite.rb
index 80b27874..67f71421 100644
--- a/lib/rack/jasmine/focused_suite.rb
+++ b/lib/rack/jasmine/focused_suite.rb
@@ -2,12 +2,12 @@ module Rack
module Jasmine
class FocusedSuite
- def initialize(config)
- @config = config
+ def initialize(runner_config)
+ @runner_config = runner_config
end
def call(env)
- run_adapter = Rack::Jasmine::RunAdapter.new(@config)
+ run_adapter = Rack::Jasmine::RunAdapter.new(@runner_config)
run_adapter.run(env["PATH_INFO"])
end
end
diff --git a/lib/rack/jasmine/redirect.rb b/lib/rack/jasmine/redirect.rb
deleted file mode 100644
index a3103c89..00000000
--- a/lib/rack/jasmine/redirect.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-module Rack
- module Jasmine
-
- class Redirect
- def initialize(url)
- @url = url
- end
-
- def call(env)
- [
- 302,
- { 'Location' => @url },
- []
- ]
- end
- end
-
- end
-end
-
diff --git a/release_notes/v1.2.1.md b/release_notes/v1.2.1.md
new file mode 100644
index 00000000..acc9d7b5
--- /dev/null
+++ b/release_notes/v1.2.1.md
@@ -0,0 +1,6 @@
+# Jasmine Gem v1.2.1
+
+* asset manifests following the Rails defaults are included as individual src files
+* Fix regression that required Jasmine restart to find new src/spec files
+* Fixes compatibility with rspec > 2.1.0
+* Internal refactorings/cleanup
diff --git a/release_notes/v1.3.2.md b/release_notes/v1.3.2.md
new file mode 100644
index 00000000..438b58ab
--- /dev/null
+++ b/release_notes/v1.3.2.md
@@ -0,0 +1,32 @@
+# Jasmine Gem v1.3.2
+
+## Summary
+
+This release removes some pre-1.3 cruft in documentation regarding the old configuration files. Also fixes the JSON/YAML require bug.
+
+Best approach is to delete your Jasmine support files and clean out jasmine from your Rakefile and call `jasmine init` again.
+
+## Changes
+
+* Removed incorrect asset_path mapping
+ * Including `asset_file` (the manifest) fails if asset file is itself templated (erb, coffee), or if asset file uses `require_self`.
+ * Use `require_self` if it is necessary to include javascript inside of a Sprockets manifest file (like `application.js`)
+ * SHA: [be9851192e78ffe635087e5583b15ebe683dc0d9](http://github.com/pivotal/jasmine-gem/commit/be9851192e78ffe635087e5583b15ebe683dc0d9)
+* Load `jasmine_helper` after configuring from yaml
+ * Allows users opportunity to add a `Jasmine.configure` block that overrides/augments `jasmine.yml` settings
+ * File defaults to `specs/javascript/support/jasmine_helper.rb` but is configurable from `jasmine.yml`
+ * *Only* processed if using `jasmine.yml` (which default rake tasks will do if `jasmine.yml` exists).
+ * SHA: [63e8d46556a421cbb3b511b52cd8c2188d72b9db](http://github.com/pivotal/jasmine-gem/commit/63e8d46556a421cbb3b511b52cd8c2188d72b9db)
+* Rails generators should be used for Rails installs
+ * SHA: [5d1d500fdc2462951de901513f2aacc5286f20c1](http://github.com/pivotal/jasmine-gem/commit/5d1d500fdc2462951de901513f2aacc5286f20c1)
+* Fix reference error of YAML and JSON
+ * Merge pull request #119 from kozy4324
+ * SHA: [442135f648970fcaf5e4163a672a78fbea65e118](http://github.com/pivotal/jasmine-gem/commit/442135f648970fcaf5e4163a672a78fbea65e118)
+* Removed references in docs to pre-1.3 files that are no longer used
+ * Merged pull request #132 from levent
+ * Merged pull request #129 from mcolyer
+ * Merged pull request #130 from mcolyer
+
+------
+
+_Release Notes generated with [Anchorman](http://github.com/infews/anchorman)_
\ No newline at end of file
diff --git a/spec/application_integration_spec.rb b/spec/application_integration_spec.rb
new file mode 100644
index 00000000..62067ad2
--- /dev/null
+++ b/spec/application_integration_spec.rb
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe "Jasmine::Application" do
+
+ it "includes no-cache headers for specs" do
+ pending
+ get "/__spec__/example_spec.js"
+ last_response.headers.should have_key("Cache-Control")
+ last_response.headers["Cache-Control"].should == "max-age=0, private, must-revalidate"
+ last_response.headers['Pragma'].each do |key|
+ last_response.headers[key].should == 'no-cache'
+ end
+ end
+
+end
diff --git a/spec/application_spec.rb b/spec/application_spec.rb
new file mode 100644
index 00000000..434fbd9c
--- /dev/null
+++ b/spec/application_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+#Rspec 1 doesn't correctly pass blocks to stubs, so skip (covered by integration tests)
+#https://groups.google.com/forum/?fromgroups=#!topic/rspec/XT7paH2asCo
+
+if Jasmine::Dependencies.rspec2?
+ describe "Jasmine::Application" do
+ it "should map paths provided by the config" do
+ handler1 = double(:handler1)
+ handler2 = double(:handler2)
+ app1 = double(:app1)
+ app2 = double(:app2)
+ rack_path_map = {"/foo" => lambda { handler1 }, "/bar" => lambda { handler2 }}
+ config = double(:config, :rack_path_map => rack_path_map, :rack_apps => [])
+ builder = double("Rack::Builder.new")
+ #Rack::Builder instance evals, so builder.run is invalid syntax,
+ #this is the only way to stub out the 'run' dsl it gives to the block.
+ Jasmine::Application.stub(:run).with(handler1).and_return(app1)
+ Jasmine::Application.stub(:run).with(handler2).and_return(app2)
+
+ builder.should_receive(:map).twice do |path, &app|
+ if path == '/foo'
+ app.call.should == app1
+ elsif path == '/bar'
+ app.call.should == app2
+ else
+ raise "Unexpected path passed"
+ end
+ end
+
+ Jasmine::Application.app(config, builder).should == builder
+ end
+ it "should run rack apps provided by the config" do
+ app1 = double(:app1)
+ app2 = double(:app2)
+ block = lambda { "foo" }
+ config = double(:config, :rack_path_map => [], :rack_apps => [[app1, nil], [app2, block]])
+ builder = double("Rack::Builder.new")
+ builder.should_receive(:use).with(app1)
+ builder.should_receive(:use).with(app2, &block)
+ Jasmine::Application.app(config, builder).should == builder
+ end
+ end
+end
diff --git a/spec/asset_expander_spec.rb b/spec/asset_expander_spec.rb
new file mode 100644
index 00000000..b14fc027
--- /dev/null
+++ b/spec/asset_expander_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+describe Jasmine::AssetExpander do
+ it "expands asset files" do
+ bundled_asset = double(:bundled_asset,
+ :to_a => ['asset1', 'asset2'],
+ :pathname => double(:pathname, :to_s => '/some_src_dir/asset_file'))
+
+ bundled_asset_getter = lambda do |filepath, ext|
+ if filepath == 'asset_file' && ext == 'js'
+ bundled_asset
+ end
+ end
+
+ asset_path_getter = lambda do |asset|
+ if asset == 'asset1'
+ 'asset1_path'
+ elsif asset == 'asset2'
+ 'asset2_path'
+ end
+ end
+
+ expander = Jasmine::AssetExpander.new(bundled_asset_getter, asset_path_getter)
+ expanded_assets = expander.expand('/some_src_dir', 'asset_file')
+ expanded_assets.should == ['/asset1_path?body=true',
+ '/asset2_path?body=true']
+ end
+
+ it "return nil if no bundled asset is found" do
+ bundled_asset = nil
+ bundled_asset_getter = lambda do |filepath, ext|
+ if filepath == 'asset_file' && ext == 'js'
+ bundled_asset
+ end
+ end
+
+ expander = Jasmine::AssetExpander.new(bundled_asset_getter, lambda {})
+ expanded_assets = expander.expand('/some_src_dir', 'asset_file')
+ expanded_assets.should be_nil
+ end
+end
diff --git a/spec/asset_pipeline_mapper_spec.rb b/spec/asset_pipeline_mapper_spec.rb
new file mode 100644
index 00000000..15ac7772
--- /dev/null
+++ b/spec/asset_pipeline_mapper_spec.rb
@@ -0,0 +1,19 @@
+require 'spec_helper'
+
+describe Jasmine::AssetPipelineMapper do
+ it "expands asset paths if available" do
+ expander = lambda do |dir, path|
+ if dir == "/some_location/" && path == 'asset1'
+ ['asset1', 'asset2']
+ elsif dir == "/some_location/" && path == 'asset2'
+ ['asset1', 'asset3']
+ end
+
+ end
+ config = double(:config, :src_dir => "/some_location/")
+
+ mapper = Jasmine::AssetPipelineMapper.new(config, expander)
+
+ mapper.map_src_paths(['asset1', 'asset2', 'asset4']).should == ['asset1', 'asset2', 'asset3', 'asset4']
+ end
+end
diff --git a/spec/base_spec.rb b/spec/base_spec.rb
new file mode 100644
index 00000000..ab4afe98
--- /dev/null
+++ b/spec/base_spec.rb
@@ -0,0 +1,14 @@
+require 'spec_helper'
+
+describe Jasmine do
+ it "should provide the root path" do
+ File.stub(:dirname).and_return('lib/jasmine')
+ File.should_receive(:expand_path) { |path| path }
+ Jasmine.root.should == 'lib/jasmine'
+ end
+ it "should append passed file paths" do
+ File.stub(:dirname).and_return('lib/jasmine')
+ File.should_receive(:expand_path) { |path| path }
+ Jasmine.root('subdir1', 'subdir2').should == File.join('lib/jasmine', 'subdir1', 'subdir2')
+ end
+end
diff --git a/spec/config_spec.rb b/spec/config_spec.rb
deleted file mode 100644
index 2086560b..00000000
--- a/spec/config_spec.rb
+++ /dev/null
@@ -1,321 +0,0 @@
-require 'spec_helper'
-require 'selenium-webdriver'
-
-describe Jasmine::Config do
- describe "configuration" do
- before :each do
- temp_dir_before
-
- Dir::chdir @tmp
- dir_name = "test_js_project"
- `mkdir -p #{dir_name}`
- Dir::chdir dir_name
- `#{@root}/bin/jasmine init .`
-
- @project_dir = Dir.pwd
-
- @template_dir = File.expand_path(File.join(@root, "generators/jasmine/templates"))
- @config = Jasmine::Config.new
- end
-
- after(:each) do
- temp_dir_after
- end
-
- describe "defaults" do
- it "src_dir uses root when src dir is blank" do
- @config.stub!(:project_root).and_return('some_project_root')
- @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
- YAML.stub!(:load).and_return({'src_dir' => nil})
- @config.src_dir.should == 'some_project_root'
- end
-
- it "should use correct default yaml config" do
- @config.stub!(:project_root).and_return('some_project_root')
- @config.simple_config_file.should == (File.join('some_project_root', 'spec/javascripts/support/jasmine.yml'))
- end
- end
-
- describe "simple_config" do
- before(:each) do
- @config.stub!(:src_dir).and_return(File.join(@project_dir, "."))
- @config.stub!(:spec_dir).and_return(File.join(@project_dir, "spec/javascripts"))
- end
-
- describe "using default jasmine.yml" do
- before(:each) do
- @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
- end
-
- it "should find the source files" do
- @config.src_files.should =~ ['public/javascripts/Player.js', 'public/javascripts/Song.js']
- end
-
- it "should find the stylesheet files" do
- @config.stylesheets.should == []
- end
-
- it "should find the spec files" do
- @config.spec_files.should == ['PlayerSpec.js']
- end
-
- it "should find any helpers" do
- @config.helpers.should == ['helpers/SpecHelper.js']
- end
-
- it "should build an array of all the JavaScript files to include, source files then spec files" do
- @config.js_files.should == [
- '/public/javascripts/Player.js',
- '/public/javascripts/Song.js',
- '/__spec__/helpers/SpecHelper.js',
- '/__spec__/PlayerSpec.js'
- ]
- end
-
- it "should allow the js_files to be filtered" do
- @config.js_files("PlayerSpec.js").should == [
- '/public/javascripts/Player.js',
- '/public/javascripts/Song.js',
- '/__spec__/helpers/SpecHelper.js',
- '/__spec__/PlayerSpec.js'
- ]
- end
-
- it "should report the full paths of the spec files" do
- @config.spec_files_full_paths.should == [File.join(@project_dir, 'spec/javascripts/PlayerSpec.js')]
- end
- end
-
- it "should parse ERB" do
- @config.stub!(:simple_config_file).and_return(File.expand_path(File.join(@root, 'spec', 'fixture','jasmine.erb.yml')))
- Dir.stub!(:glob).and_return { |glob_string| [glob_string] }
- @config.src_files.should == ['file0.js', 'file1.js', 'file2.js',]
- end
-
- describe "if jasmine.yml not found" do
- before(:each) do
- File.stub!(:exist?).and_return(false)
- end
-
- it "should default to loading no source files" do
- @config.src_files.should be_empty
- end
-
- it "should default to loading no stylesheet files" do
- @config.stylesheets.should be_empty
- end
-
- end
-
- describe "if jasmine.yml is empty" do
- before(:each) do
- @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
- YAML.stub!(:load).and_return(false)
- end
-
- it "should default to loading no source files" do
- @config.src_files.should be_empty
- end
-
- it "should default to loading no stylesheet files" do
- @config.stylesheets.should be_empty
- end
- end
-
- describe "should use the first appearance of duplicate filenames" do
- before(:each) do
- Dir.stub!(:glob).and_return { |glob_string| [glob_string] }
- fake_config = Hash.new.stub!(:[]).and_return { |x| ["file1.ext", "file2.ext", "file1.ext"] }
- @config.stub!(:simple_config).and_return(fake_config)
- end
-
- it "src_files" do
- @config.src_files.should == ['file1.ext', 'file2.ext']
- end
-
- it "stylesheets" do
- @config.stylesheets.should == ['file1.ext', 'file2.ext']
- end
-
- it "spec_files" do
- @config.spec_files.should == ['file1.ext', 'file2.ext']
- end
-
- it "helpers" do
- @config.spec_files.should == ['file1.ext', 'file2.ext']
- end
-
- it "js_files" do
- @config.js_files.should == ["/file1.ext",
- "/file2.ext",
- "/__spec__/file1.ext",
- "/__spec__/file2.ext",
- "/__spec__/file1.ext",
- "/__spec__/file2.ext"]
- end
-
- it "spec_files_full_paths" do
- @config.spec_files_full_paths.should == [
- File.expand_path("spec/javascripts/file1.ext", @project_dir),
- File.expand_path("spec/javascripts/file2.ext", @project_dir)
- ]
- end
- end
-
- describe "should permit explicity-declared filenames to pass through regardless of their existence" do
- before(:each) do
- Dir.stub!(:glob).and_return { |glob_string| [] }
- fake_config = Hash.new.stub!(:[]).and_return { |x| ["file1.ext", "!file2.ext", "**/*file3.ext"] }
- @config.stub!(:simple_config).and_return(fake_config)
- end
-
- it "should contain explicitly files" do
- @config.src_files.should == ["file1.ext"]
- end
- end
-
- describe "should allow .gitignore style negation (!pattern)" do
- before(:each) do
- Dir.stub!(:glob).and_return { |glob_string| [glob_string] }
- fake_config = Hash.new.stub!(:[]).and_return { |x| ["file1.ext", "!file1.ext", "file2.ext"] }
- @config.stub!(:simple_config).and_return(fake_config)
- end
-
- it "should not contain negated files" do
- @config.src_files.should == ["file2.ext"]
- end
- end
-
- it "simple_config stylesheets" do
- @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine.yml'))
-
- YAML.stub!(:load).and_return({'stylesheets' => ['foo.css', 'bar.css']})
- Dir.stub!(:glob).and_return { |glob_string| [glob_string] }
-
- @config.stylesheets.should == ['foo.css', 'bar.css']
- end
-
- it "using rails jasmine.yml" do
- ['public/javascripts/prototype.js',
- 'public/javascripts/effects.js',
- 'public/javascripts/controls.js',
- 'public/javascripts/dragdrop.js',
- 'public/javascripts/application.js'].each { |f| `touch #{f}` }
-
- @config.stub!(:simple_config_file).and_return(File.join(@template_dir, 'spec/javascripts/support/jasmine-rails.yml'))
-
- @config.spec_files.should == ['PlayerSpec.js']
- @config.helpers.should == ['helpers/SpecHelper.js']
- @config.src_files.should == ['public/javascripts/prototype.js',
- 'public/javascripts/effects.js',
- 'public/javascripts/controls.js',
- 'public/javascripts/dragdrop.js',
- 'public/javascripts/application.js',
- 'public/javascripts/Player.js',
- 'public/javascripts/Song.js']
- @config.js_files.should == [
- '/public/javascripts/prototype.js',
- '/public/javascripts/effects.js',
- '/public/javascripts/controls.js',
- '/public/javascripts/dragdrop.js',
- '/public/javascripts/application.js',
- '/public/javascripts/Player.js',
- '/public/javascripts/Song.js',
- '/__spec__/helpers/SpecHelper.js',
- '/__spec__/PlayerSpec.js',
- ]
- @config.js_files("PlayerSpec.js").should == [
- '/public/javascripts/prototype.js',
- '/public/javascripts/effects.js',
- '/public/javascripts/controls.js',
- '/public/javascripts/dragdrop.js',
- '/public/javascripts/application.js',
- '/public/javascripts/Player.js',
- '/public/javascripts/Song.js',
- '/__spec__/helpers/SpecHelper.js',
- '/__spec__/PlayerSpec.js'
- ]
- end
- end
- end
-
- describe "environment variables" do
- def stub_env_hash(hash)
- ENV.stub!(:[]) do |arg|
- hash[arg]
- end
- end
- describe "browser configuration" do
- it "should use firefox by default" do
- stub_env_hash({"JASMINE_BROWSER" => nil})
- config = Jasmine::Config.new
- config.stub!(:start_jasmine_server)
- Jasmine::SeleniumDriver.should_receive(:new).
- with("firefox", anything).
- and_return(mock(Jasmine::SeleniumDriver, :connect => true))
- config.start
- end
-
- it "should use ENV['JASMINE_BROWSER'] if set" do
- stub_env_hash({"JASMINE_BROWSER" => "mosaic"})
- config = Jasmine::Config.new
- config.stub!(:start_jasmine_server)
- Jasmine::SeleniumDriver.should_receive(:new).
- with("mosaic", anything).
- and_return(mock(Jasmine::SeleniumDriver, :connect => true))
- config.start
- end
- end
-
- describe "jasmine host" do
- it "should use http://localhost by default" do
- stub_env_hash({})
- config = Jasmine::Config.new
- config.instance_variable_set(:@jasmine_server_port, '1234')
- config.stub!(:start_jasmine_server)
-
- Jasmine::SeleniumDriver.should_receive(:new).
- with(anything, "http://localhost:1234/").
- and_return(mock(Jasmine::SeleniumDriver, :connect => true))
- config.start
- end
-
- it "should use ENV['JASMINE_HOST'] if set" do
- stub_env_hash({"JASMINE_HOST" => "http://some_host"})
- config = Jasmine::Config.new
- config.instance_variable_set(:@jasmine_server_port, '1234')
- config.stub!(:start_jasmine_server)
-
- Jasmine::SeleniumDriver.should_receive(:new).
- with(anything, "http://some_host:1234/").
- and_return(mock(Jasmine::SeleniumDriver, :connect => true))
- config.start
- end
-
- it "should use ENV['JASMINE_PORT'] if set" do
- stub_env_hash({"JASMINE_PORT" => "4321"})
- config = Jasmine::Config.new
- Jasmine.stub!(:wait_for_listener)
- config.stub!(:start_server)
- Jasmine::SeleniumDriver.should_receive(:new).
- with(anything, "http://localhost:4321/").
- and_return(mock(Jasmine::SeleniumDriver, :connect => true))
- config.start
- end
- end
-
- describe "external selenium server" do
- it "should use an external selenium server if SELENIUM_SERVER is set" do
- stub_env_hash({"SELENIUM_SERVER" => "http://myseleniumserver.com:4441"})
- Selenium::WebDriver.should_receive(:for).with(:remote, :url => "http://myseleniumserver.com:4441", :desired_capabilities => :firefox)
- Jasmine::SeleniumDriver.new('firefox', 'http://localhost:8888')
- end
- it "should use an local selenium server with a specific port if SELENIUM_SERVER_PORT is set" do
- stub_env_hash({"SELENIUM_SERVER_PORT" => "4441"})
- Selenium::WebDriver.should_receive(:for).with(:remote, :url => "http://localhost:4441/wd/hub", :desired_capabilities => :firefox)
- Jasmine::SeleniumDriver.new('firefox', 'http://localhost:8888')
- end
- end
- end
-
-end
diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb
new file mode 100644
index 00000000..9eda6a75
--- /dev/null
+++ b/spec/configuration_spec.rb
@@ -0,0 +1,163 @@
+require 'spec_helper'
+
+describe Jasmine::Configuration do
+ let(:test_mapper1) do
+ Class.new do
+ def initialize(config)
+ @config = config
+ end
+ def map_src_paths(paths)
+ paths.map { |f| "mapped_src/#{f}" }
+ end
+ def map_jasmine_paths(paths)
+ paths.map { |f| "mapped_jasmine/#{f}" }
+ end
+ def map_spec_paths(paths)
+ paths.map { |f| "mapped_spec/#{f}" }
+ end
+ def map_boot_paths(paths)
+ paths.map { |f| "mapped_boot/#{f}" }
+ end
+ end
+ end
+ let(:test_mapper2) do
+ Class.new do
+ def initialize(config)
+ @config = config
+ end
+ def map_src_paths(paths)
+ paths.map { |f| "#{f}/src" }
+ end
+ def map_jasmine_paths(paths)
+ paths.map { |f| "#{f}/jasmine" }
+ end
+ def map_spec_paths(paths)
+ paths.map { |f| "#{f}/spec" }
+ end
+ def map_boot_paths(paths)
+ paths.map { |f| "#{f}/boot" }
+ end
+ end
+ end
+ let(:test_mapper3) do
+ Class.new do
+ def initialize(config)
+ @config = config
+ end
+ end
+ end
+
+ describe "returning css files" do
+ it "returns mapped jasmine_css_files + css_files" do
+ config = Jasmine::Configuration.new()
+ config.add_path_mapper(lambda { |c| test_mapper1.new(c) })
+ config.add_path_mapper(lambda { |c| test_mapper2.new(c) })
+ config.add_path_mapper(lambda { |c| test_mapper3.new(c) })
+ config.css_files.should == []
+ config.jasmine_css_files = lambda { ["jasmine_css"] }
+ config.css_files = lambda { ["css"] }
+ config.css_files.should == ['mapped_jasmine/jasmine_css/jasmine', 'mapped_src/css/src']
+ end
+ end
+
+ describe "returning javascript files" do
+ it "returns the jasmine core files, then srcs, then specs, then boot" do
+ config = Jasmine::Configuration.new()
+ config.add_path_mapper(lambda { |c| test_mapper1.new(c) })
+ config.add_path_mapper(lambda { |c| test_mapper2.new(c) })
+ config.add_path_mapper(lambda { |c| test_mapper3.new(c) })
+ config.js_files.should == []
+ config.jasmine_files = lambda { ['jasmine'] }
+ config.src_files = lambda { ['src'] }
+ config.boot_files = lambda { ['boot'] }
+ config.spec_files = lambda { ['spec'] }
+ config.js_files.should == [
+ 'mapped_jasmine/jasmine/jasmine',
+ 'mapped_src/src/src',
+ 'mapped_spec/spec/spec',
+ 'mapped_boot/boot/boot',
+ ]
+ end
+ end
+
+ describe "returning rack map" do
+ it "permits arbitrary rack app path mapping" do
+ config = Jasmine::Configuration.new()
+ result = double
+ config.add_rack_path('some/path', lambda { result })
+ map = config.rack_path_map
+ map['some/path'].should be
+ map['some/path'].call.should == result
+ end
+
+ end
+
+ describe "rack apps" do
+ it "permits the addition of arbitary rack apps" do
+ config = Jasmine::Configuration.new()
+ app = double
+ config.add_rack_app(app)
+ config.rack_apps.should == [[app, nil]]
+ end
+ it "permits the addition of arbitary rack apps with arbitrary config" do
+ config = Jasmine::Configuration.new()
+ app = double
+ block = lambda { "foo" }
+ config.add_rack_app(app, &block)
+ config.rack_apps.should == [[app, block]]
+ end
+ end
+
+ describe "port" do
+ it "returns new port and caches return value" do
+ config = Jasmine::Configuration.new()
+ Jasmine.stub(:find_unused_port).and_return('1234')
+ config.port.should == '1234'
+ Jasmine.stub(:find_unused_port).and_return('4321')
+ config.port.should == '1234'
+ end
+ it "returns port if configured" do
+ config = Jasmine::Configuration.new()
+ config.port = '5678'
+ Jasmine.stub(:find_unused_port).and_return('1234')
+ config.port.should == '5678'
+ end
+ end
+
+ describe "browser" do
+ it "should default to firefox" do
+ Jasmine::Configuration.new().browser.should == 'firefox'
+ end
+
+ it "returns browser if set" do
+ config = Jasmine::Configuration.new()
+ config.browser = 'foo'
+ config.browser.should == 'foo'
+ end
+ end
+
+ describe "result_batch_size" do
+ it "should default to 50" do
+ Jasmine::Configuration.new().result_batch_size.should == 50
+ end
+
+ it "returns result_batch_size if set" do
+ config = Jasmine::Configuration.new()
+ config.result_batch_size = 25
+ config.result_batch_size.should == 25
+ end
+ end
+
+ describe "host" do
+ it "should default to localhost" do
+ Jasmine::Configuration.new().host.should == 'http://localhost'
+ end
+
+ it "returns host if set" do
+ config = Jasmine::Configuration.new()
+ config.host = 'foo'
+ config.host.should == 'foo'
+ end
+ end
+end
+
diff --git a/spec/dependencies_spec.rb b/spec/dependencies_spec.rb
index 2d6e791e..674098de 100644
--- a/spec/dependencies_spec.rb
+++ b/spec/dependencies_spec.rb
@@ -29,12 +29,21 @@ module Rails
describe ".rails2?" do
subject { Jasmine::Dependencies.rails2? }
- context "when rails 2 is present" do
+ context "when rails 2 is present and running" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", "~> 2.3").and_return(true)
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
end
+ let(:running_rails_version) { "2.3.11" }
it { should be_true }
end
+ context "when rails 2 is present but not running" do
+ before do
+ Gem::Specification.should_receive(:find_by_name).with("rails", "~> 2.3").and_raise(Gem::LoadError)
+ end
+ it { should be_false }
+ end
context "when rails 2 is not present" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", "~> 2.3").and_raise(Gem::LoadError)
@@ -45,12 +54,21 @@ module Rails
describe ".legacy_rails?" do
subject { Jasmine::Dependencies.legacy_rails? }
- context "when rails < 2.3.11 is present" do
+ context "when rails < 2.3.11 is present and running" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", "< 2.3.11").and_return(true)
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
end
+ let(:running_rails_version) { "2.3.8" }
it { should be_true }
end
+ context "when rails < 2.3.11 is present but not running" do
+ before do
+ Gem::Specification.should_receive(:find_by_name).with("rails", "< 2.3.11").and_return(true)
+ end
+ it { should be_false }
+ end
context "when rails < 2.3.11 is not present" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", "< 2.3.11").and_raise(Gem::LoadError)
@@ -61,12 +79,21 @@ module Rails
describe ".rails3?" do
subject { Jasmine::Dependencies.rails3? }
- context "when rails 3 is present" do
+ context "when rails 3 is present and running" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_return(true)
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
end
+ let(:running_rails_version) { "3.2" }
it { should be_true }
end
+ context "when rails 3 is present but not running" do
+ before do
+ Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_return(true)
+ end
+ it { should be_false }
+ end
context "when rails 3 is not present" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_raise(Gem::LoadError)
@@ -78,14 +105,17 @@ module Rails
describe ".rails_3_asset_pipeline?" do
subject { Jasmine::Dependencies.rails_3_asset_pipeline? }
let(:application) { double(:application) }
+ let(:running_rails_version) { "3.2" }
before do
Rails.stub(:respond_to?).with(:application).and_return(respond_to_application)
Rails.stub(:application).and_return(application)
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
end
context "when rails 3 is present and the application pipeline is in use" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_return(true)
- application.stub(:assets).and_return(rails_application_assets)
+ application.stub(:assets).and_return(rails_application_assets)
end
let(:rails3_present) { true }
let(:respond_to_application) { true }
@@ -95,7 +125,7 @@ module Rails
context "when rails 3 is present and the application pipeline is not in use" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_return(true)
- application.stub(:assets).and_return(rails_application_assets)
+ application.stub(:assets).and_return(rails_application_assets)
end
let(:rails3_present) { true }
let(:respond_to_application) { true }
@@ -105,7 +135,7 @@ module Rails
context "when rails 3 is present but not loaded" do
before do
Gem::Specification.should_receive(:find_by_name).with("rails", ">= 3.0").and_return(true)
- application.stub(:assets).and_return(rails_application_assets)
+ application.stub(:assets).and_return(rails_application_assets)
end
let(:rails3_present) { true }
let(:respond_to_application) { false }
@@ -157,10 +187,26 @@ module Rails
before do
Gem.should_receive(:available?).with("rails", "~> 2.3").and_return(rails2_present)
end
- context "when rails 2 is present" do
+ context "when rails 2 is present and running" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
+
+ let(:running_rails_version) { "2.3" }
let(:rails2_present) { true }
it { should be_true }
end
+ context "when rails 2 is present but not running" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
+
+ let(:running_rails_version) { "3.2" }
+ let(:rails2_present) { true }
+ it { should be_false }
+ end
context "when rails 2 is not present" do
let(:rails2_present) { false }
it { should be_false }
@@ -172,10 +218,21 @@ module Rails
before do
Gem.should_receive(:available?).with("rails", "< 2.3.11").and_return(legacy_rails_present)
end
- context "when rails < 2.3.11 is present" do
+ context "when rails < 2.3.11 is present and running" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
+ let(:running_rails_version) { "2.3.8" }
let(:legacy_rails_present) { true }
it { should be_true }
end
+
+ context "when rails < 2.3.11 is present but not running" do
+ let(:legacy_rails_present) { true }
+ it { should be_false }
+ end
+
context "when rails < 2.3.11 is not present" do
let(:legacy_rails_present) { false }
it { should be_false }
@@ -188,6 +245,11 @@ module Rails
Gem.should_receive(:available?).with("rails", ">= 3.0").and_return(rails3_present)
end
context "when rails 3 is present" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
+ let(:running_rails_version) { "3.2" }
let(:rails3_present) { true }
it { should be_true }
end
@@ -203,27 +265,45 @@ module Rails
before do
Gem.should_receive(:available?).with("rails", ">= 3.0").and_return(rails3_present)
Rails.stub(:respond_to?).with(:application).and_return(respond_to_application)
+ Rails.stub(:respond_to?).with(:version).and_return(true)
Rails.stub(:application).and_return(application)
end
- context "when rails 3 is present and the application pipeline is in use" do
+
+ context "when rails 3 is present, running, and the application pipeline is in use" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
let(:rails3_present) { true }
+ let(:running_rails_version) { "3.2" }
let(:respond_to_application) { true }
let(:rails_application_assets) { true }
it { should be_true }
end
- context "when rails 3 is present and the application pipeline is not in use" do
+ context "when rails 3 is present, running, and the application pipeline is not in use" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(true)
+ Rails.stub(:version).and_return(running_rails_version)
+ end
let(:rails3_present) { true }
+ let(:running_rails_version) { "3.2" }
let(:respond_to_application) { true }
let(:rails_application_assets) { false }
it { should be_false }
end
context "when rails 3 is present but not loaded" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(false)
+ end
let(:rails3_present) { true }
let(:respond_to_application) { false }
let(:rails_application_assets) { false }
it { should be_false }
end
context "when rails 3 is not present" do
+ before do
+ Rails.stub(:respond_to?).with(:version).and_return(false)
+ end
let(:rails3_present) { false }
let(:respond_to_application) { false }
let(:rails_application_assets) { false }
@@ -231,6 +311,5 @@ module Rails
end
end
end
-
end
end
diff --git a/spec/fixture/jasmine.erb.yml b/spec/fixture/jasmine.erb.yml
deleted file mode 100644
index 3c6b0574..00000000
--- a/spec/fixture/jasmine.erb.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-src_files:
-<% 3.times do |i| %>
- - <%= "file#{i}.js" %>
-<% end %>
\ No newline at end of file
diff --git a/spec/fixture/spec/example_spec.js b/spec/fixture/spec/example_spec.js
deleted file mode 100644
index 7403e49b..00000000
--- a/spec/fixture/spec/example_spec.js
+++ /dev/null
@@ -1,5 +0,0 @@
-describe("example_spec", function() {
- it("should be here for path loading tests", function() {
- expect(true).toBe(true);
- }
-})
diff --git a/spec/fixture/src/example.js b/spec/fixture/src/example.js
deleted file mode 100644
index 83c71184..00000000
--- a/spec/fixture/src/example.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function Example() {
- this.is_here = "for path loading tests";
-}
diff --git a/spec/jasmine_self_test_config.rb b/spec/jasmine_self_test_config.rb
deleted file mode 100644
index 16a6b334..00000000
--- a/spec/jasmine_self_test_config.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-require 'jasmine'
-
-class JasmineSelfTestConfig < Jasmine::Config
- def project_root
- File.expand_path(File.join(File.dirname(__FILE__), ".."))
- end
-
- def src_dir
- File.join(project_root, 'src')
- end
-
- def spec_dir
- Jasmine::Core.path
- end
-
- def spec_files
- Jasmine::Core.html_spec_files + Jasmine::Core.core_spec_files
- end
-end
diff --git a/spec/jasmine_self_test_spec.rb b/spec/jasmine_self_test_spec.rb
index 88cd2ca3..a8d5a5dc 100644
--- a/spec/jasmine_self_test_spec.rb
+++ b/spec/jasmine_self_test_spec.rb
@@ -1,23 +1,29 @@
require 'spec_helper'
-require 'jasmine_self_test_config'
-jasmine_config = JasmineSelfTestConfig.new
-spec_builder = Jasmine::SpecBuilder.new(jasmine_config)
+Jasmine.configure do |config|
+ root = File.expand_path(File.join(File.dirname(__FILE__), ".."))
+ config.src_dir = File.join(root, 'src')
+ config.spec_dir = Jasmine::Core.path
+ config.spec_files = lambda { (Jasmine::Core.html_spec_files + Jasmine::Core.core_spec_files).map {|f| File.join(config.spec_dir, f) } }
+end
-should_stop = false
+config = Jasmine.config
-if Jasmine::Dependencies.rspec2?
- RSpec.configuration.after(:suite) do
- spec_builder.stop if should_stop
- end
-else
- Spec::Runner.configure do |config|
- config.after(:suite) do
- spec_builder.stop if should_stop
- end
+server = Jasmine::Server.new(config.port, Jasmine::Application.app(config))
+driver = Jasmine::SeleniumDriver.new(config.browser, "#{config.host}:#{config.port}/")
+
+t = Thread.new do
+ begin
+ server.start
+ rescue ChildProcess::TimeoutError
end
+ # # ignore bad exits
end
+t.abort_on_exception = true
+Jasmine::wait_for_listener(config.port, "jasmine server")
+puts "jasmine server started."
-spec_builder.start
-should_stop = true
-spec_builder.declare_suites
+results_processor = Jasmine::ResultsProcessor.new(config)
+results = Jasmine::Runners::HTTP.new(driver, results_processor, config.result_batch_size).run
+formatter = Jasmine::RspecFormatter.new
+formatter.format_results(results)
diff --git a/spec/page_spec.rb b/spec/page_spec.rb
index 5a991d6a..448a8703 100644
--- a/spec/page_spec.rb
+++ b/spec/page_spec.rb
@@ -6,15 +6,13 @@
describe "#render" do
subject { Nokogiri::HTML(page.render) }
let(:fake_config) do
- OpenStruct.new(:js_files => ["file1.js", "file2.js"],
- :css_files => ["file1.css", "file2.css"],
- :jasmine_files => ["jasmine_file1.js", "jasmine_file2.js"])
+ OpenStruct.new(:js_files => ["file1.js", "file2.js"], :css_files => ["file1.css", "file2.css"])
end
- let(:context) { fake_config.instance_eval { binding } }
+ let(:context) { fake_config }
let(:page) { Jasmine::Page.new(context) }
it "should render javascript files in the correct order" do
js_files = subject.css("script")
- js_files.map { |file| file["src"] }.compact.should == ["jasmine_file1.js", "jasmine_file2.js", "file1.js", "file2.js"]
+ js_files.map { |file| file["src"] }.compact.should == ["file1.js", "file2.js"]
end
it "should render css files in the correct order" do
diff --git a/spec/path_expander_spec.rb b/spec/path_expander_spec.rb
new file mode 100644
index 00000000..1eea3b3c
--- /dev/null
+++ b/spec/path_expander_spec.rb
@@ -0,0 +1,96 @@
+require 'spec_helper'
+
+describe Jasmine::PathExpander do
+ it "returns absolute paths" do
+ dir_glob = lambda do |pattern|
+ case pattern
+ when 'some_base/src1*'
+ ['some_base/src1.js', 'some_base/src15.js']
+ when 'some_base/src2*'
+ ['some_base/src2.js']
+ else
+ raise "Unexpected pattern received: #{pattern}"
+ end
+ end
+
+ expanded_files = Jasmine::PathExpander.expand(
+ 'some_base',
+ ['src1*', 'src2*'],
+ dir_glob
+ )
+
+ expanded_files.should == [
+ File.join('some_base', 'src1.js'),
+ File.join('some_base', 'src15.js'),
+ File.join('some_base', 'src2.js')
+ ]
+ end
+
+ it "uniqs files" do
+ dir_glob = lambda do |pattern|
+ case pattern
+ when 'some_base/src1*'
+ ['some_base/src1.js', 'some_base/src15.js', 'some_base/src1.js']
+ when 'some_base/src2*'
+ ['some_base/src2.js']
+ else
+ raise "Unexpected pattern received: #{pattern}"
+ end
+ end
+
+ expanded_files = Jasmine::PathExpander.expand(
+ 'some_base',
+ ['src1*', 'src2*'],
+ dir_glob
+ )
+
+ expanded_files.should == [
+ File.join('some_base', 'src1.js'),
+ File.join('some_base', 'src15.js'),
+ File.join('some_base', 'src2.js')
+ ]
+ end
+
+ it "supports negation of passed patterns" do
+ dir_glob = lambda do |pattern|
+ case pattern
+ when 'some_base/src1*'
+ ['some_base/src1.js', 'some_base/src15.js']
+ when 'some_base/src1.js'
+ ['some_base/src1.js']
+ when 'some_base/src2*'
+ ['some_base/src2.js']
+ else
+ raise "Unexpected pattern received: #{pattern}"
+ end
+ end
+
+ expanded_files = Jasmine::PathExpander.expand(
+ 'some_base',
+ ['src1*', '!src1.js', 'src2*'],
+ dir_glob
+ )
+
+ expanded_files.should == [
+ File.join('some_base', 'src15.js'),
+ File.join('some_base', 'src2.js')
+ ]
+ end
+
+ it "passes through files that are not found by the globber and are not negations and not globs" do
+ #this is designed to support asset pipeline files that aren't found.
+ dir_glob = lambda do |pattern|
+ []
+ end
+
+ expanded_files = Jasmine::PathExpander.expand(
+ 'some_base',
+ ['src1*', '!src1.js', 'src2.js'],
+ dir_glob
+ )
+
+ expanded_files.should == [
+ File.join('some_base', 'src2.js')
+ ]
+ end
+end
diff --git a/spec/path_mapper_spec.rb b/spec/path_mapper_spec.rb
new file mode 100644
index 00000000..55f7d55e
--- /dev/null
+++ b/spec/path_mapper_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe Jasmine::PathMapper do
+ it "correctly remaps src files" do
+ config = double(:config, :src_dir => '/src_dir', :src_path => '/__src__')
+ mapper = Jasmine::PathMapper.new(config)
+ mapper.map_src_paths(['/src_dir/foo']).should == ['/__src__/foo']
+ mapper.map_src_paths(['foo/bar']).should == ['/__src__/foo/bar']
+ end
+ it "correctly remaps spec files" do
+ config = double(:config, :spec_dir => '/spec_dir', :spec_path => '/__spec__')
+ mapper = Jasmine::PathMapper.new(config)
+ mapper.map_spec_paths(['/spec_dir/foo']).should == ['/__spec__/foo']
+ mapper.map_spec_paths(['foo/bar']).should == ['/__spec__/foo/bar']
+ end
+ it "correctly remaps jasmine files" do
+ config = double(:config, :jasmine_dir => '/jasmine_dir', :jasmine_path => '/__jasmine__')
+ mapper = Jasmine::PathMapper.new(config)
+ mapper.map_jasmine_paths(['/jasmine_dir/foo']).should == ['/__jasmine__/foo']
+ mapper.map_jasmine_paths(['foo/bar']).should == ['/__jasmine__/foo/bar']
+ end
+ it "correctly remaps boot files" do
+ config = double(:config, :boot_dir => '/boot_dir', :boot_path => '/__boot__')
+ mapper = Jasmine::PathMapper.new(config)
+ mapper.map_boot_paths(['/boot_dir/foo']).should == ['/__boot__/foo']
+ mapper.map_boot_paths(['foo/bar']).should == ['/__boot__/foo/bar']
+ end
+ it "handles edge case where dir == path" do
+ config = double(:config, :src_dir => '/src_dir', :src_path => '/src_dir')
+ mapper = Jasmine::PathMapper.new(config)
+ mapper.map_src_paths(['/src_dir/foo']).should == ['/src_dir/foo']
+ end
+end
diff --git a/spec/results_processor_spec.rb b/spec/results_processor_spec.rb
new file mode 100644
index 00000000..702ba4ef
--- /dev/null
+++ b/spec/results_processor_spec.rb
@@ -0,0 +1,3 @@
+describe Jasmine::ResultsProcessor do
+
+end
diff --git a/spec/results_spec.rb b/spec/results_spec.rb
new file mode 100644
index 00000000..f0270233
--- /dev/null
+++ b/spec/results_spec.rb
@@ -0,0 +1,27 @@
+require 'spec_helper'
+
+describe Jasmine::Results do
+ it "should be able to return suites" do
+ suites = {:some => 'suite'}
+ Jasmine::Results.new({}, suites, {}).suites.should == suites
+ end
+
+ it "should return a result for a particular spec id" do
+ result1 = {:some => 'result'}
+ result2 = {:some => 'other result'}
+ raw_results = {'1' => result1, '2' => result2 }
+ results = Jasmine::Results.new(raw_results, {}, {})
+ results.for_spec_id('1').should == result1
+ results.for_spec_id('2').should == result2
+ end
+
+ it "should return an example location for a particular string" do
+ example_location1 = {:some => 'spec location'}
+ example_location2 = {:some => 'other spec location'}
+ example_locations = {'foo bar' => example_location1, 'baz quux' => example_location2 }
+ results = Jasmine::Results.new({}, {}, example_locations)
+ results.example_location_for('foo bar').should == example_location1
+ results.example_location_for('baz quux').should == example_location2
+ end
+end
+
diff --git a/spec/rspec_formatter_spec.rb b/spec/rspec_formatter_spec.rb
new file mode 100644
index 00000000..bac70cd6
--- /dev/null
+++ b/spec/rspec_formatter_spec.rb
@@ -0,0 +1,88 @@
+require 'spec_helper'
+
+describe Jasmine::RspecFormatter do
+ describe "environment variables" do
+ def stub_env_hash(hash)
+ ENV.stub!(:[]) do |arg|
+ hash[arg]
+ end
+ end
+ describe "browser configuration" do
+ it "should use firefox by default" do
+ pending
+ stub_env_hash({"JASMINE_BROWSER" => nil})
+ config = double('config')
+ formatter = Jasmine::RspecFormatter.new(config)
+ Jasmine::SeleniumDriver.should_receive(:new).
+ with("firefox", anything).
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
+ formatter.start
+ end
+
+ it "should use ENV['JASMINE_BROWSER'] if set" do
+ pending
+ stub_env_hash({"JASMINE_BROWSER" => "mosaic"})
+
+ Jasmine::SeleniumDriver.should_receive(:new).
+ with("mosaic", anything).
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
+ formatter.start
+ end
+ end
+
+ describe "jasmine host" do
+ it "should use http://localhost by default" do
+ pending
+ stub_env_hash({})
+ config = Jasmine::Config.new
+ config.instance_variable_set(:@jasmine_server_port, '1234')
+ config.stub!(:start_jasmine_server)
+
+ Jasmine::SeleniumDriver.should_receive(:new).
+ with(anything, "http://localhost:1234/").
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
+ config.start
+ end
+
+ it "should use ENV['JASMINE_HOST'] if set" do
+ pending
+ stub_env_hash({"JASMINE_HOST" => "http://some_host"})
+ config = Jasmine::Config.new
+ config.instance_variable_set(:@jasmine_server_port, '1234')
+ config.stub!(:start_jasmine_server)
+
+ Jasmine::SeleniumDriver.should_receive(:new).
+ with(anything, "http://some_host:1234/").
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
+ config.start
+ end
+
+ it "should use ENV['JASMINE_PORT'] if set" do
+ pending
+ stub_env_hash({"JASMINE_PORT" => "4321"})
+ config = Jasmine::Config.new
+ Jasmine.stub!(:wait_for_listener)
+ config.stub!(:start_server)
+ Jasmine::SeleniumDriver.should_receive(:new).
+ with(anything, "http://localhost:4321/").
+ and_return(mock(Jasmine::SeleniumDriver, :connect => true))
+ config.start
+ end
+ end
+
+ describe "external selenium server" do
+ it "should use an external selenium server if SELENIUM_SERVER is set" do
+ pending
+ stub_env_hash({"SELENIUM_SERVER" => "http://myseleniumserver.com:4441"})
+ Selenium::WebDriver.should_receive(:for).with(:remote, :url => "http://myseleniumserver.com:4441", :desired_capabilities => :firefox)
+ Jasmine::SeleniumDriver.new('firefox', 'http://localhost:8888')
+ end
+ it "should use an local selenium server with a specific port if SELENIUM_SERVER_PORT is set" do
+ pending
+ stub_env_hash({"SELENIUM_SERVER_PORT" => "4441"})
+ Selenium::WebDriver.should_receive(:for).with(:remote, :url => "http://localhost:4441/wd/hub", :desired_capabilities => :firefox)
+ Jasmine::SeleniumDriver.new('firefox', 'http://localhost:8888')
+ end
+ end
+ end
+end
diff --git a/spec/server_spec.rb b/spec/server_spec.rb
index 49f51fa2..f2333b71 100644
--- a/spec/server_spec.rb
+++ b/spec/server_spec.rb
@@ -1,95 +1,48 @@
require 'spec_helper'
-require 'rack/test'
-describe "Jasmine.app" do
- include Rack::Test::Methods
-
- def app
- config = Jasmine::Config.new
- @root = File.join(File.dirname(__FILE__))
- config.stub!(:project_root).and_return(@root)
- config.stub!(:spec_dir).and_return(File.join(@root, "fixture", "spec"))
- config.stub!(:src_dir).and_return(File.join(@root, "fixture", "src"))
- config.stub!(:src_files).and_return(["file1.js"])
- config.stub!(:spec_files).and_return(["file2.js"])
- Jasmine.app(config)
- end
-
- it "includes no-cache headers for specs" do
- get "/__spec__/example_spec.js"
- last_response.headers.should have_key("Cache-Control")
- last_response.headers["Cache-Control"].should == "max-age=0, private, must-revalidate"
- end
-
- it "should serve static files from spec dir under __spec__" do
- get "/__spec__/example_spec.js"
- last_response.status.should == 200
- last_response.content_type.should == "application/javascript"
- last_response.body.should == File.read(File.join(@root, "fixture/spec/example_spec.js"))
+describe Jasmine::Server do
+ describe "rack ~> 1.0" do
+ before do
+ Jasmine::Dependencies.stub(:legacy_rack?).and_return(true)
end
- it "should serve static files from root dir under __root__" do
- get "/__root__/fixture/src/example.js"
- last_response.status.should == 200
- last_response.content_type.should == "application/javascript"
- last_response.body.should == File.read(File.join(@root, "fixture/src/example.js"))
- end
-
- it "should serve static files from src dir under /" do
- get "/example.js"
- last_response.status.should == 200
- last_response.content_type.should == "application/javascript"
- last_response.body.should == File.read(File.join(@root, "fixture/src/example.js"))
- end
-
- it "should serve Jasmine static files under /__JASMINE_ROOT__/" do
- get "/__JASMINE_ROOT__/jasmine.css"
- last_response.status.should == 200
- last_response.content_type.should == "text/css"
- last_response.body.should == File.read(File.join(Jasmine::Core.path, "jasmine.css"))
- end
-
- it "should serve focused suites when prefixing spec files with /__suite__/" do
- pending "Temporarily removing this feature (maybe permanent)"
- Dir.stub!(:glob).and_return { |glob_string| [glob_string] }
- get "/__suite__/file2.js"
- last_response.status.should == 200
- last_response.content_type.should == "text/html"
- last_response.body.should include("\"/__spec__/file2.js")
- end
-
- it "should redirect /run.html to /" do
- get "/run.html"
- last_response.status.should == 302
- last_response.location.should == "/"
+ it "should run the handler with the application" do
+ server = double(:server)
+ port = 1234
+ application = double(:application)
+ Rack::Handler.should_receive(:get).with("webrick").and_return(server)
+ server.should_receive(:run).with(application, hash_including(:Port => port))
+ Jasmine::Server.new(port, application).start
+ end
end
- it "should 404 non-existent files" do
- get "/some-non-existent-file"
- last_response.should be_not_found
- end
+ describe "rack >= 1.1" do
+ before do
+ Jasmine::Dependencies.stub(:legacy_rack?).and_return(false)
+ if !Rack.constants.include?(:Server)
+ Rack::Server = double("Rack::Server")
+ end
+ end
- describe "/ page" do
- it "should load each js file in order" do
- get "/"
- last_response.status.should == 200
- last_response.body.should include("\"/file1.js")
- last_response.body.should include("\"/__spec__/file2.js")
- last_response.body.should satisfy {|s| s.index("/file1.js") < s.index("/__spec__/file2.js") }
+ it "should create a Rack::Server with the correct port when passed" do
+ port = 1234
+ Rack::Server.should_receive(:new).with(hash_including(:Port => port)).and_return(double(:server).as_null_object)
+ Jasmine::Server.new(port, double(:app)).start
end
- it "should return an empty 200 for HEAD requests to /" do
- head "/"
- last_response.status.should == 200
- last_response.headers['Content-Type'].should == 'text/html'
- last_response.body.should == ''
+ it "should start the server" do
+ server = double(:server)
+ Rack::Server.should_receive(:new) { server.as_null_object }
+ server.should_receive(:start)
+ Jasmine::Server.new('8888', double(:app)).start
end
- it "should tell the browser not to cache any assets" do
- head "/"
- ['Pragma'].each do |key|
- last_response.headers[key].should == 'no-cache'
- end
+ it "should set the app as the instance variable on the rack server" do
+ app = double('application')
+ server = double(:server)
+ Rack::Server.should_receive(:new) { server.as_null_object }
+ Jasmine::Server.new(1234, app).start
+ server.instance_variable_get(:@app).should == app
end
end
end
diff --git a/spec/yaml_config_parser_spec.rb b/spec/yaml_config_parser_spec.rb
new file mode 100644
index 00000000..2fbafba5
--- /dev/null
+++ b/spec/yaml_config_parser_spec.rb
@@ -0,0 +1,202 @@
+require 'spec_helper'
+
+describe Jasmine::YamlConfigParser do
+ it "src_dir uses current working directory when src dir is blank" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"src_dir" => nil}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.src_dir.should == 'some_project_root'
+ end
+
+ it "src_dir returns src_dir if set" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"src_dir" => 'some_src_dir'}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.src_dir.should == File.join('some_project_root', 'some_src_dir')
+ end
+
+ it "jasmine_dir returns nil when jasmine dir is blank" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"jasmine_dir" => nil}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.jasmine_dir.should be_nil
+ end
+
+ it "jasmine_dir returns jasmine_dir if set" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"jasmine_dir" => 'some_jasmine_dir'}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.jasmine_dir.should == File.join('some_project_root', 'some_jasmine_dir')
+ end
+
+ it "spec_helper returns default helper path when spec_helper is blank" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"spec_helper" => nil}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.spec_helper.should == 'some_project_root/spec/javascripts/support/jasmine_helper.rb'
+ end
+
+ it "spec_helper returns spec_helper if set" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"spec_helper" => 'some_spec_helper.rb'}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.spec_helper.should == 'some_project_root/some_spec_helper.rb'
+ end
+
+ it "spec_dir uses default path when spec dir is blank" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"spec_dir" => nil}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.spec_dir.should == File.join('some_project_root', 'spec', 'javascripts')
+ end
+
+ it "spec_dir returns spec_dir if set" do
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ {"spec_dir" => "some_spec_dir"}
+ end
+ end
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', nil, yaml_loader)
+ parser.spec_dir.should == File.join('some_project_root', 'some_spec_dir')
+ end
+
+ it "expands src_file paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_src') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'src_dir' => 'some_src', 'src_files' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.src_files.should == ['expected_results']
+ end
+
+ it "expands stylesheets paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_src') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'src_dir' => 'some_src', 'stylesheets' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.css_files.should == ['expected_results']
+ end
+
+ it "expands spec_file paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_spec') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'spec_dir' => 'some_spec', 'spec_files' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.spec_files.should == ['expected_results']
+ end
+
+ it "expands jasmine_file paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_jasmine') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'jasmine_dir' => 'some_jasmine', 'jasmine_files' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.jasmine_files.should == ['expected_results']
+ end
+
+ it "expands jasmine css file paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_jasmine') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'jasmine_dir' => 'some_jasmine', 'jasmine_css_files' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.jasmine_css_files.should == ['expected_results']
+ end
+
+ it "expands helper paths" do
+ expander = lambda do |dir, patterns|
+ if (dir == File.join('some_project_root', 'some_spec') && patterns == ['some_patterns'])
+ ['expected_results']
+ end
+ end
+ yaml_loader = lambda do |path|
+ if path == "some_path"
+ { 'spec_dir' => 'some_spec', 'helpers' => ['some_patterns'] }
+ end
+ end
+
+ parser = Jasmine::YamlConfigParser.new('some_path', 'some_project_root', expander, yaml_loader)
+
+ parser.helpers.should == ['expected_results']
+ end
+
+ it "doesn't blow up when blank values are passed" do
+ expander = lambda do |dir, patterns|
+ raise 'bad arguments' unless patterns.is_a?(Array)
+ []
+ end
+ yaml_loader = lambda do |path|
+ {}
+ end
+
+ parser = Jasmine::YamlConfigParser.new({}, 'some_project_root', expander, yaml_loader)
+ parser.src_files.should == []
+ parser.spec_files.should == []
+ parser.css_files.should == []
+ parser.helpers.should == []
+ end
+
+end