Skip to content

Commit c46e287

Browse files
authored
Merge pull request #18 from rspec-parameterized/feature/prism
Use Prism gem instead of Parser gem when Ruby 3.4+
2 parents 9bc3e25 + 0d91d2a commit c46e287

File tree

7 files changed

+145
-11
lines changed

7 files changed

+145
-11
lines changed

lib/rspec/parameterized/core.rb

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
require "rspec/parameterized/core/version"
2-
require 'parser'
3-
require 'unparser'
4-
require 'proc_to_ast'
52
require 'rspec/parameterized/core/helper_methods'
63
require 'rspec/parameterized/core/example_helper_methods'
4+
require 'rspec/parameterized/core/errors'
5+
require 'rspec/parameterized/core/composite_parser'
76

87
module RSpec
98
module Parameterized
@@ -143,11 +142,9 @@ def define_cases(parameter, *args, &block)
143142
end
144143

145144
def params_inspect(obj)
146-
begin
147-
obj.is_a?(Proc) ? obj.to_raw_source : obj.inspect
148-
rescue Parser::SyntaxError
149-
return obj.inspect
150-
end
145+
RSpec::Parameterized::Core::CompositeParser.to_raw_source(obj)
146+
rescue ParserSyntaxError
147+
return obj.inspect
151148
end
152149

153150
def set_verbose_parameters(&block)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
module RSpec
2+
module Parameterized
3+
module Core
4+
# Proxy class for parser and prism
5+
module CompositeParser
6+
# @param obj [Object]
7+
# @return [String]
8+
# @raise [RSpec::Parameterized::Core::ParserSyntaxError]
9+
def self.to_raw_source(obj)
10+
return to_raw_source_with_prism(obj) if use_prism?
11+
12+
to_raw_source_with_parser(obj)
13+
end
14+
15+
# Whether use parser or prism
16+
#
17+
# @return [true] Use prism
18+
# @return [false] Use parser
19+
def self.use_prism?
20+
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.4.0")
21+
end
22+
23+
# @param obj [Object]
24+
# @return [String]
25+
# @raise [RSpec::Parameterized::Core::ParserSyntaxError]
26+
def self.to_raw_source_with_parser(obj)
27+
obj.is_a?(Proc) ? obj.to_raw_source : obj.inspect
28+
rescue Parser::SyntaxError => e
29+
raise ParserSyntaxError
30+
end
31+
private_class_method :to_raw_source_with_parser
32+
33+
# @param obj [Object]
34+
# @return [String]
35+
def self.to_raw_source_with_prism(obj)
36+
return obj.inspect unless obj.is_a?(Proc)
37+
38+
filename, linenum = obj.source_location
39+
ast = parse_with_prism(filename, linenum)
40+
41+
return "" unless ast
42+
43+
ast.source.source.strip
44+
end
45+
private_class_method :to_raw_source_with_prism
46+
47+
# @param filename [String]
48+
# @param linenum [Integer]
49+
#
50+
# @return [Prism::ParseResult,nil]
51+
def self.parse_with_prism(filename, linenum)
52+
buf = []
53+
File.open(filename, "rb").each_with_index do |line, index|
54+
next if index < linenum - 1
55+
buf << line
56+
57+
ret = Prism.parse(buf.join)
58+
return ret if ret.success?
59+
end
60+
61+
nil
62+
end
63+
private_class_method :parse_with_prism
64+
end
65+
end
66+
end
67+
end
68+
69+
if RSpec::Parameterized::Core::CompositeParser.use_prism?
70+
require 'prism'
71+
else
72+
require 'parser'
73+
require 'unparser'
74+
require 'proc_to_ast'
75+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module RSpec
2+
module Parameterized
3+
module Core
4+
class Error < StandardError; end
5+
6+
class ParserSyntaxError < Error; end
7+
end
8+
end
9+
end

lib/rspec/parameterized/core/lazy_arg.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ def apply(obj)
1111
end
1212

1313
def inspect
14-
"#{@block.to_raw_source}"
15-
rescue Parser::SyntaxError
14+
CompositeParser.to_raw_source(@block)
15+
rescue ParserSyntaxError
1616
super.inspect
1717
end
1818
end

rspec-parameterized-core.gemspec

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,18 @@ I was inspired by [udzura's mock](https://gist.github.com/1881139).}
3232
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
3333
spec.require_paths = ["lib"]
3434

35+
spec.add_dependency "rspec", ">= 2.13", "< 4"
36+
37+
# parser dependencies
3538
spec.add_dependency "parser"
3639
spec.add_dependency "proc_to_ast", ">= 0.2.0"
37-
spec.add_dependency "rspec", ">= 2.13", "< 4"
3840
spec.add_dependency "unparser"
3941

42+
# prism dependencies
43+
spec.add_dependency "prism"
44+
4045
spec.add_development_dependency "rake", ">= 12.0.0"
46+
spec.add_development_dependency "rspec-its"
4147

4248
# For more information and examples about making a new gem, check out our
4349
# guide at: https://bundler.io/guides/creating_gem.html
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
describe RSpec::Parameterized::Core::CompositeParser do
2+
describe ".to_raw_source" do
3+
subject { RSpec::Parameterized::Core::CompositeParser.to_raw_source(arg) }
4+
5+
context "arg is not proc" do
6+
let(:arg) do
7+
123
8+
end
9+
10+
it { should eq "123" }
11+
end
12+
13+
context "arg is proc" do
14+
context "simple case" do
15+
let(:arg) do
16+
->(a) { a + 1 }
17+
end
18+
19+
it { should eq "->(a) { a + 1 }" }
20+
its(:encoding) { should eq Encoding::UTF_8 }
21+
end
22+
23+
context "arg is multibyte characters" do
24+
let(:arg) do
25+
->(a) { a + "ほげほげ" }
26+
end
27+
28+
it { should eq '->(a) { a + "ほげほげ" }' }
29+
its(:encoding) { should eq Encoding::UTF_8 }
30+
end
31+
32+
context "multiple lines" do
33+
let(:arg) do
34+
->(a) {
35+
a +
36+
1
37+
}
38+
end
39+
40+
it { should eq "->(a) {\n a +\n 1\n }" }
41+
its(:encoding) { should eq Encoding::UTF_8 }
42+
end
43+
end
44+
end
45+
end

spec/spec_helper.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
require 'rspec-parameterized-core'
22

3+
require 'rspec/its'
4+
35
RSpec.configure do |config|
46
config.treat_symbols_as_metadata_keys_with_true_values = true
57
config.run_all_when_everything_filtered = true

0 commit comments

Comments
 (0)