transpec 0.2.6 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +10 -0
- data/README.md +111 -56
- data/README.md.erb +117 -62
- data/lib/transpec/ast/node.rb +41 -0
- data/lib/transpec/base_rewriter.rb +55 -0
- data/lib/transpec/cli.rb +43 -153
- data/lib/transpec/configuration.rb +13 -9
- data/lib/transpec/{rewriter.rb → converter.rb} +44 -71
- data/lib/transpec/dynamic_analyzer/rewriter.rb +94 -0
- data/lib/transpec/dynamic_analyzer/runtime_data.rb +27 -0
- data/lib/transpec/dynamic_analyzer.rb +166 -0
- data/lib/transpec/file_finder.rb +53 -0
- data/lib/transpec/option_parser.rb +166 -0
- data/lib/transpec/{context.rb → static_context_inspector.rb} +2 -2
- data/lib/transpec/syntax/be_close.rb +7 -9
- data/lib/transpec/syntax/double.rb +6 -10
- data/lib/transpec/syntax/expect.rb +35 -0
- data/lib/transpec/syntax/have.rb +195 -0
- data/lib/transpec/syntax/method_stub.rb +22 -27
- data/lib/transpec/syntax/mixin/allow_no_message.rb +73 -0
- data/lib/transpec/syntax/mixin/any_instance.rb +22 -0
- data/lib/transpec/syntax/mixin/expectizable.rb +26 -0
- data/lib/transpec/syntax/mixin/have_matcher.rb +23 -0
- data/lib/transpec/syntax/mixin/monkey_patch.rb +37 -0
- data/lib/transpec/syntax/mixin/send.rb +109 -0
- data/lib/transpec/syntax/{matcher.rb → operator_matcher.rb} +27 -14
- data/lib/transpec/syntax/raise_error.rb +6 -10
- data/lib/transpec/syntax/rspec_configure.rb +29 -28
- data/lib/transpec/syntax/should.rb +45 -15
- data/lib/transpec/syntax/should_receive.rb +44 -16
- data/lib/transpec/syntax.rb +29 -21
- data/lib/transpec/util.rb +12 -2
- data/lib/transpec/version.rb +3 -3
- data/spec/spec_helper.rb +8 -6
- data/spec/support/cache_helper.rb +50 -0
- data/spec/support/shared_context.rb +49 -1
- data/spec/transpec/ast/node_spec.rb +65 -0
- data/spec/transpec/cli_spec.rb +33 -242
- data/spec/transpec/commit_message_spec.rb +2 -2
- data/spec/transpec/configuration_spec.rb +12 -8
- data/spec/transpec/{rewriter_spec.rb → converter_spec.rb} +198 -148
- data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +183 -0
- data/spec/transpec/dynamic_analyzer_spec.rb +164 -0
- data/spec/transpec/file_finder_spec.rb +118 -0
- data/spec/transpec/option_parser_spec.rb +185 -0
- data/spec/transpec/{context_spec.rb → static_context_inspector_spec.rb} +27 -12
- data/spec/transpec/syntax/be_close_spec.rb +8 -4
- data/spec/transpec/syntax/double_spec.rb +105 -12
- data/spec/transpec/syntax/expect_spec.rb +83 -0
- data/spec/transpec/syntax/have_spec.rb +599 -0
- data/spec/transpec/syntax/method_stub_spec.rb +276 -115
- data/spec/transpec/syntax/{matcher_spec.rb → operator_matcher_spec.rb} +277 -98
- data/spec/transpec/syntax/raise_error_spec.rb +92 -46
- data/spec/transpec/syntax/should_receive_spec.rb +298 -92
- data/spec/transpec/syntax/should_spec.rb +230 -44
- data/spec/transpec/util_spec.rb +2 -9
- data/tasks/lib/transpec_demo.rb +1 -1
- data/tasks/lib/transpec_test.rb +5 -7
- data/tasks/test.rake +5 -1
- data/transpec.gemspec +1 -1
- metadata +46 -22
- data/lib/transpec/syntax/able_to_allow_no_message.rb +0 -73
- data/lib/transpec/syntax/able_to_target_any_instance.rb +0 -24
- data/lib/transpec/syntax/expectizable.rb +0 -27
- data/lib/transpec/syntax/send_node_syntax.rb +0 -57
data/spec/transpec/cli_spec.rb
CHANGED
@@ -17,22 +17,6 @@ module Transpec
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
describe '#forced?' do
|
21
|
-
subject { cli.forced? }
|
22
|
-
|
23
|
-
context 'by default' do
|
24
|
-
it { should be_false }
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#generates_commit_message?' do
|
29
|
-
subject { cli.generates_commit_message? }
|
30
|
-
|
31
|
-
context 'by default' do
|
32
|
-
it { should be_false }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
20
|
describe '#run' do
|
37
21
|
include_context 'isolated environment'
|
38
22
|
|
@@ -53,12 +37,13 @@ module Transpec
|
|
53
37
|
before do
|
54
38
|
cli.stub(:puts)
|
55
39
|
cli.stub(:warn)
|
40
|
+
DynamicAnalyzer.any_instance.stub(:analyze).and_return(DynamicAnalyzer::RuntimeData.new)
|
56
41
|
create_file(file_path, file_content)
|
57
42
|
end
|
58
43
|
|
59
44
|
shared_examples 'rewrites files' do
|
60
45
|
it 'rewrites files' do
|
61
|
-
cli.should_receive(:
|
46
|
+
cli.should_receive(:convert_file)
|
62
47
|
cli.run(args)
|
63
48
|
end
|
64
49
|
|
@@ -76,11 +61,9 @@ module Transpec
|
|
76
61
|
context 'and the repository is not clean' do
|
77
62
|
before { Git.stub(:clean?).and_return(false) }
|
78
63
|
|
79
|
-
context '
|
80
|
-
before { cli.stub(:forced?).and_return(false) }
|
81
|
-
|
64
|
+
context '--force option is not specified' do
|
82
65
|
it 'aborts processing' do
|
83
|
-
cli.should_not_receive(:
|
66
|
+
cli.should_not_receive(:convert_file)
|
84
67
|
cli.run(args).should be_false
|
85
68
|
end
|
86
69
|
|
@@ -94,7 +77,7 @@ module Transpec
|
|
94
77
|
end
|
95
78
|
|
96
79
|
context '#forced? is true' do
|
97
|
-
before {
|
80
|
+
before { args << '--force' }
|
98
81
|
include_examples 'rewrites files'
|
99
82
|
end
|
100
83
|
end
|
@@ -135,8 +118,8 @@ module Transpec
|
|
135
118
|
end
|
136
119
|
|
137
120
|
it 'continues processing files' do
|
138
|
-
cli.should_receive(:puts).with("
|
139
|
-
cli.should_receive(:puts).with("
|
121
|
+
cli.should_receive(:puts).with("Converting #{invalid_syntax_file_path}")
|
122
|
+
cli.should_receive(:puts).with("Converting #{valid_syntax_file_path}")
|
140
123
|
cli.run(args)
|
141
124
|
end
|
142
125
|
end
|
@@ -144,41 +127,25 @@ module Transpec
|
|
144
127
|
context 'when any other error is raised while running' do
|
145
128
|
let(:args) { ['non-existent-file'] }
|
146
129
|
|
147
|
-
it '
|
148
|
-
should
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'prints message of the exception' do
|
152
|
-
cli.should_receive(:warn).with(/No such file or directory/)
|
153
|
-
cli.run(args)
|
130
|
+
it 'does not catch the error' do
|
131
|
+
-> { cli.run(args) }.should raise_error
|
154
132
|
end
|
155
133
|
end
|
156
134
|
|
157
|
-
context 'when
|
158
|
-
let(:args) { [] }
|
135
|
+
context 'when -s/--skip-dynamic-analysis option is specified' do
|
136
|
+
let(:args) { ['--skip-dynamic-analysis', file_path] }
|
159
137
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
cli.should_receive(:target_files).with(['spec'])
|
165
|
-
cli.run(args)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
context 'and there is not "spec" directory' do
|
170
|
-
let(:file_path) { 'example_spec.rb' }
|
171
|
-
|
172
|
-
it 'aborts' do
|
173
|
-
should be_false
|
174
|
-
end
|
138
|
+
it 'skips dynamic analysis' do
|
139
|
+
DynamicAnalyzer.any_instance.should_not_receive(:analysis)
|
140
|
+
cli.should_receive(:convert_file)
|
141
|
+
cli.run(args)
|
175
142
|
end
|
176
143
|
end
|
177
144
|
|
178
|
-
context 'when -m/--commit-message option is specified' do
|
145
|
+
context 'when -m/--generate-commit-message option is specified' do
|
179
146
|
include_context 'inside of git repository'
|
180
147
|
|
181
|
-
let(:args) { ['--force', '--commit-message', file_path] }
|
148
|
+
let(:args) { ['--force', '--generate-commit-message', file_path] }
|
182
149
|
|
183
150
|
context 'and any conversion is done' do
|
184
151
|
it 'writes commit message to .git/COMMIT_EDITMSG' do
|
@@ -196,9 +163,23 @@ module Transpec
|
|
196
163
|
end
|
197
164
|
end
|
198
165
|
end
|
166
|
+
|
167
|
+
context 'when -c/--rspec-command option is specified' do
|
168
|
+
include_context 'inside of git repository'
|
169
|
+
|
170
|
+
let(:args) { ['--force', '--rspec-command', 'rspec --profile'] }
|
171
|
+
|
172
|
+
it 'passes the command to DynamicAnalyzer' do
|
173
|
+
DynamicAnalyzer.should_receive(:new) do |arg|
|
174
|
+
arg[:rspec_command].should == 'rspec --profile'
|
175
|
+
end.and_call_original
|
176
|
+
|
177
|
+
cli.run(args)
|
178
|
+
end
|
179
|
+
end
|
199
180
|
end
|
200
181
|
|
201
|
-
describe '#
|
182
|
+
describe '#convert_file' do
|
202
183
|
include_context 'isolated environment'
|
203
184
|
|
204
185
|
let(:file_path) { 'example.rb' }
|
@@ -231,197 +212,7 @@ module Transpec
|
|
231
212
|
message.should =~ /context/i
|
232
213
|
end
|
233
214
|
|
234
|
-
cli.
|
235
|
-
end
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
describe '#parse_options' do
|
240
|
-
subject { cli.parse_options(args) }
|
241
|
-
let(:args) { ['some_file', '--negative-form', 'to_not', 'some_dir'] }
|
242
|
-
|
243
|
-
it 'return non-option arguments' do
|
244
|
-
should == ['some_file', 'some_dir']
|
245
|
-
end
|
246
|
-
|
247
|
-
it 'does not mutate the passed array' do
|
248
|
-
cli.parse_options(args)
|
249
|
-
args.should == ['some_file', '--negative-form', 'to_not', 'some_dir']
|
250
|
-
end
|
251
|
-
|
252
|
-
describe '-f/--force option' do
|
253
|
-
let(:args) { ['--force'] }
|
254
|
-
|
255
|
-
it 'sets #forced? true' do
|
256
|
-
cli.parse_options(args)
|
257
|
-
cli.should be_forced
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
describe '-m/--commit-message option' do
|
262
|
-
include_context 'isolated environment'
|
263
|
-
|
264
|
-
let(:args) { ['--commit-message'] }
|
265
|
-
|
266
|
-
context 'when inside of git repository' do
|
267
|
-
include_context 'inside of git repository'
|
268
|
-
|
269
|
-
it 'sets #generates_commit_message? true' do
|
270
|
-
cli.parse_options(args)
|
271
|
-
cli.generates_commit_message?.should be_true
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
context 'when not inside of git repository' do
|
276
|
-
it 'raises error' do
|
277
|
-
-> { cli.parse_options(args) }.should raise_error(/not in a Git repository/)
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
describe '-d/--disable option' do
|
283
|
-
[
|
284
|
-
['expect_to_matcher', :convert_to_expect_to_matcher?],
|
285
|
-
['expect_to_receive', :convert_to_expect_to_receive?],
|
286
|
-
['allow_to_receive', :convert_to_allow_to_receive?],
|
287
|
-
['deprecated', :replace_deprecated_method?]
|
288
|
-
].each do |cli_type, config_attr|
|
289
|
-
context "when #{cli_type.inspect} is specified" do
|
290
|
-
let(:args) { ['--disable', cli_type] }
|
291
|
-
|
292
|
-
it "sets Configuration##{config_attr} false" do
|
293
|
-
cli.parse_options(args)
|
294
|
-
cli.configuration.send(config_attr).should be_false
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
context 'when multiple types are specified with comma' do
|
300
|
-
let(:args) { ['--disable', 'allow_to_receive,deprecated'] }
|
301
|
-
|
302
|
-
it 'handles all of them' do
|
303
|
-
cli.parse_options(args)
|
304
|
-
cli.configuration.convert_to_allow_to_receive?.should be_false
|
305
|
-
cli.configuration.replace_deprecated_method?.should be_false
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'when unknown type is specified' do
|
310
|
-
let(:args) { ['--disable', 'unknown'] }
|
311
|
-
|
312
|
-
it 'raises error' do
|
313
|
-
-> { cli.parse_options(args) }.should raise_error(ArgumentError) { |error|
|
314
|
-
error.message.should == 'Unknown conversion type "unknown"'
|
315
|
-
}
|
316
|
-
end
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
describe '-n/--negative-form option' do
|
321
|
-
['not_to', 'to_not'].each do |form|
|
322
|
-
context "when #{form.inspect} is specified" do
|
323
|
-
let(:args) { ['--negative-form', form] }
|
324
|
-
|
325
|
-
it "sets Configuration#negative_form_of_to? #{form.inspect}" do
|
326
|
-
cli.parse_options(args)
|
327
|
-
cli.configuration.negative_form_of_to.should == form
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
end
|
332
|
-
|
333
|
-
describe '-p/--no-parentheses-matcher-arg option' do
|
334
|
-
let(:args) { ['--no-parentheses-matcher-arg'] }
|
335
|
-
|
336
|
-
it 'sets Configuration#parenthesize_matcher_arg? false' do
|
337
|
-
cli.parse_options(args)
|
338
|
-
cli.configuration.parenthesize_matcher_arg.should be_false
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
describe '--no-color option' do
|
343
|
-
before do
|
344
|
-
Sickill::Rainbow.enabled = true
|
345
|
-
end
|
346
|
-
|
347
|
-
let(:args) { ['--no-color'] }
|
348
|
-
|
349
|
-
it 'disables color in the output' do
|
350
|
-
cli.parse_options(args)
|
351
|
-
Sickill::Rainbow.enabled.should be_false
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
describe '--version option' do
|
356
|
-
before do
|
357
|
-
cli.stub(:puts)
|
358
|
-
cli.stub(:exit)
|
359
|
-
end
|
360
|
-
|
361
|
-
let(:args) { ['--version'] }
|
362
|
-
|
363
|
-
it 'shows version' do
|
364
|
-
cli.should_receive(:puts).with(Version.to_s)
|
365
|
-
cli.parse_options(args)
|
366
|
-
end
|
367
|
-
|
368
|
-
it 'exits' do
|
369
|
-
cli.should_receive(:exit)
|
370
|
-
cli.parse_options(args)
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
describe '#target_files' do
|
376
|
-
include_context 'isolated environment'
|
377
|
-
|
378
|
-
before do
|
379
|
-
['file', 'file.rb', 'dir/file', 'dir/file.rb'].each do |path|
|
380
|
-
create_file(path, '')
|
381
|
-
end
|
382
|
-
end
|
383
|
-
|
384
|
-
subject(:target_files) { cli.target_files(paths) }
|
385
|
-
|
386
|
-
context 'when no path is passed' do
|
387
|
-
let(:paths) { [] }
|
388
|
-
|
389
|
-
it 'returns empty array' do
|
390
|
-
should be_empty
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
context 'when a file path with .rb extension is passed' do
|
395
|
-
let(:paths) { ['file.rb'] }
|
396
|
-
|
397
|
-
it 'returns the path' do
|
398
|
-
should == ['file.rb']
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
context 'when a file path without extension is passed' do
|
403
|
-
let(:paths) { ['file'] }
|
404
|
-
|
405
|
-
it 'returns the path' do
|
406
|
-
should == ['file']
|
407
|
-
end
|
408
|
-
end
|
409
|
-
|
410
|
-
context 'when a non-existent path is passed' do
|
411
|
-
let(:paths) { ['non-existent-file'] }
|
412
|
-
|
413
|
-
it 'raises error' do
|
414
|
-
-> { target_files }.should raise_error(ArgumentError) { |error|
|
415
|
-
error.message.should == 'No such file or directory "non-existent-file"'
|
416
|
-
}
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
context 'when a directory path is passed' do
|
421
|
-
let(:paths) { ['dir'] }
|
422
|
-
|
423
|
-
it 'returns file paths with .rb extension in the directory recursively' do
|
424
|
-
should == ['dir/file.rb']
|
215
|
+
cli.convert_file(file_path)
|
425
216
|
end
|
426
217
|
end
|
427
218
|
end
|
@@ -9,7 +9,7 @@ module Transpec
|
|
9
9
|
describe CommitMessage do
|
10
10
|
subject(:commit_message) { CommitMessage.new(report, cli_args) }
|
11
11
|
let(:report) { Report.new }
|
12
|
-
let(:cli_args) { %w(--force --commit-message) }
|
12
|
+
let(:cli_args) { %w(--force --generate-commit-message) }
|
13
13
|
|
14
14
|
before do
|
15
15
|
report.records << Record.new('obj.stub(:message)', 'allow(obj).to receive(:message)')
|
@@ -40,7 +40,7 @@ module Transpec
|
|
40
40
|
body_lines[0].chomp
|
41
41
|
.should match(/^This conversion is done by Transpec \d+\.\d+\.\d+ with the following command:$/)
|
42
42
|
body_lines[1].chomp
|
43
|
-
.should == ' transpec --force --commit-message'
|
43
|
+
.should == ' transpec --force --generate-commit-message'
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'has blank line after the preface in the body' do
|
@@ -9,17 +9,21 @@ module Transpec
|
|
9
9
|
|
10
10
|
context 'by default' do
|
11
11
|
[
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
|
12
|
+
[:convert_should?, true],
|
13
|
+
[:convert_should_receive?, true],
|
14
|
+
[:convert_stub?, true],
|
15
|
+
[:convert_have_items?, true],
|
16
|
+
[:convert_deprecated_method?, true],
|
17
|
+
[:parenthesize_matcher_arg?, true],
|
18
|
+
[:forced?, false],
|
19
|
+
[:skip_dynamic_analysis?, false],
|
20
|
+
[:generate_commit_message?, false]
|
21
|
+
].each do |attribute, value|
|
18
22
|
describe "##{attribute}" do
|
19
23
|
subject { configuration.send(attribute) }
|
20
24
|
|
21
|
-
it
|
22
|
-
should
|
25
|
+
it "is #{value}" do
|
26
|
+
should == value
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|