minitest_to_rspec 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +3 -2
- data/CHANGELOG.md +19 -0
- data/README.md +3 -0
- data/lib/minitest_to_rspec/converter.rb +2 -2
- data/lib/minitest_to_rspec/input/model/base.rb +15 -0
- data/lib/minitest_to_rspec/input/model/call.rb +185 -0
- data/lib/minitest_to_rspec/input/model/defn.rb +37 -0
- data/lib/minitest_to_rspec/input/model/hash_exp.rb +24 -0
- data/lib/minitest_to_rspec/input/model/iter.rb +89 -0
- data/lib/minitest_to_rspec/input/model/klass.rb +102 -0
- data/lib/minitest_to_rspec/input/processor.rb +40 -0
- data/lib/minitest_to_rspec/input/subprocessors/base.rb +91 -0
- data/lib/minitest_to_rspec/input/subprocessors/call.rb +279 -0
- data/lib/minitest_to_rspec/input/subprocessors/defn.rb +64 -0
- data/lib/minitest_to_rspec/input/subprocessors/iter.rb +148 -0
- data/lib/minitest_to_rspec/input/subprocessors/klass.rb +101 -0
- data/lib/minitest_to_rspec/minitest/stub.rb +85 -0
- data/lib/minitest_to_rspec/{expression_builders → rspec}/stub.rb +3 -2
- data/lib/minitest_to_rspec/type.rb +1 -1
- data/lib/minitest_to_rspec/version.rb +1 -1
- metadata +17 -18
- data/lib/minitest_to_rspec/model/base.rb +0 -13
- data/lib/minitest_to_rspec/model/call.rb +0 -165
- data/lib/minitest_to_rspec/model/calls/once.rb +0 -13
- data/lib/minitest_to_rspec/model/calls/twice.rb +0 -13
- data/lib/minitest_to_rspec/model/defn.rb +0 -27
- data/lib/minitest_to_rspec/model/hash_exp.rb +0 -20
- data/lib/minitest_to_rspec/model/iter.rb +0 -79
- data/lib/minitest_to_rspec/model/klass.rb +0 -100
- data/lib/minitest_to_rspec/processor.rb +0 -38
- data/lib/minitest_to_rspec/subprocessors/base.rb +0 -89
- data/lib/minitest_to_rspec/subprocessors/call.rb +0 -391
- data/lib/minitest_to_rspec/subprocessors/defn.rb +0 -49
- data/lib/minitest_to_rspec/subprocessors/iter.rb +0 -138
- data/lib/minitest_to_rspec/subprocessors/klass.rb +0 -99
@@ -0,0 +1,148 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest_to_rspec/input/subprocessors/base'
|
4
|
+
require 'minitest_to_rspec/input/model/iter'
|
5
|
+
|
6
|
+
module MinitestToRspec
|
7
|
+
module Input
|
8
|
+
module Subprocessors
|
9
|
+
# Processes `s(:iter, ..)` expressions.
|
10
|
+
class Iter < Base
|
11
|
+
def initialize(sexp, rails, mocha)
|
12
|
+
super(rails, mocha)
|
13
|
+
@exp = Model::Iter.new(sexp)
|
14
|
+
sexp.clear
|
15
|
+
end
|
16
|
+
|
17
|
+
def process
|
18
|
+
process_exp(@exp)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Returns an expression representing an RSpec `change {}`
|
24
|
+
# matcher. See also `change_by` below.
|
25
|
+
def change(exp)
|
26
|
+
matcher_with_block(:change, exp)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns an expression representing an RSpec `change {}.by()` matcher.
|
30
|
+
def change_by(diff_exp, by_exp)
|
31
|
+
s(:call,
|
32
|
+
change(diff_exp),
|
33
|
+
:by,
|
34
|
+
by_exp
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def matcher_with_block(matcher_name, block)
|
39
|
+
s(:iter,
|
40
|
+
s(:call, nil, matcher_name),
|
41
|
+
0,
|
42
|
+
block
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def method_assert_difference(exp)
|
47
|
+
call = exp[1]
|
48
|
+
block = exp[3]
|
49
|
+
by = call[4]
|
50
|
+
what = parse(call[3][1])
|
51
|
+
matcher = by.nil? ? change(what) : change_by(what, by)
|
52
|
+
expect_to(matcher, block, false)
|
53
|
+
end
|
54
|
+
|
55
|
+
def method_assert_no_difference(exp)
|
56
|
+
call = exp[1]
|
57
|
+
block = exp[3]
|
58
|
+
what = parse(call[3][1])
|
59
|
+
expect_to_not(change(what), block, false)
|
60
|
+
end
|
61
|
+
|
62
|
+
def method_assert_nothing_raised(exp)
|
63
|
+
block = exp[3]
|
64
|
+
expect_to_not(raise_error, block, false)
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_assert_raise(iter)
|
68
|
+
method_assert_raises(iter)
|
69
|
+
end
|
70
|
+
|
71
|
+
def method_assert_raises(iter)
|
72
|
+
expect_to(raise_error(*iter.call_arguments), iter.block, false)
|
73
|
+
end
|
74
|
+
|
75
|
+
def method_refute_raise(iter)
|
76
|
+
method_refute_raises(iter)
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_refute_raises(iter)
|
80
|
+
expect_to_not(raise_error(*iter.call_arguments), iter.block, false)
|
81
|
+
end
|
82
|
+
|
83
|
+
def method_setup(exp)
|
84
|
+
replace_method_name(exp, :before)
|
85
|
+
end
|
86
|
+
|
87
|
+
def method_teardown(exp)
|
88
|
+
replace_method_name(exp, :after)
|
89
|
+
end
|
90
|
+
|
91
|
+
def name_of_processing_method(iter)
|
92
|
+
method_name = iter[1][2]
|
93
|
+
"method_#{method_name}".to_sym
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse(str)
|
97
|
+
RubyParser.new.parse(str)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Given a `Model::Iter`, returns a `Sexp`
|
101
|
+
def process_exp(exp)
|
102
|
+
if processable?(exp)
|
103
|
+
send_to_processing_method(exp)
|
104
|
+
else
|
105
|
+
process_uninteresting_iter(exp.sexp)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def processable?(iter)
|
110
|
+
if !iter.empty? && iter[1].sexp_type == :call
|
111
|
+
method_name = iter[1][2]
|
112
|
+
decision = "#{method_name}?".to_sym
|
113
|
+
iter.respond_to?(decision) && iter.public_send(decision)
|
114
|
+
else
|
115
|
+
false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def process_uninteresting_iter(exp)
|
120
|
+
iter = s(exp.shift)
|
121
|
+
until exp.empty?
|
122
|
+
iter << full_process(exp.shift)
|
123
|
+
end
|
124
|
+
iter
|
125
|
+
end
|
126
|
+
|
127
|
+
# Given `args` which came from an `assert_raise` or an
|
128
|
+
# `assert_raises`, return a `raise_error` matcher.
|
129
|
+
# When the last argument is a string, it represents the
|
130
|
+
# assertion failure message, and is discarded.
|
131
|
+
def raise_error(*args)
|
132
|
+
args.pop if !args.empty? && args.last.sexp_type == :str
|
133
|
+
matcher(:raise_error, *args)
|
134
|
+
end
|
135
|
+
|
136
|
+
def replace_method_name(exp, new_method)
|
137
|
+
iter = s(:iter, s(:call, nil, new_method))
|
138
|
+
exp.each do |e| iter << full_process(e) end
|
139
|
+
iter
|
140
|
+
end
|
141
|
+
|
142
|
+
def send_to_processing_method(exp)
|
143
|
+
send(name_of_processing_method(exp), exp)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest_to_rspec/errors'
|
4
|
+
require 'minitest_to_rspec/input/model/klass'
|
5
|
+
require 'minitest_to_rspec/input/subprocessors/base'
|
6
|
+
|
7
|
+
module MinitestToRspec
|
8
|
+
module Input
|
9
|
+
module Subprocessors
|
10
|
+
# Processes `s(:class, ..)` expressions.
|
11
|
+
class Klass < Base
|
12
|
+
# Takes `sexp`, a `:class` s-expression, and `rails`, a
|
13
|
+
# boolean indicating that `rspec-rails` conventions (like
|
14
|
+
# `:type` metadata) should be used.
|
15
|
+
def initialize(sexp, rails, mocha)
|
16
|
+
super(rails, mocha)
|
17
|
+
@exp = Model::Klass.new(sexp)
|
18
|
+
sexp.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
def process
|
22
|
+
sexp = head
|
23
|
+
ebk = @exp.block
|
24
|
+
if ebk.length > 1
|
25
|
+
sexp << block
|
26
|
+
elsif ebk.length == 1
|
27
|
+
sexp << full_process(ebk[0])
|
28
|
+
end
|
29
|
+
sexp
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Returns a :block S-expression, the contents of the class.
|
35
|
+
def block
|
36
|
+
processed = @exp.block.map { |line| full_process(line) }
|
37
|
+
s(:block, *processed)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Given a `test_class_name` like `BananaTest`, returns the
|
41
|
+
# described class, like `Banana`.
|
42
|
+
def described_class(test_class_name)
|
43
|
+
test_class_name.to_s.gsub(/Test\Z/, '').to_sym
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the head of the output Sexp. If it's a test case,
|
47
|
+
# an :iter representing an `RSpec.describe`. Otherwise, a :class.
|
48
|
+
def head
|
49
|
+
if @exp.test_case?
|
50
|
+
rspec_describe_block
|
51
|
+
else
|
52
|
+
s(:class, @exp.name, @exp.parent)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns an S-expression representing the
|
57
|
+
# RDM (RSpec Describe Metadata) hash
|
58
|
+
def rdm
|
59
|
+
s(:hash, s(:lit, :type), s(:lit, rdm_type))
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the RDM (RSpec Describe Metadata) type.
|
63
|
+
#
|
64
|
+
# > Model specs: type: :model
|
65
|
+
# > Controller specs: type: :controller
|
66
|
+
# > Request specs: type: :request
|
67
|
+
# > Feature specs: type: :feature
|
68
|
+
# > View specs: type: :view
|
69
|
+
# > Helper specs: type: :helper
|
70
|
+
# > Mailer specs: type: :mailer
|
71
|
+
# > Routing specs: type: :routing
|
72
|
+
# > http://bit.ly/1G5w7CJ
|
73
|
+
#
|
74
|
+
# TODO: Obviously, they're not all supported yet.
|
75
|
+
def rdm_type
|
76
|
+
if @exp.action_controller_test_case?
|
77
|
+
:controller
|
78
|
+
elsif @exp.draper_test_case?
|
79
|
+
:decorator
|
80
|
+
elsif @exp.action_mailer_test_case?
|
81
|
+
:mailer
|
82
|
+
else
|
83
|
+
:model
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def rspec_describe
|
88
|
+
const = s(:const, described_class(@exp.name))
|
89
|
+
call = s(:call, s(:const, :RSpec), :describe, const)
|
90
|
+
call << rdm if @rails
|
91
|
+
call
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns a S-expression representing a call to RSpec.describe
|
95
|
+
def rspec_describe_block
|
96
|
+
s(:iter, rspec_describe, 0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest_to_rspec/errors'
|
4
|
+
require 'minitest_to_rspec/type'
|
5
|
+
require 'minitest_to_rspec/input/model/call'
|
6
|
+
|
7
|
+
module MinitestToRspec
|
8
|
+
module Minitest
|
9
|
+
# Represents an `expects` or a `stubs` from mocha.
|
10
|
+
# Conceptually the same as `Rspec::Stub`.
|
11
|
+
class Stub
|
12
|
+
def initialize(call)
|
13
|
+
Type.assert(Input::Model::Call, call)
|
14
|
+
@call = call
|
15
|
+
end
|
16
|
+
|
17
|
+
# Given e.g. `X.any_instance.expects(:y)`, returns `X`.
|
18
|
+
def receiver
|
19
|
+
chain = @call.receiver_chain
|
20
|
+
last = chain[-1]
|
21
|
+
last.nil? ? chain[-2] : last
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns true if we are stubbing any instance of `receiver`.
|
25
|
+
def any_instance?
|
26
|
+
@call.calls_in_receiver_chain.any? { |i|
|
27
|
+
i.method_name.to_s.include?('any_instance')
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Given e.g. `expects(:y)`, returns `:y`.
|
32
|
+
def message
|
33
|
+
case @call.method_name
|
34
|
+
when :expects, :stubs
|
35
|
+
@call.arguments.first
|
36
|
+
else
|
37
|
+
call = the_call_to_stubs_or_expects
|
38
|
+
if call.nil?
|
39
|
+
raise UnknownVariant, 'not a mocha stub, no stubs/expects'
|
40
|
+
else
|
41
|
+
call.arguments.first
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def with
|
47
|
+
@call.find_call_in_receiver_chain(:with)&.arguments&.first
|
48
|
+
end
|
49
|
+
|
50
|
+
def returns
|
51
|
+
case @call.method_name
|
52
|
+
when :returns
|
53
|
+
@call.arguments.first
|
54
|
+
else
|
55
|
+
@call.find_call_in_receiver_chain(:returns)&.arguments&.first
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# TODO: add support for
|
60
|
+
# - at_least
|
61
|
+
# - at_least_once
|
62
|
+
# - at_most
|
63
|
+
# - at_most_once
|
64
|
+
# - never
|
65
|
+
def count
|
66
|
+
case @call.method_name
|
67
|
+
when :expects, :once
|
68
|
+
1
|
69
|
+
when :returns
|
70
|
+
the_call_to_stubs_or_expects.method_name == :expects ? 1 : nil
|
71
|
+
when :twice
|
72
|
+
2
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
# Given an `exp` representing a chain of calls, like
|
79
|
+
# `stubs(x).returns(y).once`, finds the call to `stubs` or `expects`.
|
80
|
+
def the_call_to_stubs_or_expects
|
81
|
+
@call.find_call_in_receiver_chain(%i[stubs expects])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -3,8 +3,9 @@
|
|
3
3
|
require 'minitest_to_rspec/type'
|
4
4
|
|
5
5
|
module MinitestToRspec
|
6
|
-
module
|
7
|
-
# Represents
|
6
|
+
module Rspec
|
7
|
+
# Represents a `receive` matcher from RSpec.
|
8
|
+
# Conceptually the same as `Minitest::Stub`.
|
8
9
|
class Stub
|
9
10
|
def initialize(receiver, any_instance, message, with, returns, count)
|
10
11
|
Type.assert(Sexp, receiver)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest_to_rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jared Beck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby2ruby
|
@@ -151,22 +151,21 @@ files:
|
|
151
151
|
- lib/minitest_to_rspec/cli.rb
|
152
152
|
- lib/minitest_to_rspec/converter.rb
|
153
153
|
- lib/minitest_to_rspec/errors.rb
|
154
|
-
- lib/minitest_to_rspec/
|
155
|
-
- lib/minitest_to_rspec/model/
|
156
|
-
- lib/minitest_to_rspec/model/
|
157
|
-
- lib/minitest_to_rspec/model/
|
158
|
-
- lib/minitest_to_rspec/model/
|
159
|
-
- lib/minitest_to_rspec/model/
|
160
|
-
- lib/minitest_to_rspec/
|
161
|
-
- lib/minitest_to_rspec/
|
162
|
-
- lib/minitest_to_rspec/
|
163
|
-
- lib/minitest_to_rspec/
|
154
|
+
- lib/minitest_to_rspec/input/model/base.rb
|
155
|
+
- lib/minitest_to_rspec/input/model/call.rb
|
156
|
+
- lib/minitest_to_rspec/input/model/defn.rb
|
157
|
+
- lib/minitest_to_rspec/input/model/hash_exp.rb
|
158
|
+
- lib/minitest_to_rspec/input/model/iter.rb
|
159
|
+
- lib/minitest_to_rspec/input/model/klass.rb
|
160
|
+
- lib/minitest_to_rspec/input/processor.rb
|
161
|
+
- lib/minitest_to_rspec/input/subprocessors/base.rb
|
162
|
+
- lib/minitest_to_rspec/input/subprocessors/call.rb
|
163
|
+
- lib/minitest_to_rspec/input/subprocessors/defn.rb
|
164
|
+
- lib/minitest_to_rspec/input/subprocessors/iter.rb
|
165
|
+
- lib/minitest_to_rspec/input/subprocessors/klass.rb
|
166
|
+
- lib/minitest_to_rspec/minitest/stub.rb
|
167
|
+
- lib/minitest_to_rspec/rspec/stub.rb
|
164
168
|
- lib/minitest_to_rspec/sexp_assertions.rb
|
165
|
-
- lib/minitest_to_rspec/subprocessors/base.rb
|
166
|
-
- lib/minitest_to_rspec/subprocessors/call.rb
|
167
|
-
- lib/minitest_to_rspec/subprocessors/defn.rb
|
168
|
-
- lib/minitest_to_rspec/subprocessors/iter.rb
|
169
|
-
- lib/minitest_to_rspec/subprocessors/klass.rb
|
170
169
|
- lib/minitest_to_rspec/type.rb
|
171
170
|
- lib/minitest_to_rspec/version.rb
|
172
171
|
- minitest_to_rspec.gemspec
|
@@ -190,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
189
|
version: '0'
|
191
190
|
requirements: []
|
192
191
|
rubyforge_project:
|
193
|
-
rubygems_version: 2.6
|
192
|
+
rubygems_version: 2.7.6
|
194
193
|
signing_key:
|
195
194
|
specification_version: 4
|
196
195
|
summary: Converts minitest files to rspec
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../sexp_assertions'
|
4
|
-
|
5
|
-
module MinitestToRspec
|
6
|
-
module Model
|
7
|
-
# Classes inheriting `Base` are simple data objects
|
8
|
-
# representing the S-expressions they are named after.
|
9
|
-
class Base
|
10
|
-
include SexpAssertions
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,165 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'base'
|
4
|
-
|
5
|
-
module MinitestToRspec
|
6
|
-
module Model
|
7
|
-
# Data object. Represents a `:call` s-expression.
|
8
|
-
class Call < Base
|
9
|
-
attr_reader :original
|
10
|
-
|
11
|
-
def initialize(exp)
|
12
|
-
assert_sexp_type(:call, exp)
|
13
|
-
@exp = exp.dup
|
14
|
-
@original = exp.dup
|
15
|
-
end
|
16
|
-
|
17
|
-
class << self
|
18
|
-
def assert_difference?(exp)
|
19
|
-
exp.sexp_type == :call && new(exp).assert_difference?
|
20
|
-
end
|
21
|
-
|
22
|
-
def assert_no_difference?(exp)
|
23
|
-
exp.sexp_type == :call && new(exp).assert_no_difference?
|
24
|
-
end
|
25
|
-
|
26
|
-
def assert_nothing_raised?(exp)
|
27
|
-
exp.sexp_type == :call && new(exp).assert_nothing_raised?
|
28
|
-
end
|
29
|
-
|
30
|
-
def assert_raise?(exp)
|
31
|
-
exp.sexp_type == :call && new(exp).assert_raise?
|
32
|
-
end
|
33
|
-
|
34
|
-
def assert_raises?(exp)
|
35
|
-
exp.sexp_type == :call && new(exp).assert_raises?
|
36
|
-
end
|
37
|
-
|
38
|
-
def method_name?(exp, name)
|
39
|
-
exp.sexp_type == :call && new(exp).method_name.to_s == name.to_s
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def arguments
|
44
|
-
@exp[3..-1] || []
|
45
|
-
end
|
46
|
-
|
47
|
-
def argument_types
|
48
|
-
arguments.map(&:sexp_type)
|
49
|
-
end
|
50
|
-
|
51
|
-
def assert_difference?
|
52
|
-
return false unless method_name == :assert_difference
|
53
|
-
[[:str], %i[str lit]].include?(argument_types)
|
54
|
-
end
|
55
|
-
|
56
|
-
def assert_no_difference?
|
57
|
-
method_name == :assert_no_difference &&
|
58
|
-
arguments.length == 1 &&
|
59
|
-
arguments[0].sexp_type == :str
|
60
|
-
end
|
61
|
-
|
62
|
-
def assert_nothing_raised?
|
63
|
-
method_name == :assert_nothing_raised && arguments.empty?
|
64
|
-
end
|
65
|
-
|
66
|
-
def assert_raise?
|
67
|
-
method_name == :assert_raise && raise_error_args?
|
68
|
-
end
|
69
|
-
|
70
|
-
def assert_raises?
|
71
|
-
method_name == :assert_raises && raise_error_args?
|
72
|
-
end
|
73
|
-
|
74
|
-
def calls_in_receiver_chain
|
75
|
-
receiver_chain.each_with_object([]) do |e, a|
|
76
|
-
next unless sexp_type?(:call, e)
|
77
|
-
a << self.class.new(e)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def find_call_in_receiver_chain(method_names)
|
82
|
-
name_array = [method_names].flatten
|
83
|
-
calls_in_receiver_chain.find { |i| name_array.include?(i.method_name) }
|
84
|
-
end
|
85
|
-
|
86
|
-
def method_name
|
87
|
-
@exp[2]
|
88
|
-
end
|
89
|
-
|
90
|
-
def num_arguments
|
91
|
-
arguments.length
|
92
|
-
end
|
93
|
-
|
94
|
-
def one_string_argument?
|
95
|
-
arguments.length == 1 && string?(arguments[0])
|
96
|
-
end
|
97
|
-
|
98
|
-
# Returns true if arguments can be processed into RSpec's `raise_error`
|
99
|
-
# matcher. When the last argument is a string, it represents the
|
100
|
-
# assertion failure message, which will be discarded later.
|
101
|
-
def raise_error_args?
|
102
|
-
arg_types = arguments.map(&:sexp_type)
|
103
|
-
[[], [:str], [:const], %i[const str]].include?(arg_types)
|
104
|
-
end
|
105
|
-
|
106
|
-
def receiver
|
107
|
-
@exp[1]
|
108
|
-
end
|
109
|
-
|
110
|
-
# Consider the following chain of method calls:
|
111
|
-
#
|
112
|
-
# @a.b.c
|
113
|
-
#
|
114
|
-
# whose S-expression is
|
115
|
-
#
|
116
|
-
# s(:call, s(:call, s(:call, nil, :a), :b), :c)
|
117
|
-
#
|
118
|
-
# the "receiver chain" is
|
119
|
-
#
|
120
|
-
# [
|
121
|
-
# s(:call, s(:call, nil, :a), :b),
|
122
|
-
# s(:call, nil, :a),
|
123
|
-
# nil
|
124
|
-
# ]
|
125
|
-
#
|
126
|
-
# The order of the returned array matches the order in which
|
127
|
-
# messages are received, i.e. the order of execution.
|
128
|
-
#
|
129
|
-
# Note that the final receiver `nil` is included. This `nil`
|
130
|
-
# represents the implicit receiver, e.g. `self` or `main`.
|
131
|
-
#
|
132
|
-
def receiver_chain
|
133
|
-
receivers = []
|
134
|
-
ptr = @exp
|
135
|
-
while sexp_type?(:call, ptr)
|
136
|
-
receivers << ptr[1]
|
137
|
-
ptr = ptr[1]
|
138
|
-
end
|
139
|
-
receivers
|
140
|
-
end
|
141
|
-
|
142
|
-
def receiver_chain_include?(method_name)
|
143
|
-
receiver_chain.compact.any? { |r|
|
144
|
-
self.class.method_name?(r, method_name)
|
145
|
-
}
|
146
|
-
end
|
147
|
-
|
148
|
-
def require_test_helper?
|
149
|
-
method_name == :require &&
|
150
|
-
one_string_argument? &&
|
151
|
-
arguments[0][1] == 'test_helper'
|
152
|
-
end
|
153
|
-
|
154
|
-
def question_mark_method?
|
155
|
-
method_name.to_s.end_with?('?')
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
|
160
|
-
def string?(exp)
|
161
|
-
exp.sexp_type == :str
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|