Skip to content

Commit

Permalink
Merge pull request #48807 from shouichi/rails-test-line-range
Browse files Browse the repository at this point in the history
Support filtering tests by line ranges
  • Loading branch information
byroot committed Aug 1, 2023
2 parents eff1e66 + 5931a68 commit 741cd18
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
11 changes: 11 additions & 0 deletions railties/CHANGELOG.md
@@ -1,3 +1,14 @@
* Support filtering tests by line ranges

The new syntax allows you to filter tests by line ranges. For example, the
following command runs tests from line 10 to 20.

```bash
$ rails test test/models/user_test.rb:10-20
```

*Shouichi Kamiya*, *Seonggi Yang*, *oljfte*, *Ryohei UEDA*

* Update default scaffold templates to set 303 (See Other) as status code
on redirect for the update action for XHR requests other than GET or POST
to avoid issues (e.g browsers trying to follow the redirect using the
Expand Down
15 changes: 10 additions & 5 deletions railties/lib/rails/test_unit/runner.rb
Expand Up @@ -4,6 +4,7 @@
require "rake/file_list"
require "active_support"
require "active_support/core_ext/module/attribute_accessors"
require "active_support/core_ext/range"
require "rails/test_unit/test_parser"

module Rails
Expand Down Expand Up @@ -68,7 +69,7 @@ def extract_filters(argv)

path = path.tr("\\", "/")
case
when /(:\d+)+$/.match?(path)
when /(:\d+(-\d+)?)+$/.match?(path)
file, *lines = path.split(":")
filters << [ file, lines ]
file
Expand Down Expand Up @@ -155,17 +156,21 @@ def derive_line_filters(patterns)
end

class Filter # :nodoc:
def initialize(runnable, file, line)
def initialize(runnable, file, line_or_range)
@runnable, @file = runnable, File.expand_path(file)
@line = line.to_i if line
if line_or_range
first, last = line_or_range.split("-").map(&:to_i)
last ||= first
@line_range = Range.new(first, last)
end
end

def ===(method)
return unless @runnable.method_defined?(method)

if @line
if @line_range
test_file, test_range = definition_for(@runnable.instance_method(method))
test_file == @file && test_range.include?(@line)
test_file == @file && @line_range.overlaps?(test_range)
else
@runnable.instance_method(method).source_location.first == @file
end
Expand Down
50 changes: 50 additions & 0 deletions railties/test/application/test_runner_test.rb
Expand Up @@ -416,6 +416,56 @@ class PostTest < ActiveSupport::TestCase
end
end

def test_line_range_filter_syntax
app_file "test/models/post_test.rb", <<-RUBY
require "test_helper"
class PostTest < ActiveSupport::TestCase
test "first" do # 4
puts 'PostTest:FirstFilter'
assert true
end
test "second" do # 9
puts 'PostTest:Second'
assert true
end
test "third" do # 14
puts 'PostTest:Third'
assert true
end
test "fourth" do # 19
puts 'PostTest:Fourth'
assert true
end
end
RUBY

run_test_command("test/models/post_test.rb:4-14").tap do |output|
assert_match "PostTest:First", output
assert_match "PostTest:Second", output
assert_match "PostTest:Third", output
assert_match "3 runs, 3 assertions", output
end

run_test_command("test/models/post_test.rb:4-9:19").tap do |output|
assert_match "PostTest:First", output
assert_match "PostTest:Second", output
assert_match "PostTest:Fourth", output
assert_match "3 runs, 3 assertions", output
end

run_test_command("test/models/post_test.rb:4-9:14-19").tap do |output|
assert_match "PostTest:First", output
assert_match "PostTest:Second", output
assert_match "PostTest:Third", output
assert_match "PostTest:Fourth", output
assert_match "4 runs, 4 assertions", output
end
end

def test_more_than_one_line_filter_test_method_syntax
app_file "test/models/post_test.rb", <<-RUBY
require "test_helper"
Expand Down

0 comments on commit 741cd18

Please sign in to comment.