transpec 0.2.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +1 -1
  4. data/CHANGELOG.md +10 -0
  5. data/README.md +111 -56
  6. data/README.md.erb +117 -62
  7. data/lib/transpec/ast/node.rb +41 -0
  8. data/lib/transpec/base_rewriter.rb +55 -0
  9. data/lib/transpec/cli.rb +43 -153
  10. data/lib/transpec/configuration.rb +13 -9
  11. data/lib/transpec/{rewriter.rb → converter.rb} +44 -71
  12. data/lib/transpec/dynamic_analyzer/rewriter.rb +94 -0
  13. data/lib/transpec/dynamic_analyzer/runtime_data.rb +27 -0
  14. data/lib/transpec/dynamic_analyzer.rb +166 -0
  15. data/lib/transpec/file_finder.rb +53 -0
  16. data/lib/transpec/option_parser.rb +166 -0
  17. data/lib/transpec/{context.rb → static_context_inspector.rb} +2 -2
  18. data/lib/transpec/syntax/be_close.rb +7 -9
  19. data/lib/transpec/syntax/double.rb +6 -10
  20. data/lib/transpec/syntax/expect.rb +35 -0
  21. data/lib/transpec/syntax/have.rb +195 -0
  22. data/lib/transpec/syntax/method_stub.rb +22 -27
  23. data/lib/transpec/syntax/mixin/allow_no_message.rb +73 -0
  24. data/lib/transpec/syntax/mixin/any_instance.rb +22 -0
  25. data/lib/transpec/syntax/mixin/expectizable.rb +26 -0
  26. data/lib/transpec/syntax/mixin/have_matcher.rb +23 -0
  27. data/lib/transpec/syntax/mixin/monkey_patch.rb +37 -0
  28. data/lib/transpec/syntax/mixin/send.rb +109 -0
  29. data/lib/transpec/syntax/{matcher.rb → operator_matcher.rb} +27 -14
  30. data/lib/transpec/syntax/raise_error.rb +6 -10
  31. data/lib/transpec/syntax/rspec_configure.rb +29 -28
  32. data/lib/transpec/syntax/should.rb +45 -15
  33. data/lib/transpec/syntax/should_receive.rb +44 -16
  34. data/lib/transpec/syntax.rb +29 -21
  35. data/lib/transpec/util.rb +12 -2
  36. data/lib/transpec/version.rb +3 -3
  37. data/spec/spec_helper.rb +8 -6
  38. data/spec/support/cache_helper.rb +50 -0
  39. data/spec/support/shared_context.rb +49 -1
  40. data/spec/transpec/ast/node_spec.rb +65 -0
  41. data/spec/transpec/cli_spec.rb +33 -242
  42. data/spec/transpec/commit_message_spec.rb +2 -2
  43. data/spec/transpec/configuration_spec.rb +12 -8
  44. data/spec/transpec/{rewriter_spec.rb → converter_spec.rb} +198 -148
  45. data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +183 -0
  46. data/spec/transpec/dynamic_analyzer_spec.rb +164 -0
  47. data/spec/transpec/file_finder_spec.rb +118 -0
  48. data/spec/transpec/option_parser_spec.rb +185 -0
  49. data/spec/transpec/{context_spec.rb → static_context_inspector_spec.rb} +27 -12
  50. data/spec/transpec/syntax/be_close_spec.rb +8 -4
  51. data/spec/transpec/syntax/double_spec.rb +105 -12
  52. data/spec/transpec/syntax/expect_spec.rb +83 -0
  53. data/spec/transpec/syntax/have_spec.rb +599 -0
  54. data/spec/transpec/syntax/method_stub_spec.rb +276 -115
  55. data/spec/transpec/syntax/{matcher_spec.rb → operator_matcher_spec.rb} +277 -98
  56. data/spec/transpec/syntax/raise_error_spec.rb +92 -46
  57. data/spec/transpec/syntax/should_receive_spec.rb +298 -92
  58. data/spec/transpec/syntax/should_spec.rb +230 -44
  59. data/spec/transpec/util_spec.rb +2 -9
  60. data/tasks/lib/transpec_demo.rb +1 -1
  61. data/tasks/lib/transpec_test.rb +5 -7
  62. data/tasks/test.rake +5 -1
  63. data/transpec.gemspec +1 -1
  64. metadata +46 -22
  65. data/lib/transpec/syntax/able_to_allow_no_message.rb +0 -73
  66. data/lib/transpec/syntax/able_to_target_any_instance.rb +0 -24
  67. data/lib/transpec/syntax/expectizable.rb +0 -27
  68. data/lib/transpec/syntax/send_node_syntax.rb +0 -57
@@ -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(:process_file)
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 '#forced? is false' do
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(:process_file)
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 { cli.stub(:forced?).and_return(true) }
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("Processing #{invalid_syntax_file_path}")
139
- cli.should_receive(:puts).with("Processing #{valid_syntax_file_path}")
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 'return false' do
148
- should be_false
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 no target paths are specified' do
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
- context 'and there is "spec" directory' do
161
- let(:file_path) { 'spec/example_spec.rb' }
162
-
163
- it 'targets files in the "spec" directoy' do
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 '#process_file' do
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.process_file(file_path)
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
- :convert_to_expect_to_matcher?,
13
- :convert_to_expect_to_receive?,
14
- :convert_to_allow_to_receive?,
15
- :replace_deprecated_method?,
16
- :parenthesize_matcher_arg?
17
- ].each do |attribute|
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 'is true' do
22
- should be_true
25
+ it "is #{value}" do
26
+ should == value
23
27
  end
24
28
  end
25
29
  end