From 76b7cde6b0dec04f237c15bb29d35e5e9dd37e94 Mon Sep 17 00:00:00 2001 From: "Davis W. Frank & Rajan Agaskar" Date: Mon, 26 Nov 2012 17:18:05 -0800 Subject: [PATCH] Refactor Jasmine gem - Configuration of Rack server moves into actual Jasmine config - Mapping of served files moved out of configuration - Simplify Rack application and run.html.erb template - Remove cruft: many fixtures no longer used. Jasmine Redirect (previously redirected run.html to /) removed. - Jasmine bootstrap moved out of runner template, into js file. - Add ability to customize jasmine/boot files. - Wrap Jasmine::Core calls in CoreConfiguration - Fix jasmine.yml (was missing spec_file, helper file defaults). - Regression: asset pipeline not supported after this refactor. - Break jasmine.yml processing out into a separate class. --- Rakefile | 13 +- .../javascripts/support/jasmine-rails.yml | 4 +- .../spec/javascripts/support/jasmine.yml | 3 +- lib/jasmine.rb | 9 +- lib/jasmine/application.rb | 39 +-- lib/jasmine/base.rb | 4 + lib/jasmine/config.rb | 162 +++------ lib/jasmine/configuration.rb | 83 +++++ lib/jasmine/core_configuration.rb | 28 ++ lib/jasmine/javascripts/boot.js | 28 ++ lib/jasmine/path_expander.rb | 18 + lib/jasmine/path_mapper.rb | 29 ++ lib/jasmine/results_processor.rb | 41 +-- lib/jasmine/run.html.erb | 37 --- lib/jasmine/run_specs.rb | 20 +- lib/jasmine/runner_config.rb | 71 ---- lib/jasmine/server.rb | 2 +- lib/jasmine/tasks/jasmine.rake | 7 +- lib/jasmine/yaml_config_parser.rb | 41 +++ lib/rack/jasmine/redirect.rb | 20 -- spec/application_integration_spec.rb | 15 + spec/application_spec.rb | 129 +++----- spec/base_spec.rb | 14 + spec/config_spec.rb | 309 ------------------ spec/configuration_spec.rb | 163 +++++++++ spec/fixture/jasmine.erb.yml | 4 - spec/fixture/spec/example_spec.js | 5 - spec/fixture/src/example.js | 3 - spec/jasmine_self_test_config.rb | 19 -- spec/jasmine_self_test_spec.rb | 21 +- spec/page_spec.rb | 6 +- spec/path_expander_spec.rb | 96 ++++++ spec/path_mapper_spec.rb | 33 ++ spec/runner_config_spec.rb | 136 -------- spec/server_spec.rb | 4 +- spec/yaml_config_parser_spec.rb | 156 +++++++++ 36 files changed, 877 insertions(+), 895 deletions(-) create mode 100644 lib/jasmine/configuration.rb create mode 100644 lib/jasmine/core_configuration.rb create mode 100644 lib/jasmine/javascripts/boot.js create mode 100644 lib/jasmine/path_expander.rb create mode 100644 lib/jasmine/path_mapper.rb delete mode 100644 lib/jasmine/runner_config.rb create mode 100644 lib/jasmine/yaml_config_parser.rb delete mode 100644 lib/rack/jasmine/redirect.rb create mode 100644 spec/application_integration_spec.rb create mode 100644 spec/base_spec.rb delete mode 100644 spec/config_spec.rb create mode 100644 spec/configuration_spec.rb delete mode 100644 spec/fixture/jasmine.erb.yml delete mode 100644 spec/fixture/spec/example_spec.js delete mode 100644 spec/fixture/src/example.js delete mode 100644 spec/jasmine_self_test_config.rb create mode 100644 spec/path_expander_spec.rb create mode 100644 spec/path_mapper_spec.rb delete mode 100644 spec/runner_config_spec.rb create mode 100644 spec/yaml_config_parser_spec.rb 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/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..dc3d7e53 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 # diff --git a/lib/jasmine.rb b/lib/jasmine.rb index e69456c4..6e7d3016 100644 --- a/lib/jasmine.rb +++ b/lib/jasmine.rb @@ -1,6 +1,7 @@ jasmine_files = ['base', 'dependencies', - 'runner_config', + 'core_configuration', + 'configuration', 'config', 'application', 'server', @@ -8,15 +9,21 @@ 'rspec_formatter', 'command_line_tool', 'page', + 'path_mapper', 'asset_pipeline_mapper', 'sprockets_mapper', '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 index 7295a4c5..bf64cd33 100644 --- a/lib/jasmine/application.rb +++ b/lib/jasmine/application.rb @@ -3,46 +3,19 @@ require 'jasmine-core' require 'rack/jasmine/runner' require 'rack/jasmine/focused_suite' -require 'rack/jasmine/redirect' require 'rack/jasmine/cache_control' require 'ostruct' module Jasmine class Application - def self.app(config = Jasmine::RunnerConfig.new) - page = Jasmine::Page.new(config) - if Jasmine::Dependencies.rails_3_asset_pipeline? - config.src_mapper = Jasmine::AssetPipelineMapper.new + def self.app(config, builder = Rack::Builder.new) + config.rack_apps.each do |(app, config_block)| + builder.use(app, &config_block) end - Rack::Builder.app do - use Rack::Head - use Rack::Jasmine::CacheControl - if Jasmine::Dependencies.rails_3_asset_pipeline? - map('/assets') do - #load the Sprockets asset helpers - Rails.application.assets.context_class.instance_eval do - include ::Sprockets::Helpers::IsolatedHelper - include ::Sprockets::Helpers::RailsHelper - end - run Rails.application.assets - end - end - - map('/run.html') { run Rack::Jasmine::Redirect.new('/') } - map('/__suite__') { run Rack::Jasmine::FocusedSuite.new(config) } - - #TODO: These path mappings should come from the 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) } - - map('/') do - run Rack::Cascade.new([ - Rack::URLMap.new('/' => Rack::File.new(config.src_dir)), - Rack::Jasmine::Runner.new(page) - ]) - 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/base.rb b/lib/jasmine/base.rb index 6818cdfa..a0ce77fe 100644 --- a/lib/jasmine/base.rb +++ b/lib/jasmine/base.rb @@ -47,4 +47,8 @@ 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/config.rb b/lib/jasmine/config.rb index 0cf9a3a6..36307f92 100644 --- a/lib/jasmine/config.rb +++ b/lib/jasmine/config.rb @@ -1,122 +1,56 @@ module Jasmine - class Config - attr_accessor :src_mapper - - require 'yaml' - require 'erb' - require 'json' - - 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 user_stylesheets - stylesheets.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 - - def simple_config_file - File.join(project_root, 'spec/javascripts/support/jasmine.yml') - 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 - - def src_files - return [] unless simple_config['src_files'] + def self.configure(&block) + block.call(self.config) + end - if self.src_mapper - self.src_mapper.files(simple_config['src_files']) - else - match_files(src_dir, simple_config['src_files']) - end - end + def self.initialize_config + return if @config + @config = Jasmine::Configuration.new + core_config = Jasmine::CoreConfiguration.new + + @config.add_path_mapper(Jasmine::PathMapper) + @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) + 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"]) - end - end + def self.config + initialize_config + @config + end - def stylesheets - if simple_config['stylesheets'] - match_files(src_dir, simple_config['stylesheets']) - else - [] + def self.load_configuration_from_yaml(path = nil) + path ||= File.join(Dir.pwd, 'spec', 'javascripts', 'support', 'jasmine.yml') + if File.exist?(path) + yaml_config = Jasmine::YamlConfigParser.new(path, Dir.pwd, Jasmine::PathExpander.method(:expand), YAML.method(:load_file)) + Jasmine.configure do |config| + 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 end - - def jasmine_host - ENV["JASMINE_HOST"] || 'http://localhost' - end - - def port - @port ||= ENV["JASMINE_PORT"] || Jasmine.find_unused_port - end - - def jasmine_stylesheets - ::Jasmine::Core.css_files.map {|f| "/__JASMINE_ROOT__/#{f}"} - end - - def jasmine_javascripts - ::Jasmine::Core.js_files.map {|f| "/__JASMINE_ROOT__/#{f}" } - end end + end diff --git a/lib/jasmine/configuration.rb b/lib/jasmine/configuration.rb new file mode 100644 index 00000000..5014be87 --- /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.new(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/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/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_processor.rb b/lib/jasmine/results_processor.rb index df16e204..0725eaf6 100644 --- a/lib/jasmine/results_processor.rb +++ b/lib/jasmine/results_processor.rb @@ -10,27 +10,28 @@ def process(results_hash, suites_hash) 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 + # 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 + # 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 diff --git a/lib/jasmine/run.html.erb b/lib/jasmine/run.html.erb index 030d1872..9c9124e0 100644 --- a/lib/jasmine/run.html.erb +++ b/lib/jasmine/run.html.erb @@ -7,43 +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 index 33f34269..5df89f95 100644 --- a/lib/jasmine/run_specs.rb +++ b/lib/jasmine/run_specs.rb @@ -2,18 +2,22 @@ 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_runner_config = Jasmine::RunnerConfig.new -server = Jasmine::Server.new(jasmine_runner_config.port, Jasmine::Application.app(jasmine_runner_config)) -client = Jasmine::SeleniumDriver.new(jasmine_runner_config.browser, jasmine_runner_config.jasmine_server_url) +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 @@ -22,11 +26,11 @@ # # ignore bad exits end t.abort_on_exception = true -Jasmine::wait_for_listener(jasmine_runner_config.port, "jasmine server") +Jasmine::wait_for_listener(config.port, "jasmine server") puts "jasmine server started." -results_processor = Jasmine::ResultsProcessor.new(jasmine_runner_config) -results = Jasmine::Runners::HTTP.new(client, results_processor, jasmine_runner_config.result_batch_size).run +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_config.rb b/lib/jasmine/runner_config.rb deleted file mode 100644 index 8293cfac..00000000 --- a/lib/jasmine/runner_config.rb +++ /dev/null @@ -1,71 +0,0 @@ -module Jasmine - class RunnerConfig - def initialize(config = Jasmine::Config.new) - @config = config - end - - def css_files - @config.jasmine_stylesheets + @config.user_stylesheets - end - - def jasmine_files - @config.jasmine_javascripts - end - - def js_files - @config.js_files - end - - def spec_files - @config.spec_files - end - - def spec_files_full_paths - @config.spec_files_full_paths - end - - def spec_path - @config.spec_path - end - - def spec_dir - @config.spec_dir - end - - def src_dir - @config.src_dir - end - - def project_root - @config.project_root - end - - def root_path - @config.root_path - end - - def browser - ENV["JASMINE_BROWSER"] || 'firefox' - end - - def port - @config.port - end - - def jasmine_server_url - "#{@config.jasmine_host}:#{@config.port}/" - end - - def src_mapper=(context) - @config.src_mapper = context - end - - def src_mapper - @config.src_mapper - end - - def result_batch_size - ENV["JASMINE_RESULT_BATCH_SIZE"] ? ENV["JASMINE_RESULT_BATCH_SIZE"].to_i : 50 - end - end -end diff --git a/lib/jasmine/server.rb b/lib/jasmine/server.rb index ce6f0010..ac12bb42 100644 --- a/lib/jasmine/server.rb +++ b/lib/jasmine/server.rb @@ -1,6 +1,6 @@ module Jasmine class Server - def initialize(port = 8888, application = Jasmine::Application.app) + def initialize(port = 8888, application = nil) @port = port @application = application end diff --git a/lib/jasmine/tasks/jasmine.rake b/lib/jasmine/tasks/jasmine.rake index 6219ad60..76a121fc 100644 --- a/lib/jasmine/tasks/jasmine.rake +++ b/lib/jasmine/tasks/jasmine.rake @@ -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::Server.new(port).start + Jasmine.load_configuration_from_yaml + app = Jasmine::Application.app(Jasmine.config) + Jasmine::Server.new(port, app).start end end diff --git a/lib/jasmine/yaml_config_parser.rb b/lib/jasmine/yaml_config_parser.rb new file mode 100644 index 00000000..017b2faf --- /dev/null +++ b/lib/jasmine/yaml_config_parser.rb @@ -0,0 +1,41 @@ +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 src_files + @path_expander.call(src_dir, loaded_yaml['src_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 + + private + def loaded_yaml + @yaml_loader.call(@path) + end + 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/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 index ead0da10..434fbd9c 100644 --- a/spec/application_spec.rb +++ b/spec/application_spec.rb @@ -1,99 +1,44 @@ require 'spec_helper' -require 'rack/test' -describe "Jasmine::Application" do - include Rack::Test::Methods - - def app - @root = File.join(File.dirname(__FILE__)) - runner_config = double("config", - :project_root => @root, - :spec_dir => File.join(@root, "fixture", "spec"), - :spec_path => "/__spec__", - :root_path => "/__root__", - :css_files => [], - :jasmine_files => [], - :js_files => ["path/file1.js", "path/file2.js"], - :src_dir => File.join(@root, "fixture", "src"), - :src_files => ["file1.js"], - :spec_files => ["example_spec.js"]) - Jasmine::Application.app(runner_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")) - 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 == "/" - end - - it "should 404 non-existent files" do - get "/some-non-existent-file" - last_response.should be_not_found - end - - describe "/ page" do - it "should load each js file in order" do - get "/" - last_response.status.should == 200 - last_response.body.should include("path/file1.js") - last_response.body.should include("path/file2.js") - end +#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 - 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 == '' + Jasmine::Application.app(config, builder).should == builder 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 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/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 323dc2dd..00000000 --- a/spec/config_spec.rb +++ /dev/null @@ -1,309 +0,0 @@ -require 'spec_helper' -require 'selenium-webdriver' - -describe Jasmine::Config do - describe "configuration" do - before :each do - Jasmine::Dependencies.stub(:rails_3_asset_pipeline?) { false } - - 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 "jasmine_stylesheets" do - it "should return the relative web server path to the core Jasmine css stylesheets" do - #TODO: wrap Jasmine::Core with a class that knows about the core path and the relative mapping. - Jasmine::Core.stub(:css_files).and_return(["my_css_file1.css", "my_css_file2.css"]) - Jasmine::Config.new.jasmine_stylesheets.should == ["/__JASMINE_ROOT__/my_css_file1.css", "/__JASMINE_ROOT__/my_css_file2.css"] - end - end - - describe "jasmine_javascripts" do - it "should return the relative web server path to the core Jasmine css javascripts" do - Jasmine::Core.stub(:js_files).and_return(["my_js_file1.js", "my_js_file2.js"]) - Jasmine::Config.new.jasmine_javascripts.should == ["/__JASMINE_ROOT__/my_js_file1.js", "/__JASMINE_ROOT__/my_js_file2.js"] - end - end - - describe "when the asset pipeline (or any other sprockets environment) is active" do - let(:src_files) { ["assets/some.js", "assets/files.js"] } - let(:mapped_files) { ["some.js", "files.js"] } - let(:mapper) { double("mapper") } - - let(:config) do - Jasmine::Config.new.tap do |config| - #TODO: simple_config should be a passed in hash - config.stub(:simple_config) { { 'src_files' => src_files} } - config.src_mapper = mapper - end - end - - it "should use the mapper to return src_files" do - mapper.should_receive(:files).with(src_files).and_return(mapped_files) - config.src_files.should == mapped_files - end - end - - describe "jasmine_host" do - it "should default to localhost" do - Jasmine::Config.new.jasmine_host.should == 'http://localhost' - end - - it "should use ENV['JASMINE_HOST'] if it exists" do - ENV.stub(:[], "JASMINE_HOST").and_return("foo") - Jasmine::Config.new.jasmine_host.should == 'foo' - end - end - - describe "port" do - it "should find an unused port" do - Jasmine.should_receive(:find_unused_port).and_return('1234') - Jasmine::Config.new.port.should == '1234' - end - - it "should use ENV['JASMINE_PORT'] if it exists" do - ENV.stub(:[], "JASMINE_PORT").and_return("foo") - Jasmine::Config.new.port.should == 'foo' - end - - it "should cache port" do - config = Jasmine::Config.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 - end -end diff --git a/spec/configuration_spec.rb b/spec/configuration_spec.rb new file mode 100644 index 00000000..3380130b --- /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(test_mapper1) + config.add_path_mapper(test_mapper2) + config.add_path_mapper(test_mapper3) + 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(test_mapper1) + config.add_path_mapper(test_mapper2) + config.add_path_mapper(test_mapper3) + 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/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 b9527a15..a8d5a5dc 100644 --- a/spec/jasmine_self_test_spec.rb +++ b/spec/jasmine_self_test_spec.rb @@ -1,9 +1,16 @@ require 'spec_helper' -require 'jasmine_self_test_config' -jasmine_runner_config = Jasmine::RunnerConfig.new(JasmineSelfTestConfig.new) -server = Jasmine::Server.new(jasmine_runner_config.port, Jasmine::Application.app(jasmine_runner_config)) -client = Jasmine::SeleniumDriver.new(jasmine_runner_config.browser, jasmine_runner_config.jasmine_server_url) +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(config.port, Jasmine::Application.app(config)) +driver = Jasmine::SeleniumDriver.new(config.browser, "#{config.host}:#{config.port}/") t = Thread.new do begin @@ -13,10 +20,10 @@ # # ignore bad exits end t.abort_on_exception = true -Jasmine::wait_for_listener(jasmine_runner_config.port, "jasmine server") +Jasmine::wait_for_listener(config.port, "jasmine server") puts "jasmine server started." -results_processor = Jasmine::ResultsProcessor.new(jasmine_runner_config) -results = Jasmine::Runners::HTTP.new(client, results_processor, jasmine_runner_config.result_batch_size).run +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 b2db7df2..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 } 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/runner_config_spec.rb b/spec/runner_config_spec.rb deleted file mode 100644 index c5d1d757..00000000 --- a/spec/runner_config_spec.rb +++ /dev/null @@ -1,136 +0,0 @@ -require 'spec_helper' -require 'selenium-webdriver' - -describe Jasmine::RunnerConfig do - describe "css_files" do - it "should return the jasmine stylesheets and any user defined stylesheets" do - jasmine_stylesheets = ['some/css/file'] - user_stylesheets = ['some/user/file'] - user_config = double("config", :jasmine_stylesheets => jasmine_stylesheets, :user_stylesheets => user_stylesheets) - Jasmine::RunnerConfig.new(user_config).css_files.should == jasmine_stylesheets + user_stylesheets - end - end - - describe "jasmine_files" do - it "should return the jasmine files from the config" do - jasmine_files = ['some/file'] - user_config = double('config', :jasmine_javascripts => jasmine_files) - Jasmine::RunnerConfig.new(user_config).jasmine_files.should == jasmine_files - end - end - - describe "js_files" do - it "should return the user js files from the config" do - js_files = ['some/file'] - user_config = double('config', :js_files => js_files) - Jasmine::RunnerConfig.new(user_config).js_files.should == js_files - end - end - - describe "spec_files" do - it "should return the user spec_files from the config" do - spec_files = ['some/file'] - user_config = double('config', :spec_files => spec_files) - Jasmine::RunnerConfig.new(user_config).spec_files.should == spec_files - end - end - - describe "spec_files_full_paths" do - it "should return the user spec_files_full_paths from the config" do - spec_files_full_paths = ['some/file_path'] - user_config = double('config', :spec_files_full_paths => spec_files_full_paths) - Jasmine::RunnerConfig.new(user_config).spec_files_full_paths.should == spec_files_full_paths - end - end - - describe "spec_path" do - it "should return the user spec_path from the config" do - spec_path = ['some/path'] - user_config = double('config', :spec_path => spec_path) - Jasmine::RunnerConfig.new(user_config).spec_path.should == spec_path - end - end - - describe "spec_dir" do - it "should return the user spec_dir from the config" do - spec_dir = ['some/dir'] - user_config = double('config', :spec_dir => spec_dir) - Jasmine::RunnerConfig.new(user_config).spec_dir.should == spec_dir - end - end - - describe "src_dir" do - it "should return the user src_dir from the config" do - src_dir = ['some/dir'] - user_config = double('config', :src_dir => src_dir) - Jasmine::RunnerConfig.new(user_config).src_dir.should == src_dir - end - end - - describe "project_root" do - it "should return the user project_root from the config" do - project_root = ['some/dir'] - user_config = double('config', :project_root => project_root) - Jasmine::RunnerConfig.new(user_config).project_root.should == project_root - end - end - - describe "root_path" do - it "should return the user root_path from the config" do - root_path = ['some/path'] - user_config = double('config', :root_path => root_path) - Jasmine::RunnerConfig.new(user_config).root_path.should == root_path - end - end - - describe "browser" do - it "should default to firefox" do - Jasmine::RunnerConfig.new.browser.should == 'firefox' - end - - it "should use ENV['JASMINE_BROWSER'] if it exists" do - ENV.stub(:[], "JASMINE_BROWSER").and_return("foo") - Jasmine::RunnerConfig.new.browser.should == 'foo' - end - end - - - describe "src_mapper" do - it "should update the src_mapper in the user_config" do - config = Jasmine::RunnerConfig.new(user_config = Jasmine::Config.new) - mapper = double("mapper") - config.src_mapper = mapper - config.src_mapper.should == mapper - user_config.src_mapper.should == mapper - end - end - - describe "jasmine_server_url" do - it "should return the correct server url" do - host = "the host" - port = "484" - user_config = double('config', :jasmine_host => host, :port => port) - Jasmine::RunnerConfig.new(user_config).jasmine_server_url.should == "#{host}:#{port}/" - end - end - - describe "port" do - it "should return the port from the config" do - user_config = double('config', :port => 80) - Jasmine::RunnerConfig.new(user_config).port.should == 80 - end - end - describe "result batch size" do - subject { Jasmine::RunnerConfig.new.result_batch_size } - - context "when not specified" do - it("should use default") { should == 50 } - end - - context "when overridden" do - before { ENV.stub(:[], "JASMINE_RESULT_BATCH_SIZE").and_return("500") } - it { should be(500) } - end - end -end - diff --git a/spec/server_spec.rb b/spec/server_spec.rb index 4275b4f7..f2333b71 100644 --- a/spec/server_spec.rb +++ b/spec/server_spec.rb @@ -27,14 +27,14 @@ 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).start + Jasmine::Server.new(port, double(:app)).start end 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.start + Jasmine::Server.new('8888', double(:app)).start end it "should set the app as the instance variable on the rack server" do diff --git a/spec/yaml_config_parser_spec.rb b/spec/yaml_config_parser_spec.rb new file mode 100644 index 00000000..67c0da99 --- /dev/null +++ b/spec/yaml_config_parser_spec.rb @@ -0,0 +1,156 @@ +require 'spec_helper' + +describe Jasmine::YamlConfigParser do + # before :each do + # Jasmine::Dependencies.stub(:rails_3_asset_pipeline?) { false } + + # 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 + + 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 "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 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 + + + # 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 + +end