Skip to content

Commit 4dcf592

Browse files
Fix regression in test name filters with specs
This issue is hurting my brain a little, but I'll try and explain it. It's a regression introduced by rails#44290, in the following conditions: - You use `minitest/spec` (either direction or via a wrapper like [`minitest-spec-rails`](https://github.com/metaskills/minitest-spec-rails)) - You run tests using a regex filter to identify which tests to run (either directly or via a wrapper like [`m`](https://github.com/qrush/m)) Since rails#44290 you could not execute a test that has a space in its name using the regex filter method. This is because: - https://github.com/rails/rails/blob/444df0eee1b537ecaa11509e819b071d4e87b519/activesupport/lib/active_support/testing/declarative.rb#L6 doesn't define the `test` method if `Spec` is defined. Recall that the `test` method does 2 things: it defines the test, but it also replaces spaces with underscores in the test method name. - In minitest specs, you use `it` to define tests. `it` [generates a test method name](https://github.com/minitest/minitest/blob/a9fa045044b4210cfd21a512b06d1a4527d709ba/lib/minitest/spec.rb#L223..L229) by taking user input and prepending `test_` and a number. It does *not* replace spaces with underscores. So the test method is defined as `"test_002_foo bar"`. - Since rails#44290 when you provide the test runner a filter it replaces spaces with underscores before passing the filter onto minitest. For example, the filter might become `"/test_002_foo_bar/"`. - Minitest thus can't find the test method and doesn't run it. The issue is in `escape_declarative_test_filter`. Rather than converting spaces to underscores, it should match both spaces *and* underscores. This covers all use cases. Co-authored-by: jonathanhefner <[email protected]>
1 parent a9506eb commit 4dcf592

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

railties/lib/rails/test_unit/runner.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,14 @@ def list_tests(patterns)
104104
end
105105

106106
def escape_declarative_test_filter(filter)
107-
if filter.is_a?(String) && !filter.start_with?("test_")
108-
filter = "test_#{filter}" unless regexp_filter?(filter)
109-
filter = filter.gsub(/\s+/, "_")
107+
# NOTE: This method may be applied multiple times, so any
108+
# transformations MUST BE idempotent.
109+
if filter.is_a?(String)
110+
if regexp_filter?(filter)
111+
filter = filter.gsub(/\s+/, '[\s_]+')
112+
elsif !filter.start_with?("test_")
113+
filter = "test_#{filter.gsub(/\s+/, "_")}"
114+
end
110115
end
111116
filter
112117
end

railties/test/application/test_runner_test.rb

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ class PostTest < ActiveSupport::TestCase
595595
assert true
596596
end
597597
598-
test "foo again" do
598+
test "foo + + again" do
599599
puts "hello again"
600600
assert true
601601
end
@@ -611,7 +611,7 @@ class PostTest < ActiveSupport::TestCase
611611
assert_match "1 runs, 1 assertions, 0 failures", output
612612
end
613613

614-
run_test_command("test/models/post_test.rb -n 'foo again'").tap do |output|
614+
run_test_command("test/models/post_test.rb -n 'foo + + again'").tap do |output|
615615
assert_match "hello again", output
616616
assert_match "1 runs, 1 assertions, 0 failures", output
617617
end
@@ -632,7 +632,7 @@ class PostTest < ActiveSupport::TestCase
632632
assert true
633633
end
634634
635-
test "greets bar" do
635+
test "greets + + bar" do
636636
puts "hello bar"
637637
assert true
638638
end
@@ -643,7 +643,41 @@ class PostTest < ActiveSupport::TestCase
643643
end
644644
RUBY
645645

646-
run_test_command("test/models/post_test.rb -n '/greets foo|greets bar/'").tap do |output|
646+
run_test_command("test/models/post_test.rb -n '/greets foo|greets . . bar/'").tap do |output|
647+
assert_match "hello foo", output
648+
assert_match "hello again foo", output
649+
assert_match "hello bar", output
650+
assert_match "3 runs, 3 assertions, 0 failures", output
651+
end
652+
end
653+
654+
def test_declarative_style_regexp_filter_with_minitest_spec
655+
app_file "test/models/post_test.rb", <<~RUBY
656+
require "minitest/spec"
657+
658+
class PostTest < Minitest::Spec
659+
it "greets foo" do
660+
puts "hello foo"
661+
assert true
662+
end
663+
664+
it "greets foo again" do
665+
puts "hello again foo"
666+
assert true
667+
end
668+
669+
it "greets + + bar" do
670+
puts "hello bar"
671+
assert true
672+
end
673+
674+
it "greets no one" do
675+
assert false
676+
end
677+
end
678+
RUBY
679+
680+
run_test_command("test/models/post_test.rb -n '/greets foo|greets . . bar/'").tap do |output|
647681
assert_match "hello foo", output
648682
assert_match "hello again foo", output
649683
assert_match "hello bar", output

0 commit comments

Comments
 (0)