From c523a1e31041e50aac936244904b3d3b81285e80 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Thu, 1 Sep 2011 10:39:29 -0400 Subject: [PATCH] second part - cache spec file analysis --- Rakefile | 1 + bin/jasmine-headless-webkit | 1 + lib/jasmine-headless-webkit.rb | 2 + lib/jasmine/files_list.rb | 20 +---- lib/jasmine/headless/cacheable_action.rb | 77 ++++++++++++++++ lib/jasmine/headless/coffee_script_cache.rb | 54 +----------- lib/jasmine/headless/runner.rb | 2 +- lib/jasmine/headless/spec_file_analyzer.rb | 37 ++++++++ spec/bin/jasmine-headless-webkit_spec.rb | 1 - spec/lib/jasmine/files_list_spec.rb | 44 ---------- .../jasmine/headless/cacheable_action_spec.rb | 88 +++++++++++++++++++ .../headless/coffee_script_cache_spec.rb | 84 ++---------------- .../headless/spec_file_analyzer_spec.rb | 57 ++++++++++++ spec/spec_helper.rb | 4 + specrunner.104.filter.html | 0 specrunner.123.filter.html | 0 specrunner.137.filter.html | 0 specrunner.151.filter.html | 0 specrunner.165.filter.html | 0 specrunner.835.filter.html | 0 specrunner.849.filter.html | 0 specrunner.863.filter.html | 0 specrunner.877.filter.html | 0 specrunner.891.filter.html | 0 specrunner.99208.filter.html | 0 specrunner.99222.filter.html | 0 specrunner.99236.filter.html | 0 specrunner.99250.filter.html | 0 specrunner.99264.filter.html | 0 29 files changed, 283 insertions(+), 189 deletions(-) create mode 100644 lib/jasmine/headless/cacheable_action.rb create mode 100644 lib/jasmine/headless/spec_file_analyzer.rb create mode 100644 spec/lib/jasmine/headless/cacheable_action_spec.rb create mode 100644 spec/lib/jasmine/headless/spec_file_analyzer_spec.rb create mode 100644 specrunner.104.filter.html create mode 100644 specrunner.123.filter.html create mode 100644 specrunner.137.filter.html create mode 100644 specrunner.151.filter.html create mode 100644 specrunner.165.filter.html create mode 100644 specrunner.835.filter.html create mode 100644 specrunner.849.filter.html create mode 100644 specrunner.863.filter.html create mode 100644 specrunner.877.filter.html create mode 100644 specrunner.891.filter.html create mode 100644 specrunner.99208.filter.html create mode 100644 specrunner.99222.filter.html create mode 100644 specrunner.99236.filter.html create mode 100644 specrunner.99250.filter.html create mode 100644 specrunner.99264.filter.html 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