Merge branch 'master' of github.com:johnbintz/flowerbox
This commit is contained in:
commit
be5c7f25cd
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,3 +17,5 @@ test/version_tmp
|
|||||||
tmp
|
tmp
|
||||||
.tmp
|
.tmp
|
||||||
node_modules/
|
node_modules/
|
||||||
|
.tmp-sprockets/
|
||||||
|
|
||||||
|
@ -4,7 +4,9 @@ require 'flowerbox'
|
|||||||
require 'thor'
|
require 'thor'
|
||||||
|
|
||||||
class Flowerbox::CLI < Thor
|
class Flowerbox::CLI < Thor
|
||||||
desc "test DIR FILES...", "Run the specs found in spec dir, loading spec_helper.rb for configuration details"
|
include Thor::Actions
|
||||||
|
|
||||||
|
desc "test", "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
|
||||||
@ -22,6 +24,26 @@ class Flowerbox::CLI < Thor
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
desc "transplant DIR", "Convert an existing Jasmine gem-style project to Flowerbox"
|
||||||
|
def transplant(dir)
|
||||||
|
Flowerbox.transplant(dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "clean", "Clean the Sprockets cache"
|
||||||
|
def clean
|
||||||
|
FileUtils.rm_rf(Flowerbox::CACHE_DIR)
|
||||||
|
puts "Sprockets cache cleaned."
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "plant", "Start a new Flowerbox project"
|
||||||
|
def plant(type, dir = nil)
|
||||||
|
env = Flowerbox::TestEnvironment.for(type)
|
||||||
|
|
||||||
|
self.class.source_root(Flowerbox.path.join(env.plant_source))
|
||||||
|
|
||||||
|
directory('.', dir || env.plant_target)
|
||||||
|
end
|
||||||
|
|
||||||
default_task :test
|
default_task :test
|
||||||
|
|
||||||
no_tasks do
|
no_tasks do
|
||||||
|
@ -4,8 +4,8 @@ require File.expand_path('../lib/flowerbox/version', __FILE__)
|
|||||||
Gem::Specification.new do |gem|
|
Gem::Specification.new do |gem|
|
||||||
gem.authors = ["John Bintz"]
|
gem.authors = ["John Bintz"]
|
||||||
gem.email = ["john@coswellproductions.com"]
|
gem.email = ["john@coswellproductions.com"]
|
||||||
gem.description = %q{TODO: Write a gem description}
|
gem.description = %q{No-nonsense JavaScript testing solution.}
|
||||||
gem.summary = %q{TODO: Write a gem summary}
|
gem.summary = %q{No-nonsense JavaScript testing solution.}
|
||||||
gem.homepage = ""
|
gem.homepage = ""
|
||||||
|
|
||||||
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
||||||
@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
|
|||||||
gem.add_dependency 'selenium-webdriver'
|
gem.add_dependency 'selenium-webdriver'
|
||||||
gem.add_dependency 'sinatra'
|
gem.add_dependency 'sinatra'
|
||||||
gem.add_dependency 'rainbow'
|
gem.add_dependency 'rainbow'
|
||||||
|
gem.add_dependency 'sprockets-vendor_gems'
|
||||||
end
|
end
|
||||||
|
@ -21,7 +21,7 @@ Flowerbox =
|
|||||||
|
|
||||||
onQueueStateChange: ->
|
onQueueStateChange: ->
|
||||||
|
|
||||||
queueRunner: ->
|
queueRunner: (failsafe = 5) ->
|
||||||
Flowerbox.onQueueStateChange("checking queue")
|
Flowerbox.onQueueStateChange("checking queue")
|
||||||
if Flowerbox.contactQueue.length > 0
|
if Flowerbox.contactQueue.length > 0
|
||||||
Flowerbox.started = true
|
Flowerbox.started = true
|
||||||
@ -55,7 +55,10 @@ Flowerbox =
|
|||||||
xhr.abort()
|
xhr.abort()
|
||||||
Flowerbox.onQueueStateChange("aborted #{url}, rerunning")
|
Flowerbox.onQueueStateChange("aborted #{url}, rerunning")
|
||||||
Flowerbox.contactQueue.unshift(info)
|
Flowerbox.contactQueue.unshift(info)
|
||||||
Flowerbox.queueRunner()
|
|
||||||
|
if failsafe > 0
|
||||||
|
failsafe -= 1
|
||||||
|
Flowerbox.queueRunner(failsafe)
|
||||||
, Flowerbox.delay * 5
|
, Flowerbox.delay * 5
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,16 +17,22 @@ Flowerbox.World = (code = null) ->
|
|||||||
Flowerbox.Matchers =
|
Flowerbox.Matchers =
|
||||||
toEqual: (expected) ->
|
toEqual: (expected) ->
|
||||||
@message = "Expected #{@actual} #{@notMessage} equal #{expected}"
|
@message = "Expected #{@actual} #{@notMessage} equal #{expected}"
|
||||||
if typeof @actual == 'object'
|
result = null
|
||||||
|
|
||||||
|
if @actual? && expected?
|
||||||
|
switch (typeof @actual)
|
||||||
|
when 'object'
|
||||||
|
result = true
|
||||||
for key, value of @actual
|
for key, value of @actual
|
||||||
return false if expected[key] != value
|
result = false if expected[key] != value
|
||||||
|
|
||||||
for key, value of expected
|
for key, value of expected
|
||||||
return false if @actual[key] != value
|
result = false if @actual[key] != value
|
||||||
|
|
||||||
true
|
if result == null
|
||||||
else
|
result = (@actual == expected)
|
||||||
@actual == expected
|
|
||||||
|
result
|
||||||
|
|
||||||
Flowerbox.World ->
|
Flowerbox.World ->
|
||||||
@assert = (what, message = 'failed') ->
|
@assert = (what, message = 'failed') ->
|
||||||
|
@ -39,7 +39,7 @@ class Flowerbox.Cucumber.Reporter
|
|||||||
when 'StepResult'
|
when 'StepResult'
|
||||||
stepResult = event.getPayloadItem('stepResult')
|
stepResult = event.getPayloadItem('stepResult')
|
||||||
|
|
||||||
file = Flowerbox.Step.matchFile(@step.getName()) || "unknown:0"
|
file = Flowerbox.Step.matchFile(@step.getName()) || "#{Flowerbox.UNKNOWN}:0"
|
||||||
|
|
||||||
result = new Flowerbox.Result(step_type: this.type(), source: 'cucumber', original_name: @step.getName(), name: this.nameParts(), file: file)
|
result = new Flowerbox.Result(step_type: this.type(), source: 'cucumber', original_name: @step.getName(), name: this.nameParts(), file: file)
|
||||||
|
|
||||||
@ -49,6 +49,8 @@ class Flowerbox.Cucumber.Reporter
|
|||||||
result.status = Flowerbox.Result.PENDING
|
result.status = Flowerbox.Result.PENDING
|
||||||
else if stepResult.isUndefined()
|
else if stepResult.isUndefined()
|
||||||
result.status = Flowerbox.Result.UNDEFINED
|
result.status = Flowerbox.Result.UNDEFINED
|
||||||
|
result.hasDataTable = @step.hasDataTable()
|
||||||
|
result.hasDocString = @step.hasDocString()
|
||||||
else if stepResult.isFailed()
|
else if stepResult.isFailed()
|
||||||
result.status = Flowerbox.Result.FAILURE
|
result.status = Flowerbox.Result.FAILURE
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ class jasmine.FlowerboxReporter
|
|||||||
status: Flowerbox.Result.SUCCESS
|
status: Flowerbox.Result.SUCCESS
|
||||||
source: 'jasmine'
|
source: 'jasmine'
|
||||||
name: spec.getSpecSplitName()
|
name: spec.getSpecSplitName()
|
||||||
file: 'unknown:0'
|
file: "#{Flowerbox.UNKNOWN}:0"
|
||||||
|
|
||||||
for key, value of overrides
|
for key, value of overrides
|
||||||
data[key] = value
|
data[key] = value
|
||||||
@ -38,6 +38,7 @@ class jasmine.FlowerboxReporter
|
|||||||
for item in spec.results().items_
|
for item in spec.results().items_
|
||||||
if !item.passed_
|
if !item.passed_
|
||||||
result.status = Flowerbox.Result.FAILURE
|
result.status = Flowerbox.Result.FAILURE
|
||||||
|
|
||||||
stack = item.trace.stack || []
|
stack = item.trace.stack || []
|
||||||
if stack.constructor != Array
|
if stack.constructor != Array
|
||||||
stack = stack.split("\n")
|
stack = stack.split("\n")
|
||||||
|
@ -5,11 +5,13 @@ jasmine.Spec.beforeAddMatcherResult().push ->
|
|||||||
lol.wut
|
lol.wut
|
||||||
catch e
|
catch e
|
||||||
if e.stack
|
if e.stack
|
||||||
file = switch Flowerbox.environment
|
file = switch Flowerbox.environment.toLowerCase()
|
||||||
when 'firefox'
|
when 'firefox'
|
||||||
e.stack.split("\n")[3]
|
e.stack.split("\n")[3]
|
||||||
when 'chrome'
|
when 'chrome'
|
||||||
e.stack.split("\n")[4]
|
e.stack.split("\n")[4]
|
||||||
|
else
|
||||||
|
"#{Flowerbox.UNKNOWN}:0"
|
||||||
|
|
||||||
@trace = { stack: [ file ] }
|
@trace = { stack: [ @message, file ] }
|
||||||
|
|
||||||
|
@ -1,44 +1,27 @@
|
|||||||
require "flowerbox/version"
|
require "flowerbox/version"
|
||||||
require 'flowerbox-delivery'
|
|
||||||
require 'rainbow'
|
require 'rainbow'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module CoreExt
|
require 'flowerbox/core_ext/module'
|
||||||
autoload :Module, 'flowerbox/core_ext/module'
|
|
||||||
|
require 'flowerbox/runner'
|
||||||
|
|
||||||
|
require 'flowerbox/run/base'
|
||||||
|
require 'flowerbox/run/test'
|
||||||
|
require 'flowerbox/run/debug'
|
||||||
|
|
||||||
|
require 'flowerbox/test_environment'
|
||||||
|
require 'flowerbox/result'
|
||||||
|
require 'flowerbox/result_set'
|
||||||
|
require 'flowerbox/gathered_result'
|
||||||
|
|
||||||
|
require 'flowerbox/reporter'
|
||||||
|
|
||||||
|
if defined?(Rails::Engine)
|
||||||
|
require 'flowerbox/rails/engine'
|
||||||
end
|
end
|
||||||
|
|
||||||
autoload :Runner, 'flowerbox/runner'
|
CACHE_DIR = '.tmp-sprockets'
|
||||||
autoload :Task, 'flowerbox/task'
|
|
||||||
|
|
||||||
module Run
|
|
||||||
autoload :Base, 'flowerbox/run/base'
|
|
||||||
autoload :Test, 'flowerbox/run/test'
|
|
||||||
autoload :Debug, 'flowerbox/run/debug'
|
|
||||||
end
|
|
||||||
|
|
||||||
module Runner
|
|
||||||
autoload :Node, 'flowerbox/runner/node'
|
|
||||||
autoload :Selenium, 'flowerbox/runner/selenium'
|
|
||||||
autoload :Firefox, 'flowerbox/runner/firefox'
|
|
||||||
autoload :Chrome, 'flowerbox/runner/chrome'
|
|
||||||
autoload :Base, 'flowerbox/runner/base'
|
|
||||||
end
|
|
||||||
|
|
||||||
autoload :TestEnvironment, 'flowerbox/test_environment'
|
|
||||||
|
|
||||||
module TestEnvironment
|
|
||||||
autoload :Base, 'flowerbox/test_environment/base'
|
|
||||||
autoload :Jasmine, 'flowerbox/test_environment/jasmine'
|
|
||||||
autoload :Cucumber, 'flowerbox/test_environment/cucumber'
|
|
||||||
end
|
|
||||||
|
|
||||||
autoload :Rack, 'flowerbox/rack'
|
|
||||||
|
|
||||||
autoload :ResultSet, 'flowerbox/result_set'
|
|
||||||
autoload :GatheredResult, 'flowerbox/gathered_result'
|
|
||||||
autoload :Result, 'flowerbox/result'
|
|
||||||
|
|
||||||
autoload :Reporter, 'flowerbox/reporter'
|
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
attr_writer :reporters
|
attr_writer :reporters
|
||||||
@ -84,7 +67,7 @@ module Flowerbox
|
|||||||
Pathname(File.expand_path('../..', __FILE__))
|
Pathname(File.expand_path('../..', __FILE__))
|
||||||
end
|
end
|
||||||
|
|
||||||
attr_accessor :test_environment, :runner_environment, :bare_coffeescript
|
attr_accessor :test_environment, :runner_environment, :bare_coffeescript, :server
|
||||||
|
|
||||||
def configure
|
def configure
|
||||||
yield self
|
yield self
|
||||||
@ -126,6 +109,12 @@ module Flowerbox
|
|||||||
|
|
||||||
@browsers = {}
|
@browsers = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def transplant(dir)
|
||||||
|
Flowerbox::TestEnvironment.transplantable_environments.each do |env|
|
||||||
|
break if env.transplant(dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
require 'tilt'
|
|
||||||
|
|
||||||
module Flowerbox::Delivery::Tilt
|
|
||||||
class FeatureTemplate < Tilt::Template
|
|
||||||
self.default_mime_type = 'application/javascript'
|
|
||||||
|
|
||||||
def prepare; end
|
|
||||||
|
|
||||||
def evaluate(scope, locals, &block)
|
|
||||||
<<-JS
|
|
||||||
Flowerbox.Cucumber.Features = Flowerbox.Cucumber.Features || [];
|
|
||||||
|
|
||||||
Flowerbox.Cucumber.Features.push("#{escaped_data}");
|
|
||||||
JS
|
|
||||||
end
|
|
||||||
|
|
||||||
def escaped_data
|
|
||||||
data.gsub("\n", "\\n").gsub('"', '\\"')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -66,6 +66,8 @@ module Flowerbox
|
|||||||
get %r{^/__F__/(.*)$} do |file|
|
get %r{^/__F__/(.*)$} do |file|
|
||||||
asset = sprockets.asset_for(file, :bundle => false)
|
asset = sprockets.asset_for(file, :bundle => false)
|
||||||
|
|
||||||
|
halt(404) if !asset
|
||||||
|
|
||||||
content_type asset.content_type
|
content_type asset.content_type
|
||||||
asset.body
|
asset.body
|
||||||
end
|
end
|
||||||
@ -75,12 +77,6 @@ module Flowerbox
|
|||||||
|
|
||||||
runner.template
|
runner.template
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
|
||||||
private
|
|
||||||
def setup_protetion(builder)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
15
lib/flowerbox/rails/engine.rb
Normal file
15
lib/flowerbox/rails/engine.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require 'rails/engine'
|
||||||
|
|
||||||
|
module Flowerbox
|
||||||
|
module Rails
|
||||||
|
class Engine < ::Rails::Engine
|
||||||
|
rake_tasks do
|
||||||
|
require 'flowerbox/task'
|
||||||
|
|
||||||
|
Flowerbox::Task.create("flowerbox:spec", :dir => "spec/javascripts")
|
||||||
|
Flowerbox::Task.create("flowerbox:integration", :dir => "js-features")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,11 +2,12 @@ module Flowerbox
|
|||||||
module Reporter
|
module Reporter
|
||||||
extend Flowerbox::CoreExt::Module
|
extend Flowerbox::CoreExt::Module
|
||||||
|
|
||||||
autoload :Base, 'flowerbox/reporter/base'
|
require 'flowerbox/reporter/file_display'
|
||||||
autoload :ConsoleBase, 'flowerbox/reporter/console_base'
|
|
||||||
autoload :Verbose, 'flowerbox/reporter/verbose'
|
require 'flowerbox/reporter/base'
|
||||||
autoload :Progress, 'flowerbox/reporter/progress'
|
require 'flowerbox/reporter/console_base'
|
||||||
autoload :FileDisplay, 'flowerbox/reporter/file_display'
|
require 'flowerbox/reporter/verbose'
|
||||||
|
require 'flowerbox/reporter/progress'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,12 +10,12 @@ module Flowerbox
|
|||||||
extend Flowerbox::CoreExt::Module
|
extend Flowerbox::CoreExt::Module
|
||||||
end
|
end
|
||||||
|
|
||||||
autoload :Base, 'flowerbox/result/base'
|
require 'flowerbox/result/base'
|
||||||
autoload :Exception, 'flowerbox/result/exception'
|
require 'flowerbox/result/exception'
|
||||||
autoload :Failure, 'flowerbox/result/failure'
|
require 'flowerbox/result/failure'
|
||||||
autoload :Pending, 'flowerbox/result/pending'
|
require 'flowerbox/result/pending'
|
||||||
autoload :FailureMessage, 'flowerbox/result/failure_message'
|
require 'flowerbox/result/failure_message'
|
||||||
autoload :FileInfo, 'flowerbox/result/file_info'
|
require 'flowerbox/result/file_info'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def for(test_env, type)
|
def for(test_env, type)
|
||||||
|
@ -3,6 +3,7 @@ require 'forwardable'
|
|||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Result
|
module Result
|
||||||
class Base
|
class Base
|
||||||
|
require 'flowerbox/result/file_info'
|
||||||
include Flowerbox::Result::FileInfo
|
include Flowerbox::Result::FileInfo
|
||||||
|
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
@ -31,7 +31,7 @@ module Flowerbox::Result
|
|||||||
end
|
end
|
||||||
|
|
||||||
def stack
|
def stack
|
||||||
@data['stack']
|
@data['stack'] || []
|
||||||
end
|
end
|
||||||
|
|
||||||
def first_local_stack
|
def first_local_stack
|
||||||
|
@ -1,28 +1,38 @@
|
|||||||
module Flowerbox::Result::FileInfo
|
module Flowerbox::Result::FileInfo
|
||||||
|
UNKNOWN = '__unknown__'
|
||||||
|
|
||||||
def translated_file
|
def translated_file
|
||||||
@translated_file ||= filename
|
return @translated_file if @translated_file
|
||||||
|
|
||||||
|
if filename == UNKNOWN
|
||||||
|
@translated_file = UNKNOWN
|
||||||
|
else
|
||||||
|
@translated_file = Flowerbox.test_environment.actual_path_for(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
@translated_file
|
||||||
end
|
end
|
||||||
|
|
||||||
def file_translated?
|
def file_translated?
|
||||||
translated_file != filename
|
translated_file[%r{\.coffee$}]
|
||||||
end
|
end
|
||||||
|
|
||||||
def filename
|
def filename
|
||||||
file.to_s.split(":").first || 'unknown'
|
file.to_s.split(":").first || UNKNOWN
|
||||||
end
|
end
|
||||||
|
|
||||||
def line_number
|
def line_number
|
||||||
return @line_number if @line_number
|
return @line_number if @line_number
|
||||||
|
|
||||||
@line_number = file.to_s.split(":")[1]
|
@line_number = file.to_s.split(":")[1]
|
||||||
@line_number = "~#{@line_number}" if file_translated?
|
@line_number = "~#{(@line_number.to_i * 0.67).to_i}" if file_translated?
|
||||||
@line_number ||= "0"
|
@line_number ||= "0"
|
||||||
end
|
end
|
||||||
|
|
||||||
alias :line :line_number
|
alias :line :line_number
|
||||||
|
|
||||||
def translated_file_and_line
|
def translated_file_and_line
|
||||||
"#{translated_file.gsub(%r{^/}, '')}:#{line_number}"
|
"#{translated_file.gsub(%r{^#{Dir.pwd}/}, '')}:#{line_number}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def system_files
|
def system_files
|
||||||
|
@ -41,7 +41,13 @@ module Flowerbox
|
|||||||
end
|
end
|
||||||
|
|
||||||
def exitstatus
|
def exitstatus
|
||||||
results.any?(&:failure?) ? 1 : 0
|
if results.any?(&:failure?)
|
||||||
|
1
|
||||||
|
elsif results.any?(&:pending?)
|
||||||
|
2
|
||||||
|
else
|
||||||
|
0
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def print(data = {})
|
def print(data = {})
|
||||||
|
@ -33,7 +33,9 @@ module Flowerbox::Run
|
|||||||
end
|
end
|
||||||
|
|
||||||
def sprockets
|
def sprockets
|
||||||
Flowerbox::Delivery::SprocketsHandler.new(
|
require 'flowerbox/sprockets_handler'
|
||||||
|
|
||||||
|
Flowerbox::SprocketsHandler.new(
|
||||||
:asset_paths => [
|
: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"),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
module Flowerbox::Run
|
module Flowerbox::Run
|
||||||
class Test < Base
|
class Test < Base
|
||||||
|
require 'flowerbox/runner/base'
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
prep!
|
prep!
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Runner
|
module Runner
|
||||||
extend Flowerbox::CoreExt::Module
|
extend Flowerbox::CoreExt::Module
|
||||||
|
|
||||||
|
def self.find_constant(string)
|
||||||
|
require "flowerbox/runner/#{string}"
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
require 'thread'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Runner
|
module Runner
|
||||||
class Base
|
class Base
|
||||||
@ -9,6 +11,10 @@ module Flowerbox
|
|||||||
|
|
||||||
class RunnerDiedError < StandardError ; end
|
class RunnerDiedError < StandardError ; end
|
||||||
|
|
||||||
|
def self.mutex
|
||||||
|
@mutex ||= Mutex.new
|
||||||
|
end
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@results = ResultSet.new
|
@results = ResultSet.new
|
||||||
@started = false
|
@started = false
|
||||||
@ -27,6 +33,9 @@ module Flowerbox
|
|||||||
if !finished?
|
if !finished?
|
||||||
puts "Something died hard. Here are the tests that did get run before Flowerbox died.".foreground(:red)
|
puts "Something died hard. Here are the tests that did get run before Flowerbox died.".foreground(:red)
|
||||||
puts tests.flatten.join("\n").foreground(:red)
|
puts tests.flatten.join("\n").foreground(:red)
|
||||||
|
server.stop
|
||||||
|
Flowerbox.server = nil
|
||||||
|
|
||||||
raise RunnerDiedError.new
|
raise RunnerDiedError.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -40,6 +49,7 @@ module Flowerbox
|
|||||||
end
|
end
|
||||||
|
|
||||||
def run(*args)
|
def run(*args)
|
||||||
|
self.class.mutex.synchronize do
|
||||||
setup(*args)
|
setup(*args)
|
||||||
|
|
||||||
@count = 0
|
@count = 0
|
||||||
@ -52,6 +62,7 @@ module Flowerbox
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
server.stop
|
server.stop
|
||||||
|
end
|
||||||
|
|
||||||
@results
|
@results
|
||||||
end
|
end
|
||||||
@ -60,8 +71,7 @@ module Flowerbox
|
|||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def configure
|
def configure ; end
|
||||||
end
|
|
||||||
|
|
||||||
def pause_timer
|
def pause_timer
|
||||||
@timer_running = false
|
@timer_running = false
|
||||||
@ -100,17 +110,20 @@ module Flowerbox
|
|||||||
end
|
end
|
||||||
|
|
||||||
def server
|
def server
|
||||||
return @server if @server
|
require 'flowerbox/rack'
|
||||||
|
|
||||||
|
Flowerbox::Rack.runner = self
|
||||||
|
Flowerbox::Rack.sprockets = @sprockets
|
||||||
|
|
||||||
|
return Flowerbox.server if Flowerbox.server
|
||||||
|
|
||||||
|
require 'flowerbox/server'
|
||||||
|
|
||||||
server_options = { :app => Flowerbox::Rack }
|
server_options = { :app => Flowerbox::Rack }
|
||||||
server_options[:logging] = true if options[:verbose_server]
|
server_options[:logging] = true if options[:verbose_server]
|
||||||
server_options[:port] = Flowerbox.port
|
server_options[:port] = Flowerbox.port
|
||||||
|
|
||||||
@server = Flowerbox::Delivery::Server.new(server_options)
|
Flowerbox.server = Flowerbox::Server.new(server_options)
|
||||||
Flowerbox::Rack.runner = self
|
|
||||||
Flowerbox::Rack.sprockets = @sprockets
|
|
||||||
|
|
||||||
@server
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def log(message)
|
def log(message)
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
|
require 'flowerbox/runner/selenium'
|
||||||
|
|
||||||
class Flowerbox::Runner::Chrome < Flowerbox::Runner::Selenium
|
class Flowerbox::Runner::Chrome < Flowerbox::Runner::Selenium
|
||||||
|
|
||||||
def name
|
def name
|
||||||
"Chrome"
|
"Chrome"
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
require 'flowerbox/runner/selenium'
|
||||||
|
|
||||||
class Flowerbox::Runner::Firefox < Flowerbox::Runner::Selenium
|
class Flowerbox::Runner::Firefox < Flowerbox::Runner::Selenium
|
||||||
def name
|
def name
|
||||||
"Firefox"
|
"Firefox"
|
||||||
@ -8,7 +10,7 @@ class Flowerbox::Runner::Firefox < Flowerbox::Runner::Selenium
|
|||||||
end
|
end
|
||||||
|
|
||||||
def browser
|
def browser
|
||||||
@browser ||= ::Selenium::WebDriver.for(:firefox)
|
Flowerbox.browsers[:firefox] ||= ::Selenium::WebDriver.for(:firefox)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
require 'tempfile'
|
require 'tempfile'
|
||||||
require 'flowerbox/delivery/server'
|
|
||||||
require 'json'
|
require 'json'
|
||||||
|
require 'flowerbox/runner/base'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Runner
|
module Runner
|
||||||
@ -22,7 +22,7 @@ module Flowerbox
|
|||||||
|
|
||||||
def configured?
|
def configured?
|
||||||
File.directory?(File.join(Dir.pwd, 'node_modules/jsdom')) &&
|
File.directory?(File.join(Dir.pwd, 'node_modules/jsdom')) &&
|
||||||
File.directory?(File.join(Dir.pwd, 'node_modules/XMLHttpRequest'))
|
File.directory?(File.join(Dir.pwd, 'node_modules/xmlhttprequest'))
|
||||||
end
|
end
|
||||||
|
|
||||||
def cleanup ; end
|
def cleanup ; end
|
||||||
@ -95,6 +95,7 @@ jsdom.env(
|
|||||||
if (!gotFlowerbox && context.Flowerbox) {
|
if (!gotFlowerbox && context.Flowerbox) {
|
||||||
context.Flowerbox.baseUrl = "http://localhost:#{server.port}/";
|
context.Flowerbox.baseUrl = "http://localhost:#{server.port}/";
|
||||||
context.Flowerbox.environment = 'node';
|
context.Flowerbox.environment = 'node';
|
||||||
|
context.Flowerbox.UNKNOWN = '#{Flowerbox::Result::FileInfo::UNKNOWN}';
|
||||||
|
|
||||||
gotFlowerbox = true;
|
gotFlowerbox = true;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
require 'selenium-webdriver'
|
require 'selenium-webdriver'
|
||||||
|
require 'flowerbox/runner/base'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module Runner
|
module Runner
|
||||||
@ -55,6 +56,7 @@ console.log = function(msg) {
|
|||||||
Flowerbox.onQueueStateChange = function(msg) {
|
Flowerbox.onQueueStateChange = function(msg) {
|
||||||
//document.getElementById('queue').innerHTML = document.getElementById('queue').innerHTML + "\\n" + msg;
|
//document.getElementById('queue').innerHTML = document.getElementById('queue').innerHTML + "\\n" + msg;
|
||||||
};
|
};
|
||||||
|
Flowerbox.UNKNOWN = '#{Flowerbox::Result::FileInfo::UNKNOWN}';
|
||||||
|
|
||||||
var context = this;
|
var context = this;
|
||||||
|
|
||||||
@ -69,7 +71,7 @@ HTML
|
|||||||
end
|
end
|
||||||
|
|
||||||
def template_files
|
def template_files
|
||||||
sprockets.files.collect { |file| %{<script type="text/javascript" src="/__F__/#{file.logical_path}"></script>} }
|
sprockets.files.collect { |file| %{<script type="text/javascript" src="/__F__/#{sprockets.logical_path_for(file)}"></script>} }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
123
lib/flowerbox/server.rb
Normal file
123
lib/flowerbox/server.rb
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
require 'rack'
|
||||||
|
require 'net/http'
|
||||||
|
require 'socket'
|
||||||
|
require 'rack/builder'
|
||||||
|
require 'thin'
|
||||||
|
|
||||||
|
module Flowerbox
|
||||||
|
class Server
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
|
def initialize(options = {})
|
||||||
|
@options = { :logging => false }.merge(options || {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
@server_thread = Thread.new do
|
||||||
|
server_options = { :Port => port, :Host => interface }
|
||||||
|
|
||||||
|
app = options[:app]
|
||||||
|
|
||||||
|
Thin::Logging.silent = !options[:logging]
|
||||||
|
|
||||||
|
if options[:logging]
|
||||||
|
real_app = app
|
||||||
|
app = ::Rack::Builder.new do
|
||||||
|
use ::Rack::CommonLogger, STDOUT
|
||||||
|
run real_app
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
::Rack::Handler::Thin.run(app, server_options) do |server|
|
||||||
|
Thread.current[:server] = server
|
||||||
|
|
||||||
|
trap('QUIT') { server.stop }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while !@server_thread[:server] && @server_thread.alive?
|
||||||
|
sleep 0.1
|
||||||
|
end
|
||||||
|
|
||||||
|
raise StandardError.new("Server died") if !@server_thread[:server].running?
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
if @server_thread
|
||||||
|
@server_thread[:server].stop
|
||||||
|
|
||||||
|
wait_for_server_to_stop
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def interface
|
||||||
|
options[:interface] || '0.0.0.0'
|
||||||
|
end
|
||||||
|
|
||||||
|
def port
|
||||||
|
return @port if @port ||= options[:port]
|
||||||
|
|
||||||
|
attempts = 20
|
||||||
|
|
||||||
|
begin
|
||||||
|
attempts -= 1
|
||||||
|
|
||||||
|
current_port = random_port
|
||||||
|
|
||||||
|
begin
|
||||||
|
socket = TCPSocket.new(interface, current_port)
|
||||||
|
socket.close
|
||||||
|
rescue Errno::ECONNREFUSED => e
|
||||||
|
@port = current_port
|
||||||
|
end
|
||||||
|
end while !@port and attempts > 0
|
||||||
|
|
||||||
|
raise StandardError.new("can't start server") if attempts == 0
|
||||||
|
|
||||||
|
@port
|
||||||
|
end
|
||||||
|
|
||||||
|
def address
|
||||||
|
"http://#{interface}:#{port}/"
|
||||||
|
end
|
||||||
|
|
||||||
|
def alive?
|
||||||
|
@server_thread.alive?
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def wait_for_server_to_start
|
||||||
|
while true do
|
||||||
|
begin
|
||||||
|
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
|
||||||
|
|
||||||
|
TCPSocket.new(connect_interface, port)
|
||||||
|
break
|
||||||
|
rescue Errno::ECONNREFUSED => e
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait_for_server_to_stop
|
||||||
|
while alive? do
|
||||||
|
begin
|
||||||
|
connect_interface = '127.0.0.1' if interface == '0.0.0.0'
|
||||||
|
|
||||||
|
socket = TCPSocket.new(connect_interface, port)
|
||||||
|
socket.close
|
||||||
|
rescue Errno::ECONNREFUSED => e
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
sleep 0.1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def random_port
|
||||||
|
25000 + Kernel.rand(1000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
71
lib/flowerbox/sprockets_handler.rb
Normal file
71
lib/flowerbox/sprockets_handler.rb
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
require 'sprockets'
|
||||||
|
require 'sprockets/engines'
|
||||||
|
require 'forwardable'
|
||||||
|
require 'sprockets-vendor_gems'
|
||||||
|
|
||||||
|
module Flowerbox
|
||||||
|
class SprocketsHandler
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
|
attr_reader :files, :options
|
||||||
|
|
||||||
|
def_delegators :environment, :append_path, :register_engine, :[]
|
||||||
|
|
||||||
|
def self.gem_asset_paths
|
||||||
|
@gem_asset_paths ||= Sprockets.find_gem_vendor_paths
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(options)
|
||||||
|
@options = options
|
||||||
|
|
||||||
|
require 'flowerbox/unique_asset_list'
|
||||||
|
|
||||||
|
@files = Flowerbox::UniqueAssetList.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add(asset)
|
||||||
|
paths_for(asset).each { |path| add_paths_for_compiled_asset(path) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def paths_for(asset)
|
||||||
|
environment.find_asset(asset).to_a.collect(&:pathname)
|
||||||
|
end
|
||||||
|
|
||||||
|
def expire_index!
|
||||||
|
@environment.send(:expire_index!)
|
||||||
|
end
|
||||||
|
|
||||||
|
def environment
|
||||||
|
return @environment if @environment
|
||||||
|
|
||||||
|
@environment = Sprockets::Environment.new
|
||||||
|
@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) }
|
||||||
|
|
||||||
|
@environment
|
||||||
|
end
|
||||||
|
|
||||||
|
def asset_for(*args)
|
||||||
|
environment.find_asset(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_paths_for_compiled_asset(path)
|
||||||
|
asset_for(path, :bundle => false).to_a.each { |file_path| @files.add(file_path) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def logical_path_for(asset)
|
||||||
|
asset_path = asset.pathname.to_s
|
||||||
|
|
||||||
|
environment.paths.each do |path|
|
||||||
|
if asset_path[%r{^#{path}}]
|
||||||
|
return asset_path.gsub(%r{^#{path}/}, '')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
raise StandardError.new("Could not find logical path for #{asset_path}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,10 +2,18 @@ module Flowerbox
|
|||||||
module TestEnvironment
|
module TestEnvironment
|
||||||
extend Flowerbox::CoreExt::Module
|
extend Flowerbox::CoreExt::Module
|
||||||
|
|
||||||
class << self
|
def self.for(env)
|
||||||
def for(env)
|
require "flowerbox/test_environment/#{env}"
|
||||||
|
|
||||||
find_constant(env).new
|
find_constant(env).new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.transplantable_environments
|
||||||
|
Dir[File.expand_path('../test_environment/*.rb', __FILE__)].each do |file|
|
||||||
|
require file
|
||||||
|
end
|
||||||
|
|
||||||
|
constants.collect { |k| const_get(k) }.find_all(&:transplantable?)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,6 +13,10 @@ module Flowerbox
|
|||||||
@reporters ||= []
|
@reporters ||= []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.transplantable?
|
||||||
|
respond_to?(:transplant)
|
||||||
|
end
|
||||||
|
|
||||||
def set_additional_options(opts = nil)
|
def set_additional_options(opts = nil)
|
||||||
@options = {}
|
@options = {}
|
||||||
|
|
||||||
@ -41,6 +45,10 @@ module Flowerbox
|
|||||||
def start
|
def start
|
||||||
runner.spec_files.each { |file| @sprockets.add(file) }
|
runner.spec_files.each { |file| @sprockets.add(file) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def actual_path_for(file)
|
||||||
|
@sprockets.asset_for(file, :bundle => false).pathname.to_s
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
require 'flowerbox/test_environment/base'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module TestEnvironment
|
module TestEnvironment
|
||||||
class Cucumber < Base
|
class Cucumber < Base
|
||||||
@ -12,7 +14,9 @@ module Flowerbox
|
|||||||
def inject_into(sprockets)
|
def inject_into(sprockets)
|
||||||
super
|
super
|
||||||
|
|
||||||
@sprockets.register_engine('.feature', Flowerbox::Delivery::Tilt::FeatureTemplate)
|
require 'flowerbox/tilt/feature_template'
|
||||||
|
|
||||||
|
@sprockets.register_engine('.feature', Flowerbox::Tilt::FeatureTemplate)
|
||||||
end
|
end
|
||||||
|
|
||||||
def global_system_files
|
def global_system_files
|
||||||
@ -56,20 +60,34 @@ JS
|
|||||||
" (\d+) "
|
" (\d+) "
|
||||||
end
|
end
|
||||||
|
|
||||||
|
messages = []
|
||||||
|
|
||||||
|
if result['hasDataTable']
|
||||||
|
args << "table"
|
||||||
|
messages << "table is a Cucumber AST data table"
|
||||||
|
end
|
||||||
|
|
||||||
|
if result['hasDocString']
|
||||||
|
args << "string"
|
||||||
|
messages << "string is a doc string"
|
||||||
|
end
|
||||||
|
|
||||||
args_string = args.join(', ')
|
args_string = args.join(', ')
|
||||||
|
|
||||||
|
output = []
|
||||||
|
|
||||||
if primarily_coffeescript?
|
if primarily_coffeescript?
|
||||||
<<-COFFEE
|
output << %{Flowerbox.#{result.step_type} /^#{matcher}$/, #{"(#{args_string}) " if !args_string.empty?}->}
|
||||||
Flowerbox.#{result.step_type} /^#{matcher}$/, #{"(#{args_string}) " if !args_string.empty?}->
|
output += messages.collect { |msg| " # #{msg}" }
|
||||||
@pending() # add your code here
|
output << %{ @pending() # add your code here}
|
||||||
COFFEE
|
|
||||||
else
|
else
|
||||||
<<-JS
|
output << "Flowerbox.#{result.step_type}(/^#{matcher}$/, function(#{args_string}) {"
|
||||||
Flowerbox.#{result.step_type}(/^#{matcher}$/, function(#{args_string}) {
|
output += messages.collect { |msg| " // #{msg}" }
|
||||||
this.pending(); // add your code here
|
output << %{ this.pending(); // add your code here}
|
||||||
});
|
output << "});"
|
||||||
JS
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
output.collect { |line| "#{line}\n" }.join
|
||||||
end
|
end
|
||||||
|
|
||||||
def primarily_coffeescript?
|
def primarily_coffeescript?
|
||||||
@ -80,11 +98,15 @@ JS
|
|||||||
|
|
||||||
coffee_count > js_count
|
coffee_count > js_count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def plant_source
|
||||||
|
"skel/cucumber"
|
||||||
|
end
|
||||||
|
|
||||||
|
def plant_target
|
||||||
|
"js-features"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Flowerbox::Delivery::Tilt
|
|
||||||
autoload :FeatureTemplate, 'flowerbox/delivery/tilt/feature_template'
|
|
||||||
end
|
|
||||||
|
|
||||||
|
@ -1,8 +1,56 @@
|
|||||||
|
require 'flowerbox/test_environment/base'
|
||||||
require 'jasmine-core'
|
require 'jasmine-core'
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
module Flowerbox
|
module Flowerbox
|
||||||
module TestEnvironment
|
module TestEnvironment
|
||||||
class Jasmine < Base
|
class Jasmine < Base
|
||||||
|
def self.transplant(dir)
|
||||||
|
if File.file?(jasmine_yml = File.join(dir, 'support/jasmine.yml'))
|
||||||
|
puts "Transplanting #{jasmine_yml} into Flowerbox..."
|
||||||
|
|
||||||
|
config = [
|
||||||
|
%{f.test_with :jasmine},
|
||||||
|
%{f.run_with :firefox},
|
||||||
|
%{f.report_with :verbose}
|
||||||
|
]
|
||||||
|
|
||||||
|
YAML.load_file(jasmine_yml).each do |key, value|
|
||||||
|
case key
|
||||||
|
when 'src_dir'
|
||||||
|
[ value ].flatten.each do |dir|
|
||||||
|
config << %{f.asset_paths << "#{dir}"}
|
||||||
|
end
|
||||||
|
when 'src_files'
|
||||||
|
[ value ].flatten.each do |file|
|
||||||
|
config << %{f.additional_files << "#{file}"}
|
||||||
|
end
|
||||||
|
when 'helpers'
|
||||||
|
[ value ].flatten.each do |pattern|
|
||||||
|
Dir[File.join(dir, pattern)].each do |file|
|
||||||
|
config << %{f.additional_files << "#{file.gsub("#{dir}/", '')}"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
when 'spec_files'
|
||||||
|
[ value ].flatten.each do |pattern|
|
||||||
|
config << %{f.spec_patterns << "#{pattern}"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
File.open(target = File.join(dir, 'spec_helper.rb'), 'wb') do |fh|
|
||||||
|
fh.puts "Flowerbox.configure do |f|"
|
||||||
|
config.each do |line|
|
||||||
|
fh.puts " #{line}"
|
||||||
|
end
|
||||||
|
fh.puts "end"
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "#{target} created. Run your tests with:"
|
||||||
|
puts " flowerbox test #{dir}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def inject_into(sprockets)
|
def inject_into(sprockets)
|
||||||
sprockets.append_path(::Jasmine::Core.path)
|
sprockets.append_path(::Jasmine::Core.path)
|
||||||
|
|
||||||
|
24
lib/flowerbox/tilt/feature_template.rb
Normal file
24
lib/flowerbox/tilt/feature_template.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
require 'tilt'
|
||||||
|
|
||||||
|
module Flowerbox
|
||||||
|
module Tilt
|
||||||
|
class FeatureTemplate < ::Tilt::Template
|
||||||
|
self.default_mime_type = 'application/javascript'
|
||||||
|
|
||||||
|
def prepare; end
|
||||||
|
|
||||||
|
def evaluate(scope, locals, &block)
|
||||||
|
<<-JS
|
||||||
|
Flowerbox.Cucumber.Features = Flowerbox.Cucumber.Features || [];
|
||||||
|
|
||||||
|
Flowerbox.Cucumber.Features.push("#{escaped_data}");
|
||||||
|
JS
|
||||||
|
end
|
||||||
|
|
||||||
|
def escaped_data
|
||||||
|
data.gsub("\n", "\\n").gsub('"', '\\"')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
25
lib/flowerbox/unique_asset_list.rb
Normal file
25
lib/flowerbox/unique_asset_list.rb
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
module Flowerbox
|
||||||
|
class UniqueAssetList < ::Array
|
||||||
|
attr_reader :sprockets
|
||||||
|
|
||||||
|
def initialize(sprockets)
|
||||||
|
super([])
|
||||||
|
|
||||||
|
@sprockets = sprockets
|
||||||
|
end
|
||||||
|
|
||||||
|
def add(files)
|
||||||
|
[ files ].flatten.each { |file| self << file if !include?(file) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_json
|
||||||
|
collect { |file| sprockets.logical_path_for(file) }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def include?(file)
|
||||||
|
any? { |other_file| other_file.pathname.to_s == file.pathname.to_s }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
7
skel/cucumber/features/my_first_feature.feature
Normal file
7
skel/cucumber/features/my_first_feature.feature
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Feature: My First Feature
|
||||||
|
Scenario: Do Something
|
||||||
|
Given I have a flowerbox
|
||||||
|
When I plant a "cucumber" seed
|
||||||
|
Then I should get the following when I pick:
|
||||||
|
| cucumber |
|
||||||
|
|
10
skel/cucumber/spec_helper.rb
Normal file
10
skel/cucumber/spec_helper.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
Flowerbox.configure do |f|
|
||||||
|
f.test_with :cucumber
|
||||||
|
f.run_with :firefox
|
||||||
|
|
||||||
|
f.additional_files << "support/env.js.coffee"
|
||||||
|
f.spec_patterns << "features/**/*.feature"
|
||||||
|
|
||||||
|
f.test_environment.prefer_step_language :coffeescript
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
Flowerbox.Given /^I have a flowerbox$/, ->
|
||||||
|
@flowerbox =
|
||||||
|
plantSeed: (type) ->
|
||||||
|
@types ||= []
|
||||||
|
@types.push(type)
|
||||||
|
pick: ->
|
||||||
|
@types
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
Flowerbox.Then /^I should get the following when I pick:$/, (table) ->
|
||||||
|
# table is a Cucumber AST data table
|
||||||
|
data = (row[0] for row in table.raw())
|
||||||
|
@expect(@flowerbox.pick()).toEqual(data)
|
||||||
|
|
@ -0,0 +1,3 @@
|
|||||||
|
Flowerbox.When /^I plant a "([^"]+)" seed$/, (type) ->
|
||||||
|
@flowerbox.plantSeed(type)
|
||||||
|
|
1
skel/cucumber/support/env.js.coffee
Normal file
1
skel/cucumber/support/env.js.coffee
Normal file
@ -0,0 +1 @@
|
|||||||
|
#= require_tree ../step_definitions
|
59
spec/flowerbox/delivery/template_renderer_spec.rb
Normal file
59
spec/flowerbox/delivery/template_renderer_spec.rb
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Flowerbox::Delivery::TemplateRenderer do
|
||||||
|
let(:template_renderer) { described_class.new(:template => template, :files => files) }
|
||||||
|
let(:template) { 'template' }
|
||||||
|
let(:files) { 'files' }
|
||||||
|
|
||||||
|
let(:rendered_template) { 'rendered template' }
|
||||||
|
let(:erb_template) { "#{rendered_template} <%= resource_tags %>" }
|
||||||
|
|
||||||
|
describe '#render' do
|
||||||
|
subject { template_renderer.render }
|
||||||
|
|
||||||
|
let(:rendered_files) { 'with files' }
|
||||||
|
let(:result) { "#{rendered_template} #{rendered_files}" }
|
||||||
|
|
||||||
|
before do
|
||||||
|
template_renderer.expects(:resource_tags).returns(rendered_files)
|
||||||
|
template_renderer.expects(:template).returns(erb_template)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == result }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#template' do
|
||||||
|
include FakeFS::SpecHelpers
|
||||||
|
|
||||||
|
before do
|
||||||
|
File.open(template, 'wb') { |fh| fh.print erb_template }
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { template_renderer.template }
|
||||||
|
|
||||||
|
it { should == erb_template }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#resource_tags' do
|
||||||
|
subject { template_renderer.resource_tags }
|
||||||
|
|
||||||
|
context 'success' do
|
||||||
|
let(:files) { [ js, css ] }
|
||||||
|
let(:js) { 'file.js' }
|
||||||
|
let(:css) { 'file.css' }
|
||||||
|
|
||||||
|
it { should == [
|
||||||
|
%{<script src="#{js}" type="text/javascript"></script>},
|
||||||
|
%{<link rel="stylesheet" href="#{css}" type="text/css" />}
|
||||||
|
].join }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'failure' do
|
||||||
|
let(:files) { [ 'what.ever' ] }
|
||||||
|
|
||||||
|
it 'should raise error' do
|
||||||
|
expect { subject }.to raise_error(Flowerbox::Delivery::TemplateRenderer::FileTypeError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
62
spec/flowerbox/delivery/tilt/js_template_spec.rb
Normal file
62
spec/flowerbox/delivery/tilt/js_template_spec.rb
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Flowerbox::Delivery::Tilt::JSTemplate do
|
||||||
|
let(:js_template) { described_class.new { '' } }
|
||||||
|
|
||||||
|
describe '#evaluate' do
|
||||||
|
subject { js_template.evaluate(Object.new, {}) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
js_template.stubs(:file).returns(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
context '.js' do
|
||||||
|
let(:file) { 'file.js' }
|
||||||
|
|
||||||
|
it { should == file }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'other extension' do
|
||||||
|
let(:file) { 'file.coffee' }
|
||||||
|
let(:temp_file) { 'temp file' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
js_template.expects(:save).returns(temp_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == temp_file }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#save' do
|
||||||
|
include FakeFS::SpecHelpers
|
||||||
|
|
||||||
|
let(:temp_file) { 'dir/temp file' }
|
||||||
|
let(:data) { 'data' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
js_template.stubs(:temp_file).returns(temp_file)
|
||||||
|
js_template.stubs(:data).returns(data)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should save the file to disk and return the temp path' do
|
||||||
|
js_template.save.should == temp_file
|
||||||
|
|
||||||
|
File.read(temp_file).should == data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#temp_file' do
|
||||||
|
subject { js_template.temp_file }
|
||||||
|
|
||||||
|
let(:filename) { "#{root_filename}.ext" }
|
||||||
|
let(:root_filename) { "dir/file.js" }
|
||||||
|
|
||||||
|
before do
|
||||||
|
js_template.stubs(:file).returns(filename)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == File.join(Dir.pwd, '.tmp/sprockets', root_filename) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
100
spec/flowerbox/server_spec.rb
Normal file
100
spec/flowerbox/server_spec.rb
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
require 'socket'
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
|
describe Flowerbox::Delivery::Server do
|
||||||
|
let(:server) { described_class.new(options) }
|
||||||
|
let(:options) { nil }
|
||||||
|
|
||||||
|
subject { server }
|
||||||
|
|
||||||
|
describe '#initialize' do
|
||||||
|
let(:options) { { :port => port, :interface => interface } }
|
||||||
|
let(:port) { 'port' }
|
||||||
|
let(:interface) { 'interface' }
|
||||||
|
|
||||||
|
its(:port) { should == port }
|
||||||
|
its(:interface) { should == interface }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#start' do
|
||||||
|
let(:port) { 12345 }
|
||||||
|
let(:interface) { '127.0.0.1' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
server.stubs(:port).returns(port)
|
||||||
|
server.stubs(:interface).returns(interface)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should start a Rack server' do
|
||||||
|
server.start
|
||||||
|
|
||||||
|
TCPSocket.new(server.interface, server.port)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#interface' do
|
||||||
|
subject { server.interface }
|
||||||
|
|
||||||
|
it { should == '0.0.0.0' }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#port' do
|
||||||
|
let(:interface) { '127.0.0.1' }
|
||||||
|
let(:base) { 25000 }
|
||||||
|
let(:initial) { base + @offset }
|
||||||
|
|
||||||
|
before do
|
||||||
|
server.stubs(:interface).returns(interface)
|
||||||
|
|
||||||
|
@offset = 0
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
begin
|
||||||
|
[ 0, 1 ].each do |index|
|
||||||
|
begin
|
||||||
|
TCPSocket.new(interface, base + @offset + index)
|
||||||
|
@offset += 1
|
||||||
|
ok = false
|
||||||
|
rescue Errno::ECONNREFUSED => e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end while !ok
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { server.port }
|
||||||
|
|
||||||
|
context 'no running service' do
|
||||||
|
before do
|
||||||
|
Kernel.stubs(:rand).returns(@offset)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == initial }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'running service' do
|
||||||
|
before do
|
||||||
|
@server = Thread.new do
|
||||||
|
TCPServer.new(interface, initial)
|
||||||
|
end
|
||||||
|
|
||||||
|
server.stubs(:random_port).returns(initial, initial + 1)
|
||||||
|
|
||||||
|
while true
|
||||||
|
begin
|
||||||
|
TCPSocket.new(interface, initial)
|
||||||
|
break
|
||||||
|
rescue Errno::ECONNREFUSED
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == initial + 1 }
|
||||||
|
|
||||||
|
after do
|
||||||
|
@server.kill
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
52
spec/flowerbox/sprockets_handler_spec.rb
Normal file
52
spec/flowerbox/sprockets_handler_spec.rb
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Flowerbox::Delivery::SprocketsHandler do
|
||||||
|
let(:sprockets_handler) { described_class.new(options) }
|
||||||
|
let(:options) { { :asset_paths => asset_paths } }
|
||||||
|
let(:asset_paths) { [ File.expand_path('asset path') ] }
|
||||||
|
|
||||||
|
describe '#add' do
|
||||||
|
let(:asset) { 'asset' }
|
||||||
|
let(:path) { 'path' }
|
||||||
|
let(:paths) { [ path ] }
|
||||||
|
|
||||||
|
let(:pathname_path) { 'pathname path' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sprockets_handler.expects(:paths_for).with(asset).returns(paths)
|
||||||
|
sprockets_handler.expects(:path_for_compiled_asset).with(path).returns(pathname_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should add the asset to the list of ones to work with' do
|
||||||
|
sprockets_handler.add(asset)
|
||||||
|
|
||||||
|
sprockets_handler.files.should == [ pathname_path ]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#paths_for' do
|
||||||
|
subject { sprockets_handler.paths_for(asset) }
|
||||||
|
|
||||||
|
let(:asset) { 'asset' }
|
||||||
|
let(:environment) { stub }
|
||||||
|
let(:bundled_asset) { stub(:to_a => [ processed_asset ]) }
|
||||||
|
let(:processed_asset) { stub(:pathname => path) }
|
||||||
|
|
||||||
|
let(:path) { 'path' }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sprockets_handler.stubs(:environment).returns(environment)
|
||||||
|
environment.expects(:find_asset).with(asset).returns(bundled_asset)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { should == [ path ] }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#environment' do
|
||||||
|
subject { sprockets_handler.environment }
|
||||||
|
|
||||||
|
it { should be_a_kind_of(Sprockets::Environment) }
|
||||||
|
its(:paths) { should == asset_paths }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
18
spec/flowerbox/unique_asset_list_spec.rb
Normal file
18
spec/flowerbox/unique_asset_list_spec.rb
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Flowerbox::Delivery::UniqueAssetList do
|
||||||
|
let(:unique_asset_list) { described_class.new }
|
||||||
|
|
||||||
|
describe "#add" do
|
||||||
|
let(:first) { Pathname.new('one') }
|
||||||
|
let(:second) { Pathname.new('one') }
|
||||||
|
let(:third) { Pathname.new('two') }
|
||||||
|
|
||||||
|
it 'should not add assets already added' do
|
||||||
|
unique_asset_list.add(first)
|
||||||
|
unique_asset_list.add([ second, third ])
|
||||||
|
|
||||||
|
unique_asset_list.should == [ first, third ]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
spec/spec_helper.rb
Normal file
7
spec/spec_helper.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
require 'flowerbox-delivery'
|
||||||
|
require 'mocha'
|
||||||
|
require 'fakefs/spec_helpers'
|
||||||
|
|
||||||
|
RSpec.configure do |c|
|
||||||
|
c.mock_with :mocha
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user