transpec 0.1.2 → 0.1.3
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 +2 -0
- data/CHANGELOG.md +6 -0
- data/Guardfile +1 -0
- data/Rakefile +2 -138
- data/lib/transpec/ast/scanner.rb +5 -19
- data/lib/transpec/context.rb +101 -0
- data/lib/transpec/rewriter.rb +3 -4
- data/lib/transpec/syntax.rb +8 -4
- data/lib/transpec/syntax/matcher.rb +74 -36
- data/lib/transpec/syntax/method_stub.rb +7 -28
- data/lib/transpec/syntax/send_node_syntax.rb +12 -0
- data/lib/transpec/syntax/should.rb +2 -2
- data/lib/transpec/syntax/should_receive.rb +1 -1
- data/lib/transpec/version.rb +1 -1
- data/spec/spec_helper.rb +12 -15
- data/spec/support/shared_context.rb +0 -3
- data/spec/transpec/ast/scanner_spec.rb +0 -53
- data/spec/transpec/context_spec.rb +256 -0
- data/spec/transpec/syntax/be_close_spec.rb +0 -3
- data/spec/transpec/syntax/double_spec.rb +0 -3
- data/spec/transpec/syntax/matcher_spec.rb +171 -3
- data/spec/transpec/syntax/method_stub_spec.rb +22 -3
- data/spec/transpec/syntax/raise_error_spec.rb +0 -3
- data/spec/transpec/syntax/rspec_configure_spec.rb +0 -3
- data/spec/transpec/syntax/should_receive_spec.rb +3 -2
- data/spec/transpec/syntax/should_spec.rb +4 -0
- data/tasks/ci/spec.rake +14 -0
- data/tasks/readme.rake +18 -0
- data/tasks/test.rake +164 -0
- metadata +8 -7
- data/lib/transpec/ast/scope_stack.rb +0 -78
- data/spec/spec_spec.rb +0 -51
- data/spec/transpec/ast/scope_stack_spec.rb +0 -95
@@ -11,7 +11,10 @@ module Transpec
|
|
11
11
|
class MethodStub < Syntax
|
12
12
|
include AbleToAllowNoMessage, AbleToTargetAnyInstance, Util
|
13
13
|
|
14
|
-
|
14
|
+
CLASSES_DEFINING_OWN_STUB_METHOD = [
|
15
|
+
'Typhoeus', # https://github.com/typhoeus/typhoeus/blob/6a59c62/lib/typhoeus.rb#L66-L85
|
16
|
+
'Excon' # https://github.com/geemus/excon/blob/6af4f9c/lib/excon.rb#L143-L178
|
17
|
+
]
|
15
18
|
|
16
19
|
def allowize!
|
17
20
|
# There's no way of unstubbing in #allow syntax.
|
@@ -19,7 +22,7 @@ module Transpec
|
|
19
22
|
|
20
23
|
fail 'Already replaced deprecated method, cannot allowize.' if @replaced_deprecated_method
|
21
24
|
|
22
|
-
unless
|
25
|
+
unless context.in_example_group?
|
23
26
|
fail NotInExampleGroupContextError.new(selector_range, "##{method_name}", '#allow')
|
24
27
|
end
|
25
28
|
|
@@ -54,7 +57,7 @@ module Transpec
|
|
54
57
|
def self.target_receiver_node?(node)
|
55
58
|
return false if node.nil?
|
56
59
|
const_name = Util.const_name(node)
|
57
|
-
!
|
60
|
+
!CLASSES_DEFINING_OWN_STUB_METHOD.include?(const_name)
|
58
61
|
end
|
59
62
|
|
60
63
|
def self.target_method_names
|
@@ -76,7 +79,7 @@ module Transpec
|
|
76
79
|
|
77
80
|
def build_allow_expression(message_node, return_value_node = nil, keep_form_around_arg = true)
|
78
81
|
expression = allow_source
|
79
|
-
expression <<
|
82
|
+
expression << range_in_between_receiver_and_selector.source
|
80
83
|
expression << 'to receive'
|
81
84
|
expression << (keep_form_around_arg ? range_in_between_selector_and_arg.source : '(')
|
82
85
|
expression << message_source(message_node)
|
@@ -104,30 +107,6 @@ module Transpec
|
|
104
107
|
message_source.prepend(':') if node.type == :sym && !message_source.start_with?(':')
|
105
108
|
message_source
|
106
109
|
end
|
107
|
-
|
108
|
-
def range_in_between_subject_and_selector
|
109
|
-
Parser::Source::Range.new(
|
110
|
-
subject_range.source_buffer,
|
111
|
-
subject_range.end_pos,
|
112
|
-
selector_range.begin_pos
|
113
|
-
)
|
114
|
-
end
|
115
|
-
|
116
|
-
def range_in_between_selector_and_arg
|
117
|
-
Parser::Source::Range.new(
|
118
|
-
selector_range.source_buffer,
|
119
|
-
selector_range.end_pos,
|
120
|
-
arg_range.begin_pos
|
121
|
-
)
|
122
|
-
end
|
123
|
-
|
124
|
-
def range_after_arg
|
125
|
-
Parser::Source::Range.new(
|
126
|
-
arg_range.source_buffer,
|
127
|
-
arg_range.end_pos,
|
128
|
-
expression_range.end_pos
|
129
|
-
)
|
130
|
-
end
|
131
110
|
end
|
132
111
|
end
|
133
112
|
end
|
@@ -36,6 +36,18 @@ module Transpec
|
|
36
36
|
def parentheses_range
|
37
37
|
selector_range.end.join(expression_range.end)
|
38
38
|
end
|
39
|
+
|
40
|
+
def range_in_between_receiver_and_selector
|
41
|
+
receiver_range.end.join(selector_range.begin)
|
42
|
+
end
|
43
|
+
|
44
|
+
def range_in_between_selector_and_arg
|
45
|
+
selector_range.end.join(arg_range.begin)
|
46
|
+
end
|
47
|
+
|
48
|
+
def range_after_arg
|
49
|
+
arg_range.end.join(expression_range.end)
|
50
|
+
end
|
39
51
|
end
|
40
52
|
end
|
41
53
|
end
|
@@ -15,7 +15,7 @@ module Transpec
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def expectize!(negative_form = 'not_to', parenthesize_matcher_arg = true)
|
18
|
-
unless
|
18
|
+
unless context.in_example_group?
|
19
19
|
fail NotInExampleGroupContextError.new(selector_range, "##{method_name}", '#expect')
|
20
20
|
end
|
21
21
|
|
@@ -31,7 +31,7 @@ module Transpec
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def matcher
|
34
|
-
@matcher ||= Matcher.new(matcher_node,
|
34
|
+
@matcher ||= Matcher.new(matcher_node, @source_rewriter)
|
35
35
|
end
|
36
36
|
|
37
37
|
def matcher_node
|
data/lib/transpec/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,6 @@ RSpec.configure do |config|
|
|
12
12
|
|
13
13
|
config.color_enabled = true
|
14
14
|
config.treat_symbols_as_metadata_keys_with_true_values = true
|
15
|
-
config.filter_run_excluding do_not_run_in_converted_spec: ENV['TRANSPEC_CONVERTED_SPEC']
|
16
15
|
|
17
16
|
config.before(:all) do
|
18
17
|
require 'rainbow'
|
@@ -25,22 +24,20 @@ RSpec.configure do |config|
|
|
25
24
|
end
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
SimpleCov.coverage_dir(File.join('spec', 'coverage'))
|
27
|
+
require 'simplecov'
|
28
|
+
SimpleCov.coverage_dir(File.join('spec', 'coverage'))
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
30
|
+
if ENV['TRAVIS']
|
31
|
+
require 'coveralls'
|
32
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
33
|
+
elsif ENV['CI']
|
34
|
+
require 'simplecov-rcov'
|
35
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
36
|
+
end
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
38
|
+
SimpleCov.start do
|
39
|
+
add_filter '/spec/'
|
40
|
+
add_filter '/vendor/bundle/'
|
44
41
|
end
|
45
42
|
|
46
43
|
Dir[File.join(File.dirname(__FILE__), 'support', '*')].each do |path|
|
@@ -33,15 +33,12 @@ shared_context 'should object' do
|
|
33
33
|
return Transpec::Syntax::Should.new(
|
34
34
|
node,
|
35
35
|
ancestor_nodes,
|
36
|
-
in_example_group_context?,
|
37
36
|
source_rewriter
|
38
37
|
)
|
39
38
|
end
|
40
39
|
|
41
40
|
fail 'No should node is found!'
|
42
41
|
end
|
43
|
-
|
44
|
-
let(:in_example_group_context?) { true }
|
45
42
|
end
|
46
43
|
|
47
44
|
shared_context 'isolated environment' do
|
@@ -119,59 +119,6 @@ module Transpec
|
|
119
119
|
index.should_not == 0
|
120
120
|
end
|
121
121
|
end
|
122
|
-
|
123
|
-
describe '#scope_stack' do
|
124
|
-
def brief_of_node(node)
|
125
|
-
brief = node.type.to_s
|
126
|
-
node.children.each do |child|
|
127
|
-
break if child.is_a?(Parser::AST::Node)
|
128
|
-
brief << " #{child.inspect}"
|
129
|
-
end
|
130
|
-
brief
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'returns current scope stack' do
|
134
|
-
scanner = Scanner.new do |node|
|
135
|
-
expected_scope_stack = begin
|
136
|
-
case brief_of_node(node)
|
137
|
-
when 'lvasgn :some_var'
|
138
|
-
[]
|
139
|
-
when 'send nil :prepare_something'
|
140
|
-
[:rspec_configure, :block]
|
141
|
-
when 'module'
|
142
|
-
[]
|
143
|
-
when 'const nil :SomeModule'
|
144
|
-
# [:module] # TODO
|
145
|
-
when 'casgn nil :SOME_CONST'
|
146
|
-
[:module]
|
147
|
-
when 'send nil :describe'
|
148
|
-
# [:module] # TODO
|
149
|
-
when 'def :some_method'
|
150
|
-
[:module, :example_group]
|
151
|
-
when 'arg :some_arg'
|
152
|
-
# [:module, :example_group] # TODO
|
153
|
-
when 'send nil :do_something'
|
154
|
-
[:module, :example_group, :def]
|
155
|
-
when 'send nil :it'
|
156
|
-
# [:module, :example_group] # TODO
|
157
|
-
when 'str "is 1"'
|
158
|
-
# [:module, :example_group] # TODO
|
159
|
-
when 'send nil :something'
|
160
|
-
[:module, :example_group, :block]
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
# TODO: Some scope nodes have special child nodes
|
165
|
-
# such as their arguments or their subject.
|
166
|
-
# But from scope point of view, the child nodes are not in the parent's scope,
|
167
|
-
# they should be in the next outer scope.
|
168
|
-
|
169
|
-
scanner.scope_stack.should == expected_scope_stack if expected_scope_stack
|
170
|
-
end
|
171
|
-
|
172
|
-
scanner.scan(ast, true)
|
173
|
-
end
|
174
|
-
end
|
175
122
|
end
|
176
123
|
end
|
177
124
|
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'transpec/context'
|
5
|
+
|
6
|
+
module Transpec
|
7
|
+
describe Context do
|
8
|
+
include_context 'parsed objects'
|
9
|
+
|
10
|
+
def node_id(node)
|
11
|
+
id = node.type.to_s
|
12
|
+
node.children.each do |child|
|
13
|
+
break if child.is_a?(Parser::AST::Node)
|
14
|
+
id << " #{child.inspect}"
|
15
|
+
end
|
16
|
+
id
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#scopes' do
|
20
|
+
let(:source) do
|
21
|
+
<<-END
|
22
|
+
some_var = 1
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
config.before do
|
26
|
+
prepare_something
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module SomeModule
|
31
|
+
SOME_CONST = 1
|
32
|
+
|
33
|
+
describe 'something' do
|
34
|
+
def some_method(some_arg)
|
35
|
+
do_something
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'is 1' do
|
39
|
+
something.should == 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
END
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'returns scope stack' do
|
47
|
+
AST::Scanner.scan(ast) do |node, ancestor_nodes|
|
48
|
+
expected_scopes = begin
|
49
|
+
case node_id(node)
|
50
|
+
when 'lvasgn :some_var'
|
51
|
+
[]
|
52
|
+
when 'send nil :prepare_something'
|
53
|
+
[:rspec_configure, :block]
|
54
|
+
when 'module'
|
55
|
+
[]
|
56
|
+
when 'const nil :SomeModule'
|
57
|
+
# [:module] # TODO
|
58
|
+
when 'casgn nil :SOME_CONST'
|
59
|
+
[:module]
|
60
|
+
when 'send nil :describe'
|
61
|
+
# [:module] # TODO
|
62
|
+
when 'def :some_method'
|
63
|
+
[:module, :example_group]
|
64
|
+
when 'arg :some_arg'
|
65
|
+
# [:module, :example_group] # TODO
|
66
|
+
when 'send nil :do_something'
|
67
|
+
[:module, :example_group, :def]
|
68
|
+
when 'send nil :it'
|
69
|
+
# [:module, :example_group] # TODO
|
70
|
+
when 'str "is 1"'
|
71
|
+
# [:module, :example_group] # TODO
|
72
|
+
when 'send nil :something'
|
73
|
+
[:module, :example_group, :block]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# TODO: Some scope nodes have special child nodes
|
78
|
+
# such as their arguments or their subject.
|
79
|
+
# But from scope point of view, the child nodes are not in the parent's scope,
|
80
|
+
# they should be in the next outer scope.
|
81
|
+
|
82
|
+
next unless expected_scopes
|
83
|
+
|
84
|
+
context_object = Context.new(ancestor_nodes)
|
85
|
+
context_object.scopes.should == expected_scopes
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#in_example_group?' do
|
91
|
+
let(:source) do
|
92
|
+
<<-END
|
93
|
+
top
|
94
|
+
|
95
|
+
def some_method
|
96
|
+
imethod_top
|
97
|
+
|
98
|
+
1.times do
|
99
|
+
block_imethod_top
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'foo' do
|
104
|
+
describe_top
|
105
|
+
|
106
|
+
def some_method
|
107
|
+
imethod_describe_top
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'is an example' do
|
111
|
+
block_describe_top
|
112
|
+
|
113
|
+
class SomeClass
|
114
|
+
class_block_describe_top
|
115
|
+
|
116
|
+
def some_method
|
117
|
+
imethod_class_block_describe_top
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
module SomeModule
|
124
|
+
describe 'bar' do
|
125
|
+
describe_module
|
126
|
+
|
127
|
+
def some_method
|
128
|
+
imethod_describe_module
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'is an example' do
|
132
|
+
block_describe_module
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
module AnotherModule
|
138
|
+
def some_method
|
139
|
+
imethod_module
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class SomeClass
|
144
|
+
def some_method
|
145
|
+
imethod_class
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
RSpec.configure do |config|
|
150
|
+
rspecconfigure
|
151
|
+
|
152
|
+
def some_method
|
153
|
+
imethod_rspecconfigure
|
154
|
+
end
|
155
|
+
|
156
|
+
config.before do
|
157
|
+
block_rspecconfigure
|
158
|
+
end
|
159
|
+
end
|
160
|
+
END
|
161
|
+
end
|
162
|
+
|
163
|
+
let(:context_object) do
|
164
|
+
AST::Scanner.scan(ast) do |node, ancestor_nodes|
|
165
|
+
next unless node_id(node) == target_node_id
|
166
|
+
return Context.new(ancestor_nodes)
|
167
|
+
end
|
168
|
+
|
169
|
+
fail 'Target node not found!'
|
170
|
+
end
|
171
|
+
|
172
|
+
subject { context_object.in_example_group? }
|
173
|
+
|
174
|
+
context 'when in top level' do
|
175
|
+
let(:target_node_id) { 'send nil :top' }
|
176
|
+
it { should be_false }
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'when in an instance method in top level' do
|
180
|
+
let(:target_node_id) { 'send nil :imethod_top' }
|
181
|
+
it { should be_true }
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when in a block in an instance method in top level' do
|
185
|
+
let(:target_node_id) { 'send nil :block_imethod_top' }
|
186
|
+
it { should be_true }
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when in #describe block in top level' do
|
190
|
+
let(:target_node_id) { 'send nil :describe_top' }
|
191
|
+
it { should be_false }
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'when in an instance method in #describe block in top level' do
|
195
|
+
let(:target_node_id) { 'send nil :imethod_describe_top' }
|
196
|
+
it { should be_true }
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'when in a block in #describe block in top level' do
|
200
|
+
let(:target_node_id) { 'send nil :block_describe_top' }
|
201
|
+
it { should be_true }
|
202
|
+
end
|
203
|
+
|
204
|
+
context 'when in a class in a block in #describe block' do
|
205
|
+
let(:target_node_id) { 'send nil :class_block_describe_top' }
|
206
|
+
it { should be_false }
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when in an instance method in a class in a block in #describe block' do
|
210
|
+
let(:target_node_id) { 'send nil :imethod_class_block_describe_top' }
|
211
|
+
it { should be_false }
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'when in #describe block in a module' do
|
215
|
+
let(:target_node_id) { 'send nil :describe_module' }
|
216
|
+
it { should be_false }
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when in an instance method in #describe block in a module' do
|
220
|
+
let(:target_node_id) { 'send nil :imethod_describe_module' }
|
221
|
+
it { should be_true }
|
222
|
+
end
|
223
|
+
|
224
|
+
context 'when in a block in #describe block in a module' do
|
225
|
+
let(:target_node_id) { 'send nil :block_describe_module' }
|
226
|
+
it { should be_true }
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'when in an instance method in a module' do
|
230
|
+
# Instance methods of module can be used by `include SomeModule` in #describe block.
|
231
|
+
let(:target_node_id) { 'send nil :imethod_module' }
|
232
|
+
it { should be_true }
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'when in an instance method in a class' do
|
236
|
+
let(:target_node_id) { 'send nil :imethod_class' }
|
237
|
+
it { should be_false }
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'when in RSpec.configure' do
|
241
|
+
let(:target_node_id) { 'send nil :rspecconfigure' }
|
242
|
+
it { should be_false }
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'when in a block in RSpec.configure' do
|
246
|
+
let(:target_node_id) { 'send nil :block_rspecconfigure' }
|
247
|
+
it { should be_true }
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'when in an instance method in RSpec.configure' do
|
251
|
+
let(:target_node_id) { 'send nil :imethod_rspecconfigure' }
|
252
|
+
it { should be_true }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|