transpec 1.7.0 → 1.8.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 +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +66 -25
- data/README.md.erb +65 -24
- data/lib/transpec/cli.rb +2 -1
- data/lib/transpec/configuration.rb +1 -0
- data/lib/transpec/converter.rb +7 -1
- data/lib/transpec/option_parser.rb +15 -1
- data/lib/transpec/syntax/have.rb +2 -13
- data/lib/transpec/syntax/method_stub.rb +7 -17
- data/lib/transpec/syntax/mixin/any_instance_block.rb +14 -0
- data/lib/transpec/syntax/mixin/owned_matcher.rb +27 -0
- data/lib/transpec/syntax/receive.rb +2 -13
- data/lib/transpec/syntax/rspec_configure.rb +8 -2
- data/lib/transpec/syntax/rspec_configure/expectations.rb +1 -1
- data/lib/transpec/syntax/rspec_configure/framework.rb +114 -105
- data/lib/transpec/syntax/rspec_configure/mocks.rb +1 -1
- data/lib/transpec/syntax/should_receive.rb +17 -37
- data/lib/transpec/util.rb +6 -0
- data/lib/transpec/version.rb +1 -1
- data/spec/transpec/configuration_spec.rb +1 -0
- data/spec/transpec/converter_spec.rb +61 -5
- data/spec/transpec/option_parser_spec.rb +9 -0
- data/spec/transpec/syntax/have_spec.rb +3 -3
- data/spec/transpec/syntax/method_stub_spec.rb +42 -10
- data/spec/transpec/syntax/oneliner_should_spec.rb +12 -12
- data/spec/transpec/syntax/raise_error_spec.rb +5 -5
- data/spec/transpec/syntax/receive_spec.rb +4 -4
- data/spec/transpec/syntax/rspec_configure_spec.rb +1 -1
- data/spec/transpec/syntax/should_receive_spec.rb +13 -13
- data/tasks/readme.rake +2 -1
- data/transpec.gemspec +1 -1
- metadata +11 -4
@@ -55,6 +55,10 @@ module Transpec
|
|
55
55
|
check_syntax_availability(__method__)
|
56
56
|
end
|
57
57
|
|
58
|
+
def hash_arg?
|
59
|
+
arg_node.hash_type?
|
60
|
+
end
|
61
|
+
|
58
62
|
def allowize!(rspec_version)
|
59
63
|
# There's no way of unstubbing in #allow syntax.
|
60
64
|
return unless [:stub, :stub!, :stub_chain].include?(method_name)
|
@@ -90,7 +94,7 @@ module Transpec
|
|
90
94
|
if method_name == :stub_chain
|
91
95
|
[build_allow_to(:receive_message_chain), :allow_to_receive_message_chain]
|
92
96
|
else
|
93
|
-
if
|
97
|
+
if hash_arg?
|
94
98
|
if rspec_version.receive_messages_available?
|
95
99
|
[build_allow_to(:receive_messages), :allow_to_receive_messages]
|
96
100
|
else
|
@@ -181,7 +185,7 @@ module Transpec
|
|
181
185
|
if @method_stub.method_name == :stub_chain
|
182
186
|
syntax << '(:message1, :message2)'
|
183
187
|
else
|
184
|
-
syntax << (@method_stub.
|
188
|
+
syntax << (@method_stub.hash_arg? ? '(:message => value)' : '(:message)')
|
185
189
|
end
|
186
190
|
end
|
187
191
|
|
@@ -192,7 +196,7 @@ module Transpec
|
|
192
196
|
case @conversion_type
|
193
197
|
when :allow_to_receive
|
194
198
|
syntax << 'receive(:message)'
|
195
|
-
syntax << '.and_return(value)' if @method_stub.
|
199
|
+
syntax << '.and_return(value)' if @method_stub.hash_arg?
|
196
200
|
when :allow_to_receive_messages
|
197
201
|
syntax << 'receive_messages(:message => value)'
|
198
202
|
when :allow_to_receive_message_chain
|
@@ -219,20 +223,6 @@ module Transpec
|
|
219
223
|
syntax << '(:message)'
|
220
224
|
end
|
221
225
|
end
|
222
|
-
|
223
|
-
class AnyInstanceBlockRecord < Record
|
224
|
-
def initialize(method_stub, *)
|
225
|
-
@method_stub = method_stub
|
226
|
-
end
|
227
|
-
|
228
|
-
def original_syntax
|
229
|
-
"Klass.any_instance.#{@method_stub.method_name}(:message) { |arg| }"
|
230
|
-
end
|
231
|
-
|
232
|
-
def converted_syntax
|
233
|
-
"Klass.any_instance.#{@method_stub.method_name}(:message) { |instance, arg| }"
|
234
|
-
end
|
235
|
-
end
|
236
226
|
end
|
237
227
|
end
|
238
228
|
end
|
@@ -28,6 +28,20 @@ module Transpec
|
|
28
28
|
return node if node.block_type?
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
class AnyInstanceBlockRecord < Record
|
33
|
+
def initialize(host, *)
|
34
|
+
@host = host
|
35
|
+
end
|
36
|
+
|
37
|
+
def original_syntax
|
38
|
+
"Klass.any_instance.#{@host.method_name}(:message) { |arg| }"
|
39
|
+
end
|
40
|
+
|
41
|
+
def converted_syntax
|
42
|
+
"Klass.any_instance.#{@host.method_name}(:message) { |instance, arg| }"
|
43
|
+
end
|
44
|
+
end
|
31
45
|
end
|
32
46
|
end
|
33
47
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Transpec
|
6
|
+
class Syntax
|
7
|
+
module Mixin
|
8
|
+
module OwnedMatcher
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
def standalone?
|
13
|
+
false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(node, expectation, source_rewriter = nil, runtime_data = nil, report = nil)
|
18
|
+
@node = node
|
19
|
+
@expectation = expectation
|
20
|
+
@source_rewriter = source_rewriter
|
21
|
+
@runtime_data = runtime_data
|
22
|
+
@report = report || Report.new
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -2,31 +2,20 @@
|
|
2
2
|
|
3
3
|
require 'transpec/syntax'
|
4
4
|
require 'transpec/syntax/mixin/send'
|
5
|
+
require 'transpec/syntax/mixin/owned_matcher'
|
5
6
|
require 'transpec/syntax/mixin/any_instance_block'
|
6
7
|
|
7
8
|
module Transpec
|
8
9
|
class Syntax
|
9
10
|
class Receive < Syntax
|
10
|
-
include Mixin::Send, Mixin::AnyInstanceBlock
|
11
|
+
include Mixin::Send, Mixin::OwnedMatcher, Mixin::AnyInstanceBlock
|
11
12
|
|
12
13
|
attr_reader :expectation
|
13
14
|
|
14
|
-
def self.standalone?
|
15
|
-
false
|
16
|
-
end
|
17
|
-
|
18
15
|
def self.target_method?(receiver_node, method_name)
|
19
16
|
receiver_node.nil? && method_name == :receive
|
20
17
|
end
|
21
18
|
|
22
|
-
def initialize(node, expectation, source_rewriter = nil, runtime_data = nil, report = nil)
|
23
|
-
@node = node
|
24
|
-
@expectation = expectation
|
25
|
-
@source_rewriter = source_rewriter
|
26
|
-
@runtime_data = runtime_data
|
27
|
-
@report = report || Report.new
|
28
|
-
end
|
29
|
-
|
30
19
|
def add_receiver_arg_to_any_instance_implementation_block!
|
31
20
|
added = super
|
32
21
|
return unless added
|
@@ -9,6 +9,8 @@ module Transpec
|
|
9
9
|
require 'transpec/syntax/rspec_configure/expectations'
|
10
10
|
require 'transpec/syntax/rspec_configure/mocks'
|
11
11
|
|
12
|
+
include Util
|
13
|
+
|
12
14
|
def self.target_node?(node, runtime_data = nil)
|
13
15
|
return false unless node && node.block_type?
|
14
16
|
send_node = node.children.first
|
@@ -17,11 +19,15 @@ module Transpec
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def expectations
|
20
|
-
@expectations ||= Expectations.new(
|
22
|
+
@expectations ||= Expectations.new(self, source_rewriter)
|
21
23
|
end
|
22
24
|
|
23
25
|
def mocks
|
24
|
-
@mocks ||= Mocks.new(
|
26
|
+
@mocks ||= Mocks.new(self, source_rewriter)
|
27
|
+
end
|
28
|
+
|
29
|
+
def block_arg_name
|
30
|
+
first_block_arg_name(node)
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
@@ -7,65 +7,18 @@ module Transpec
|
|
7
7
|
class Syntax
|
8
8
|
class RSpecConfigure
|
9
9
|
class Framework
|
10
|
-
|
11
|
-
def syntaxes
|
12
|
-
return [] unless syntaxes_node
|
13
|
-
|
14
|
-
case syntaxes_node.type
|
15
|
-
when :sym
|
16
|
-
[syntaxes_node.children.first]
|
17
|
-
when :array
|
18
|
-
syntaxes_node.children.map do |child_node|
|
19
|
-
child_node.children.first
|
20
|
-
end
|
21
|
-
else
|
22
|
-
fail UnknownSyntaxError, "Unknown syntax specification: #{syntaxes_node}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def syntaxes=(syntaxes)
|
27
|
-
unless [Array, Symbol].include?(syntaxes.class)
|
28
|
-
fail ArgumentError, 'Syntaxes must be either an array or a symbol.'
|
29
|
-
end
|
30
|
-
|
31
|
-
set_configuration!(:syntax, syntaxes.inspect)
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def syntaxes_node
|
37
|
-
return @syntaxes_node if instance_variable_defined?(:@syntaxes_node)
|
38
|
-
|
39
|
-
syntax_setter_node = find_configuration_node(:syntax=)
|
40
|
-
|
41
|
-
@syntaxes_node = if syntax_setter_node
|
42
|
-
syntax_setter_node.children[2]
|
43
|
-
else
|
44
|
-
nil
|
45
|
-
end
|
46
|
-
end
|
10
|
+
include Util, ::AST::Sexp
|
47
11
|
|
48
|
-
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
12
|
+
attr_reader :rspec_configure
|
54
13
|
|
55
|
-
|
56
|
-
|
57
|
-
class RSpecConfigure
|
58
|
-
class Framework
|
59
|
-
include SyntaxConfiguration, Util, ::AST::Sexp
|
60
|
-
|
61
|
-
def initialize(rspec_configure_node, source_rewriter)
|
62
|
-
@rspec_configure_node = rspec_configure_node
|
14
|
+
def initialize(rspec_configure, source_rewriter)
|
15
|
+
@rspec_configure = rspec_configure
|
63
16
|
@source_rewriter = source_rewriter
|
64
17
|
end
|
65
18
|
|
66
19
|
private
|
67
20
|
|
68
|
-
def
|
21
|
+
def block_method_name
|
69
22
|
fail NotImplementedError
|
70
23
|
end
|
71
24
|
|
@@ -80,86 +33,142 @@ module Transpec
|
|
80
33
|
end
|
81
34
|
end
|
82
35
|
|
83
|
-
def add_configuration!(config_name, value)
|
84
|
-
block_arg_name = framework_block_arg_name || new_framework_block_arg_name
|
85
|
-
|
86
|
-
lines = [framework_indentation + "#{block_arg_name}.#{config_name} = #{value}"]
|
87
|
-
|
88
|
-
unless framework_block_node
|
89
|
-
indentation = indentation_of_line(@rspec_configure_node) + ' '
|
90
|
-
block_invocation = format(
|
91
|
-
'%s.%s :rspec do |%s|',
|
92
|
-
rspec_configure_block_arg_name, framework_block_method_name, block_arg_name
|
93
|
-
)
|
94
|
-
lines.unshift(indentation + block_invocation)
|
95
|
-
lines << indentation + 'end'
|
96
|
-
end
|
97
|
-
|
98
|
-
block_node = framework_block_node || @rspec_configure_node
|
99
|
-
insertion_position = beginning_of_line_range(block_node.loc.end)
|
100
|
-
|
101
|
-
lines.unshift('') unless (block_node.loc.end.line - block_node.loc.begin.line) <= 1
|
102
|
-
lines.map! { |line| line + "\n" }
|
103
|
-
|
104
|
-
@source_rewriter.insert_before(insertion_position, lines.join(''))
|
105
|
-
end
|
106
|
-
|
107
36
|
def find_configuration_node(configuration_method_name)
|
108
|
-
return nil unless
|
37
|
+
return nil unless block_node
|
109
38
|
|
110
39
|
configuration_method_name = configuration_method_name.to_sym
|
111
40
|
|
112
|
-
|
41
|
+
block_node.each_descendent_node.find do |node|
|
113
42
|
next unless node.send_type?
|
114
43
|
receiver_node, method_name, = *node
|
115
|
-
next unless receiver_node == s(:lvar,
|
44
|
+
next unless receiver_node == s(:lvar, block_arg_name)
|
116
45
|
method_name == configuration_method_name
|
117
46
|
end
|
118
47
|
end
|
119
48
|
|
120
|
-
def
|
121
|
-
return nil unless
|
122
|
-
first_block_arg_name(
|
49
|
+
def block_arg_name
|
50
|
+
return nil unless block_node
|
51
|
+
first_block_arg_name(block_node)
|
123
52
|
end
|
124
53
|
|
125
|
-
def
|
126
|
-
return @
|
54
|
+
def block_node
|
55
|
+
return @block_node if instance_variable_defined?(:@block_node)
|
127
56
|
|
128
|
-
@
|
57
|
+
@block_node = rspec_configure.node.each_descendent_node.find do |node|
|
129
58
|
next unless node.block_type?
|
130
59
|
send_node = node.children.first
|
131
60
|
receiver_node, method_name, *_ = *send_node
|
132
|
-
next unless receiver_node == s(:lvar,
|
133
|
-
method_name ==
|
61
|
+
next unless receiver_node == s(:lvar, rspec_configure.block_arg_name)
|
62
|
+
method_name == block_method_name
|
134
63
|
# TODO: Check expectation framework.
|
135
64
|
end
|
136
65
|
end
|
137
66
|
|
138
|
-
|
139
|
-
|
140
|
-
|
67
|
+
module ConfigurationAddition
|
68
|
+
def add_configuration!(config_name, value)
|
69
|
+
lines = [body_indentation + "#{config_variable_name}.#{config_name} = #{value}"]
|
141
70
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
71
|
+
unless block_node
|
72
|
+
lines.unshift(framework_begin_code)
|
73
|
+
lines << framework_end_code
|
74
|
+
end
|
75
|
+
|
76
|
+
lines.unshift('') unless empty_block_body?(block_node_to_insert_code)
|
77
|
+
lines.map! { |line| line + "\n" }
|
78
|
+
|
79
|
+
insertion_position = beginning_of_line_range(block_node_to_insert_code.loc.end)
|
80
|
+
@source_rewriter.insert_before(insertion_position, lines.join(''))
|
81
|
+
end
|
82
|
+
|
83
|
+
def config_variable_name
|
84
|
+
block_arg_name || new_config_variable_name
|
85
|
+
end
|
86
|
+
|
87
|
+
def new_config_variable_name
|
88
|
+
case rspec_configure.block_arg_name
|
89
|
+
when :rspec then self.class.name.split('::').last.downcase
|
90
|
+
when :c then 'config'
|
91
|
+
else 'c'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def body_indentation
|
96
|
+
if block_node
|
97
|
+
indentation_of_line(block_node) + (' ' * 2)
|
98
|
+
else
|
99
|
+
indentation_of_line(rspec_configure.node) + (' ' * 4)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def framework_begin_code
|
104
|
+
code = format(
|
105
|
+
'%s.%s :rspec do |%s|',
|
106
|
+
rspec_configure.block_arg_name, block_method_name, config_variable_name
|
107
|
+
)
|
108
|
+
rspec_configure_body_indentation + code
|
147
109
|
end
|
148
|
-
end
|
149
110
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
111
|
+
def framework_end_code
|
112
|
+
rspec_configure_body_indentation + 'end'
|
113
|
+
end
|
114
|
+
|
115
|
+
def rspec_configure_body_indentation
|
116
|
+
indentation_of_line(rspec_configure.node) + (' ' * 2)
|
117
|
+
end
|
118
|
+
|
119
|
+
def block_node_to_insert_code
|
120
|
+
block_node || rspec_configure.node
|
121
|
+
end
|
122
|
+
|
123
|
+
def empty_block_body?(block_node)
|
124
|
+
(block_node.loc.end.line - block_node.loc.begin.line) <= 1
|
155
125
|
end
|
156
126
|
end
|
157
127
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
128
|
+
include ConfigurationAddition
|
129
|
+
|
130
|
+
module SyntaxConfiguration
|
131
|
+
def syntaxes
|
132
|
+
return [] unless syntaxes_node
|
133
|
+
|
134
|
+
case syntaxes_node.type
|
135
|
+
when :sym
|
136
|
+
[syntaxes_node.children.first]
|
137
|
+
when :array
|
138
|
+
syntaxes_node.children.map do |child_node|
|
139
|
+
child_node.children.first
|
140
|
+
end
|
141
|
+
else
|
142
|
+
fail UnknownSyntaxError, "Unknown syntax specification: #{syntaxes_node}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def syntaxes=(syntaxes)
|
147
|
+
unless [Array, Symbol].include?(syntaxes.class)
|
148
|
+
fail ArgumentError, 'Syntaxes must be either an array or a symbol.'
|
149
|
+
end
|
150
|
+
|
151
|
+
set_configuration!(:syntax, syntaxes.inspect)
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def syntaxes_node
|
157
|
+
return @syntaxes_node if instance_variable_defined?(:@syntaxes_node)
|
158
|
+
|
159
|
+
syntax_setter_node = find_configuration_node(:syntax=)
|
160
|
+
|
161
|
+
@syntaxes_node = if syntax_setter_node
|
162
|
+
syntax_setter_node.children[2]
|
163
|
+
else
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class UnknownSyntaxError < StandardError; end
|
162
169
|
end
|
170
|
+
|
171
|
+
include SyntaxConfiguration
|
163
172
|
end
|
164
173
|
end
|
165
174
|
end
|