updates and junk

This commit is contained in:
John Bintz 2012-03-21 12:22:42 -04:00
commit 092e503ec7
13 changed files with 177 additions and 79 deletions

3
.gitignore vendored
View File

@ -18,4 +18,5 @@ tmp
.tmp .tmp
node_modules/ node_modules/
.tmp-sprockets/ .tmp-sprockets/
_site/
.sass-cache/

View File

@ -6,7 +6,19 @@ require 'thor'
class Flowerbox::CLI < Thor class Flowerbox::CLI < Thor
include Thor::Actions 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 method_options :pwd => :string, :env_options => nil, :runners => :string, :runner => :string, :verbose_server => false
def test(dir = "spec/javascripts", *files) def test(dir = "spec/javascripts", *files)
Dir.chdir(pwd) do Dir.chdir(pwd) do
@ -24,7 +36,21 @@ class Flowerbox::CLI < Thor
end end
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) def transplant(dir)
Flowerbox.transplant(dir) Flowerbox.transplant(dir)
end end
@ -35,7 +61,7 @@ class Flowerbox::CLI < Thor
puts "Sprockets cache cleaned." puts "Sprockets cache cleaned."
end 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) def plant(type, dir = nil)
env = Flowerbox::TestEnvironment.for(type) env = Flowerbox::TestEnvironment.for(type)
@ -44,16 +70,18 @@ class Flowerbox::CLI < Thor
directory('.', dir || env.plant_target) directory('.', dir || env.plant_target)
end end
default_task :test def method_missing(method, *args)
if File.directory?(method.to_s)
test(method.to_s, *args)
else
super
end
end
no_tasks do no_tasks do
def pwd def pwd
options[:pwd] || Dir.pwd options[:pwd] || Dir.pwd
end end
def asset_paths
Flowerbox.asset_paths.collect { |path| File.join(pwd, path) }
end
end end
end end

View File

@ -1,5 +1,6 @@
require "flowerbox/version" require "flowerbox/version"
require 'rainbow' require 'rainbow'
require 'forwardable'
module Flowerbox module Flowerbox
require 'flowerbox/core_ext/module' require 'flowerbox/core_ext/module'
@ -16,70 +17,29 @@ module Flowerbox
require 'flowerbox/gathered_result' require 'flowerbox/gathered_result'
require 'flowerbox/reporter' require 'flowerbox/reporter'
require 'flowerbox/configuration'
if defined?(Rails::Engine) if defined?(Rails::Engine)
require 'flowerbox/rails/engine' require 'flowerbox/rails/engine'
end end
CACHE_DIR = '.tmp-sprockets' CACHE_DIR = 'tmp/sprockets'
class << self class << self
attr_writer :reporters
attr_accessor :port
def reset! def reset!
@spec_patterns = nil @configuration = nil
@spec_files = nil
@asset_paths = nil
@reporters = nil
@port = nil
end end
def spec_patterns def configuration
@spec_patterns ||= [] @configuration ||= Flowerbox::Configuration.new
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) }
end end
def path def path
Pathname(File.expand_path('../..', __FILE__)) Pathname(File.expand_path('../..', __FILE__))
end end
attr_accessor :test_environment, :runner_environment, :bare_coffeescript, :server def configure(&block)
configuration.configure(&block)
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
def bare_coffeescript def bare_coffeescript
@ -115,6 +75,18 @@ module Flowerbox
break if env.transplant(dir) break if env.transplant(dir)
end end
end end
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
end end

View File

@ -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

View File

@ -20,7 +20,7 @@ module Flowerbox::Reporter
puts result.name.join(" - ").foreground(:red) puts result.name.join(" - ").foreground(:red)
result.failures.each do |failure| result.failures.each do |failure|
puts " " + failure.message.foreground(:red) + " [" + failure.runners.join(',') + "] " + path_for(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
end end

View File

@ -12,6 +12,8 @@ module Flowerbox::Reporter
if result.name if result.name
result.name.each_with_index do |name, index| result.name.each_with_index do |name, index|
if @name_stack[index] != name if @name_stack[index] != name
@name_stack = []
if name != result.name.last if name != result.name.last
message = name message = name
else else

View File

@ -34,6 +34,19 @@ module Flowerbox::Result
@data['stack'] || [] @data['stack'] || []
end end
def filtered_stack
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 def first_local_stack
@first_local_stack ||= stack[1..-1].find do |line| @first_local_stack ||= stack[1..-1].find do |line|
!system_files.any? { |file| line[%r{\(#{file}}] } !system_files.any? { |file| line[%r{\(#{file}}] }
@ -41,7 +54,7 @@ module Flowerbox::Result
end end
def exception? def exception?
stack[0][%r{^.+Error: }] (stack[0] || '')[%r{^.+Error: }]
end end
end end
end end

View File

@ -35,14 +35,16 @@ module Flowerbox::Run
def sprockets def sprockets
require 'flowerbox/sprockets_handler' require 'flowerbox/sprockets_handler'
Flowerbox::SprocketsHandler.new( Flowerbox::SprocketsHandler.new(:asset_paths => asset_paths)
:asset_paths => [ end
def asset_paths
[
Flowerbox.path.join("lib/assets/javascripts"), Flowerbox.path.join("lib/assets/javascripts"),
Flowerbox.path.join("vendor/assets/javascripts"), Flowerbox.path.join("vendor/assets/javascripts"),
@dir, @dir,
Flowerbox.asset_paths Flowerbox.asset_paths
].flatten ].flatten
)
end end
def spec_files def spec_files

View File

@ -57,8 +57,21 @@ module Flowerbox
puts "Flowerbox running your #{Flowerbox.test_environment.name} tests on #{console_name}..." puts "Flowerbox running your #{Flowerbox.test_environment.name} tests on #{console_name}..."
attempts = 3
while true
begin
server.start server.start
break
rescue Flowerbox::Server::ServerDiedError
attempts -= 1
raise RunnerDiedError.new if attempts == 0
Flowerbox.server = nil
end
end
yield yield
server.stop server.stop

View File

@ -38,6 +38,10 @@ module Flowerbox
<html> <html>
<head> <head>
<title>Flowerbox - #{Flowerbox.test_environment.name} Runner</title> <title>Flowerbox - #{Flowerbox.test_environment.name} Runner</title>
</head>
<body>
<h1>Flowerbox - #{Flowerbox.test_environment.name} Runner</h1>
<pre id="queue"></pre>
<script type="text/javascript"> <script type="text/javascript">
console._log = console.log; console._log = console.log;
@ -47,10 +51,6 @@ console.log = function(msg) {
} }
</script> </script>
#{template_files.join("\n")} #{template_files.join("\n")}
</head>
<body>
<h1>Flowerbox - #{Flowerbox.test_environment.name} Runner</h1>
<pre id="queue"></pre>
<script type="text/javascript"> <script type="text/javascript">
Flowerbox.environment = '#{name}'; Flowerbox.environment = '#{name}';
Flowerbox.onQueueStateChange = function(msg) { Flowerbox.onQueueStateChange = function(msg) {

View File

@ -9,6 +9,7 @@ module Flowerbox
attr_reader :options attr_reader :options
class MissingRackApp < StandardError ; end class MissingRackApp < StandardError ; end
class ServerDiedError < StandardError ; end
def initialize(options = {}) def initialize(options = {})
@options = { :logging => false }.merge(options || {}) @options = { :logging => false }.merge(options || {})
@ -44,7 +45,7 @@ module Flowerbox
sleep 0.1 sleep 0.1
end end
raise StandardError.new("Server died") if !@server_thread[:server].running? raise ServerDiedError.new if !@server_thread[:server].running?
end end
def stop def stop

View File

@ -2,6 +2,7 @@ require 'sprockets'
require 'sprockets/engines' require 'sprockets/engines'
require 'forwardable' require 'forwardable'
require 'sprockets-vendor_gems' require 'sprockets-vendor_gems'
require 'fileutils'
module Flowerbox module Flowerbox
class SprocketsHandler class SprocketsHandler
@ -39,7 +40,9 @@ module Flowerbox
return @environment if @environment return @environment if @environment
@environment = Sprockets::Environment.new @environment = Sprockets::Environment.new
@environment.cache = Sprockets::Cache::FileStore.new(Flowerbox::CACHE_DIR) 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) } self.class.gem_asset_paths.each { |path| append_path(path) }
options[:asset_paths].each { |path| append_path(path) } options[:asset_paths].each { |path| append_path(path) }
@ -59,8 +62,8 @@ module Flowerbox
asset_path = asset.pathname.to_s asset_path = asset.pathname.to_s
environment.paths.each do |path| environment.paths.each do |path|
if asset_path[%r{^#{path}}] if result = asset_path[%r{^#{path}/(.*)}, 1]
return asset_path.gsub(%r{^#{path}/}, '') return result
end end
end end

View File

@ -6,10 +6,19 @@ module Flowerbox
super([]) super([])
@sprockets = sprockets @sprockets = sprockets
@included = {}
end end
def add(files) 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 end
def to_json def to_json
@ -17,8 +26,8 @@ module Flowerbox
end end
private private
def include?(file) def included?(file)
any? { |other_file| other_file.pathname.to_s == file.pathname.to_s } @included[file.pathname.to_s]
end end
end end
end end