diff --git a/Rakefile b/Rakefile index d13a827..db8bed4 100644 --- a/Rakefile +++ b/Rakefile @@ -9,6 +9,7 @@ RSpec::Core::RakeTask.new(:spec) $: << File.expand_path('../lib', __FILE__) +require 'jasmine-headless-webkit' require 'jasmine/headless/task' Jasmine::Headless::Task.new diff --git a/bin/jasmine-headless-webkit b/bin/jasmine-headless-webkit index a38610d..8d48998 100755 --- a/bin/jasmine-headless-webkit +++ b/bin/jasmine-headless-webkit @@ -8,6 +8,7 @@ def gem_dir end $:.unshift(File.join(gem_dir, 'lib')) +require 'jasmine-headless-webkit' require 'jasmine/headless/errors' require 'jasmine/headless/runner' require 'jasmine/headless/options' diff --git a/lib/jasmine-headless-webkit.rb b/lib/jasmine-headless-webkit.rb index 0ca38a4..9626790 100644 --- a/lib/jasmine-headless-webkit.rb +++ b/lib/jasmine-headless-webkit.rb @@ -1,6 +1,8 @@ module Jasmine module Headless autoload :CoffeeScriptCache, 'jasmine/headless/coffee_script_cache' + autoload :SpecFileAnalyzer, 'jasmine/headless/spec_file_analyzer' + autoload :CacheableAction, 'jasmine/headless/cacheable_action' end end diff --git a/lib/jasmine/files_list.rb b/lib/jasmine/files_list.rb index 21ed3ce..def12b8 100644 --- a/lib/jasmine/files_list.rb +++ b/lib/jasmine/files_list.rb @@ -12,22 +12,6 @@ module Jasmine File.expand_path('../../../jasmine/jasmine.headless-reporter.js', __FILE__) ] - class << self - def get_spec_line_numbers(file) - line_numbers = {} - - ic = Iconv.new('UTF-8//IGNORE', 'UTF-8') - file.lines.each_with_index.each { |line, index| - line = ic.iconv(line + ' ')[0..-2] - if description = line[%r{(describe|context|it)[( ]*(["'])(.*)\2}, 3] - (line_numbers[description] ||= []) << (index + 1) - end - } - - line_numbers - end - end - def initialize(options = {}) @options = options @files = DEFAULT_FILES.dup @@ -56,7 +40,7 @@ module Jasmine def spec_file_line_numbers @spec_file_line_numbers ||= Hash[@spec_files.collect { |file| if File.exist?(file) - if !(lines = self.class.get_spec_line_numbers(File.read(file))).empty? + if !(lines = Jasmine::Headless::SpecFileAnalyzer.for(file)).empty? [ file, lines ] end else @@ -105,7 +89,7 @@ module Jasmine @files += found_files if searches == 'spec_files' - @spec_files = @files + spec_filter + @spec_files += spec_filter end @filtered_files += (if searches == 'spec_files' diff --git a/lib/jasmine/headless/cacheable_action.rb b/lib/jasmine/headless/cacheable_action.rb new file mode 100644 index 0000000..1b7e474 --- /dev/null +++ b/lib/jasmine/headless/cacheable_action.rb @@ -0,0 +1,77 @@ +module Jasmine::Headless + class CacheableAction + class << self + def enabled=(bool) + @enabled = bool + end + + def enabled? + @enabled = true if @enabled == nil + @enabled + end + + def cache_type + raise ArgumentError.new("No cache type defined for #{self.name}") if @cache_type == nil + @cache_type + end + + def cache_type=(type) + @cache_type = type + end + + def cache_dir=(dir) + @cache_dir = dir + end + + def cache_dir + @cache_dir ||= '.jhw-cache' + end + + def for(file) + new(file).handle + end + end + + attr_reader :file + + def initialize(file) + @file = file + end + + def handle + if CacheableAction.enabled? + if fresh? + unserialize(File.read(cache_file)) + else + result = action + FileUtils.mkdir_p File.split(cache_file).first + File.open(cache_file, 'wb') { |fh| fh.print serialize(result) } + result + end + else + action + end + end + + def cache_file + @cache_file ||= File.join(self.class.cache_dir, self.class.cache_type, Digest::SHA1.hexdigest(file)) + end + + def fresh? + File.exist?(cache_file) && (File.mtime(file) < File.mtime(cache_file)) + end + + def action + raise StandardError.new("Override action") + end + + def serialize(data) + data + end + + def unserialize(data) + data + end + end +end + diff --git a/lib/jasmine/headless/coffee_script_cache.rb b/lib/jasmine/headless/coffee_script_cache.rb index 5a1b103..5ae5efe 100644 --- a/lib/jasmine/headless/coffee_script_cache.rb +++ b/lib/jasmine/headless/coffee_script_cache.rb @@ -4,60 +4,14 @@ require 'fileutils' module Jasmine module Headless - class CoffeeScriptCache + class CoffeeScriptCache < CacheableAction class << self - def enabled=(bool) - @enabled = bool - end - - def enabled? - @enabled = true if @enabled == nil - @enabled - end - - def cache_dir=(dir) - @cache_dir = dir - end - - def cache_dir - @cache_dir ||= '.jhw-cache' - end - - def for(file) - new(file).handle + def cache_type + "coffee_script" end end - attr_reader :file - - def initialize(file) - @file = file - end - - def handle - if self.class.enabled? - if fresh? - File.read(cache_file) - else - result = compile - FileUtils.mkdir_p self.class.cache_dir - File.open(cache_file, 'wb') { |fh| fh.print result } - result - end - else - compile - end - end - - def cache_file - @cache_file ||= File.join(self.class.cache_dir, Digest::SHA1.hexdigest(file)) - end - - def fresh? - File.exist?(cache_file) && (File.mtime(file) < File.mtime(cache_file)) - end - - def compile + def action CoffeeScript.compile(File.read(file)) end end diff --git a/lib/jasmine/headless/runner.rb b/lib/jasmine/headless/runner.rb index 7f7613b..672a8c6 100644 --- a/lib/jasmine/headless/runner.rb +++ b/lib/jasmine/headless/runner.rb @@ -61,7 +61,7 @@ module Jasmine end def run - Jasmine::Headless::CoffeeScriptCache.enabled = @options[:enable_cache] + Jasmine::Headless::CacheableAction.enabled = @options[:enable_cache] files_list = Jasmine::FilesList.new( :config => jasmine_config, diff --git a/lib/jasmine/headless/spec_file_analyzer.rb b/lib/jasmine/headless/spec_file_analyzer.rb new file mode 100644 index 0000000..252b067 --- /dev/null +++ b/lib/jasmine/headless/spec_file_analyzer.rb @@ -0,0 +1,37 @@ +require 'iconv' +require 'multi_json' + +module Jasmine::Headless + class SpecFileAnalyzer < CacheableAction + class << self + def cache_type + "spec_file_analysis" + end + end + + def action + line_numbers = {} + + ic = Iconv.new('UTF-8//IGNORE', 'US-ASCII') + data = ic.iconv(File.read(file) + ' ')[0..-2] + data.force_encoding('US-ASCII') if data.respond_to?(:force_encoding) + + data.lines.each_with_index.each { |line, index| + if description = line[%r{(describe|context|it)[( ]*(["'])(.*)\2}, 3] + (line_numbers[description] ||= []) << (index + 1) + end + } + + line_numbers + end + + def serialize(data) + MultiJson.encode(data) + end + + def unserialize(data) + MultiJson.decode(data) + end + end +end + diff --git a/spec/bin/jasmine-headless-webkit_spec.rb b/spec/bin/jasmine-headless-webkit_spec.rb index 37a4fbf..9bd3765 100644 --- a/spec/bin/jasmine-headless-webkit_spec.rb +++ b/spec/bin/jasmine-headless-webkit_spec.rb @@ -120,7 +120,6 @@ describe "jasmine-headless-webkit" do describe 'files' do it 'should list all the files that will be found' do files = %x{bin/jasmine-headless-webkit -l -j spec/jasmine/success/success.yml} - p files $?.exitstatus.should == 0 files.lines.to_a.should include("./spec/jasmine/success/success.js\n") diff --git a/spec/lib/jasmine/files_list_spec.rb b/spec/lib/jasmine/files_list_spec.rb index 9daaade..39bc53a 100644 --- a/spec/lib/jasmine/files_list_spec.rb +++ b/spec/lib/jasmine/files_list_spec.rb @@ -182,50 +182,6 @@ describe Jasmine::FilesList do end end - describe '.get_spec_line_numbers' do - let(:line_numbers) do - described_class.get_spec_line_numbers(file) - end - - context 'coffeescript' do - let(:file) do - <<-SPEC -describe 'test', -> - context 'yes', -> - it 'should do something', -> - "yes" - "PR.registerLangHandler(PR.createSimpleLexer([[\"com\",/^#[^\\n\\r]*/,null,\"#\"],[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \xC2\\xa0\"],[\"str\",/^\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$)/,null,'\"']],[[\"kwd\",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\\s/,\n" - SPEC - end - - it 'should get the line numbers' do - line_numbers['test'].should == [ 1 ] - line_numbers['yes'].should == [ 2 ] - line_numbers['should do something'].should == [ 3 ] - end - end - - context 'javascript' do - let(:file) do - <<-SPEC -describe('test', function() { - context('yes', function() { - it('should do something', function() { - - }); - }); -}); - SPEC - end - - it 'should get the line numbers' do - line_numbers['test'].should == [ 1 ] - line_numbers['yes'].should == [ 2 ] - line_numbers['should do something'].should == [ 3 ] - end - end - end - describe '#spec_file_line_numbers' do include FakeFS::SpecHelpers diff --git a/spec/lib/jasmine/headless/cacheable_action_spec.rb b/spec/lib/jasmine/headless/cacheable_action_spec.rb new file mode 100644 index 0000000..5e55a91 --- /dev/null +++ b/spec/lib/jasmine/headless/cacheable_action_spec.rb @@ -0,0 +1,88 @@ +require 'spec_helper' + +describe Jasmine::Headless::CacheableAction do + include FakeFS::SpecHelpers + + let(:file) { 'file.whatever' } + let(:data) { 'data' } + let(:compiled) { 'compiled' } + + before do + File.open(file, 'wb') { |fh| fh.print(data) } + described_class.cache_dir = cache_dir + described_class.cache_type = cache_type + end + + let(:action_runs!) do + described_class.any_instance.expects(:action).returns(compiled) + end + + let(:cache_type) { 'action' } + let(:cache_dir) { 'cache' } + let(:cache_file) { File.join(cache_dir, cache_type, Digest::SHA1.hexdigest(file)) } + let(:cache_file_data) { YAML.load(File.read(cache_file)) } + + describe '.for' do + context 'cache disabled' do + before do + described_class.enabled = false + end + + it 'should compile' do + action_runs! + described_class.for(file).should == compiled + cache_file.should_not be_a_file + end + end + + context 'cache enabled' do + before do + described_class.enabled = true + FileUtils.mkdir_p(cache_dir) + + File.stubs(:mtime).with(file).returns(Time.at(10)) + File.stubs(:mtime).with(cache_file).returns(Time.at(cache_file_mtime)) + end + + context 'cache empty' do + let(:cache_file_mtime) { 0 } + + it 'should compile' do + action_runs! + described_class.for(file).should == compiled + + cache_file_data.should == compiled + end + end + + context 'cache fresh' do + let(:cache_file_mtime) { 15 } + + before do + File.open(cache_file, 'wb') { |fh| fh.print compiled } + end + + it 'should not compile' do + action_runs!.never + + described_class.for(file).should == compiled + + cache_file_data.should == compiled + end + end + + context 'cache stale' do + let(:cache_file_mtime) { 5 } + + it 'should compile' do + action_runs! + + described_class.for(file).should == compiled + + cache_file_data.should == compiled + end + end + end + end +end + diff --git a/spec/lib/jasmine/headless/coffee_script_cache_spec.rb b/spec/lib/jasmine/headless/coffee_script_cache_spec.rb index 9629a00..9952270 100644 --- a/spec/lib/jasmine/headless/coffee_script_cache_spec.rb +++ b/spec/lib/jasmine/headless/coffee_script_cache_spec.rb @@ -3,84 +3,18 @@ require 'spec_helper' describe Jasmine::Headless::CoffeeScriptCache do include FakeFS::SpecHelpers - let(:file) { 'file.coffee' } - let(:data) { 'data' } - let(:compiled) { 'compiled' } + describe '#action' do + let(:file) { 'file' } + let(:data) { 'data' } + let(:compiled) { 'compiled' } - before do - File.open(file, 'wb') { |fh| fh.print(data) } - described_class.cache_dir = cache_dir - end - - let(:coffee_script_compiles!) do - CoffeeScript.expects(:compile).with(data).returns(compiled) - end - - let(:cache_dir) { 'cache' } - let(:cache_file) { File.join(cache_dir, Digest::SHA1.hexdigest(file)) } - let(:cache_file_data) { File.read(cache_file) } - - describe '.for' do - context 'cache disabled' do - before do - described_class.enabled = false - p described_class.enabled? - end - - it 'should compile' do - coffee_script_compiles! - described_class.for(file).should == compiled - cache_file.should_not be_a_file - end + before do + CoffeeScript.expects(:compile).with(data).returns(compiled) + File.open(file, 'wb') { |fh| fh.print(data) } end - context 'cache enabled' do - before do - described_class.enabled = true - FileUtils.mkdir_p(cache_dir) - - File.stubs(:mtime).with(file).returns(Time.at(10)) - File.stubs(:mtime).with(cache_file).returns(Time.at(cache_file_mtime)) - end - - context 'cache empty' do - let(:cache_file_mtime) { 0 } - - it 'should compile' do - coffee_script_compiles! - described_class.for(file).should == compiled - - cache_file_data.should == compiled - end - end - - context 'cache fresh' do - let(:cache_file_mtime) { 15 } - - before do - File.open(cache_file, 'wb') { |fh| fh.print compiled } - end - - it 'should not compile' do - coffee_script_compiles!.never - - described_class.for(file).should == compiled - - cache_file_data.should == compiled - end - end - - context 'cache stale' do - let(:cache_file_mtime) { 5 } - - it 'should compile' do - coffee_script_compiles! - - described_class.for(file).should == compiled - - cache_file_data.should == compiled - end - end + it 'should compile coffeescript' do + described_class.new(file).action.should == compiled end end end diff --git a/spec/lib/jasmine/headless/spec_file_analyzer_spec.rb b/spec/lib/jasmine/headless/spec_file_analyzer_spec.rb new file mode 100644 index 0000000..fbde25c --- /dev/null +++ b/spec/lib/jasmine/headless/spec_file_analyzer_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe Jasmine::Headless::SpecFileAnalyzer do + include FakeFS::SpecHelpers + + let(:file) { 'file' } + let(:analyzer) { described_class.new(file) } + + describe '#action' do + let(:line_numbers) do + analyzer.action + end + + before do + File.open(file, 'wb') { |fh| fh.print file_data } + end + + context 'coffeescript' do + let(:file_data) do + <<-SPEC +describe 'test', -> + context 'yes', -> + it 'should do something', -> + "yes" + "PR.registerLangHandler(PR.createSimpleLexer([[\"com\",/^#[^\\n\\r]*/,null,\"#\"],[\"pln\",/^[\\t\\n\\r \\xa0]+/,null,\"\\t\\n\\r \xC2\\xa0\"],[\"str\",/^\"(?:[^\"\\\\]|\\\\[\\S\\s])*(?:\"|$)/,null,'\"']],[[\"kwd\",/^(?:ADS|AD|AUG|BZF|BZMF|CAE|CAF|CA|CCS|COM|CS|DAS|DCA|DCOM|DCS|DDOUBL|DIM|DOUBLE|DTCB|DTCF|DV|DXCH|EDRUPT|EXTEND|INCR|INDEX|NDX|INHINT|LXCH|MASK|MSK|MP|MSU|NOOP|OVSK|QXCH|RAND|READ|RELINT|RESUME|RETURN|ROR|RXOR|SQUARE|SU|TCR|TCAA|OVSK|TCF|TC|TS|WAND|WOR|WRITE|XCH|XLQ|XXALQ|ZL|ZQ|ADD|ADZ|SUB|SUZ|MPY|MPR|MPZ|DVP|COM|ABS|CLA|CLZ|LDQ|STO|STQ|ALS|LLS|LRS|TRA|TSQ|TMI|TOV|AXT|TIX|DLY|INP|OUT)\\s/,\n" +SPEC + end + + it 'should get the line numbers' do + line_numbers['test'].should == [ 1 ] + line_numbers['yes'].should == [ 2 ] + line_numbers['should do something'].should == [ 3 ] + end + end + + context 'javascript' do + let(:file_data) do + <<-SPEC +describe('test', function() { + context('yes', function() { + it('should do something', function() { + + }); + }); +}); +SPEC + end + + it 'should get the line numbers' do + line_numbers['test'].should == [ 1 ] + line_numbers['yes'].should == [ 2 ] + line_numbers['should do something'].should == [ 3 ] + end + end + end +end + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0fcd858..472d170 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,10 @@ require 'fakefs/spec_helpers' RSpec.configure do |c| c.mock_with :mocha + + c.before(:each) do + Jasmine::Headless::CacheableAction.enabled = false + end end specrunner = 'ext/jasmine-webkit-specrunner/jasmine-webkit-specrunner' diff --git a/specrunner.104.filter.html b/specrunner.104.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.123.filter.html b/specrunner.123.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.137.filter.html b/specrunner.137.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.151.filter.html b/specrunner.151.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.165.filter.html b/specrunner.165.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.835.filter.html b/specrunner.835.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.849.filter.html b/specrunner.849.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.863.filter.html b/specrunner.863.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.877.filter.html b/specrunner.877.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.891.filter.html b/specrunner.891.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.99208.filter.html b/specrunner.99208.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.99222.filter.html b/specrunner.99222.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.99236.filter.html b/specrunner.99236.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.99250.filter.html b/specrunner.99250.filter.html new file mode 100644 index 0000000..e69de29 diff --git a/specrunner.99264.filter.html b/specrunner.99264.filter.html new file mode 100644 index 0000000..e69de29