diff --git a/lib/jasmine/headless/files_list.rb b/lib/jasmine/headless/files_list.rb
index 5c8f8be..ed37c43 100644
--- a/lib/jasmine/headless/files_list.rb
+++ b/lib/jasmine/headless/files_list.rb
@@ -1,44 +1,42 @@
require 'jasmine-core'
require 'time'
require 'multi_json'
-require 'set'
-require 'sprockets/directive_processor'
module Jasmine::Headless
class FilesList
- attr_reader :spec_outside_scope
-
class << self
- def find_vendored_asset_paths(*names)
+ def vendor_asset_paths
+ return @vendor_asset_paths if @vendor_asset_paths
+
require 'rubygems'
raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:map)
- all_spec_files.find_all do |file|
- names.any? { |name| file["/#{name}.js"] }
- end
- end
- def all_spec_files
- @all_spec_files ||= Gem::Specification.map { |spec| spec.files.find_all { |file|
- file["vendor/assets/javascripts"]
- }.compact.collect { |file| File.join(spec.gem_dir, file) } }.flatten
+ @vendor_asset_paths = []
+
+ Gem::Specification.map { |spec|
+ path = File.join(spec.gem_dir, 'vendor/assets/javascripts')
+
+ File.directory?(path) ? path : nil
+ }.compact
end
end
- DEFAULT_FILES =
- %w{jasmine.js jasmine-html.js jasmine.css}.collect { |name| File.join(Jasmine::Core.path, name) } +
- %w{jasmine-extensions intense headless_reporter_result jasmine.HeadlessConsoleReporter jsDump beautify-html}.collect { |name|
- Jasmine::Headless.root.join("vendor/assets/javascripts/#{name}.js").to_s
- }
+ DEFAULT_FILES = %w{jasmine.js jasmine-html jasmine.css jasmine-extensions intense headless_reporter_result jasmine.HeadlessConsoleReporter jsDump beautify-html}
PLEASE_WAIT_IM_WORKING_TIME = 2
def initialize(options = {})
@options = options
- @files = Set.new(DEFAULT_FILES.dup)
- @filtered_files = @files.dup
+
+ @files = []
+ @filtered_files = []
+
+ DEFAULT_FILES.each { |file| add_dependency('require', file) }
+
@spec_outside_scope = false
- @spec_files = Set.new
+ @spec_files = []
+
use_config! if config?
end
@@ -54,6 +52,10 @@ module Jasmine::Headless
@spec_files.to_a
end
+ def search_paths
+ @search_paths ||= [ Jasmine::Core.path, src_dir, spec_dir ] + self.class.vendor_asset_paths
+ end
+
def has_spec_outside_scope?
@spec_outside_scope
end
@@ -82,16 +84,35 @@ module Jasmine::Headless
}.compact]
end
- def add_dependencies(file)
- if File.file?(file)
- processor = Sprockets::DirectiveProcessor.new(file)
- processor.directives.each do |line, type, name|
- case type
- when 'require'
- find_vendored(name)
+ def add_dependencies(file, source_root)
+ TestFile.new(file, source_root).dependencies.each { |type, name| add_dependency(type, name) }
+ end
+
+ def add_dependency(type, file)
+ if result = find_dependency(file)
+ path, source_root = result
+
+ case type
+ when 'require'
+ add_file(path, source_root)
+ end
+ end
+ end
+
+ def find_dependency(file)
+ search_paths.each do |dir|
+ if file[%r{\.(js|css|coffee)$}]
+ if File.file?(path = File.join(dir, file))
+ return [ File.expand_path(path), dir ]
+ end
+ else
+ if path = Dir[File.join(dir, "#{file}.*")].first
+ return [ File.expand_path(path), dir ]
end
end
end
+
+ false
end
private
@@ -132,33 +153,23 @@ module Jasmine::Headless
@config = @options[:config].dup
- %w{src_files stylesheets vendored_helpers helpers spec_files}.each do |searches|
+ %w{src_files stylesheets helpers spec_files}.each do |searches|
if data = @config[searches]
- if self.respond_to?("add_#{searches}_files", true)
- send("add_#{searches}_files", data.flatten)
- else
- add_files(data.flatten, searches)
- end
- end
- end
- end
-
- def add_vendored_helpers_files(searches)
- searches.each do |name|
- self.class.find_vendored_asset_path(name).each do |file|
- add_file(file)
+ add_files(data.flatten, searches)
end
end
end
def add_files(searches, type)
searches.each do |search|
- path = search
- path = File.join(@config[SEARCH_ROOTS[type]], path) if @config[SEARCH_ROOTS[type]]
+ dir = @config[SEARCH_ROOTS[type]] || Dir.pwd
+
+ path = File.expand_path(File.join(dir, search))
+
found_files = expanded_dir(path) - files
found_files.each do |file|
- type == 'spec_files' ? add_spec_file(file) : add_file(file)
+ type == 'spec_files' ? add_spec_file(file) : add_file(file, dir)
end
end
@@ -177,22 +188,22 @@ module Jasmine::Headless
Dir[path].collect { |file| File.expand_path(file) }
end
- def add_file(file)
- add_dependencies(file)
+ def add_file(file, source_root)
+ add_dependencies(file, source_root)
- @files << file
- @filtered_files << file
+ @files << file if !@files.include?(file)
+ @filtered_files << file if !@filtered_files.include?(file)
end
def add_spec_file(file)
- add_dependencies(file)
+ add_dependencies(file, spec_dir)
if !@files.include?(file)
- @files << file
+ @files << file if !@files.include?(file)
if include_spec_file?(file)
- @filtered_files << file
- @spec_files << file if spec_filter.empty? || spec_filter.include?(file)
+ @filtered_files << file if !@filtered_files.include?(file)
+ @spec_files << file if !@spec_files.include?(file) && spec_filter.empty? || spec_filter.include?(file)
end
true
@@ -203,6 +214,23 @@ module Jasmine::Headless
spec_filter.empty? || spec_filter.include?(file)
end
+ def src_dir
+ config_dir_or_pwd('src_dir')
+ end
+
+ def spec_dir
+ config_dir_or_pwd('spec_dir')
+ end
+
+ def config_dir_or_pwd(dir)
+ found_dir = Dir.pwd
+
+ if @options[:config]
+ found_dir = @options[:config][dir] || found_dir
+ end
+
+ found_dir
+ end
end
end
diff --git a/lib/jasmine/headless/test_file.rb b/lib/jasmine/headless/test_file.rb
index cf12667..9605d2b 100644
--- a/lib/jasmine/headless/test_file.rb
+++ b/lib/jasmine/headless/test_file.rb
@@ -1,11 +1,12 @@
require 'rainbow'
+require 'sprockets/directive_processor'
module Jasmine::Headless
class TestFile
- attr_reader :path
+ attr_reader :path, :source_root
- def initialize(path)
- @path = path
+ def initialize(path, source_root = nil)
+ @path, @source_root = path, source_root
end
def ==(other)
@@ -27,7 +28,7 @@ module Jasmine::Headless
%{}
end
rescue CoffeeScript::CompilationError => ne
- puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), path.color(:yellow), ne.message.to_s.color(:white) ]
+ puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), path.color(:yellow), ne.message.dup.to_s.color(:white) ]
raise ne
rescue StandardError => e
puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), path.color(:yellow) ]
@@ -39,5 +40,19 @@ module Jasmine::Headless
%{}
end
end
+
+ def dependencies
+ return @dependencies if @dependencies
+
+ processor = Sprockets::DirectiveProcessor.new(path)
+ @dependencies = processor.directives.collect do |_, type, name|
+ if name[%r{^./}]
+ name = File.expand_path(File.join(File.dirname(path), name)).gsub(%r{^#{source_root}/}, '')
+ end
+
+ [ type, name ]
+ end
+ end
end
end
+
diff --git a/spec/bin/jasmine-headless-webkit_spec.rb b/spec/bin/jasmine-headless-webkit_spec.rb
index 9105391..e8fcbf9 100644
--- a/spec/bin/jasmine-headless-webkit_spec.rb
+++ b/spec/bin/jasmine-headless-webkit_spec.rb
@@ -144,14 +144,14 @@ describe "jasmine-headless-webkit" do
files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml}
$?.exitstatus.should == 0
- puts files
-
- files.lines.to_a.should include('vendor/assets/javascripts/jquery.js')
- files.lines.to_a.should include('assets/code.js')
- files.lines.to_a.should include('assets/required.js')
- files.lines.to_a.should include('assets/subcode/more_code.js')
- files.lines.to_a.should include('spec/spec_helper.js')
- files.lines.to_a.should include('spec/code_spec.js')
+ files.lines.to_a.should contain_in_order_in_file_list(
+ 'vendor/assets/javascripts/jquery.js',
+ 'assets/things/required.js',
+ 'assets/things/code.js',
+ 'assets/things/subcode/more_code.js',
+ 'spec_helper.js',
+ 'spec/things/code_spec.js'
+ )
end
end
end
diff --git a/spec/jasmine/with_sprockets_includes/assets/code.js b/spec/jasmine/with_sprockets_includes/assets/code.js
deleted file mode 100644
index bd8cb0d..0000000
--- a/spec/jasmine/with_sprockets_includes/assets/code.js
+++ /dev/null
@@ -1,2 +0,0 @@
-window.a = '1';
-
diff --git a/spec/jasmine/with_sprockets_includes/assets/required.js b/spec/jasmine/with_sprockets_includes/assets/required.js
deleted file mode 100644
index e69de29..0000000
diff --git a/spec/jasmine/with_sprockets_includes/assets/things/code.js b/spec/jasmine/with_sprockets_includes/assets/things/code.js
new file mode 100644
index 0000000..bb2e8ae
--- /dev/null
+++ b/spec/jasmine/with_sprockets_includes/assets/things/code.js
@@ -0,0 +1,4 @@
+//= require 'things/required'
+
+window.a = '1';
+
diff --git a/spec/jasmine/with_sprockets_includes/assets/things/required.js b/spec/jasmine/with_sprockets_includes/assets/things/required.js
new file mode 100644
index 0000000..18241c9
--- /dev/null
+++ b/spec/jasmine/with_sprockets_includes/assets/things/required.js
@@ -0,0 +1,2 @@
+//= require 'jquery'
+
diff --git a/spec/jasmine/with_sprockets_includes/assets/subcode/more_code.js b/spec/jasmine/with_sprockets_includes/assets/things/subcode/more_code.js
similarity index 100%
rename from spec/jasmine/with_sprockets_includes/assets/subcode/more_code.js
rename to spec/jasmine/with_sprockets_includes/assets/things/subcode/more_code.js
diff --git a/spec/jasmine/with_sprockets_includes/spec/code_spec.js b/spec/jasmine/with_sprockets_includes/spec/things/code_spec.js
similarity index 100%
rename from spec/jasmine/with_sprockets_includes/spec/code_spec.js
rename to spec/jasmine/with_sprockets_includes/spec/things/code_spec.js
diff --git a/spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml b/spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml
index 3b859d0..f5943f8 100644
--- a/spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml
+++ b/spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml
@@ -2,10 +2,10 @@ src_dir: spec/jasmine/with_sprockets_includes/assets
spec_dir: spec/jasmine/with_sprockets_includes/spec
spec_files:
- - "*_spec.js"
+ - "**/*_spec.js"
src_files:
- - "*.js"
+ - "things/**/*.js"
helpers:
- "spec_helper.js"
diff --git a/spec/lib/jasmine/headless/files_list_spec.rb b/spec/lib/jasmine/headless/files_list_spec.rb
index 2bf78ea..ec53257 100644
--- a/spec/lib/jasmine/headless/files_list_spec.rb
+++ b/spec/lib/jasmine/headless/files_list_spec.rb
@@ -46,7 +46,7 @@ describe Jasmine::Headless::FilesList do
shared_examples_for :reading_data do
let(:expected_files) do
- Jasmine::Headless::FilesList::DEFAULT_FILES + [
+ [
File.expand_path(first_file),
File.expand_path(src_file),
File.expand_path(stylesheet_file),
@@ -87,33 +87,6 @@ describe Jasmine::Headless::FilesList do
it_should_behave_like :reading_data
end
-
- context 'with vendored helpers' do
- let(:config) { {
- 'src_dir' => src_dir,
- 'spec_dir' => spec_dir,
- 'src_files' => [ 'js/first_file.js', 'js/*.js' ],
- 'spec_files' => [ '*_spec.js' ],
- 'helpers' => [],
- 'stylesheets' => [ 'stylesheet/*.css' ],
- 'vendored_helpers' => [ 'one', 'two' ]
- } }
-
- let(:helper_file) { "path/one.js" }
- let(:other_helper_file) { "path/two.js" }
-
- before do
- described_class.expects(:find_vendored_asset_path).with('one').returns([ helper_file ])
- described_class.expects(:find_vendored_asset_path).with('two').returns([ other_helper_file ])
- end
-
- it 'should find the vendored file' do
- files_list.files.should include(helper_file)
- files_list.files.should include(other_helper_file)
-
- files_list.files.index(helper_file).should be < files_list.files.index(other_helper_file)
- end
- end
end
context 'with filtered specs' do
@@ -248,46 +221,120 @@ describe Jasmine::Headless::FilesList do
end
end
- describe '#add_dependencies' do
- include FakeFS::SpecHelpers
-
- let(:file) { 'file.js' }
+ describe '#add_dependency' do
+ let(:file) { 'file' }
+ let(:other_file) { 'other' }
+ let(:path) { 'path' }
before do
- File.open(file, 'wb') { |fh| fh.print data }
+ files_list.stubs(:find_dependency).with(file).returns(path)
+ files_list.stubs(:find_dependency).with(other_file).returns(false)
end
- subject { files_list.add_dependencies(file) }
-
- context 'no requires' do
- let(:data) { 'javascript' }
-
+ context 'not found' do
before do
files_list.expects(:add_file).never
end
- it 'should succeed' do
- subject
+ it 'should do nothing' do
+ files_list.add_dependency('', other_file)
end
end
context 'require' do
- let(:data) { %{//= require 'other'\njavascript} }
-
before do
- File.open(other, 'wb')
+ files_list.expects(:add_file).with(path, nil)
end
- context 'with js' do
- let(:other) { 'other.js' }
+ it 'should add the file to the front' do
+ files_list.add_dependency('require', file)
+ end
+ end
+ end
- before do
- files_list.expects(:add_file).with(other)
- end
+ describe '#search_paths' do
+ let(:files_list) { described_class.new(:config => config) }
- it 'should succeed' do
- subject
- end
+ let(:config) { {
+ 'src_dir' => src_dir,
+ 'spec_dir' => spec_dir
+ } }
+
+ let(:src_dir) { 'src dir' }
+ let(:spec_dir) { 'spec dir' }
+ let(:path) { 'path' }
+
+ context 'no vendored gem paths' do
+ before do
+ Jasmine::Headless::FilesList.stubs(:vendor_asset_paths).returns([])
+ end
+
+ it 'should take the src dir and spec dirs' do
+ files_list.search_paths.should == [ Jasmine::Core.path, src_dir, spec_dir ]
+ end
+ end
+
+ context 'vendored gem paths' do
+ before do
+ Jasmine::Headless::FilesList.stubs(:vendor_asset_paths).returns([ path ])
+ end
+
+ it 'should add the vendor gem paths to the list' do
+ files_list.search_paths.should == [ Jasmine::Core.path, src_dir, spec_dir, path ]
+ end
+ end
+ end
+
+ describe '.vendor_asset_paths' do
+ include FakeFS::SpecHelpers
+
+ let(:dir_one) { 'dir_one' }
+ let(:dir_two) { 'dir_two' }
+
+ let(:gem_one) { stub(:gem_dir => dir_one) }
+ let(:gem_two) { stub(:gem_dir => dir_two) }
+
+ before do
+ described_class.instance_variable_set(:@vendor_asset_paths, nil)
+
+ FileUtils.mkdir_p File.join(dir_two, 'vendor/assets/javascripts')
+
+ Gem::Specification.stubs(:_all).returns([gem_one, gem_two])
+ end
+
+ it 'should return all matching gems with vendor/assets/javascripts directories' do
+ described_class.vendor_asset_paths.should == [ File.join(dir_two, 'vendor/assets/javascripts') ]
+ end
+ end
+
+ describe '#find_dependency' do
+ include FakeFS::SpecHelpers
+
+ let(:dir) { File.expand_path('dir') }
+ let(:filename) { 'file' }
+ let(:file) { "#{filename}.js" }
+
+ before do
+ files_list.stubs(:search_paths).returns([ dir ])
+
+ FileUtils.mkdir_p dir
+ end
+
+ context 'does not exist' do
+ it 'should not be found' do
+ files_list.find_dependency(file).should be_false
+ end
+ end
+
+ context 'exists' do
+ let(:path) { File.join(dir, file) }
+
+ before do
+ File.open(path, 'wb')
+ end
+
+ it 'should be found' do
+ files_list.find_dependency(filename).should == [ File.expand_path(path), dir ]
end
end
end
diff --git a/spec/lib/jasmine/headless/test_file_spec.rb b/spec/lib/jasmine/headless/test_file_spec.rb
index f916d9a..8758ba0 100644
--- a/spec/lib/jasmine/headless/test_file_spec.rb
+++ b/spec/lib/jasmine/headless/test_file_spec.rb
@@ -1,8 +1,10 @@
require 'spec_helper'
describe Jasmine::Headless::TestFile do
- let(:file) { described_class.new(path) }
- let(:path) { 'path' }
+ let(:source_root) { File.expand_path('source_root') }
+ let(:path) { File.join(source_root, 'path.js') }
+
+ let(:file) { described_class.new(path, source_root) }
subject { file }
@@ -36,7 +38,7 @@ describe Jasmine::Headless::TestFile do
end
it 'should pass along the error' do
- expect { subject }.to raise_error(error)
+ expect { subject }.to raise_error(CoffeeScript::CompilationError)
end
end
@@ -71,4 +73,31 @@ describe Jasmine::Headless::TestFile do
end
end
end
+
+ describe '#dependencies' do
+ include FakeFS::SpecHelpers
+
+ before do
+ FileUtils.mkdir_p File.dirname(path)
+ File.open(path, 'wb') { |fh| fh.print "//= require '#{req}'\njavascript" }
+ end
+
+ context 'absolute' do
+ let(:req) { 'test' }
+
+ subject { file.dependencies }
+
+ it { should == [ [ 'require', req ] ] }
+ end
+
+ context 'relative' do
+ let(:path) { File.join(source_root, 'subdir/subsubdir/path.js') }
+
+ let(:req) { './test' }
+
+ subject { file.dependencies }
+
+ it { should == [ [ 'require', 'subdir/subsubdir/test' ] ] }
+ end
+ end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 2348573..0066121 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -6,6 +6,7 @@ RSpec.configure do |c|
c.before(:each) do
Jasmine::Headless::CacheableAction.enabled = false
+ Jasmine::Headless::FilesList.instance_variable_set(:@vendor_asset_paths, nil)
end
end
@@ -51,4 +52,21 @@ module RSpec::Matchers
File.file?(file)
end
end
+
+ define :contain_in_order_in_file_list do |*files|
+ match do |lines|
+ file_list = files.dup
+
+ lines.each do |line|
+ next if !file_list.first
+
+ if line[file_list.first]
+ file_list.shift
+ end
+ end
+
+ file_list.length == 0
+ end
+ end
end
+