transpec 0.2.6 → 1.0.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/.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
@@ -0,0 +1,183 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'transpec/dynamic_analyzer/rewriter'
|
5
|
+
|
6
|
+
module Transpec
|
7
|
+
class DynamicAnalyzer
|
8
|
+
describe Rewriter do
|
9
|
+
include ::AST::Sexp
|
10
|
+
|
11
|
+
subject(:rewriter) { Rewriter.new }
|
12
|
+
|
13
|
+
describe '#rewrite' do
|
14
|
+
subject { rewriter.rewrite(source) }
|
15
|
+
|
16
|
+
let(:source) do
|
17
|
+
<<-END
|
18
|
+
describe 'example' do
|
19
|
+
it 'is foo' do
|
20
|
+
subject.should be(foo)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
END
|
24
|
+
end
|
25
|
+
|
26
|
+
# rubocop:disable LineLength
|
27
|
+
let(:expected_source) do
|
28
|
+
<<-END
|
29
|
+
describe 'example' do
|
30
|
+
it 'is foo' do
|
31
|
+
transpec_analysis((transpec_analysis((subject), self, { :should_source_location => [:object, "method(:should).source_location"] }, __FILE__, 79, 86).should be(foo)), self, { :expect_available? => [:context, "self.class.name.start_with?('RSpec::') && respond_to?(:expect)"] }, __FILE__, 79, 101)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
END
|
35
|
+
end
|
36
|
+
# rubocop:enable LineLength
|
37
|
+
|
38
|
+
it 'wraps target object with analysis helper method' do
|
39
|
+
should == expected_source
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when the target includes here document' do
|
43
|
+
let(:source) do
|
44
|
+
<<-END
|
45
|
+
describe 'example' do
|
46
|
+
it 'matches to foo' do
|
47
|
+
subject.should =~ <<-HEREDOC.gsub('foo', 'bar')
|
48
|
+
foo
|
49
|
+
HEREDOC
|
50
|
+
end
|
51
|
+
end
|
52
|
+
END
|
53
|
+
end
|
54
|
+
|
55
|
+
# rubocop:disable LineLength
|
56
|
+
let(:expected_source) do
|
57
|
+
<<-END
|
58
|
+
describe 'example' do
|
59
|
+
it 'matches to foo' do
|
60
|
+
transpec_analysis((transpec_analysis((subject), self, { :should_source_location => [:object, "method(:should).source_location"] }, __FILE__, 93, 100).should), self, { :expect_available? => [:context, "self.class.name.start_with?('RSpec::') && respond_to?(:expect)"] }, __FILE__, 93, 107) =~ transpec_analysis((<<-HEREDOC.gsub('foo', 'bar')
|
61
|
+
foo
|
62
|
+
HEREDOC
|
63
|
+
), self, { :arg_is_enumerable? => [:object, "is_a?(Enumerable)"] }, __FILE__, 111, 188)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
END
|
67
|
+
end
|
68
|
+
# rubocop:enable LineLength
|
69
|
+
|
70
|
+
it 'wraps the here document properly' do
|
71
|
+
should == expected_source
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when the target takes block' do
|
76
|
+
let(:source) do
|
77
|
+
<<-END
|
78
|
+
describe 'example' do
|
79
|
+
it 'raises error' do
|
80
|
+
expect { do_something }.to throw_symbol
|
81
|
+
end
|
82
|
+
end
|
83
|
+
END
|
84
|
+
end
|
85
|
+
|
86
|
+
# rubocop:disable LineLength
|
87
|
+
let(:expected_source) do
|
88
|
+
<<-END
|
89
|
+
describe 'example' do
|
90
|
+
it 'raises error' do
|
91
|
+
transpec_analysis((expect { do_something }), self, { :expect_source_location => [:context, "method(:expect).source_location"] }, __FILE__, 91, 97).to throw_symbol
|
92
|
+
end
|
93
|
+
end
|
94
|
+
END
|
95
|
+
end
|
96
|
+
# rubocop:enable LineLength
|
97
|
+
|
98
|
+
it 'wraps the block properly' do
|
99
|
+
should == expected_source
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when the target is only the expression in a block' do
|
104
|
+
let(:source) do
|
105
|
+
<<-END
|
106
|
+
describe 'example' do
|
107
|
+
it 'raises error' do
|
108
|
+
expect
|
109
|
+
end
|
110
|
+
end
|
111
|
+
END
|
112
|
+
end
|
113
|
+
|
114
|
+
# rubocop:disable LineLength
|
115
|
+
let(:expected_source) do
|
116
|
+
<<-END
|
117
|
+
describe 'example' do
|
118
|
+
it 'raises error' do
|
119
|
+
transpec_analysis((expect), self, { :expect_source_location => [:context, "method(:expect).source_location"] }, __FILE__, 91, 97)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
END
|
123
|
+
end
|
124
|
+
# rubocop:enable LineLength
|
125
|
+
|
126
|
+
it 'wraps the target properly' do
|
127
|
+
should == expected_source
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context 'when the target is method invocation without parentheses' do
|
132
|
+
let(:source) do
|
133
|
+
<<-END
|
134
|
+
describe 'example' do
|
135
|
+
it 'raises error' do
|
136
|
+
expect subject
|
137
|
+
end
|
138
|
+
end
|
139
|
+
END
|
140
|
+
end
|
141
|
+
|
142
|
+
# rubocop:disable LineLength
|
143
|
+
let(:expected_source) do
|
144
|
+
<<-END
|
145
|
+
describe 'example' do
|
146
|
+
it 'raises error' do
|
147
|
+
transpec_analysis((expect subject), self, { :expect_source_location => [:context, "method(:expect).source_location"] }, __FILE__, 91, 105)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
END
|
151
|
+
end
|
152
|
+
# rubocop:enable LineLength
|
153
|
+
|
154
|
+
it 'wraps the target properly' do
|
155
|
+
should == expected_source
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe '#register_request' do
|
161
|
+
let(:some_node) { s(:int, 1) }
|
162
|
+
let(:another_node) { s(:int, 2) }
|
163
|
+
|
164
|
+
it 'stores requests for each node' do
|
165
|
+
rewriter.register_request(some_node, :odd, 'odd?', :object)
|
166
|
+
rewriter.register_request(another_node, :even, 'even?', :object)
|
167
|
+
rewriter.requests.should == {
|
168
|
+
some_node => { odd: [:object, 'odd?'] },
|
169
|
+
another_node => { even: [:object, 'even?'] }
|
170
|
+
}
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'merges multiple requests for same node' do
|
174
|
+
rewriter.register_request(some_node, :odd, 'odd?', :object)
|
175
|
+
rewriter.register_request(some_node, :even, 'even?', :object)
|
176
|
+
rewriter.requests.should == {
|
177
|
+
some_node => { odd: [:object, 'odd?'], even: [:object, 'even?'] }
|
178
|
+
}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'transpec/dynamic_analyzer'
|
5
|
+
|
6
|
+
module Transpec
|
7
|
+
describe DynamicAnalyzer do
|
8
|
+
include FileHelper
|
9
|
+
include ::AST::Sexp
|
10
|
+
include_context 'isolated environment'
|
11
|
+
|
12
|
+
subject(:dynamic_analyzer) { DynamicAnalyzer.new(rspec_command: rspec_command, silent: true) }
|
13
|
+
let(:rspec_command) { nil }
|
14
|
+
|
15
|
+
describe '.new' do
|
16
|
+
context 'when when block is passed' do
|
17
|
+
it 'yields instance' do
|
18
|
+
yielded = false
|
19
|
+
|
20
|
+
DynamicAnalyzer.new(silent: true) do |analyzer|
|
21
|
+
yielded = true
|
22
|
+
analyzer.should be_a(DynamicAnalyzer)
|
23
|
+
end
|
24
|
+
|
25
|
+
yielded.should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'changes working directory to copied project directory' do
|
29
|
+
initial_directory = Dir.pwd
|
30
|
+
DynamicAnalyzer.new(silent: true) do |analyzer|
|
31
|
+
Dir.pwd.should_not == initial_directory
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#rspec_command' do
|
38
|
+
subject { dynamic_analyzer.rspec_command }
|
39
|
+
|
40
|
+
context 'when command is specified' do
|
41
|
+
let(:rspec_command) { 'rspec some_argument' }
|
42
|
+
|
43
|
+
it 'returns the specified command' do
|
44
|
+
should == rspec_command
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when command is not specified' do
|
49
|
+
context 'and there is a Gemfile' do
|
50
|
+
before do
|
51
|
+
create_file('Gemfile', '')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns "bundle exec rspec"' do
|
55
|
+
should == 'bundle exec rspec'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'and there is no Gemfile' do
|
60
|
+
it 'returns "rspec"' do
|
61
|
+
should == 'rspec'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#analyze' do
|
68
|
+
let(:source) do
|
69
|
+
<<-END
|
70
|
+
describe [1, 2] do
|
71
|
+
it 'has 2 items' do
|
72
|
+
expect(subject).to have(2).items
|
73
|
+
end
|
74
|
+
end
|
75
|
+
END
|
76
|
+
end
|
77
|
+
|
78
|
+
let(:file_path) { 'spec/example_spec.rb' }
|
79
|
+
|
80
|
+
before do
|
81
|
+
create_file(file_path, source)
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'when already in copied project directory' do
|
85
|
+
it 'does not change working directory' do
|
86
|
+
DynamicAnalyzer.new(silent: true) do |analyzer|
|
87
|
+
Dir.should_not_receive(:chdir)
|
88
|
+
analyzer.analyze
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'when no path is passed' do
|
94
|
+
it 'rewrites all files in the "spec" directory' do
|
95
|
+
DynamicAnalyzer::Rewriter.any_instance.should_receive(:rewrite_file!).with(file_path)
|
96
|
+
dynamic_analyzer.analyze
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when some paths are passed' do
|
101
|
+
before do
|
102
|
+
create_file('spec/another_spec.rb', '')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'rewrites only files in the passed paths' do
|
106
|
+
DynamicAnalyzer::Rewriter.any_instance.should_receive(:rewrite_file!).with(file_path)
|
107
|
+
dynamic_analyzer.analyze([file_path])
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context 'when there is invalid syntax source file' do
|
112
|
+
before do
|
113
|
+
create_file('spec/fixtures/invalid.rb', 'This is invalid syntax <')
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'does not raise error' do
|
117
|
+
-> { dynamic_analyzer.analyze }.should_not raise_error
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
runtime_data_cache = {}
|
122
|
+
|
123
|
+
subject(:runtime_data) do
|
124
|
+
if runtime_data_cache[source]
|
125
|
+
runtime_data_cache[source]
|
126
|
+
else
|
127
|
+
runtime_data_cache[source] = dynamic_analyzer.analyze
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'returns an instance of DynamicAnalyzer::RuntimeData' do
|
132
|
+
runtime_data.should be_an(DynamicAnalyzer::RuntimeData)
|
133
|
+
end
|
134
|
+
|
135
|
+
describe 'its element' do
|
136
|
+
let(:ast) do
|
137
|
+
source_buffer = Parser::Source::Buffer.new(file_path)
|
138
|
+
source_buffer.source = source
|
139
|
+
|
140
|
+
builder = AST::Builder.new
|
141
|
+
|
142
|
+
parser = Parser::CurrentRuby.new(builder)
|
143
|
+
parser.parse(source_buffer)
|
144
|
+
end
|
145
|
+
|
146
|
+
let(:target_node) do
|
147
|
+
ast.each_descendent_node do |node|
|
148
|
+
return node if node == s(:send, nil, :subject)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
subject(:element) { runtime_data[target_node] }
|
153
|
+
|
154
|
+
it 'is a hash' do
|
155
|
+
should be_a(Hash)
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'has result of requested analysis' do
|
159
|
+
element[:available_query_methods].result.should =~ [:size, :count, :length]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'transpec/file_finder'
|
5
|
+
|
6
|
+
module Transpec
|
7
|
+
describe FileFinder do
|
8
|
+
include FileHelper
|
9
|
+
|
10
|
+
describe '.find' do
|
11
|
+
include_context 'isolated environment'
|
12
|
+
|
13
|
+
before do
|
14
|
+
['file', 'file.rb', 'dir/file', 'dir/file.rb'].each do |path|
|
15
|
+
create_file(path, '')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { FileFinder.find(paths) }
|
20
|
+
|
21
|
+
context 'when no path is passed' do
|
22
|
+
let(:paths) { [] }
|
23
|
+
|
24
|
+
context 'and there is "spec" directory' do
|
25
|
+
before do
|
26
|
+
create_file('spec/file.rb', '')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns file paths with .rb extension in the "spec" directory recursively' do
|
30
|
+
should == ['spec/file.rb']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'and there is not "spec" directory' do
|
35
|
+
it 'raises error' do
|
36
|
+
-> { FileFinder.find(paths) }.should raise_error(ArgumentError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when a file path with .rb extension is passed' do
|
42
|
+
let(:paths) { ['file.rb'] }
|
43
|
+
|
44
|
+
it 'returns the path' do
|
45
|
+
should == ['file.rb']
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'when a file path without extension is passed' do
|
50
|
+
let(:paths) { ['file'] }
|
51
|
+
|
52
|
+
it 'returns the path' do
|
53
|
+
should == ['file']
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when a non-existent path is passed' do
|
58
|
+
let(:paths) { ['non-existent-file'] }
|
59
|
+
|
60
|
+
it 'raises error' do
|
61
|
+
-> { FileFinder.find(paths) }.should raise_error(ArgumentError) { |error|
|
62
|
+
error.message.should == 'No such file or directory "non-existent-file"'
|
63
|
+
}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when a directory path is passed' do
|
68
|
+
let(:paths) { ['dir'] }
|
69
|
+
|
70
|
+
it 'returns file paths with .rb extension in the directory recursively' do
|
71
|
+
should == ['dir/file.rb']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '.base_paths' do
|
77
|
+
include_context 'isolated environment'
|
78
|
+
|
79
|
+
subject { FileFinder.base_paths(paths) }
|
80
|
+
|
81
|
+
context 'when target paths are specified' do
|
82
|
+
let(:paths) { ['foo_spec.rb', 'spec/bar_spec.rb'] }
|
83
|
+
|
84
|
+
it 'returns the passed paths' do
|
85
|
+
should == paths
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when paths outside of the current working directory are specified' do
|
90
|
+
let(:paths) { ['../foo_spec.rb', 'spec/bar_spec.rb'] }
|
91
|
+
|
92
|
+
it 'raises error' do
|
93
|
+
-> { FileFinder.base_paths(paths) }.should raise_error(ArgumentError)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when no target paths are specified' do
|
98
|
+
let(:paths) { [] }
|
99
|
+
|
100
|
+
context 'and there is "spec" directory' do
|
101
|
+
before do
|
102
|
+
Dir.mkdir('spec')
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns ["spec"]' do
|
106
|
+
should == ['spec']
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'and there is not "spec" directory' do
|
111
|
+
it 'raises error' do
|
112
|
+
-> { FileFinder.base_paths(paths) }.should raise_error(ArgumentError)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'transpec/option_parser'
|
5
|
+
|
6
|
+
module Transpec
|
7
|
+
describe OptionParser do
|
8
|
+
subject(:parser) { OptionParser.new(configuration) }
|
9
|
+
let(:configuration) { Configuration.new }
|
10
|
+
|
11
|
+
describe '#parse' do
|
12
|
+
subject { parser.parse(args) }
|
13
|
+
let(:args) { ['some_file', '--negative-form', 'to_not', 'some_dir'] }
|
14
|
+
|
15
|
+
it 'return non-option arguments' do
|
16
|
+
should == ['some_file', 'some_dir']
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not mutate the passed array' do
|
20
|
+
parser.parse(args)
|
21
|
+
args.should == ['some_file', '--negative-form', 'to_not', 'some_dir']
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '-f/--force option' do
|
25
|
+
let(:args) { ['--force'] }
|
26
|
+
|
27
|
+
it 'sets Configuration#forced? true' do
|
28
|
+
parser.parse(args)
|
29
|
+
configuration.forced?.should be_true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '-s/--skip-dynamic-analysis option' do
|
34
|
+
let(:args) { ['--skip-dynamic-analysis'] }
|
35
|
+
|
36
|
+
it 'sets Configuration#skip_dynamic_analysis? true' do
|
37
|
+
parser.parse(args)
|
38
|
+
configuration.skip_dynamic_analysis?.should be_true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '-m/--generate-commit-message option' do
|
43
|
+
include_context 'isolated environment'
|
44
|
+
|
45
|
+
let(:args) { ['--generate-commit-message'] }
|
46
|
+
|
47
|
+
context 'when inside of git repository' do
|
48
|
+
include_context 'inside of git repository'
|
49
|
+
|
50
|
+
it 'sets Configuration#generate_commit_message? true' do
|
51
|
+
parser.parse(args)
|
52
|
+
configuration.generate_commit_message?.should be_true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when not inside of git repository' do
|
57
|
+
it 'raises error' do
|
58
|
+
-> { parser.parse(args) }.should raise_error(/not in a Git repository/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '-k/--keep option' do
|
64
|
+
[
|
65
|
+
['should', :convert_should?],
|
66
|
+
['should_receive', :convert_should_receive?],
|
67
|
+
['stub', :convert_stub?],
|
68
|
+
['have_items', :convert_have_items],
|
69
|
+
['deprecated', :convert_deprecated_method?]
|
70
|
+
].each do |cli_type, config_attr|
|
71
|
+
context "when #{cli_type.inspect} is specified" do
|
72
|
+
let(:args) { ['--keep', cli_type] }
|
73
|
+
|
74
|
+
it "sets Configuration##{config_attr} false" do
|
75
|
+
parser.parse(args)
|
76
|
+
configuration.send(config_attr).should be_false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when multiple types are specified with comma' do
|
82
|
+
let(:args) { ['--keep', 'should_receive,deprecated'] }
|
83
|
+
|
84
|
+
it 'handles all of them' do
|
85
|
+
parser.parse(args)
|
86
|
+
configuration.convert_should_receive?.should be_false
|
87
|
+
configuration.convert_deprecated_method?.should be_false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when unknown type is specified' do
|
92
|
+
let(:args) { ['--keep', 'unknown'] }
|
93
|
+
|
94
|
+
it 'raises error' do
|
95
|
+
-> { parser.parse(args) }.should raise_error(ArgumentError) { |error|
|
96
|
+
error.message.should == 'Unknown syntax type "unknown"'
|
97
|
+
}
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '-n/--negative-form option' do
|
103
|
+
['not_to', 'to_not'].each do |form|
|
104
|
+
context "when #{form.inspect} is specified" do
|
105
|
+
let(:args) { ['--negative-form', form] }
|
106
|
+
|
107
|
+
it "sets Configuration#negative_form_of_to? #{form.inspect}" do
|
108
|
+
parser.parse(args)
|
109
|
+
configuration.negative_form_of_to.should == form
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe '-p/--no-parentheses-matcher-arg option' do
|
116
|
+
let(:args) { ['--no-parentheses-matcher-arg'] }
|
117
|
+
|
118
|
+
it 'sets Configuration#parenthesize_matcher_arg? false' do
|
119
|
+
parser.parse(args)
|
120
|
+
configuration.parenthesize_matcher_arg.should be_false
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '--no-color option' do
|
125
|
+
before do
|
126
|
+
Sickill::Rainbow.enabled = true
|
127
|
+
end
|
128
|
+
|
129
|
+
let(:args) { ['--no-color'] }
|
130
|
+
|
131
|
+
it 'disables color in the output' do
|
132
|
+
parser.parse(args)
|
133
|
+
Sickill::Rainbow.enabled.should be_false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '--version option' do
|
138
|
+
before do
|
139
|
+
parser.stub(:puts)
|
140
|
+
parser.stub(:exit)
|
141
|
+
end
|
142
|
+
|
143
|
+
let(:args) { ['--version'] }
|
144
|
+
|
145
|
+
it 'shows version' do
|
146
|
+
parser.should_receive(:puts).with(Version.to_s)
|
147
|
+
parser.parse(args)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'exits' do
|
151
|
+
parser.should_receive(:exit)
|
152
|
+
parser.parse(args)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe 'help text' do
|
158
|
+
subject(:help_text) do
|
159
|
+
parser.help
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'does not exceed 80 characters in each line' do
|
163
|
+
help_text.each_line do |line|
|
164
|
+
line.chomp.length.should <= 80
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'describes all conversion types for -k/--keep option' do
|
169
|
+
option_sections = help_text.lines.slice_before(/^\s*-/)
|
170
|
+
|
171
|
+
keep_section = option_sections.find do |lines|
|
172
|
+
lines.first =~ /^\s*-k/
|
173
|
+
end
|
174
|
+
|
175
|
+
conversion_types = keep_section.reduce([]) do |types, line|
|
176
|
+
match = line.match(/^[ ]{37}([a-z_]+)/)
|
177
|
+
next types unless match
|
178
|
+
types << match.captures.first
|
179
|
+
end
|
180
|
+
|
181
|
+
conversion_types.should =~ OptionParser.available_conversion_types.map(&:to_s)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|