diff --git a/lib/jasmine/headless/files_list.rb b/lib/jasmine/headless/files_list.rb index 97b05d3..5c8f8be 100644 --- a/lib/jasmine/headless/files_list.rb +++ b/lib/jasmine/headless/files_list.rb @@ -1,10 +1,12 @@ require 'jasmine-core' require 'time' require 'multi_json' +require 'set' +require 'sprockets/directive_processor' module Jasmine::Headless class FilesList - attr_reader :files, :spec_files, :filtered_files, :spec_outside_scope + attr_reader :spec_outside_scope class << self def find_vendored_asset_paths(*names) @@ -23,25 +25,35 @@ module Jasmine::Headless end end - DEFAULT_FILES = [ - File.join(Jasmine::Core.path, "jasmine.js"), - File.join(Jasmine::Core.path, "jasmine-html.js"), - File.join(Jasmine::Core.path, "jasmine.css") - ] + %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.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 def initialize(options = {}) @options = options - @files = DEFAULT_FILES.dup + @files = Set.new(DEFAULT_FILES.dup) @filtered_files = @files.dup @spec_outside_scope = false - @spec_files = [] + @spec_files = Set.new use_config! if config? end + def files + @files.to_a + end + + def filtered_files + @filtered_files.to_a + end + + def spec_files + @spec_files.to_a + end + def has_spec_outside_scope? @spec_outside_scope end @@ -60,7 +72,7 @@ module Jasmine::Headless def spec_file_line_numbers @spec_file_line_numbers ||= Hash[@spec_files.collect { |file| - if ::File.exist?(file) + if File.exist?(file) if !(lines = Jasmine::Headless::SpecFileAnalyzer.for(file)).empty? [ file, lines ] end @@ -70,6 +82,18 @@ 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) + end + end + end + end + private def to_html(files) alert_time = Time.now + PLEASE_WAIT_IM_WORKING_TIME @@ -80,37 +104,7 @@ module Jasmine::Headless alert_time = nil end - source = nil - - next file.to_html - - result = case File.extname(file) - when '.coffee' - begin - cache = Jasmine::Headless::CoffeeScriptCache.new(file) - source = cache.handle - if cache.cached? - %{ - } - else - %{} - end - rescue CoffeeScript::CompilationError => ne - puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), file.color(:yellow), ne.message.to_s.color(:white) ] - raise ne - rescue StandardError => e - puts "[%s] Error in compiling one of the followng: %s" % [ 'coffeescript'.color(:red), files.join(' ').color(:yellow) ] - raise e - end - when '.js' - %{} - when '.css' - %{} - end - - result + Jasmine::Headless::TestFile.new(file).to_html }.flatten.compact.reject(&:empty?) end @@ -126,47 +120,53 @@ module Jasmine::Headless end end + SEARCH_ROOTS = { + 'src_files' => 'src_dir', + 'stylesheets' => 'src_dir', + 'helpers' => 'spec_dir', + 'spec_files' => 'spec_dir' + } + def use_config! @filtered_files = @files.dup - data = @options[:config].dup - [ [ 'src_files', 'src_dir' ], [ 'stylesheets', 'src_dir' ], [ 'vendored_helpers' ], [ 'helpers', 'spec_dir' ], [ 'spec_files', 'spec_dir' ] ].each do |searches, root| - if data[searches] - case searches - when 'vendored_helpers' - data[searches].each do |name| - found_files = self.class.find_vendored_asset_path(name) + @config = @options[:config].dup - @files += found_files - @filtered_files += found_files - end + %w{src_files stylesheets vendored_helpers 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 - data[searches].flatten.collect do |search| - path = search - path = File.join(data[root], path) if data[root] - found_files = expanded_dir(path) - @files - - @files += found_files - - if searches == 'spec_files' - @spec_files += spec_filter.empty? ? found_files : (found_files & spec_filter) - end - - @filtered_files += begin - if searches == 'spec_files' - @spec_outside_scope = ((spec_filter | found_files).sort != found_files.sort) - spec_filter.empty? ? found_files : (spec_filter || found_files) - else - found_files - end - end - end + add_files(data.flatten, searches) end end end + end - @files.collect! { |file| Jasmine::Headless::TestFile.new(file) } - @filtered_files.collect! { |file| Jasmine::Headless::TestFile.new(file) } + 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) + searches.each do |search| + path = search + path = File.join(@config[SEARCH_ROOTS[type]], path) if @config[SEARCH_ROOTS[type]] + found_files = expanded_dir(path) - files + + found_files.each do |file| + type == 'spec_files' ? add_spec_file(file) : add_file(file) + end + end + + if type == 'spec_files' + spec_filter.each do |file| + @spec_outside_scope ||= add_spec_file(file) + end + end end def config? @@ -176,6 +176,33 @@ module Jasmine::Headless def expanded_dir(path) Dir[path].collect { |file| File.expand_path(file) } end + + def add_file(file) + add_dependencies(file) + + @files << file + @filtered_files << file + end + + def add_spec_file(file) + add_dependencies(file) + + if !@files.include?(file) + @files << file + + if include_spec_file?(file) + @filtered_files << file + @spec_files << file if spec_filter.empty? || spec_filter.include?(file) + end + + true + end + end + + def include_spec_file?(file) + spec_filter.empty? || spec_filter.include?(file) + end + end end diff --git a/lib/jasmine/headless/test_file.rb b/lib/jasmine/headless/test_file.rb index afaeac3..cf12667 100644 --- a/lib/jasmine/headless/test_file.rb +++ b/lib/jasmine/headless/test_file.rb @@ -1,3 +1,5 @@ +require 'rainbow' + module Jasmine::Headless class TestFile attr_reader :path @@ -5,5 +7,37 @@ module Jasmine::Headless def initialize(path) @path = path end + + def ==(other) + self.path == other.path + end + + def to_html + case File.extname(path) + when '.coffee' + begin + cache = Jasmine::Headless::CoffeeScriptCache.new(path) + source = cache.handle + if cache.cached? + %{ + } + else + %{} + end + rescue CoffeeScript::CompilationError => ne + puts "[%s] %s: %s" % [ 'coffeescript'.color(:red), path.color(:yellow), ne.message.to_s.color(:white) ] + raise ne + rescue StandardError => e + puts "[%s] Error in compiling file: %s" % [ 'coffeescript'.color(:red), path.color(:yellow) ] + raise e + end + when '.js' + %{} + when '.css' + %{} + end + end end end diff --git a/spec/lib/jasmine/headless/files_list_spec.rb b/spec/lib/jasmine/headless/files_list_spec.rb index b5674bc..2bf78ea 100644 --- a/spec/lib/jasmine/headless/files_list_spec.rb +++ b/spec/lib/jasmine/headless/files_list_spec.rb @@ -45,14 +45,18 @@ describe Jasmine::Headless::FilesList do end shared_examples_for :reading_data do - it 'should read the data from the jasmine.yml file and add the files' do - files_list.files.should == Jasmine::Headless::FilesList::DEFAULT_FILES + [ + let(:expected_files) do + Jasmine::Headless::FilesList::DEFAULT_FILES + [ File.expand_path(first_file), File.expand_path(src_file), File.expand_path(stylesheet_file), File.expand_path(helper_file), File.expand_path(spec_file) ] + end + + it 'should read the data from the jasmine.yml file and add the files' do + files_list.files.should == expected_files files_list.spec_files.should == [ File.expand_path(spec_file) ] end @@ -243,5 +247,49 @@ describe Jasmine::Headless::FilesList do } end end + + describe '#add_dependencies' do + include FakeFS::SpecHelpers + + let(:file) { 'file.js' } + + before do + File.open(file, 'wb') { |fh| fh.print data } + end + + subject { files_list.add_dependencies(file) } + + context 'no requires' do + let(:data) { 'javascript' } + + before do + files_list.expects(:add_file).never + end + + it 'should succeed' do + subject + end + end + + context 'require' do + let(:data) { %{//= require 'other'\njavascript} } + + before do + File.open(other, 'wb') + end + + context 'with js' do + let(:other) { 'other.js' } + + before do + files_list.expects(:add_file).with(other) + end + + it 'should succeed' do + subject + end + end + end + end end diff --git a/spec/lib/jasmine/headless/template_writer_spec.rb b/spec/lib/jasmine/headless/template_writer_spec.rb index 25a9cc6..a6e8579 100644 --- a/spec/lib/jasmine/headless/template_writer_spec.rb +++ b/spec/lib/jasmine/headless/template_writer_spec.rb @@ -53,7 +53,7 @@ describe Jasmine::Headless::TemplateWriter do runner.stubs(:runner_filename).returns(false) end - let(:files_list) { Jasmine::FilesList.new } + let(:files_list) { Jasmine::Headless::FilesList.new } before do files_list.files << 'file.js' @@ -70,7 +70,7 @@ describe Jasmine::Headless::TemplateWriter do context 'filtered files' do before do - files_list.files << 'file2.js' + files_list.instance_variable_get(:@files) << 'file2.js' end it 'should write two files' do diff --git a/spec/lib/jasmine/headless/test_file_spec.rb b/spec/lib/jasmine/headless/test_file_spec.rb index 8a25edc..f916d9a 100644 --- a/spec/lib/jasmine/headless/test_file_spec.rb +++ b/spec/lib/jasmine/headless/test_file_spec.rb @@ -20,7 +20,7 @@ describe Jasmine::Headless::TestFile do context '.css' do let(:path) { 'path.css' } - it { should == %{} } + it { should == %{} } end context '.coffee' do @@ -32,7 +32,7 @@ describe Jasmine::Headless::TestFile do let(:error) { CoffeeScript::CompilationError.new("fail") } before do - handle_exception.raises(error) + handle_expectation.raises(error) end it 'should pass along the error' do @@ -41,10 +41,32 @@ describe Jasmine::Headless::TestFile do end context 'compiles fine' do - let(:cached_expectation) { Jasmine::Headless::CoffeeScriptCache.any_instance.stubs(:cached?).returns(cache_return) } + let(:source) { 'source' } before do + Jasmine::Headless::CoffeeScriptCache.any_instance.stubs(:cached?).returns(cache_return) + handle_expectation.returns(source) + end + context 'cached' do + let(:file_path) { 'dir/file.js' } + let(:cache_return) { true } + + before do + Jasmine::Headless::CoffeeScriptCache.any_instance.stubs(:cache_file).returns(file_path) + end + + it 'should return the cached file' do + subject.should include(%{}) + end + end + + context 'not cached' do + let(:cache_return) { false } + + it 'should return the generated js' do + subject.should include(%{}) + end end end end