From 2be2edb9109960b0b282d0303e77f630780cadb1 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 19 Mar 2012 11:11:29 -0400 Subject: [PATCH 1/6] a few more tweaks for things --- lib/flowerbox.rb | 6 +++++- lib/flowerbox/reporter/console_base.rb | 2 +- lib/flowerbox/reporter/verbose.rb | 2 ++ lib/flowerbox/result/failure_message.rb | 8 ++++++++ lib/flowerbox/runner/base.rb | 15 ++++++++++++++- lib/flowerbox/server.rb | 4 +++- lib/flowerbox/sprockets_handler.rb | 2 +- 7 files changed, 34 insertions(+), 5 deletions(-) diff --git a/lib/flowerbox.rb b/lib/flowerbox.rb index 8c9caa2..fcd2294 100644 --- a/lib/flowerbox.rb +++ b/lib/flowerbox.rb @@ -21,7 +21,7 @@ module Flowerbox require 'flowerbox/rails/engine' end - CACHE_DIR = '.tmp-sprockets' + CACHE_DIR = 'tmp/sprockets' class << self attr_writer :reporters @@ -115,6 +115,10 @@ module Flowerbox break if env.transplant(dir) end end + + def cache_dir + File.join(CACHE_DIR, Flowerbox.test_environment.name) + end end end diff --git a/lib/flowerbox/reporter/console_base.rb b/lib/flowerbox/reporter/console_base.rb index 7d1fdbe..de167d9 100644 --- a/lib/flowerbox/reporter/console_base.rb +++ b/lib/flowerbox/reporter/console_base.rb @@ -20,7 +20,7 @@ module Flowerbox::Reporter puts result.name.join(" - ").foreground(:red) result.failures.each do |failure| puts " " + failure.message.foreground(:red) + " [" + failure.runners.join(',') + "] " + path_for(failure) - puts failure.stack.join("\n").foreground(:red) if failure.exception? + puts failure.filtered_stack.join("\n").foreground(:red) if failure.exception? end end diff --git a/lib/flowerbox/reporter/verbose.rb b/lib/flowerbox/reporter/verbose.rb index 6cf2b32..02f8e71 100644 --- a/lib/flowerbox/reporter/verbose.rb +++ b/lib/flowerbox/reporter/verbose.rb @@ -12,6 +12,8 @@ module Flowerbox::Reporter if result.name result.name.each_with_index do |name, index| if @name_stack[index] != name + @name_stack = [] + if name != result.name.last message = name else diff --git a/lib/flowerbox/result/failure_message.rb b/lib/flowerbox/result/failure_message.rb index 6dc5c2a..d5ba474 100644 --- a/lib/flowerbox/result/failure_message.rb +++ b/lib/flowerbox/result/failure_message.rb @@ -34,6 +34,14 @@ module Flowerbox::Result @data['stack'] || [] end + def filtered_stack + stack.collect do |line| + line.gsub(%r{\.coffee:(\d+)}) do |_| + ".coffee:~#{($1.to_i * 0.67 + 1).to_i}" + end + end + end + def first_local_stack @first_local_stack ||= stack[1..-1].find do |line| !system_files.any? { |file| line[%r{\(#{file}}] } diff --git a/lib/flowerbox/runner/base.rb b/lib/flowerbox/runner/base.rb index 4ccedfc..e63ee9d 100644 --- a/lib/flowerbox/runner/base.rb +++ b/lib/flowerbox/runner/base.rb @@ -57,7 +57,20 @@ module Flowerbox puts "Flowerbox running your #{Flowerbox.test_environment.name} tests on #{console_name}..." - server.start + attempts = 3 + + while true + begin + server.start + + break + rescue Flowerbox::Server::ServerDiedError + attempts -= 1 + raise RunnerDiedError.new if attempts == 0 + + Flowerbox.server = nil + end + end yield diff --git a/lib/flowerbox/server.rb b/lib/flowerbox/server.rb index 2e64e27..7ed22af 100644 --- a/lib/flowerbox/server.rb +++ b/lib/flowerbox/server.rb @@ -8,6 +8,8 @@ module Flowerbox class Server attr_reader :options + class ServerDiedError < StandardError ; end + def initialize(options = {}) @options = { :logging => false }.merge(options || {}) end @@ -39,7 +41,7 @@ module Flowerbox sleep 0.1 end - raise StandardError.new("Server died") if !@server_thread[:server].running? + raise ServerDiedError.new if !@server_thread[:server].running? end def stop diff --git a/lib/flowerbox/sprockets_handler.rb b/lib/flowerbox/sprockets_handler.rb index a0bb219..a716f10 100644 --- a/lib/flowerbox/sprockets_handler.rb +++ b/lib/flowerbox/sprockets_handler.rb @@ -39,7 +39,7 @@ module Flowerbox return @environment if @environment @environment = Sprockets::Environment.new - @environment.cache = Sprockets::Cache::FileStore.new(Flowerbox::CACHE_DIR) + @environment.cache = Sprockets::Cache::FileStore.new(Flowerbox.cache_dir) self.class.gem_asset_paths.each { |path| append_path(path) } options[:asset_paths].each { |path| append_path(path) } From b6db1384d6ab359f0232b4beafb0134164d97d4a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 19 Mar 2012 17:10:23 -0400 Subject: [PATCH 2/6] a few more fixes --- lib/flowerbox/result/failure_message.rb | 4 ++-- lib/flowerbox/sprockets_handler.rb | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/flowerbox/result/failure_message.rb b/lib/flowerbox/result/failure_message.rb index d5ba474..27f325a 100644 --- a/lib/flowerbox/result/failure_message.rb +++ b/lib/flowerbox/result/failure_message.rb @@ -43,13 +43,13 @@ module Flowerbox::Result end def first_local_stack - @first_local_stack ||= stack[1..-1].find do |line| + @first_local_stack ||= stack.find do |line| !system_files.any? { |file| line[%r{\(#{file}}] } end || stack[1] || '' end def exception? - stack[0][%r{^.+Error: }] + (stack[0] || '')[%r{^.+Error: }] end end end diff --git a/lib/flowerbox/sprockets_handler.rb b/lib/flowerbox/sprockets_handler.rb index a716f10..46ba5a9 100644 --- a/lib/flowerbox/sprockets_handler.rb +++ b/lib/flowerbox/sprockets_handler.rb @@ -2,6 +2,7 @@ require 'sprockets' require 'sprockets/engines' require 'forwardable' require 'sprockets-vendor_gems' +require 'fileutils' module Flowerbox class SprocketsHandler @@ -39,6 +40,8 @@ module Flowerbox return @environment if @environment @environment = Sprockets::Environment.new + FileUtils.rm_rf(Flowerbox.cache_dir) + @environment.cache = Sprockets::Cache::FileStore.new(Flowerbox.cache_dir) self.class.gem_asset_paths.each { |path| append_path(path) } From 36519aec31055e8b62c5a763dd65d7866a2c4469 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Tue, 20 Mar 2012 10:53:20 -0400 Subject: [PATCH 3/6] move config to separate object, fix 1.9.2-style require issue in sprockets loading, backtrace filtering --- lib/flowerbox.rb | 62 ++++++------------------- lib/flowerbox/configuration.rb | 54 +++++++++++++++++++++ lib/flowerbox/result/failure_message.rb | 6 ++- lib/flowerbox/run/base.rb | 18 +++---- lib/flowerbox/unique_asset_list.rb | 15 ++++-- 5 files changed, 95 insertions(+), 60 deletions(-) create mode 100644 lib/flowerbox/configuration.rb diff --git a/lib/flowerbox.rb b/lib/flowerbox.rb index fcd2294..1e767fe 100644 --- a/lib/flowerbox.rb +++ b/lib/flowerbox.rb @@ -1,5 +1,6 @@ require "flowerbox/version" require 'rainbow' +require 'forwardable' module Flowerbox require 'flowerbox/core_ext/module' @@ -16,6 +17,7 @@ module Flowerbox require 'flowerbox/gathered_result' require 'flowerbox/reporter' + require 'flowerbox/configuration' if defined?(Rails::Engine) require 'flowerbox/rails/engine' @@ -24,62 +26,20 @@ module Flowerbox CACHE_DIR = 'tmp/sprockets' class << self - attr_writer :reporters - attr_accessor :port - def reset! - @spec_patterns = nil - @spec_files = nil - @asset_paths = nil - @reporters = nil - @port = nil + @configuration = nil end - def spec_patterns - @spec_patterns ||= [] - end - - def asset_paths - @asset_paths ||= [] - end - - def reporters - @reporters ||= [] - end - - def additional_files - @additional_files ||= [] - end - - def test_with(what) - self.test_environment = Flowerbox::TestEnvironment.for(what) - end - - def run_with(*whats) - self.runner_environment = whats.flatten.collect { |what| Flowerbox::Runner.for(what.to_s) } - end - - def report_with(*whats) - self.reporters = whats.flatten.collect { |what| Flowerbox::Reporter.for(what.to_s) } + def configuration + @configuration ||= Flowerbox::Configuration.new end def path Pathname(File.expand_path('../..', __FILE__)) end - attr_accessor :test_environment, :runner_environment, :bare_coffeescript, :server - - def configure - yield self - - if spec_patterns.empty? - spec_patterns << "**/*_spec*" - spec_patterns << "*/*_spec*" - end - - if reporters.empty? - reporters << Flowerbox::Reporter.for(:progress) - end + def configure(&block) + configuration.configure(&block) end def bare_coffeescript @@ -119,6 +79,14 @@ module Flowerbox def cache_dir File.join(CACHE_DIR, Flowerbox.test_environment.name) end + + def method_missing(method, *args) + if configuration.respond_to?(method) + configuration.send(method, *args) + else + super + end + end end end diff --git a/lib/flowerbox/configuration.rb b/lib/flowerbox/configuration.rb new file mode 100644 index 0000000..1ba758a --- /dev/null +++ b/lib/flowerbox/configuration.rb @@ -0,0 +1,54 @@ +module Flowerbox + class Configuration + attr_writer :reporters, :backtrace_filter + attr_accessor :port + + attr_accessor :test_environment, :runner_environment, :bare_coffeescript, :server + + def spec_patterns + @spec_patterns ||= [] + end + + def asset_paths + @asset_paths ||= [] + end + + def reporters + @reporters ||= [] + end + + def additional_files + @additional_files ||= [] + end + + def backtrace_filter + @backtrace_filter ||= [] + end + + def test_with(what) + self.test_environment = Flowerbox::TestEnvironment.for(what) + end + + def run_with(*whats) + self.runner_environment = whats.flatten.collect { |what| Flowerbox::Runner.for(what.to_s) } + end + + def report_with(*whats) + self.reporters = whats.flatten.collect { |what| Flowerbox::Reporter.for(what.to_s) } + end + + def configure + yield self + + if spec_patterns.empty? + spec_patterns << "**/*_spec*" + spec_patterns << "*/*_spec*" + end + + if reporters.empty? + reporters << Flowerbox::Reporter.for(:progress) + end + end + end +end + diff --git a/lib/flowerbox/result/failure_message.rb b/lib/flowerbox/result/failure_message.rb index 27f325a..d6a8084 100644 --- a/lib/flowerbox/result/failure_message.rb +++ b/lib/flowerbox/result/failure_message.rb @@ -35,11 +35,13 @@ module Flowerbox::Result end def filtered_stack - stack.collect do |line| + stack.reject { |line| + Flowerbox.backtrace_filter.any? { |filter| line[filter] } + }.collect { |line| line.gsub(%r{\.coffee:(\d+)}) do |_| ".coffee:~#{($1.to_i * 0.67 + 1).to_i}" end - end + } end def first_local_stack diff --git a/lib/flowerbox/run/base.rb b/lib/flowerbox/run/base.rb index fe2e134..418c3a2 100644 --- a/lib/flowerbox/run/base.rb +++ b/lib/flowerbox/run/base.rb @@ -35,14 +35,16 @@ module Flowerbox::Run def sprockets require 'flowerbox/sprockets_handler' - Flowerbox::SprocketsHandler.new( - :asset_paths => [ - Flowerbox.path.join("lib/assets/javascripts"), - Flowerbox.path.join("vendor/assets/javascripts"), - @dir, - Flowerbox.asset_paths - ].flatten - ) + Flowerbox::SprocketsHandler.new(:asset_paths => asset_paths) + end + + def asset_paths + [ + Flowerbox.path.join("lib/assets/javascripts"), + Flowerbox.path.join("vendor/assets/javascripts"), + @dir, + Flowerbox.asset_paths + ].flatten end def spec_files diff --git a/lib/flowerbox/unique_asset_list.rb b/lib/flowerbox/unique_asset_list.rb index 03353a7..47fe21b 100644 --- a/lib/flowerbox/unique_asset_list.rb +++ b/lib/flowerbox/unique_asset_list.rb @@ -6,10 +6,19 @@ module Flowerbox super([]) @sprockets = sprockets + + @included = {} end def add(files) - [ files ].flatten.each { |file| self << file if !include?(file) } + [ files ].flatten.each do |file| + self << file if !included?(file) + end + end + + def <<(file) + super(file) + @included[file.pathname.to_s] = true end def to_json @@ -17,8 +26,8 @@ module Flowerbox end private - def include?(file) - any? { |other_file| other_file.pathname.to_s == file.pathname.to_s } + def included?(file) + @included[file.pathname.to_s] end end end From c78174a600d1c7ace58c5e3a8436b8b449bc04a2 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Tue, 20 Mar 2012 14:52:23 -0400 Subject: [PATCH 4/6] improve things --- bin/flowerbox | 40 ++++++++++++++++++++++--- lib/flowerbox/result/failure_message.rb | 7 +++-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/bin/flowerbox b/bin/flowerbox index aa8ecf7..56d5b5d 100755 --- a/bin/flowerbox +++ b/bin/flowerbox @@ -6,7 +6,19 @@ require 'thor' class Flowerbox::CLI < Thor include Thor::Actions - desc "test", "Run the specs found in spec dir, loading spec_helper.rb for configuration details" + default_task :help + + def help(*args) + if !args.first + puts "Flowerbox is a multi-environment, multi-runner JavaScript testing tool." + puts "It supports Jasmine and Cucumber.js, and it runs tests on Node.js and Selenium-driven browsers." + puts + end + + super + end + + desc "test [DIR]", "Run the specs found in spec dir, loading spec_helper.rb for configuration details" method_options :pwd => :string, :env_options => nil, :runners => :string, :runner => :string, :verbose_server => false def test(dir = "spec/javascripts", *files) Dir.chdir(pwd) do @@ -24,7 +36,21 @@ class Flowerbox::CLI < Thor end end - desc "transplant DIR", "Convert an existing Jasmine gem-style project to Flowerbox" + desc "transplant DIR", "Convert an existing JavaScript testing project to Flowerbox" + long_desc <<-TXT + `flowerbox transplant` converts an existing JavaScript testing project type + to Flowerbox. Currently, you can transplant the following types of projects: + + * Pivotal Labs Jasmine gem-style + \x5 (also covers jasmine-headless-webkit) + + These types of projects live in `spec/javascripts` (or the specified directory) + and have the file `support/jasmine.yml` that defines what files are loaded + at what parts in the test load process. `jasmine.yml` is converted to a + Flowerbox `spec_helper.rb` file and placed into `spec/javascripts`. + + Flowerbox will ask before overwriting existing files. + TXT def transplant(dir) Flowerbox.transplant(dir) end @@ -35,7 +61,7 @@ class Flowerbox::CLI < Thor puts "Sprockets cache cleaned." end - desc "plant", "Start a new Flowerbox project" + desc "plant TYPE [DIR]", "Start a new Flowerbox project of TYPE, potentially specifying a different DIR to install" def plant(type, dir = nil) env = Flowerbox::TestEnvironment.for(type) @@ -44,7 +70,13 @@ class Flowerbox::CLI < Thor directory('.', dir || env.plant_target) end - default_task :test + def method_missing(method, *args) + if File.directory?(method.to_s) + invoke :test, method.to_s, *args + else + super + end + end no_tasks do def pwd diff --git a/lib/flowerbox/result/failure_message.rb b/lib/flowerbox/result/failure_message.rb index d6a8084..0f4f036 100644 --- a/lib/flowerbox/result/failure_message.rb +++ b/lib/flowerbox/result/failure_message.rb @@ -35,17 +35,20 @@ module Flowerbox::Result end def filtered_stack - stack.reject { |line| + filtered_stack = stack.reject { |line| Flowerbox.backtrace_filter.any? { |filter| line[filter] } }.collect { |line| line.gsub(%r{\.coffee:(\d+)}) do |_| ".coffee:~#{($1.to_i * 0.67 + 1).to_i}" end } + + filtered_stack.shift if exception? + filtered_stack end def first_local_stack - @first_local_stack ||= stack.find do |line| + @first_local_stack ||= stack[1..-1].find do |line| !system_files.any? { |file| line[%r{\(#{file}}] } end || stack[1] || '' end From 7b09dae45366beef2cbdf02b73688556370d165a Mon Sep 17 00:00:00 2001 From: John Bintz Date: Tue, 20 Mar 2012 15:34:42 -0400 Subject: [PATCH 5/6] speed and running tweaks --- bin/flowerbox | 6 +----- lib/flowerbox/runner/selenium.rb | 8 ++++---- lib/flowerbox/sprockets_handler.rb | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/bin/flowerbox b/bin/flowerbox index 56d5b5d..441b0d6 100755 --- a/bin/flowerbox +++ b/bin/flowerbox @@ -72,7 +72,7 @@ class Flowerbox::CLI < Thor def method_missing(method, *args) if File.directory?(method.to_s) - invoke :test, method.to_s, *args + test(method.to_s, *args) else super end @@ -82,10 +82,6 @@ class Flowerbox::CLI < Thor def pwd options[:pwd] || Dir.pwd end - - def asset_paths - Flowerbox.asset_paths.collect { |path| File.join(pwd, path) } - end end end diff --git a/lib/flowerbox/runner/selenium.rb b/lib/flowerbox/runner/selenium.rb index 770389c..602668b 100644 --- a/lib/flowerbox/runner/selenium.rb +++ b/lib/flowerbox/runner/selenium.rb @@ -38,6 +38,10 @@ module Flowerbox Flowerbox - #{Flowerbox.test_environment.name} Runner + + +

Flowerbox - #{Flowerbox.test_environment.name} Runner

+

     
     #{template_files.join("\n")}
-  
-  
-    

Flowerbox - #{Flowerbox.test_environment.name} Runner

-