From e28703b047925193b6d91c8566b1e6175ae86004 Mon Sep 17 00:00:00 2001 From: John Bintz Date: Mon, 26 Mar 2012 17:15:58 -0400 Subject: [PATCH] start basic JS instrumentation, so alpha it hurts --- lib/assets/javascripts/flowerbox.js.coffee | 6 +++- lib/flowerbox/configuration.rb | 11 +++++- lib/flowerbox/instrumented_files_list.rb | 22 ++++++++++++ lib/flowerbox/runner/base.rb | 12 +++++-- lib/flowerbox/sprockets_handler.rb | 6 ++++ lib/flowerbox/tilt/instrument_js.rb | 42 ++++++++++++++++++++++ 6 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 lib/flowerbox/instrumented_files_list.rb create mode 100644 lib/flowerbox/tilt/instrument_js.rb diff --git a/lib/assets/javascripts/flowerbox.js.coffee b/lib/assets/javascripts/flowerbox.js.coffee index ee4ec8c..fd574d0 100644 --- a/lib/assets/javascripts/flowerbox.js.coffee +++ b/lib/assets/javascripts/flowerbox.js.coffee @@ -21,7 +21,11 @@ Flowerbox = message = Flowerbox.messageQueue.shift() Flowerbox.socket.send(JSON.stringify(message)) - Flowerbox.done = true if url == 'results' + if url == 'results' + if __$instrument? + Flowerbox.socket.send(JSON.stringify(['instrument', __$instrument])) + + Flowerbox.done = true started: false done: false diff --git a/lib/flowerbox/configuration.rb b/lib/flowerbox/configuration.rb index d1f56e4..ea97dff 100644 --- a/lib/flowerbox/configuration.rb +++ b/lib/flowerbox/configuration.rb @@ -1,8 +1,9 @@ require 'flowerbox/reporter_list' +require 'flowerbox/instrumented_files_list' module Flowerbox class Configuration - attr_writer :reporters, :backtrace_filter + attr_writer :reporters, :backtrace_filter, :instrument_js attr_accessor :port attr_accessor :test_environment, :runner_environment, :bare_coffeescript @@ -27,6 +28,14 @@ module Flowerbox @backtrace_filter ||= [] end + def instrument_files + @instrument_files ||= Flowerbox::InstrumentedFilesList.new + end + + def instrument_js? + !@instrument_files.empty? + end + def test_with(what) self.test_environment = Flowerbox::TestEnvironment.for(what) end diff --git a/lib/flowerbox/instrumented_files_list.rb b/lib/flowerbox/instrumented_files_list.rb new file mode 100644 index 0000000..0f1fd2f --- /dev/null +++ b/lib/flowerbox/instrumented_files_list.rb @@ -0,0 +1,22 @@ +require 'forwardable' + +module Flowerbox + class InstrumentedFilesList + extend Forwardable + + def_delegators :@files_list, :empty? + + def initialize + @files_list = [] + end + + def <<(pattern) + @files_list << pattern + end + + def include?(filename) + @files_list.any? { |pattern| filename[pattern] } + end + end +end + diff --git a/lib/flowerbox/runner/base.rb b/lib/flowerbox/runner/base.rb index efde11e..0a22420 100644 --- a/lib/flowerbox/runner/base.rb +++ b/lib/flowerbox/runner/base.rb @@ -36,6 +36,9 @@ module Flowerbox sprockets.find_asset(file.first, :bundle => false).body end + def instrument(data) + end + def ensure_alive while @count < MAX_COUNT && !finished? @count += 1 if @timer_running @@ -92,8 +95,13 @@ module Flowerbox end @results - rescue ExecJS::RuntimeError => e - handle_coffeescript_compilation_error(e) + rescue => e + case e + when ExecJS::RuntimeError, ExecJS::ProgramError + handle_coffeescript_compilation_error(e) + else + raise e + end end def configured? diff --git a/lib/flowerbox/sprockets_handler.rb b/lib/flowerbox/sprockets_handler.rb index 98003f6..f4e25c5 100644 --- a/lib/flowerbox/sprockets_handler.rb +++ b/lib/flowerbox/sprockets_handler.rb @@ -40,6 +40,12 @@ module Flowerbox @environment = Sprockets::Environment.new @environment.cache = cache + if Flowerbox.instrument_js? + require 'flowerbox/tilt/instrument_js' + + @environment.register_postprocessor 'application/javascript', Flowerbox::Tilt::InstrumentJS + end + default_asset_paths.each { |path| @environment.append_path(path) } @environment diff --git a/lib/flowerbox/tilt/instrument_js.rb b/lib/flowerbox/tilt/instrument_js.rb new file mode 100644 index 0000000..0199c5b --- /dev/null +++ b/lib/flowerbox/tilt/instrument_js.rb @@ -0,0 +1,42 @@ +require 'tilt' + +module Flowerbox + module Tilt + class InstrumentJS < ::Tilt::Template + def prepare ; end + + def evaluate(scope, locals, &block) + if Flowerbox.instrument_files.include?(file) + block_comment = false + + lines = data.lines.to_a + + output = [ + 'if (typeof __$instrument == "undefined") { __$instrument = {} }', + "__$instrument['#{file}'] = [];", + "__$instrument['#{file}'][#{lines.length - 1}] = 0;" + ] + + prior_comma_end = comma_end = false + + lines.each_with_index do |line, index| + line.rstrip! + + instrument = "__$instrument['#{file}'][#{index}] = 1;" + + if line[%r{; *$}] + line = line + instrument + end + + output << line + end + + output.join("\n") + else + data + end + end + end + end +end +