transpec 3.0.8 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +4 -0
- data/README.md +12 -0
- data/README.md.erb +14 -2
- data/lib/transpec/cli.rb +1 -1
- data/lib/transpec/cli/option_parser.rb +236 -0
- data/lib/transpec/config.rb +40 -11
- data/lib/transpec/converter.rb +31 -31
- data/lib/transpec/version.rb +2 -2
- data/tasks/lib/test.rb +4 -1
- data/tasks/readme.rake +4 -2
- metadata +3 -3
- data/lib/transpec/option_parser.rb +0 -236
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89106c8a70598e1c56947bcb35e207db8839317c
|
4
|
+
data.tar.gz: 3333ebd452e3be727f9261d815f7ecbf6200a5fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c05920d4e39d10bf6c5dd15ad1d2075cb95d7e8a5e9a6becab4e1ac768688b19c2e2010c063d5dc58af0f9224fd72fbe0921cf34d229fd7b0ca4c7e1ad3ed69
|
7
|
+
data.tar.gz: d58f9e39daebde5544b9efbdb5172d54e00bd4c5160aad57d5dff28571ce85eec84b05d01d25af0d2342c1731a9b5c4d7309e1034517704b2a82517e5dd9b2b6
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
## Development
|
4
4
|
|
5
|
+
## v3.1.0
|
6
|
+
|
7
|
+
* Add `-o/--convert-only` option for converting specific syntaxes while keeping all other syntaxes. ([#91](https://github.com/yujinakayama/transpec/issues/91))
|
8
|
+
|
5
9
|
## v3.0.8
|
6
10
|
|
7
11
|
* Fix error on converting spec with AWS.stub! without dynamic analysis. ([#100](https://github.com/yujinakayama/transpec/issues/100))
|
data/README.md
CHANGED
@@ -275,6 +275,18 @@ regardless of this option.
|
|
275
275
|
|
276
276
|
See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
|
277
277
|
|
278
|
+
### `-o/--convert-only`
|
279
|
+
|
280
|
+
Convert specific syntaxes while keeping all other syntaxes.
|
281
|
+
|
282
|
+
This option would be useful when you want to convert a non-deprecated syntax
|
283
|
+
while keeping another syntax that would be converted by default.
|
284
|
+
(e.g. converting the hook scope aliases while keeping the one-liner `should`).
|
285
|
+
|
286
|
+
```bash
|
287
|
+
$ transpec --convert-only example_group,hook_scope
|
288
|
+
```
|
289
|
+
|
278
290
|
### `-s/--skip-dynamic-analysis`
|
279
291
|
|
280
292
|
Skip dynamic analysis and convert with only static analysis.
|
data/README.md.erb
CHANGED
@@ -221,7 +221,7 @@ conversion_type_table = <<END
|
|
221
221
|
`deprecated` | All other deprecated syntaxes | Latest syntaxes
|
222
222
|
END
|
223
223
|
|
224
|
-
validate_syntax_type_table(conversion_type_table,
|
224
|
+
validate_syntax_type_table(conversion_type_table, true)
|
225
225
|
conversion_type_table
|
226
226
|
-%>
|
227
227
|
|
@@ -250,7 +250,7 @@ conversion_type_table = <<END
|
|
250
250
|
`stub_with_hash` | `obj.stub(:message => value)` | `allow(obj).to receive(:message).and_return(value)`
|
251
251
|
END
|
252
252
|
|
253
|
-
validate_syntax_type_table(conversion_type_table,
|
253
|
+
validate_syntax_type_table(conversion_type_table, false)
|
254
254
|
conversion_type_table
|
255
255
|
-%>
|
256
256
|
|
@@ -263,6 +263,18 @@ regardless of this option.
|
|
263
263
|
|
264
264
|
See [Supported Conversions - Method stubs with a hash argument](#method-stubs-with-a-hash-argument) for more details.
|
265
265
|
|
266
|
+
### `-o/--convert-only`
|
267
|
+
|
268
|
+
Convert specific syntaxes while keeping all other syntaxes.
|
269
|
+
|
270
|
+
This option would be useful when you want to convert a non-deprecated syntax
|
271
|
+
while keeping another syntax that would be converted by default.
|
272
|
+
(e.g. converting the hook scope aliases while keeping the one-liner `should`).
|
273
|
+
|
274
|
+
```bash
|
275
|
+
$ transpec --convert-only example_group,hook_scope
|
276
|
+
```
|
277
|
+
|
266
278
|
### `-s/--skip-dynamic-analysis`
|
267
279
|
|
268
280
|
Skip dynamic analysis and convert with only static analysis.
|
data/lib/transpec/cli.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
|
+
require 'transpec/cli/option_parser'
|
3
4
|
require 'transpec/commit_message'
|
4
5
|
require 'transpec/config'
|
5
6
|
require 'transpec/converter'
|
6
7
|
require 'transpec/dynamic_analyzer'
|
7
|
-
require 'transpec/option_parser'
|
8
8
|
require 'transpec/project'
|
9
9
|
require 'transpec/report'
|
10
10
|
require 'transpec/spec_suite'
|
@@ -0,0 +1,236 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'transpec/config'
|
4
|
+
require 'transpec/git'
|
5
|
+
require 'transpec/version'
|
6
|
+
require 'optparse'
|
7
|
+
require 'rainbow'
|
8
|
+
require 'rainbow/ext/string' unless String.respond_to?(:color)
|
9
|
+
|
10
|
+
module Transpec
|
11
|
+
class CLI
|
12
|
+
class OptionParser # rubocop:disable ClassLength
|
13
|
+
VALID_BOOLEAN_MATCHER_TYPES = %w(truthy,falsey truthy,falsy true,false)
|
14
|
+
|
15
|
+
attr_reader :config
|
16
|
+
|
17
|
+
def initialize(config = Config.new)
|
18
|
+
@config = config
|
19
|
+
setup_parser
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse(args)
|
23
|
+
args = convert_deprecated_options(args)
|
24
|
+
@parser.parse!(args)
|
25
|
+
args
|
26
|
+
end
|
27
|
+
|
28
|
+
def help
|
29
|
+
@parser.help
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def setup_parser # rubocop:disable MethodLength
|
35
|
+
@parser = create_parser
|
36
|
+
|
37
|
+
define_option('-f', '--force') do
|
38
|
+
config.forced = true
|
39
|
+
end
|
40
|
+
|
41
|
+
define_option('-c', '--rspec-command COMMAND') do |command|
|
42
|
+
config.rspec_command = command
|
43
|
+
end
|
44
|
+
|
45
|
+
define_option('-k', '--keep TYPE[,TYPE...]') do |types|
|
46
|
+
configure_conversion(types, false)
|
47
|
+
end
|
48
|
+
|
49
|
+
define_option('-v', '--convert TYPE[,TYPE...]') do |types|
|
50
|
+
configure_conversion(types, true)
|
51
|
+
end
|
52
|
+
|
53
|
+
define_option('-o', '--convert-only TYPE[,TYPE...]') do |types|
|
54
|
+
Config.conversion_types.each do |type|
|
55
|
+
config.conversion[type] = false
|
56
|
+
end
|
57
|
+
|
58
|
+
configure_conversion(types, true)
|
59
|
+
end
|
60
|
+
|
61
|
+
define_option('-s', '--skip-dynamic-analysis') do
|
62
|
+
config.skip_dynamic_analysis = true
|
63
|
+
end
|
64
|
+
|
65
|
+
define_option('-n', '--negative-form FORM') do |form|
|
66
|
+
config.negative_form_of_to = form
|
67
|
+
end
|
68
|
+
|
69
|
+
define_option('-b', '--boolean-matcher TYPE') do |type|
|
70
|
+
configure_boolean_matcher(type)
|
71
|
+
end
|
72
|
+
|
73
|
+
define_option('-e', '--explicit-spec-type') do
|
74
|
+
config.add_explicit_type_metadata_to_example_group = true
|
75
|
+
end
|
76
|
+
|
77
|
+
define_option('-a', '--no-yield-any-instance') do
|
78
|
+
config.add_receiver_arg_to_any_instance_implementation_block = false
|
79
|
+
end
|
80
|
+
|
81
|
+
define_option('-p', '--no-parens-matcher-arg') do
|
82
|
+
config.parenthesize_matcher_arg = false
|
83
|
+
end
|
84
|
+
|
85
|
+
define_option('--no-color') do
|
86
|
+
Rainbow.enabled = false
|
87
|
+
end
|
88
|
+
|
89
|
+
define_option('--version') do
|
90
|
+
puts Version.to_s
|
91
|
+
exit
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_parser
|
96
|
+
banner = "Usage: transpec [options] [files or directories]\n\n"
|
97
|
+
summary_width = 34
|
98
|
+
indentation = ' ' * 2
|
99
|
+
::OptionParser.new(banner, summary_width, indentation)
|
100
|
+
end
|
101
|
+
|
102
|
+
def define_option(*options, &block)
|
103
|
+
description_lines = descriptions[options.first]
|
104
|
+
description_lines = description_lines.map { |line| highlight_text(line) }
|
105
|
+
@parser.on(*options, *description_lines, &block)
|
106
|
+
end
|
107
|
+
|
108
|
+
# rubocop:disable AlignHash
|
109
|
+
def descriptions # rubocop:disable MethodLength
|
110
|
+
@descriptions ||= {
|
111
|
+
'-f' => [
|
112
|
+
'Force processing even if the current Git repository is not',
|
113
|
+
'clean.'
|
114
|
+
],
|
115
|
+
'-s' => [
|
116
|
+
'Skip dynamic analysis and convert with only static analysis.',
|
117
|
+
'The use of this option is basically *discouraged* since it',
|
118
|
+
'significantly decreases the overall conversion accuracy.'
|
119
|
+
],
|
120
|
+
'-c' => [
|
121
|
+
'Specify a command to run your specs that is used for dynamic',
|
122
|
+
'analysis.',
|
123
|
+
'Default: "bundle exec rspec"'
|
124
|
+
],
|
125
|
+
'-k' => [
|
126
|
+
'Keep specific syntaxes by disabling conversions.',
|
127
|
+
'Conversion Types:',
|
128
|
+
' *should* (to `expect(obj).to`)',
|
129
|
+
' *oneliner* (`it { should ... }` to `it { is_expected.to ... }`)',
|
130
|
+
' *should_receive* (to `expect(obj).to receive`)',
|
131
|
+
' *stub* (to `allow(obj).to receive`)',
|
132
|
+
' *have_items* (to `expect(collection.size).to eq(n)`)',
|
133
|
+
" *its* (to `describe '#attr' { subject { }; it { } }`)",
|
134
|
+
' *pending* (to `skip`)',
|
135
|
+
' *deprecated* (all other deprecated syntaxes to latest syntaxes)',
|
136
|
+
'These conversions are enabled by default.'
|
137
|
+
],
|
138
|
+
'-v' => [
|
139
|
+
'Enable specific conversions that are disabled by default.',
|
140
|
+
'Conversion Types:',
|
141
|
+
' *example_group* (`describe` to `RSpec.describe`)',
|
142
|
+
' *hook_scope* (`before(:all)` to `before(:context)`)',
|
143
|
+
' *stub_with_hash* (`obj.stub(:msg => val)` to',
|
144
|
+
' `allow(obj).to receive(:msg).and_return(val)`)',
|
145
|
+
'These conversions are disabled by default.'
|
146
|
+
],
|
147
|
+
'-o' => [
|
148
|
+
'Convert specific syntaxes while keeping all other syntaxes.'
|
149
|
+
],
|
150
|
+
'-n' => [
|
151
|
+
'Specify a negative form of `to` that is used in the',
|
152
|
+
'`expect(...).to syntax. Either *not_to* or *to_not*.',
|
153
|
+
'Default: *not_to*'
|
154
|
+
],
|
155
|
+
'-b' => [
|
156
|
+
'Specify a matcher type that `be_true` and `be_false` will be',
|
157
|
+
'converted to.',
|
158
|
+
' *truthy,falsey* (conditional semantics)',
|
159
|
+
' *truthy,falsy* (alias of `falsey`)',
|
160
|
+
' *true,false* (exact equality)',
|
161
|
+
'Default: *truthy,falsey*'
|
162
|
+
],
|
163
|
+
'-e' => [
|
164
|
+
'Add explicit `:type` metadata to example groups in a project',
|
165
|
+
'using rspec-rails.'
|
166
|
+
],
|
167
|
+
'-a' => [
|
168
|
+
'Suppress yielding receiver instances to `any_instance`',
|
169
|
+
'implementation blocks as the first block argument.'
|
170
|
+
],
|
171
|
+
'-p' => [
|
172
|
+
'Suppress parenthesizing arguments of matchers when converting',
|
173
|
+
'`should` with operator matcher to `expect` with non-operator',
|
174
|
+
'matcher. Note that it will be parenthesized even if this option',
|
175
|
+
'is specified when parentheses are necessary to keep the meaning',
|
176
|
+
'of the expression. By default, arguments of the following',
|
177
|
+
'operator matchers will be parenthesized.',
|
178
|
+
' `== 10` to `eq(10)`',
|
179
|
+
' `=~ /pattern/` to `match(/pattern/)`',
|
180
|
+
' `=~ [1, 2]` to `match_array([1, 2])`'
|
181
|
+
],
|
182
|
+
'--no-color' => [
|
183
|
+
'Disable color in the output.'
|
184
|
+
],
|
185
|
+
'--version' => [
|
186
|
+
'Show Transpec version.'
|
187
|
+
]
|
188
|
+
}
|
189
|
+
end
|
190
|
+
# rubocop:enable AlignHash
|
191
|
+
|
192
|
+
def highlight_text(text)
|
193
|
+
text.gsub(/`.+?`/) { |code| code.gsub('`', '').underline }
|
194
|
+
.gsub(/\*.+?\*/) { |code| code.gsub('*', '').bright }
|
195
|
+
end
|
196
|
+
|
197
|
+
def convert_deprecated_options(raw_args)
|
198
|
+
raw_args.each_with_object([]) do |arg, args|
|
199
|
+
case arg
|
200
|
+
when '--no-parentheses-matcher-arg'
|
201
|
+
deprecate('--no-parentheses-matcher-arg option', '--no-parens-matcher-arg')
|
202
|
+
args << '--no-parens-matcher-arg'
|
203
|
+
else
|
204
|
+
args << arg
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def deprecate(subject, alternative = nil)
|
210
|
+
message = "DEPRECATION: #{subject} is deprecated."
|
211
|
+
message << " Use #{alternative} instead." if alternative
|
212
|
+
warn message
|
213
|
+
end
|
214
|
+
|
215
|
+
def configure_conversion(inputted_types, boolean)
|
216
|
+
inputted_types.split(',').each do |type|
|
217
|
+
unless Config.valid_conversion_type?(type)
|
218
|
+
fail ArgumentError, "Unknown syntax type #{type.inspect}"
|
219
|
+
end
|
220
|
+
|
221
|
+
config.conversion[type] = boolean
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def configure_boolean_matcher(type)
|
226
|
+
unless VALID_BOOLEAN_MATCHER_TYPES.include?(type)
|
227
|
+
types = VALID_BOOLEAN_MATCHER_TYPES.map(&:inspect).join(', ')
|
228
|
+
fail ArgumentError, "Boolean matcher type must be any of #{types}"
|
229
|
+
end
|
230
|
+
|
231
|
+
config.boolean_matcher_type = type.include?('truthy') ? :conditional : :exact
|
232
|
+
config.form_of_be_falsey = type.include?('falsy') ? 'be_falsy' : 'be_falsey'
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
data/lib/transpec/config.rb
CHANGED
@@ -8,40 +8,59 @@ module Transpec
|
|
8
8
|
|
9
9
|
PREDICATES = [
|
10
10
|
[:forced, false],
|
11
|
-
[:convert_should, true],
|
12
|
-
[:convert_oneliner, true],
|
13
|
-
[:convert_should_receive, true],
|
14
|
-
[:convert_stub, true],
|
15
|
-
[:convert_have_items, true],
|
16
|
-
[:convert_its, true],
|
17
|
-
[:convert_pending, true],
|
18
|
-
[:convert_deprecated_method, true],
|
19
|
-
[:convert_example_group, false],
|
20
|
-
[:convert_hook_scope, false],
|
21
|
-
[:convert_stub_with_hash_to_allow_to_receive_and_return, false],
|
22
11
|
[:skip_dynamic_analysis, false],
|
23
12
|
[:add_explicit_type_metadata_to_example_group, false],
|
24
13
|
[:add_receiver_arg_to_any_instance_implementation_block, true],
|
25
14
|
[:parenthesize_matcher_arg, true]
|
26
15
|
].freeze
|
27
16
|
|
17
|
+
DEFAULT_CONVERSIONS = {
|
18
|
+
should: true,
|
19
|
+
oneliner: true,
|
20
|
+
should_receive: true,
|
21
|
+
stub: true,
|
22
|
+
have_items: true,
|
23
|
+
its: true,
|
24
|
+
pending: true,
|
25
|
+
deprecated: true,
|
26
|
+
example_group: false,
|
27
|
+
hook_scope: false,
|
28
|
+
stub_with_hash: false # to allow(obj).to receive(:message).and_return(value) prior to RSpec 3
|
29
|
+
}.freeze
|
30
|
+
|
28
31
|
PREDICATES.each do |predicate, _|
|
29
32
|
attr_accessor predicate
|
30
33
|
alias_method predicate.to_s + '?', predicate
|
31
34
|
end
|
32
35
|
|
36
|
+
attr_reader :conversion
|
33
37
|
attr_accessor :negative_form_of_to, :boolean_matcher_type, :form_of_be_falsey, :rspec_command
|
34
38
|
|
39
|
+
def self.valid_conversion_type?(type)
|
40
|
+
conversion_types.include?(type.to_sym)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.conversion_types
|
44
|
+
DEFAULT_CONVERSIONS.keys
|
45
|
+
end
|
46
|
+
|
35
47
|
def initialize
|
36
48
|
PREDICATES.each do |predicate, default_value|
|
37
49
|
instance_variable_set('@' + predicate.to_s, default_value)
|
38
50
|
end
|
39
51
|
|
52
|
+
@conversion = SymbolKeyHash.new
|
53
|
+
@conversion.update(DEFAULT_CONVERSIONS)
|
54
|
+
|
40
55
|
self.negative_form_of_to = 'not_to'
|
41
56
|
self.boolean_matcher_type = :conditional
|
42
57
|
self.form_of_be_falsey = 'be_falsey'
|
43
58
|
end
|
44
59
|
|
60
|
+
def convert?(type)
|
61
|
+
@conversion[type]
|
62
|
+
end
|
63
|
+
|
45
64
|
def negative_form_of_to=(form)
|
46
65
|
validate!(form.to_s, NEGATIVE_FORMS_OF_TO, 'Negative form of "to"')
|
47
66
|
@negative_form_of_to = form.to_s.freeze
|
@@ -65,5 +84,15 @@ module Transpec
|
|
65
84
|
message << valid_values.map(&:inspect).join(' or ')
|
66
85
|
fail ArgumentError, message
|
67
86
|
end
|
87
|
+
|
88
|
+
class SymbolKeyHash < Hash
|
89
|
+
def [](key)
|
90
|
+
super(key.to_sym)
|
91
|
+
end
|
92
|
+
|
93
|
+
def []=(key, value)
|
94
|
+
super(key.to_sym, value)
|
95
|
+
end
|
96
|
+
end
|
68
97
|
end
|
69
98
|
end
|
data/lib/transpec/converter.rb
CHANGED
@@ -47,64 +47,64 @@ module Transpec
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def process_should(should)
|
50
|
-
return unless config.
|
50
|
+
return unless config.convert?(:should)
|
51
51
|
should.expectize!(config.negative_form_of_to)
|
52
52
|
end
|
53
53
|
|
54
54
|
def process_oneliner_should(oneliner_should)
|
55
55
|
negative_form = config.negative_form_of_to
|
56
|
-
should_convert_have_items = config.
|
56
|
+
should_convert_have_items = config.convert?(:have_items) &&
|
57
57
|
oneliner_should.have_matcher.conversion_target?
|
58
58
|
|
59
59
|
if should_convert_have_items
|
60
|
-
if config.
|
60
|
+
if config.convert?(:should)
|
61
61
|
oneliner_should.convert_have_items_to_standard_expect!(negative_form)
|
62
62
|
else
|
63
63
|
oneliner_should.convert_have_items_to_standard_should!
|
64
64
|
end
|
65
|
-
elsif config.
|
65
|
+
elsif config.convert?(:oneliner) && rspec_version.oneliner_is_expected_available?
|
66
66
|
oneliner_should.expectize!(negative_form)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def process_should_receive(should_receive)
|
71
71
|
if should_receive.useless_expectation?
|
72
|
-
if config.
|
73
|
-
if config.
|
72
|
+
if config.convert?(:deprecated)
|
73
|
+
if config.convert?(:stub)
|
74
74
|
should_receive.allowize_useless_expectation!(config.negative_form_of_to)
|
75
75
|
else
|
76
76
|
should_receive.stubize_useless_expectation!
|
77
77
|
end
|
78
|
-
elsif config.
|
78
|
+
elsif config.convert?(:should_receive)
|
79
79
|
should_receive.expectize!(config.negative_form_of_to)
|
80
80
|
end
|
81
|
-
elsif config.
|
81
|
+
elsif config.convert?(:should_receive)
|
82
82
|
should_receive.expectize!(config.negative_form_of_to)
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
def process_double(double)
|
87
|
-
double.convert_to_double! if config.
|
87
|
+
double.convert_to_double! if config.convert?(:deprecated)
|
88
88
|
end
|
89
89
|
|
90
90
|
def process_method_stub(method_stub)
|
91
|
-
if config.
|
91
|
+
if config.convert?(:stub)
|
92
92
|
if !method_stub.hash_arg? ||
|
93
93
|
rspec_version.receive_messages_available? ||
|
94
|
-
config.
|
94
|
+
config.convert?(:stub_with_hash)
|
95
95
|
method_stub.allowize!
|
96
|
-
elsif config.
|
96
|
+
elsif config.convert?(:deprecated)
|
97
97
|
method_stub.convert_deprecated_method!
|
98
98
|
end
|
99
|
-
elsif config.
|
99
|
+
elsif config.convert?(:deprecated)
|
100
100
|
method_stub.convert_deprecated_method!
|
101
101
|
end
|
102
102
|
|
103
|
-
method_stub.remove_no_message_allowance! if config.
|
103
|
+
method_stub.remove_no_message_allowance! if config.convert?(:deprecated)
|
104
104
|
end
|
105
105
|
|
106
106
|
def process_operator(operator)
|
107
|
-
return unless config.
|
107
|
+
return unless config.convert?(:should)
|
108
108
|
return if operator.expectation.is_a?(Syntax::OnelinerShould) &&
|
109
109
|
!rspec_version.oneliner_is_expected_available?
|
110
110
|
operator.convert_operator!(config.parenthesize_matcher_arg?)
|
@@ -112,7 +112,7 @@ module Transpec
|
|
112
112
|
|
113
113
|
def process_be_boolean(be_boolean)
|
114
114
|
return unless rspec_version.be_truthy_available?
|
115
|
-
return unless config.
|
115
|
+
return unless config.convert?(:deprecated)
|
116
116
|
|
117
117
|
case config.boolean_matcher_type
|
118
118
|
when :conditional
|
@@ -123,42 +123,42 @@ module Transpec
|
|
123
123
|
end
|
124
124
|
|
125
125
|
def process_be_close(be_close)
|
126
|
-
be_close.convert_to_be_within! if config.
|
126
|
+
be_close.convert_to_be_within! if config.convert?(:deprecated)
|
127
127
|
end
|
128
128
|
|
129
129
|
def process_raise_error(raise_error)
|
130
130
|
return unless raise_error
|
131
|
-
if config.
|
131
|
+
if config.convert?(:deprecated)
|
132
132
|
raise_error.remove_error_specification_with_negative_expectation!
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
136
|
def process_its(its)
|
137
|
-
its.convert_to_describe_subject_it! if config.
|
137
|
+
its.convert_to_describe_subject_it! if config.convert?(:its)
|
138
138
|
end
|
139
139
|
|
140
140
|
def process_example(example)
|
141
|
-
return if !rspec_version.rspec_2_99? || !config.
|
141
|
+
return if !rspec_version.rspec_2_99? || !config.convert?(:pending)
|
142
142
|
example.convert_pending_to_skip!
|
143
143
|
end
|
144
144
|
|
145
145
|
def process_pending(pending)
|
146
|
-
return if !rspec_version.rspec_2_99? || !config.
|
146
|
+
return if !rspec_version.rspec_2_99? || !config.convert?(:pending)
|
147
147
|
pending.convert_deprecated_syntax!
|
148
148
|
end
|
149
149
|
|
150
150
|
def process_current_example(current_example)
|
151
151
|
return unless rspec_version.yielded_example_available?
|
152
|
-
current_example.convert! if config.
|
152
|
+
current_example.convert! if config.convert?(:deprecated)
|
153
153
|
end
|
154
154
|
|
155
155
|
def process_matcher_definition(matcher_definition)
|
156
156
|
return unless rspec_version.non_should_matcher_protocol_available?
|
157
|
-
matcher_definition.convert_deprecated_method! if config.
|
157
|
+
matcher_definition.convert_deprecated_method! if config.convert?(:deprecated)
|
158
158
|
end
|
159
159
|
|
160
160
|
def process_example_group(example_group)
|
161
|
-
if rspec_version.non_monkey_patch_example_group_available? && config.
|
161
|
+
if rspec_version.non_monkey_patch_example_group_available? && config.convert?(:example_group)
|
162
162
|
example_group.convert_to_non_monkey_patch!
|
163
163
|
end
|
164
164
|
|
@@ -169,13 +169,13 @@ module Transpec
|
|
169
169
|
end
|
170
170
|
|
171
171
|
def process_rspec_configure(rspec_configure)
|
172
|
-
if config.
|
172
|
+
if config.convert?(:deprecated)
|
173
173
|
rspec_configure.convert_deprecated_options!
|
174
174
|
end
|
175
175
|
|
176
176
|
if spec_suite.main_rspec_configure_node?(rspec_configure.node)
|
177
177
|
if rspec_version.non_monkey_patch_example_group_available? &&
|
178
|
-
config.
|
178
|
+
config.convert?(:example_group)
|
179
179
|
rspec_configure.expose_dsl_globally = false
|
180
180
|
end
|
181
181
|
|
@@ -192,31 +192,31 @@ module Transpec
|
|
192
192
|
end
|
193
193
|
|
194
194
|
def process_have(have)
|
195
|
-
return if !have || !config.
|
195
|
+
return if !have || !config.convert?(:have_items)
|
196
196
|
have.convert_to_standard_expectation!(config.parenthesize_matcher_arg)
|
197
197
|
end
|
198
198
|
|
199
199
|
def process_hook(hook)
|
200
|
-
return if !config.
|
200
|
+
return if !config.convert?(:hook_scope) || !rspec_version.hook_scope_alias_available?
|
201
201
|
hook.convert_scope_name!
|
202
202
|
end
|
203
203
|
|
204
204
|
def process_useless_and_return(messaging_host)
|
205
205
|
return unless messaging_host
|
206
|
-
return unless config.
|
206
|
+
return unless config.convert?(:deprecated)
|
207
207
|
messaging_host.remove_useless_and_return!
|
208
208
|
end
|
209
209
|
|
210
210
|
def process_any_instance_block(messaging_host)
|
211
211
|
return unless messaging_host
|
212
212
|
return unless rspec_version.rspec_2_99?
|
213
|
-
return unless config.
|
213
|
+
return unless config.convert?(:deprecated)
|
214
214
|
return unless config.add_receiver_arg_to_any_instance_implementation_block?
|
215
215
|
messaging_host.add_receiver_arg_to_any_instance_implementation_block!
|
216
216
|
end
|
217
217
|
|
218
218
|
def need_to_modify_yield_receiver_to_any_instance_implementation_blocks_config?
|
219
|
-
rspec_version.rspec_2_99? && config.
|
219
|
+
rspec_version.rspec_2_99? && config.convert?(:deprecated) &&
|
220
220
|
spec_suite.need_to_modify_yield_receiver_to_any_instance_implementation_blocks_config?
|
221
221
|
end
|
222
222
|
end
|
data/lib/transpec/version.rb
CHANGED
data/tasks/lib/test.rb
CHANGED
@@ -29,7 +29,10 @@ class Test < Project
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def transpec(*args)
|
32
|
-
|
32
|
+
with_clean_bundler_env do
|
33
|
+
ENV['BUNDLE_GEMFILE'] = File.join(Transpec.root, 'Gemfile')
|
34
|
+
sh 'bundle', 'exec', File.join(Transpec.root, 'bin', 'transpec'), *args
|
35
|
+
end
|
33
36
|
end
|
34
37
|
|
35
38
|
def add_rspec_3_to_gemfile
|
data/tasks/readme.rake
CHANGED
@@ -158,13 +158,15 @@ class READMEContext
|
|
158
158
|
/^#{'#' * level}[^#]/
|
159
159
|
end
|
160
160
|
|
161
|
-
def validate_syntax_type_table(markdown_table,
|
161
|
+
def validate_syntax_type_table(markdown_table, enabled_by_default)
|
162
162
|
types_in_doc = markdown_table.lines.map do |line|
|
163
163
|
first_column = line.split('|').first
|
164
164
|
first_column.gsub(/[^\w]/, '').to_sym
|
165
165
|
end.sort
|
166
166
|
|
167
|
-
types_in_code.
|
167
|
+
types_in_code = Config::DEFAULT_CONVERSIONS.select do |_type, enabled|
|
168
|
+
enabled == enabled_by_default
|
169
|
+
end.keys.sort
|
168
170
|
|
169
171
|
unless types_in_doc == types_in_code
|
170
172
|
types_missing_description = types_in_code - types_in_doc
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transpec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yuji Nakayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -133,6 +133,7 @@ files:
|
|
133
133
|
- lib/transpec/ast/node.rb
|
134
134
|
- lib/transpec/base_rewriter.rb
|
135
135
|
- lib/transpec/cli.rb
|
136
|
+
- lib/transpec/cli/option_parser.rb
|
136
137
|
- lib/transpec/commit_message.rb
|
137
138
|
- lib/transpec/config.rb
|
138
139
|
- lib/transpec/conversion_error.rb
|
@@ -145,7 +146,6 @@ files:
|
|
145
146
|
- lib/transpec/dynamic_analyzer/runtime_data.rb
|
146
147
|
- lib/transpec/dynamic_analyzer/transpec_analysis_helper.rb.erb
|
147
148
|
- lib/transpec/git.rb
|
148
|
-
- lib/transpec/option_parser.rb
|
149
149
|
- lib/transpec/processed_source.rb
|
150
150
|
- lib/transpec/project.rb
|
151
151
|
- lib/transpec/record.rb
|
@@ -1,236 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
|
3
|
-
require 'transpec/config'
|
4
|
-
require 'transpec/git'
|
5
|
-
require 'transpec/version'
|
6
|
-
require 'optparse'
|
7
|
-
require 'rainbow'
|
8
|
-
require 'rainbow/ext/string' unless String.respond_to?(:color)
|
9
|
-
|
10
|
-
module Transpec
|
11
|
-
class OptionParser # rubocop:disable ClassLength
|
12
|
-
CONFIG_ATTRS_FOR_KEEP_TYPES = {
|
13
|
-
should: :convert_should=,
|
14
|
-
oneliner: :convert_oneliner=,
|
15
|
-
should_receive: :convert_should_receive=,
|
16
|
-
stub: :convert_stub=,
|
17
|
-
have_items: :convert_have_items=,
|
18
|
-
its: :convert_its=,
|
19
|
-
pending: :convert_pending=,
|
20
|
-
deprecated: :convert_deprecated_method=
|
21
|
-
}
|
22
|
-
|
23
|
-
CONFIG_ATTRS_FOR_CONVERT_TYPES = {
|
24
|
-
example_group: :convert_example_group=,
|
25
|
-
hook_scope: :convert_hook_scope=,
|
26
|
-
stub_with_hash: :convert_stub_with_hash_to_allow_to_receive_and_return=
|
27
|
-
}
|
28
|
-
|
29
|
-
VALID_BOOLEAN_MATCHER_TYPES = %w(truthy,falsey truthy,falsy true,false)
|
30
|
-
|
31
|
-
attr_reader :config
|
32
|
-
|
33
|
-
def self.available_conversion_types
|
34
|
-
CONFIG_ATTRS_FOR_KEEP_TYPES.keys
|
35
|
-
end
|
36
|
-
|
37
|
-
def initialize(config = Config.new)
|
38
|
-
@config = config
|
39
|
-
setup_parser
|
40
|
-
end
|
41
|
-
|
42
|
-
def parse(args)
|
43
|
-
args = convert_deprecated_options(args)
|
44
|
-
@parser.parse!(args)
|
45
|
-
args
|
46
|
-
end
|
47
|
-
|
48
|
-
def help
|
49
|
-
@parser.help
|
50
|
-
end
|
51
|
-
|
52
|
-
private
|
53
|
-
|
54
|
-
def setup_parser # rubocop:disable MethodLength
|
55
|
-
@parser = create_parser
|
56
|
-
|
57
|
-
define_option('-f', '--force') do
|
58
|
-
config.forced = true
|
59
|
-
end
|
60
|
-
|
61
|
-
define_option('-c', '--rspec-command COMMAND') do |command|
|
62
|
-
config.rspec_command = command
|
63
|
-
end
|
64
|
-
|
65
|
-
define_option('-k', '--keep TYPE[,TYPE...]') do |types|
|
66
|
-
configure_conversion(CONFIG_ATTRS_FOR_KEEP_TYPES, types, false)
|
67
|
-
end
|
68
|
-
|
69
|
-
define_option('-v', '--convert TYPE[,TYPE...]') do |types|
|
70
|
-
configure_conversion(CONFIG_ATTRS_FOR_CONVERT_TYPES, types, true)
|
71
|
-
end
|
72
|
-
|
73
|
-
define_option('-s', '--skip-dynamic-analysis') do
|
74
|
-
config.skip_dynamic_analysis = true
|
75
|
-
end
|
76
|
-
|
77
|
-
define_option('-n', '--negative-form FORM') do |form|
|
78
|
-
config.negative_form_of_to = form
|
79
|
-
end
|
80
|
-
|
81
|
-
define_option('-b', '--boolean-matcher TYPE') do |type|
|
82
|
-
unless VALID_BOOLEAN_MATCHER_TYPES.include?(type)
|
83
|
-
types = VALID_BOOLEAN_MATCHER_TYPES.map(&:inspect).join(', ')
|
84
|
-
fail ArgumentError, "Boolean matcher type must be any of #{types}"
|
85
|
-
end
|
86
|
-
config.boolean_matcher_type = type.include?('truthy') ? :conditional : :exact
|
87
|
-
config.form_of_be_falsey = type.include?('falsy') ? 'be_falsy' : 'be_falsey'
|
88
|
-
end
|
89
|
-
|
90
|
-
define_option('-e', '--explicit-spec-type') do
|
91
|
-
config.add_explicit_type_metadata_to_example_group = true
|
92
|
-
end
|
93
|
-
|
94
|
-
define_option('-a', '--no-yield-any-instance') do
|
95
|
-
config.add_receiver_arg_to_any_instance_implementation_block = false
|
96
|
-
end
|
97
|
-
|
98
|
-
define_option('-p', '--no-parens-matcher-arg') do
|
99
|
-
config.parenthesize_matcher_arg = false
|
100
|
-
end
|
101
|
-
|
102
|
-
define_option('--no-color') do
|
103
|
-
Rainbow.enabled = false
|
104
|
-
end
|
105
|
-
|
106
|
-
define_option('--version') do
|
107
|
-
puts Version.to_s
|
108
|
-
exit
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def create_parser
|
113
|
-
banner = "Usage: transpec [options] [files or directories]\n\n"
|
114
|
-
summary_width = 32 # Default
|
115
|
-
indentation = ' ' * 2
|
116
|
-
::OptionParser.new(banner, summary_width, indentation)
|
117
|
-
end
|
118
|
-
|
119
|
-
def define_option(*options, &block)
|
120
|
-
description_lines = descriptions[options.first]
|
121
|
-
description_lines = description_lines.map { |line| highlight_text(line) }
|
122
|
-
@parser.on(*options, *description_lines, &block)
|
123
|
-
end
|
124
|
-
|
125
|
-
# rubocop:disable AlignHash
|
126
|
-
def descriptions # rubocop:disable MethodLength
|
127
|
-
@descriptions ||= {
|
128
|
-
'-f' => [
|
129
|
-
'Force processing even if the current Git repository is not clean.'
|
130
|
-
],
|
131
|
-
'-s' => [
|
132
|
-
'Skip dynamic analysis and convert with only static analysis. The',
|
133
|
-
'use of this option is basically *discouraged* since it',
|
134
|
-
'significantly decreases the overall conversion accuracy.'
|
135
|
-
],
|
136
|
-
'-c' => [
|
137
|
-
'Specify a command to run your specs that is used for dynamic',
|
138
|
-
'analysis.',
|
139
|
-
'Default: "bundle exec rspec"'
|
140
|
-
],
|
141
|
-
'-k' => [
|
142
|
-
'Keep specific syntaxes by disabling conversions.',
|
143
|
-
'Conversion Types:',
|
144
|
-
' *should* (to `expect(obj).to`)',
|
145
|
-
' *oneliner* (`it { should ... }` to `it { is_expected.to ... }`)',
|
146
|
-
' *should_receive* (to `expect(obj).to receive`)',
|
147
|
-
' *stub* (to `allow(obj).to receive`)',
|
148
|
-
' *have_items* (to `expect(collection.size).to eq(n)`)',
|
149
|
-
" *its* (to `describe '#attr' { subject { }; it { } }`)",
|
150
|
-
' *pending* (to `skip`)',
|
151
|
-
' *deprecated* (all other deprecated syntaxes to latest syntaxes)',
|
152
|
-
'These conversions are enabled by default.'
|
153
|
-
],
|
154
|
-
'-v' => [
|
155
|
-
'Enable specific conversions that are disabled by default.',
|
156
|
-
'Conversion Types:',
|
157
|
-
' *example_group* (`describe` to `RSpec.describe`)',
|
158
|
-
' *hook_scope* (`before(:all)` to `before(:context)`)',
|
159
|
-
' *stub_with_hash* (`obj.stub(:msg => val)` to',
|
160
|
-
' `allow(obj).to receive(:msg).and_return(val)`)',
|
161
|
-
'These conversions are disabled by default.'
|
162
|
-
],
|
163
|
-
'-n' => [
|
164
|
-
'Specify a negative form of `to` that is used in the `expect(...).to`',
|
165
|
-
'syntax. Either *not_to* or *to_not*.',
|
166
|
-
'Default: *not_to*'
|
167
|
-
],
|
168
|
-
'-b' => [
|
169
|
-
'Specify a matcher type that `be_true` and `be_false` will be',
|
170
|
-
'converted to.',
|
171
|
-
' *truthy,falsey* (conditional semantics)',
|
172
|
-
' *truthy,falsy* (alias of `falsey`)',
|
173
|
-
' *true,false* (exact equality)',
|
174
|
-
'Default: *truthy,falsey*'
|
175
|
-
],
|
176
|
-
'-e' => [
|
177
|
-
'Add explicit `:type` metadata to example groups in a project using',
|
178
|
-
'rspec-rails.'
|
179
|
-
],
|
180
|
-
'-a' => [
|
181
|
-
'Suppress yielding receiver instances to `any_instance`',
|
182
|
-
'implementation blocks as the first block argument.'
|
183
|
-
],
|
184
|
-
'-p' => [
|
185
|
-
'Suppress parenthesizing arguments of matchers when converting',
|
186
|
-
'`should` with operator matcher to `expect` with non-operator matcher.',
|
187
|
-
'Note that it will be parenthesized even if this option is',
|
188
|
-
'specified when parentheses are necessary to keep the meaning of',
|
189
|
-
'the expression. By default, arguments of the following operator',
|
190
|
-
'matchers will be parenthesized.',
|
191
|
-
' `== 10` to `eq(10)`',
|
192
|
-
' `=~ /pattern/` to `match(/pattern/)`',
|
193
|
-
' `=~ [1, 2]` to `match_array([1, 2])`'
|
194
|
-
],
|
195
|
-
'--no-color' => [
|
196
|
-
'Disable color in the output.'
|
197
|
-
],
|
198
|
-
'--version' => [
|
199
|
-
'Show Transpec version.'
|
200
|
-
]
|
201
|
-
}
|
202
|
-
end
|
203
|
-
# rubocop:enable AlignHash
|
204
|
-
|
205
|
-
def highlight_text(text)
|
206
|
-
text.gsub(/`.+?`/) { |code| code.gsub('`', '').underline }
|
207
|
-
.gsub(/\*.+?\*/) { |code| code.gsub('*', '').bright }
|
208
|
-
end
|
209
|
-
|
210
|
-
def convert_deprecated_options(raw_args)
|
211
|
-
raw_args.each_with_object([]) do |arg, args|
|
212
|
-
case arg
|
213
|
-
when '--no-parentheses-matcher-arg'
|
214
|
-
deprecate('--no-parentheses-matcher-arg option', '--no-parens-matcher-arg')
|
215
|
-
args << '--no-parens-matcher-arg'
|
216
|
-
else
|
217
|
-
args << arg
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def deprecate(subject, alternative = nil)
|
223
|
-
message = "DEPRECATION: #{subject} is deprecated."
|
224
|
-
message << " Use #{alternative} instead." if alternative
|
225
|
-
warn message
|
226
|
-
end
|
227
|
-
|
228
|
-
def configure_conversion(type_to_attr_map, inputted_types, boolean)
|
229
|
-
inputted_types.split(',').each do |type|
|
230
|
-
config_attr = type_to_attr_map[type.to_sym]
|
231
|
-
fail ArgumentError, "Unknown syntax type #{type.inspect}" unless config_attr
|
232
|
-
config.send(config_attr, boolean)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
end
|