aboutsummaryrefslogtreecommitdiffstats
path: root/railties/lib
diff options
context:
space:
mode:
authorKasper Timm Hansen <kaspth@gmail.com>2016-01-09 17:07:01 +0100
committerKasper Timm Hansen <kaspth@gmail.com>2016-01-09 17:21:21 +0100
commit69e5547162af5ce9537230239b66a6887699e7c1 (patch)
tree8c7845b92879809d3f5dcf327694c91db9a56322 /railties/lib
parentb588653ac0ce12b8caf448b3a08cb099db8ac356 (diff)
downloadrails-69e5547162af5ce9537230239b66a6887699e7c1.tar.gz
rails-69e5547162af5ce9537230239b66a6887699e7c1.tar.bz2
rails-69e5547162af5ce9537230239b66a6887699e7c1.zip
Extract line filtering to Railties.
The line filter parsing added to ActiveSupport::TestCase is only half the story to enable line filtering. The other half, of adding the patterns to the options, is done in the Minitest plugin that Railties has. Thus it makes more sense to have the filter in Railties with the other half and all the line filtering tests. Move the filter and extend Active Support in an initializer, so that when users or `rails/all.rb` require `rails/test_unit/railtie` we can still filter by line.
Diffstat (limited to 'railties/lib')
-rw-r--r--railties/lib/rails/test_unit/line_filtering.rb63
-rw-r--r--railties/lib/rails/test_unit/railtie.rb6
2 files changed, 69 insertions, 0 deletions
diff --git a/railties/lib/rails/test_unit/line_filtering.rb b/railties/lib/rails/test_unit/line_filtering.rb
new file mode 100644
index 0000000000..65f76f21a6
--- /dev/null
+++ b/railties/lib/rails/test_unit/line_filtering.rb
@@ -0,0 +1,63 @@
+require 'method_source'
+
+module Rails
+ module LineFiltering # :nodoc:
+ def run(reporter, options = {})
+ if options[:patterns] && options[:patterns].any? { |p| p =~ /:\d+/ }
+ options[:filter] = \
+ CompositeFilter.new(self, options[:filter], options[:patterns])
+ end
+
+ super
+ end
+ end
+
+ class CompositeFilter # :nodoc:
+ def initialize(runnable, filter, patterns)
+ @runnable = runnable
+ @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact
+ end
+
+ def ===(method)
+ @filters.any? { |filter| filter === method }
+ end
+
+ private
+ def derive_regexp(filter)
+ filter =~ %r%/(.*)/% ? Regexp.new($1) : filter
+ end
+
+ def derive_line_filters(patterns)
+ patterns.map do |file_and_line|
+ file, line = file_and_line.split(':')
+ Filter.new(@runnable, file, line) if file
+ end
+ end
+ end
+
+ class Filter # :nodoc:
+ def initialize(runnable, file, line)
+ @runnable, @file = runnable, File.expand_path(file)
+ @line = line.to_i if line
+ end
+
+ def ===(method)
+ return unless @runnable.method_defined?(method)
+
+ if @line
+ test_file, test_range = definition_for(@runnable.instance_method(method))
+ test_file == @file && test_range.include?(@line)
+ else
+ @runnable.instance_method(method).source_location.first == @file
+ end
+ end
+
+ private
+ def definition_for(method)
+ file, start_line = method.source_location
+ end_line = method.source.count("\n") + start_line - 1
+
+ return file, start_line..end_line
+ end
+ end
+end
diff --git a/railties/lib/rails/test_unit/railtie.rb b/railties/lib/rails/test_unit/railtie.rb
index 75180ff978..511cee33bd 100644
--- a/railties/lib/rails/test_unit/railtie.rb
+++ b/railties/lib/rails/test_unit/railtie.rb
@@ -1,3 +1,5 @@
+require 'rails/test_unit/line_filtering'
+
if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/^(default$|test(:|$))/).any?
ENV['RAILS_ENV'] ||= 'test'
end
@@ -11,6 +13,10 @@ module Rails
c.integration_tool :test_unit
end
+ initializer "test_unit.line_filtering" do
+ ActiveSupport::TestCase.extend Rails::LineFiltering
+ end
+
rake_tasks do
load "rails/test_unit/testing.rake"
end