require works, whoa

This commit is contained in:
John Bintz 2011-11-17 22:16:04 -05:00
parent 1583807c14
commit a2e3ea90c9
13 changed files with 264 additions and 123 deletions

View File

@ -1,44 +1,42 @@
require 'jasmine-core' require 'jasmine-core'
require 'time' require 'time'
require 'multi_json' require 'multi_json'
require 'set'
require 'sprockets/directive_processor'
module Jasmine::Headless module Jasmine::Headless
class FilesList class FilesList
attr_reader :spec_outside_scope
class << self class << self
def find_vendored_asset_paths(*names) def vendor_asset_paths
return @vendor_asset_paths if @vendor_asset_paths
require 'rubygems' require 'rubygems'
raise StandardError.new("A newer version of Rubygems is required to use vendored assets. Please upgrade.") if !Gem::Specification.respond_to?(:map) 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"] } @vendor_asset_paths = []
Gem::Specification.map { |spec|
path = File.join(spec.gem_dir, 'vendor/assets/javascripts')
File.directory?(path) ? path : nil
}.compact
end end
end end
def all_spec_files DEFAULT_FILES = %w{jasmine.js jasmine-html jasmine.css jasmine-extensions intense headless_reporter_result jasmine.HeadlessConsoleReporter jsDump beautify-html}
@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
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
}
PLEASE_WAIT_IM_WORKING_TIME = 2 PLEASE_WAIT_IM_WORKING_TIME = 2
def initialize(options = {}) def initialize(options = {})
@options = 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_outside_scope = false
@spec_files = Set.new @spec_files = []
use_config! if config? use_config! if config?
end end
@ -54,6 +52,10 @@ module Jasmine::Headless
@spec_files.to_a @spec_files.to_a
end end
def search_paths
@search_paths ||= [ Jasmine::Core.path, src_dir, spec_dir ] + self.class.vendor_asset_paths
end
def has_spec_outside_scope? def has_spec_outside_scope?
@spec_outside_scope @spec_outside_scope
end end
@ -82,16 +84,35 @@ module Jasmine::Headless
}.compact] }.compact]
end end
def add_dependencies(file) def add_dependencies(file, source_root)
if File.file?(file) TestFile.new(file, source_root).dependencies.each { |type, name| add_dependency(type, name) }
processor = Sprockets::DirectiveProcessor.new(file) end
processor.directives.each do |line, type, name|
def add_dependency(type, file)
if result = find_dependency(file)
path, source_root = result
case type case type
when 'require' when 'require'
find_vendored(name) add_file(path, source_root)
end end
end 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 end
private private
@ -132,33 +153,23 @@ module Jasmine::Headless
@config = @options[:config].dup @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 data = @config[searches]
if self.respond_to?("add_#{searches}_files", true)
send("add_#{searches}_files", data.flatten)
else
add_files(data.flatten, searches) add_files(data.flatten, searches)
end end
end 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)
end
end
end
def add_files(searches, type) def add_files(searches, type)
searches.each do |search| searches.each do |search|
path = search dir = @config[SEARCH_ROOTS[type]] || Dir.pwd
path = File.join(@config[SEARCH_ROOTS[type]], path) if @config[SEARCH_ROOTS[type]]
path = File.expand_path(File.join(dir, search))
found_files = expanded_dir(path) - files found_files = expanded_dir(path) - files
found_files.each do |file| 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
end end
@ -177,22 +188,22 @@ module Jasmine::Headless
Dir[path].collect { |file| File.expand_path(file) } Dir[path].collect { |file| File.expand_path(file) }
end end
def add_file(file) def add_file(file, source_root)
add_dependencies(file) add_dependencies(file, source_root)
@files << file @files << file if !@files.include?(file)
@filtered_files << file @filtered_files << file if !@filtered_files.include?(file)
end end
def add_spec_file(file) def add_spec_file(file)
add_dependencies(file) add_dependencies(file, spec_dir)
if !@files.include?(file) if !@files.include?(file)
@files << file @files << file if !@files.include?(file)
if include_spec_file?(file) if include_spec_file?(file)
@filtered_files << file @filtered_files << file if !@filtered_files.include?(file)
@spec_files << file if spec_filter.empty? || spec_filter.include?(file) @spec_files << file if !@spec_files.include?(file) && spec_filter.empty? || spec_filter.include?(file)
end end
true true
@ -203,6 +214,23 @@ module Jasmine::Headless
spec_filter.empty? || spec_filter.include?(file) spec_filter.empty? || spec_filter.include?(file)
end 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
end end

View File

@ -1,11 +1,12 @@
require 'rainbow' require 'rainbow'
require 'sprockets/directive_processor'
module Jasmine::Headless module Jasmine::Headless
class TestFile class TestFile
attr_reader :path attr_reader :path, :source_root
def initialize(path) def initialize(path, source_root = nil)
@path = path @path, @source_root = path, source_root
end end
def ==(other) def ==(other)
@ -27,7 +28,7 @@ module Jasmine::Headless
%{<script type="text/javascript">#{source}</script>} %{<script type="text/javascript">#{source}</script>}
end end
rescue CoffeeScript::CompilationError => ne 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 raise ne
rescue StandardError => e rescue StandardError => e
puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), path.color(:yellow) ] puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), path.color(:yellow) ]
@ -39,5 +40,19 @@ module Jasmine::Headless
%{<link rel="stylesheet" href="#{path}" type="text/css" />} %{<link rel="stylesheet" href="#{path}" type="text/css" />}
end end
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
end
end

View File

@ -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} files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/with_sprockets_includes/with_sprockets_includes.yml}
$?.exitstatus.should == 0 $?.exitstatus.should == 0
puts files files.lines.to_a.should contain_in_order_in_file_list(
'vendor/assets/javascripts/jquery.js',
files.lines.to_a.should include('vendor/assets/javascripts/jquery.js') 'assets/things/required.js',
files.lines.to_a.should include('assets/code.js') 'assets/things/code.js',
files.lines.to_a.should include('assets/required.js') 'assets/things/subcode/more_code.js',
files.lines.to_a.should include('assets/subcode/more_code.js') 'spec_helper.js',
files.lines.to_a.should include('spec/spec_helper.js') 'spec/things/code_spec.js'
files.lines.to_a.should include('spec/code_spec.js') )
end end
end end
end end

View File

@ -1,2 +0,0 @@
window.a = '1';

View File

@ -0,0 +1,4 @@
//= require 'things/required'
window.a = '1';

View File

@ -0,0 +1,2 @@
//= require 'jquery'

View File

@ -2,10 +2,10 @@ src_dir: spec/jasmine/with_sprockets_includes/assets
spec_dir: spec/jasmine/with_sprockets_includes/spec spec_dir: spec/jasmine/with_sprockets_includes/spec
spec_files: spec_files:
- "*_spec.js" - "**/*_spec.js"
src_files: src_files:
- "*.js" - "things/**/*.js"
helpers: helpers:
- "spec_helper.js" - "spec_helper.js"

View File

@ -46,7 +46,7 @@ describe Jasmine::Headless::FilesList do
shared_examples_for :reading_data do shared_examples_for :reading_data do
let(:expected_files) do let(:expected_files) do
Jasmine::Headless::FilesList::DEFAULT_FILES + [ [
File.expand_path(first_file), File.expand_path(first_file),
File.expand_path(src_file), File.expand_path(src_file),
File.expand_path(stylesheet_file), File.expand_path(stylesheet_file),
@ -87,33 +87,6 @@ describe Jasmine::Headless::FilesList do
it_should_behave_like :reading_data it_should_behave_like :reading_data
end 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 end
context 'with filtered specs' do context 'with filtered specs' do
@ -248,47 +221,121 @@ describe Jasmine::Headless::FilesList do
end end
end end
describe '#add_dependencies' do describe '#add_dependency' do
include FakeFS::SpecHelpers let(:file) { 'file' }
let(:other_file) { 'other' }
let(:file) { 'file.js' } let(:path) { 'path' }
before do 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 end
subject { files_list.add_dependencies(file) } context 'not found' do
context 'no requires' do
let(:data) { 'javascript' }
before do before do
files_list.expects(:add_file).never files_list.expects(:add_file).never
end end
it 'should succeed' do it 'should do nothing' do
subject files_list.add_dependency('', other_file)
end end
end end
context 'require' do context 'require' do
let(:data) { %{//= require 'other'\njavascript} } before do
files_list.expects(:add_file).with(path, nil)
end
it 'should add the file to the front' do
files_list.add_dependency('require', file)
end
end
end
describe '#search_paths' do
let(:files_list) { described_class.new(:config => config) }
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 before do
File.open(other, 'wb') 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 end
context 'with js' do it 'should return all matching gems with vendor/assets/javascripts directories' do
let(:other) { 'other.js' } 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 before do
files_list.expects(:add_file).with(other) files_list.stubs(:search_paths).returns([ dir ])
FileUtils.mkdir_p dir
end end
it 'should succeed' do context 'does not exist' do
subject it 'should not be found' do
files_list.find_dependency(file).should be_false
end end
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
end end
end end

View File

@ -1,8 +1,10 @@
require 'spec_helper' require 'spec_helper'
describe Jasmine::Headless::TestFile do describe Jasmine::Headless::TestFile do
let(:file) { described_class.new(path) } let(:source_root) { File.expand_path('source_root') }
let(:path) { 'path' } let(:path) { File.join(source_root, 'path.js') }
let(:file) { described_class.new(path, source_root) }
subject { file } subject { file }
@ -36,7 +38,7 @@ describe Jasmine::Headless::TestFile do
end end
it 'should pass along the error' do it 'should pass along the error' do
expect { subject }.to raise_error(error) expect { subject }.to raise_error(CoffeeScript::CompilationError)
end end
end end
@ -71,4 +73,31 @@ describe Jasmine::Headless::TestFile do
end end
end 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 end

View File

@ -6,6 +6,7 @@ RSpec.configure do |c|
c.before(:each) do c.before(:each) do
Jasmine::Headless::CacheableAction.enabled = false Jasmine::Headless::CacheableAction.enabled = false
Jasmine::Headless::FilesList.instance_variable_set(:@vendor_asset_paths, nil)
end end
end end
@ -51,4 +52,21 @@ module RSpec::Matchers
File.file?(file) File.file?(file)
end end
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
end
file_list.length == 0
end
end
end