From e6bdbf63139ac389ea6b9e0a83f0bb4fda84f795 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Wed, 14 Mar 2012 13:07:13 -0400 Subject: [PATCH] whoa more stuff and it works in production projects --- bin/flowerbox | 12 +++- lib/assets/javascripts/flowerbox.js.coffee | 36 +++++----- .../javascripts/flowerbox/exception.js.coffee | 4 +- .../javascripts/flowerbox/jasmine.js.coffee | 3 + .../flowerbox/jasmine/reporter.js.coffee | 20 ++++-- lib/flowerbox.rb | 70 +++++++++++++++++-- lib/flowerbox/rack.rb | 15 +++- lib/flowerbox/reporter/verbose.rb | 28 ++++---- lib/flowerbox/result.rb | 1 + lib/flowerbox/runner/base.rb | 12 +++- lib/flowerbox/runner/chrome.rb | 2 +- lib/flowerbox/runner/firefox.rb | 2 +- lib/flowerbox/runner/node.rb | 4 +- lib/flowerbox/runner/selenium.rb | 27 +++---- lib/guard/flowerbox.rb | 23 ++++++ 15 files changed, 192 insertions(+), 67 deletions(-) create mode 100644 lib/guard/flowerbox.rb diff --git a/bin/flowerbox b/bin/flowerbox index bd186fc..b1c436f 100755 --- a/bin/flowerbox +++ b/bin/flowerbox @@ -5,10 +5,18 @@ require 'thor' class Flowerbox::CLI < Thor desc "test DIR", "Run the specs found in spec dir, loading spec_helper.rb for configuration details" - method_options :pwd => :string, :runners => :string, :verbose_server => false + method_options :pwd => :string, :runners => :string, :runner => :string, :verbose_server => false def test(dir = "spec/javascripts") Dir.chdir(pwd) do - exit Flowerbox.run(dir, options) + exit Flowerbox.run(dir, options.dup) + end + end + + desc "debug DIR", "Start the Flowerbox server to help debug loading issues." + method_options :pwd => :string, :runners => :string, :runner => :string, :verbose_server => false + def debug(dir = "spec/javascripts") + Dir.chdir(pwd) do + Flowerbox.debug(dir, options.dup) end end diff --git a/lib/assets/javascripts/flowerbox.js.coffee b/lib/assets/javascripts/flowerbox.js.coffee index 53c8ae2..d119667 100644 --- a/lib/assets/javascripts/flowerbox.js.coffee +++ b/lib/assets/javascripts/flowerbox.js.coffee @@ -4,32 +4,28 @@ # Flowerbox = baseUrl: '/' + debug: false ping: -> Flowerbox.contact('ping') - pause: (time) -> - t = (new Date()).getTime() - - while (t + time) > (new Date().getTime()) - Flowerbox.ping() - contact: (url, data...) -> - attempts = 3 + if !Flowerbox.debug + attempts = 3 - doContact = -> - attempts -= 1 + doContact = -> + attempts -= 1 - try - xhr = new XMLHttpRequest() - xhr.open("POST", Flowerbox.baseUrl + url, false) - xhr.setRequestHeader("Accept", "application/json") - xhr.send(JSON.stringify(data)) - catch e - if attempts == 0 - throw e - else - doContact() + try + xhr = new XMLHttpRequest() + xhr.open("POST", Flowerbox.baseUrl + url, false) + xhr.setRequestHeader("Accept", "application/json") + xhr.send(JSON.stringify(data)) + catch e + if attempts == 0 + throw e + else + doContact() - doContact() + doContact() fail: -> diff --git a/lib/assets/javascripts/flowerbox/exception.js.coffee b/lib/assets/javascripts/flowerbox/exception.js.coffee index bb22b30..e6903a7 100644 --- a/lib/assets/javascripts/flowerbox/exception.js.coffee +++ b/lib/assets/javascripts/flowerbox/exception.js.coffee @@ -1,5 +1,5 @@ class Flowerbox.Exception - constructor: (@stack) -> + constructor: (@source, @name, @stack) -> toJSON: -> - { trace: { stack: @stack } } + { status: Flowerbox.Result.FAILURE, source: @source, name: @name, trace: { stack: @stack } } diff --git a/lib/assets/javascripts/flowerbox/jasmine.js.coffee b/lib/assets/javascripts/flowerbox/jasmine.js.coffee index 3a54ef4..ea08ab2 100644 --- a/lib/assets/javascripts/flowerbox/jasmine.js.coffee +++ b/lib/assets/javascripts/flowerbox/jasmine.js.coffee @@ -1,5 +1,8 @@ #= require flowerbox/jasmine/reporter +# because why not? +@context = @describe + getSplitName = (parts) -> parts.push(String(@description).replace(/[\n\r]/g, ' ')) parts diff --git a/lib/assets/javascripts/flowerbox/jasmine/reporter.js.coffee b/lib/assets/javascripts/flowerbox/jasmine/reporter.js.coffee index 1a56c1a..9e42f45 100644 --- a/lib/assets/javascripts/flowerbox/jasmine/reporter.js.coffee +++ b/lib/assets/javascripts/flowerbox/jasmine/reporter.js.coffee @@ -1,4 +1,16 @@ class jasmine.FlowerboxReporter + buildResult: (spec, overrides = {}) -> + data = + status: Flowerbox.Result.SUCCESS + source: 'jasmine' + name: spec.getSpecSplitName() + file: 'unknown:0' + + for key, value of overrides + data[key] = value + + new Flowerbox.Result(data) + reportRunnerStarting: (runner) -> @time = (new Date()).getTime() @@ -7,17 +19,15 @@ class jasmine.FlowerboxReporter Flowerbox.contact("start_test", spec.description) if spec.description == 'encountered a declaration exception' - Flowerbox.contact("finish_test", new Flowerbox.Exception([ spec.description ])) - Flowerbox.contact("results", 0) - Flowerbox.fail() if Flowerbox.fail? + Flowerbox.contact("finish_test", this.buildResult(spec, status: Flowerbox.Result.FAILURE)) reportSpecResults: (spec) -> - result = new Flowerbox.Result(status: Flowerbox.Result.SUCCESS, source: 'jasmine', name: spec.getSpecSplitName(), file: 'unknown:0') + result = this.buildResult(spec) for item in spec.results().items_ if !item.passed_ result.status = Flowerbox.Result.FAILURE - failure = { runner: Flowerbox.environment, message: item.message, stack: item.trace.stack } + failure = { runner: Flowerbox.environment, message: item.message, stack: (item.trace.stack || '').split("\n") } result.failures.push(failure) diff --git a/lib/flowerbox.rb b/lib/flowerbox.rb index 22a8e67..0752817 100644 --- a/lib/flowerbox.rb +++ b/lib/flowerbox.rb @@ -2,6 +2,10 @@ require "flowerbox/version" require 'flowerbox-delivery' require 'rainbow' +module Guard + autoload :Flowerbox, 'guard/flowerbox' +end + module Flowerbox module CoreExt autoload :Module, 'flowerbox/core_ext/module' @@ -35,12 +39,14 @@ module Flowerbox class << self attr_writer :reporters + attr_accessor :port def reset! @spec_patterns = nil @spec_files = nil @asset_paths = nil @reporters = nil + @port = nil end def spec_patterns @@ -55,6 +61,10 @@ module Flowerbox @reporters ||= [] end + def additional_files + @additional_files ||= [] + end + def test_with(what) self.test_environment = Flowerbox::TestEnvironment.for(what) end @@ -90,34 +100,80 @@ module Flowerbox @bare_coffeescript ||= true end - def run(dir, options = {}) + def prep(dir, options = {}) reset! load File.join(dir, 'spec_helper.rb') - if options[:runners] - Flowerbox.run_with(options[:runners].split(',')) - end - require 'coffee_script' require 'tilt/coffee' Tilt::CoffeeScriptTemplate.default_bare = Flowerbox.bare_coffeescript + if runners = options[:runners] || options[:runner] + Flowerbox.run_with(runners.split(',')) + end + end + + def debug(dir, options = {}) + options[:debug] = true + + prep(dir, options) + + env = Flowerbox.runner_environment.first + env.setup(build_sprockets_for(dir), spec_files_for(dir), options) + + Flowerbox.reporters.replace([]) + + puts "Flowerbox debug server running test prepared for #{env.console_name} on #{env.server.address}" + + env.server.start + + trap('INT') do + env.server.stop + end + + @restart = false + + trap('QUIT') do + puts "Restarting Flowerbox server..." + @restart = true + env.server.stop + end + + while env.server.alive? + sleep 0.25 + end + + if @restart + debug(dir, options) + else + puts "Flowerbox finished." + end + end + + def run(dir, options = {}) + prep(dir, options) + result_set = ResultSet.new time = 0 realtime = Time.now.to_i - Flowerbox.runner_environment.each do |env| + runner_envs = Flowerbox.runner_environment.collect do |env| env.ensure_configured! result_set << env.run(build_sprockets_for(dir), spec_files_for(dir), options) time += env.time + + env end result_set.print(:time => time, :realtime => Time.now.to_i - realtime) + + runner_envs.each(&:cleanup) + result_set.exitstatus end @@ -136,6 +192,8 @@ module Flowerbox Flowerbox.test_environment.inject_into(sprockets) + Flowerbox.additional_files.each { |file| sprockets.add(file) } + sprockets end diff --git a/lib/flowerbox/rack.rb b/lib/flowerbox/rack.rb index e6f7317..9b0bdc0 100644 --- a/lib/flowerbox/rack.rb +++ b/lib/flowerbox/rack.rb @@ -5,13 +5,17 @@ require 'cgi' module Flowerbox class Rack < Sinatra::Base class << self - attr_accessor :runner + attr_accessor :runner, :sprockets end def runner self.class.runner end + def sprockets + self.class.sprockets + end + def data JSON.parse(request.body.string) end @@ -44,11 +48,16 @@ module Flowerbox runner.ping end - get %r{^/__F__(/.*)$} do |file| - File.read(file) + get %r{^/__F__/(.*)$} do |file| + asset = sprockets.asset_for(file, :bundle => false) + + content_type asset.content_type + asset.body end get '/' do + sprockets.expire_index! + runner.template end end diff --git a/lib/flowerbox/reporter/verbose.rb b/lib/flowerbox/reporter/verbose.rb index 833751c..6cf2b32 100644 --- a/lib/flowerbox/reporter/verbose.rb +++ b/lib/flowerbox/reporter/verbose.rb @@ -9,22 +9,26 @@ module Flowerbox::Reporter end def report_progress(result) - result.name.each_with_index do |name, index| - if @name_stack[index] != name - if name != result.name.last - message = name - else - message = self.send("progress_#{result.type}", result) - if !(file_display = path_for(result)).empty? - message << " # #{file_display}" + if result.name + result.name.each_with_index do |name, index| + if @name_stack[index] != name + if name != result.name.last + message = name + else + message = self.send("progress_#{result.type}", result) + if !(file_display = path_for(result)).empty? + message << " # #{file_display}" + end end + + puts indent(message, index) end - - puts indent(message, index) end - end - @name_stack = result.name.dup + @name_stack = result.name.dup + else + puts result.data + end end def progress_skipped(result) diff --git a/lib/flowerbox/result.rb b/lib/flowerbox/result.rb index e5e99a7..cd9588d 100644 --- a/lib/flowerbox/result.rb +++ b/lib/flowerbox/result.rb @@ -11,6 +11,7 @@ module Flowerbox end autoload :Base, 'flowerbox/result/base' + autoload :Exception, 'flowerbox/result/exception' autoload :Failure, 'flowerbox/result/failure' autoload :Pending, 'flowerbox/result/pending' autoload :FailureMessage, 'flowerbox/result/failure_message' diff --git a/lib/flowerbox/runner/base.rb b/lib/flowerbox/runner/base.rb index 7708bfc..7fc5bdc 100644 --- a/lib/flowerbox/runner/base.rb +++ b/lib/flowerbox/runner/base.rb @@ -18,8 +18,12 @@ module Flowerbox end end - def run(sprockets, spec_files, options) + def setup(sprockets, spec_files, options) @sprockets, @spec_files, @options = sprockets, spec_files, options + end + + def run(*args) + setup(*args) @count = 0 @@ -41,6 +45,10 @@ module Flowerbox def configure end + def debug? + options[:debug] == true + end + def ensure_configured! if !configured? puts "#{console_name} is not configured for this project, configuring now..." @@ -65,9 +73,11 @@ module Flowerbox server_options = { :app => Flowerbox::Rack } server_options[:logging] = true if options[:verbose_server] + server_options[:port] = Flowerbox.port @server = Flowerbox::Delivery::Server.new(server_options) Flowerbox::Rack.runner = self + Flowerbox::Rack.sprockets = @sprockets @server end diff --git a/lib/flowerbox/runner/chrome.rb b/lib/flowerbox/runner/chrome.rb index 3c77a49..a39c002 100644 --- a/lib/flowerbox/runner/chrome.rb +++ b/lib/flowerbox/runner/chrome.rb @@ -13,7 +13,7 @@ class Flowerbox::Runner::Chrome < Flowerbox::Runner::Selenium end def browser - :chrome + @browser ||= ::Selenium::WebDriver.for(:chrome) end end diff --git a/lib/flowerbox/runner/firefox.rb b/lib/flowerbox/runner/firefox.rb index 8281276..a86cf3f 100644 --- a/lib/flowerbox/runner/firefox.rb +++ b/lib/flowerbox/runner/firefox.rb @@ -8,7 +8,7 @@ class Flowerbox::Runner::Firefox < Flowerbox::Runner::Selenium end def browser - :firefox + @browser ||= ::Selenium::WebDriver.for(:firefox) end end diff --git a/lib/flowerbox/runner/node.rb b/lib/flowerbox/runner/node.rb index 1aae5bc..07ed0b1 100644 --- a/lib/flowerbox/runner/node.rb +++ b/lib/flowerbox/runner/node.rb @@ -26,6 +26,8 @@ module Flowerbox File.directory?(File.join(Dir.pwd, 'node_modules/cucumber')) end + def cleanup ; end + def configure system %{bash -c "mkdir -p node_modules && npm link jsdom && npm link xmlhttprequest && npm link cucumber"} end @@ -73,7 +75,7 @@ jsdom.env( var options = { host: "localhost", port: #{server.port}, - path: "/__F__" + file, + path: "/__F__/" + file, method: "GET" }; diff --git a/lib/flowerbox/runner/selenium.rb b/lib/flowerbox/runner/selenium.rb index d9894da..8828ab4 100644 --- a/lib/flowerbox/runner/selenium.rb +++ b/lib/flowerbox/runner/selenium.rb @@ -3,7 +3,6 @@ require 'selenium-webdriver' module Flowerbox module Runner class Selenium < Base - def name raise StandardError.new("Override me") end @@ -12,17 +11,19 @@ module Flowerbox :selenium end + def cleanup + @browser.close if @browser + end + + def browser + raise StandardError.new("Define a browser") + end + def run(sprockets, spec_files, options) super do - begin - selenium = ::Selenium::WebDriver.for(browser) + browser.navigate.to "http://localhost:#{server.port}/" - selenium.navigate.to "http://localhost:#{server.port}/" - - ensure_alive - ensure - selenium.quit if selenium - end + ensure_alive end end @@ -50,13 +51,13 @@ console.log = function(msg) {

Flowerbox - #{Flowerbox.test_environment.name} Runner

@@ -64,7 +65,7 @@ HTML end def template_files - sprockets.files.collect { |file| %{} } + sprockets.files.collect { |file| %{} } end end end diff --git a/lib/guard/flowerbox.rb b/lib/guard/flowerbox.rb new file mode 100644 index 0000000..0b8068d --- /dev/null +++ b/lib/guard/flowerbox.rb @@ -0,0 +1,23 @@ +require 'guard' +require 'guard/guard' + +module Guard + class Flowerbox < ::Guard::Guard + def initialize(watchers = [], options = {}) + @options = options + end + + def start + puts "Starting Guard::Flowerbox..." + end + + def run_all + ::Flowerbox.run(@options[:dir], @options) + end + + def run_on_change(files = []) + ::Flowerbox.run(@options[:dir], @options.merge(:files => files)) + end + end +end +