Skip to content

Commit

Permalink
Simplify normalization of regexp test filters
Browse files Browse the repository at this point in the history
Follow-up to rails#47942.

This commit simplifies the normalization of regexp test filters.
Instead of modifying a given regexp to match a union of whitespace and
underscores, the regexp is unioned with the underscore-normalized
version of itself.  This allows filters that include escaped spaces,
such as `/foo\ bar/`.

This commit also fixes `Rails::LineFiltering#run` such that
normalization isn't reapplied for every test suite.  Thus
`normalize_declarative_test_filter` is no longer required to be
idempotent.

Co-authored-by: Jonathan Hefner <[email protected]>
  • Loading branch information
ghiculescu and jonathanhefner committed Sep 7, 2023
1 parent 31052d0 commit 0a8e537
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 9 deletions.
2 changes: 1 addition & 1 deletion railties/lib/rails/test_unit/line_filtering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module Rails
module LineFiltering # :nodoc:
def run(reporter, options = {})
options[:filter] = Rails::TestUnit::Runner.compose_filter(self, options[:filter])
options = options.merge(filter: Rails::TestUnit::Runner.compose_filter(self, options[:filter]))

super
end
Expand Down
10 changes: 5 additions & 5 deletions railties/lib/rails/test_unit/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def load_tests(argv)
end

def compose_filter(runnable, filter)
filter = escape_declarative_test_filter(filter)
filter = normalize_declarative_test_filter(filter)

if filters.any? { |_, lines| lines.any? }
CompositeFilter.new(runnable, filter, filters)
Expand Down Expand Up @@ -104,12 +104,12 @@ def list_tests(patterns)
tests
end

def escape_declarative_test_filter(filter)
# NOTE: This method may be applied multiple times, so any
# transformations MUST BE idempotent.
def normalize_declarative_test_filter(filter)
if filter.is_a?(String)
if regexp_filter?(filter)
filter = filter.gsub(/\s+/, '[\s_]+')
# Minitest::Spec::DSL#it does not replace whitespace in method
# names, so match unmodified method names as well.
filter = filter.gsub(/\s+/, "_").delete_suffix("/") + "|" + filter.delete_prefix("/")
elsif !filter.start_with?("test_")
filter = "test_#{filter.gsub(/\s+/, "_")}"
end
Expand Down
9 changes: 6 additions & 3 deletions railties/test/application/test_runner_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ class PostTest < ActiveSupport::TestCase
end
RUBY

run_test_command("test/models/post_test.rb -n '/greets foo|greets . . bar/'").tap do |output|
run_test_command("test/models/post_test.rb -n '/greets foo|greets . .\\ bar/'").tap do |output|
assert_match "hello foo", output
assert_match "hello again foo", output
assert_match "hello bar", output
Expand All @@ -703,9 +703,12 @@ class PostTest < ActiveSupport::TestCase

def test_declarative_style_regexp_filter_with_minitest_spec
app_file "test/models/post_test.rb", <<~RUBY
require "test_helper"
require "minitest/spec"
class PostTest < Minitest::Spec
class PostTest < ActiveSupport::TestCase
extend Minitest::Spec::DSL
it "greets foo" do
puts "hello foo"
assert true
Expand All @@ -727,7 +730,7 @@ class PostTest < Minitest::Spec
end
RUBY

run_test_command("test/models/post_test.rb -n '/greets foo|greets . . bar/'").tap do |output|
run_test_command("test/models/post_test.rb -n '/greets foo|greets . .\\ bar/'").tap do |output|
assert_match "hello foo", output
assert_match "hello again foo", output
assert_match "hello bar", output
Expand Down

0 comments on commit 0a8e537

Please sign in to comment.