nicetest 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8b1e58e35c866d01e21b5b8e397e05c3506002d3af25681a8178e6c26d4f2e3
4
- data.tar.gz: 8f032d23008336df8010de48bb4a4cf872e4416d52a092ce76e231a7a09cb934
3
+ metadata.gz: 61441e7efe86d553594ec78afb04d59b8f6d33581624dc4854feef7958fe1793
4
+ data.tar.gz: 1efcd585b516002dcdea5c8aa6f20adbb559dcb4bab7d03c53ee530132d6bfd3
5
5
  SHA512:
6
- metadata.gz: 1cc1cd63f09d3d3c5a2abca7fcd6bf9b914eb61391efb146cb0c01c0c77139b32ee8a32d493f1cef49b69bcf8df9ebda39bda69607f84f94b39535f30ef7b0fd
7
- data.tar.gz: a19a0494f63b94dd40cfa2a493d31eb0ee1eea53ab33b08fc05e775d715dfc9c3f8e0eda533e1923cbdbe984da52d6fd6c9325da67b13ed968955dbf86e5c217
6
+ metadata.gz: b10a7f41792d304f1d5ab721353b324b1afa0bc586cfbedaf461959da2c7bce8c0ac11e45e95baba219de92c368fc3aacdc7cf57c207111efeb0f4440b02f7e8
7
+ data.tar.gz: 97caebe046160f28cc37ccfe3e8db7778641cf5812af8b161675825016ac82c44f6ad49866a9b85a87533830d9ed72dfefef2c4f2c53e43adb1d11f065241573
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # opts.banner = "Usage: example.rb [options]"
4
- require "nicetest/cli"
4
+ require "nicetest"
5
5
 
6
6
  module Minitest
7
7
  class << self
data/lib/nicetest/cli.rb CHANGED
@@ -20,11 +20,11 @@ module Nicetest
20
20
  elsif File.exist?("Gemfile") && !File.read("Gemfile").include?("nicetest")
21
21
  run_in_directory(".")
22
22
  else
23
- run_tests
23
+ run_tests(cli_options)
24
24
  end
25
25
  end
26
26
 
27
- def run_tests
27
+ def run_tests(cli_options = Opts.parse!(@argv))
28
28
  disable_autorun!
29
29
  adjust_load_path!
30
30
 
@@ -32,12 +32,24 @@ module Nicetest
32
32
  argv_test_files = select_file_args(args)
33
33
  argv_test_files = glob_test_files("test") if argv_test_files.empty?
34
34
  args -= argv_test_files
35
+ finder = TestFinder.new
36
+ filters = Set.new
37
+
38
+ if cli_options.name
39
+ name = cli_options.name
40
+ name = name[1..-1] if name.start_with?("/")
41
+ name = name[0..-2] if name.end_with?("/")
42
+ filters << name
43
+ end
35
44
 
36
- required_files = argv_test_files.flat_map do |file_or_dir|
45
+ required_files = argv_test_files.map do |pattern|
46
+ file_or_dir, filter = finder.filter_for(pattern)
47
+ filters << filter if filter && !cli_options.name
37
48
  require_path_or_dir(file_or_dir)
38
49
  end
39
50
 
40
51
  @logger.fatal!("no test files found") if required_files.compact.empty?
52
+ args << "--name=/#{filters.to_a.join("|")}/" if filters.any?
41
53
 
42
54
  Minitest.run(args)
43
55
  end
@@ -164,7 +176,7 @@ module Nicetest
164
176
  end
165
177
  end
166
178
 
167
- Opts = Struct.new(:cd) do
179
+ Opts = Struct.new(:cd, :name) do
168
180
  class << self
169
181
  def parse!(argv)
170
182
  old_officious = OptionParser::Officious.dup
@@ -177,6 +189,10 @@ module Nicetest
177
189
  opts.on("--cd=DIR", "Change directory before running tests") do |dir|
178
190
  options[:cd] = dir
179
191
  end
192
+
193
+ opts.on("-n", "--name=PATTERN", "Filter test names on pattern") do |pattern|
194
+ options[:name] = pattern
195
+ end
180
196
  end
181
197
 
182
198
  parser.parse!(argv)
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "prism"
4
+ require "set"
5
+
6
+ module Nicetest
7
+ class TestFinder
8
+ def initialize
9
+ @parse_cache = {}
10
+ end
11
+
12
+ def filter_for(target)
13
+ filename, lineno = target.split(":", 2)
14
+ filepath = File.expand_path(filename)
15
+ lineno = lineno&.to_i
16
+
17
+ return [filepath, nil] unless lineno
18
+
19
+ [filepath, find_test(filepath, lineno)]
20
+ end
21
+
22
+ private
23
+
24
+ def find_test(filename, lineno)
25
+ range_finder = @parse_cache[filename] ||= RangeFinder.parse_file(filename)
26
+ range_finder.nearest_test_for_line(lineno)
27
+ rescue => e
28
+ Nicetest.logger.warn("Failed to parse #{filename} (#{e.class}: #{e.message})")
29
+ nil
30
+ end
31
+
32
+ class RangeFinder < Prism::Compiler
33
+ class << self
34
+ def parse_file(filename)
35
+ node = Prism.parse_file(filename)
36
+ new(filename).populate(node.value)
37
+ end
38
+ end
39
+
40
+ attr_reader :scopes
41
+
42
+ def initialize(filename)
43
+ super()
44
+ @namespace_stack = []
45
+ @class_scopes = []
46
+ @tests = []
47
+ @program_nodes = []
48
+ @scopes = []
49
+ end
50
+
51
+ def populate(node)
52
+ visit(node)
53
+ @scopes += @tests
54
+ @scopes += @class_scopes
55
+ self
56
+ end
57
+
58
+ def nearest_test_for_line(lineno)
59
+ found = @scopes.find do |range, _test_name|
60
+ range.cover?(lineno)
61
+ end
62
+ found&.last
63
+ end
64
+
65
+ def visit_program_node(node)
66
+ @program_nodes << node
67
+ ret = super
68
+
69
+ if (last_scope = @class_scopes.last)
70
+ @class_scopes << [last_scope[0].end..node.location.end_line, last_scope[1]]
71
+ end
72
+
73
+ ret
74
+ end
75
+
76
+ def visit_module_node(node)
77
+ @namespace_stack.push(node)
78
+ super
79
+ @namespace_stack.pop
80
+ end
81
+
82
+ def visit_class_node(node)
83
+ @namespace_stack.push(node)
84
+ super
85
+ @namespace_stack.pop
86
+ end
87
+
88
+ def visit_def_node(node)
89
+ node_name = node.name.to_s
90
+ return super unless node_name.start_with?("test_")
91
+
92
+ @tests << [test_range_for(node.location), test_id_for(node_name)]
93
+ end
94
+
95
+ def visit_call_node(node)
96
+ return super unless node.name == :test
97
+
98
+ test_name = "test_#{node.arguments.arguments.first.unescaped}"
99
+ test_name.gsub!(/\s+/, "_")
100
+ @tests << [test_range_for(node.location), test_id_for(test_name)]
101
+ end
102
+
103
+ def test_id_for(test_name)
104
+ "#{@namespace_stack.map(&:name).join("::")}##{test_name}"
105
+ end
106
+
107
+ def test_range_for(location)
108
+ if @tests.empty?
109
+ current_nesting = @namespace_stack.map(&:name).join("::")
110
+ @class_scopes << [0..(location.start_line - 1), current_nesting]
111
+ end
112
+
113
+ last_scope = @tests.last || @class_scopes.last
114
+ last_scope_start = last_scope[0].begin
115
+ last_scope[0] = last_scope_start..(location.start_line - 1)
116
+
117
+ location.start_line..location.end_line
118
+ end
119
+ end
120
+ end
121
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nicetest
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/nicetest.rb CHANGED
@@ -7,6 +7,7 @@ require_relative "nicetest/version"
7
7
  require_relative "nicetest/logger"
8
8
  require_relative "nicetest/cli"
9
9
  require_relative "nicetest/backtrace_filter"
10
+ require_relative "nicetest/test_finder"
10
11
 
11
12
  module Nicetest
12
13
  class Error < StandardError; end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nicetest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ian Ker-Seymer
@@ -29,7 +29,7 @@ cert_chain:
29
29
  Lvd35BNvZkhFzs9xfykhurpkT2TiP2F3ZFn9dwLXMFe41pwrtEYLIWhYi8mUG4Ek
30
30
  6aR8M/tqIpChVV39
31
31
  -----END CERTIFICATE-----
32
- date: 2024-07-21 00:00:00.000000000 Z
32
+ date: 2024-07-22 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: minitest
@@ -101,6 +101,20 @@ dependencies:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0.8'
104
+ - !ruby/object:Gem::Dependency
105
+ name: prism
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0.30'
111
+ type: :runtime
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0.30'
104
118
  - !ruby/object:Gem::Dependency
105
119
  name: super_diff
106
120
  requirement: !ruby/object:Gem::Requirement
@@ -134,6 +148,7 @@ files:
134
148
  - lib/nicetest/backtrace_filter.rb
135
149
  - lib/nicetest/cli.rb
136
150
  - lib/nicetest/logger.rb
151
+ - lib/nicetest/test_finder.rb
137
152
  - lib/nicetest/version.rb
138
153
  homepage: https://github.com/ianks/nicetest
139
154
  licenses:
metadata.gz.sig CHANGED
Binary file