transpec 1.13.1 → 2.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/CHANGELOG.md +6 -0
  4. data/README.md +63 -22
  5. data/README.md.erb +55 -16
  6. data/lib/transpec/cli.rb +9 -9
  7. data/lib/transpec/commit_message.rb +2 -0
  8. data/lib/transpec/{configuration.rb → config.rb} +7 -6
  9. data/lib/transpec/converter.rb +57 -46
  10. data/lib/transpec/option_parser.rb +23 -25
  11. data/lib/transpec/rspec_version.rb +6 -0
  12. data/lib/transpec/spec_suite.rb +2 -6
  13. data/lib/transpec/syntax/example.rb +2 -15
  14. data/lib/transpec/syntax/example_group.rb +111 -9
  15. data/lib/transpec/syntax/have/dynamic_analysis.rb +1 -1
  16. data/lib/transpec/syntax/mixin/metadata.rb +29 -0
  17. data/lib/transpec/syntax/mixin/rspec_rails.rb +27 -0
  18. data/lib/transpec/syntax/rspec_configure.rb +14 -3
  19. data/lib/transpec/syntax/rspec_configure/{configuration_modification.rb → config_modification.rb} +18 -15
  20. data/lib/transpec/syntax/rspec_configure/framework.rb +7 -7
  21. data/lib/transpec/syntax/rspec_configure/mocks.rb +1 -1
  22. data/lib/transpec/version.rb +3 -3
  23. data/spec/transpec/commit_message_spec.rb +9 -1
  24. data/spec/transpec/{configuration_spec.rb → config_spec.rb} +19 -18
  25. data/spec/transpec/converter_spec.rb +245 -210
  26. data/spec/transpec/option_parser_spec.rb +27 -59
  27. data/spec/transpec/rspec_version_spec.rb +26 -0
  28. data/spec/transpec/syntax/example_group_spec.rb +277 -0
  29. data/spec/transpec/syntax/have_spec.rb +1 -1
  30. data/spec/transpec/syntax/rspec_configure_spec.rb +117 -0
  31. data/tasks/fixtures/guard/2.99.0/COMMIT_EDITMSG +3 -1
  32. data/tasks/fixtures/guard/3.0.0/COMMIT_EDITMSG +3 -1
  33. data/tasks/fixtures/mail/2.99.0/COMMIT_EDITMSG +3 -1
  34. data/tasks/fixtures/mail/3.0.0/COMMIT_EDITMSG +3 -1
  35. data/tasks/fixtures/twitter/2.99.0/COMMIT_EDITMSG +3 -1
  36. data/tasks/fixtures/twitter/3.0.0/COMMIT_EDITMSG +3 -1
  37. data/tasks/readme.rake +3 -2
  38. metadata +8 -6
@@ -20,6 +20,8 @@ module Transpec
20
20
  | transpec #{smart_cli_args}
21
21
  |
22
22
  |#{conversion_summary}
23
+ |
24
+ |See also: https://github.com/yujinakayama/transpec#supported-conversions
23
25
  END
24
26
  end
25
27
 
@@ -1,12 +1,13 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module Transpec
4
- class Configuration
4
+ class Config
5
5
  NEGATIVE_FORMS_OF_TO = ['not_to', 'to_not'].freeze
6
6
  FORMS_OF_BE_FALSEY = ['be_falsey', 'be_falsy'].freeze
7
7
  BOOLEAN_MATCHER_TYPES = [:conditional, :exact].freeze
8
8
 
9
9
  PREDICATES = [
10
+ [:forced, false],
10
11
  [:convert_should, true],
11
12
  [:convert_oneliner, true],
12
13
  [:convert_should_receive, true],
@@ -15,13 +16,13 @@ module Transpec
15
16
  [:convert_its, true],
16
17
  [:convert_pending, true],
17
18
  [:convert_deprecated_method, true],
18
- [:parenthesize_matcher_arg, true],
19
- [:add_receiver_arg_to_any_instance_implementation_block, true],
20
- [:convert_stub_with_hash_to_allow_to_receive_and_return, false],
21
19
  [:convert_example_group, false],
22
20
  [:convert_hook_scope, false],
23
- [:forced, false],
24
- [:skip_dynamic_analysis, false]
21
+ [:convert_stub_with_hash_to_allow_to_receive_and_return, false],
22
+ [:skip_dynamic_analysis, false],
23
+ [:add_receiver_arg_to_any_instance_implementation_block, true],
24
+ [:add_explicit_type_metadata_to_example_group, true],
25
+ [:parenthesize_matcher_arg, true]
25
26
  ].freeze
26
27
 
27
28
  PREDICATES.each do |predicate, _|
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
 
3
3
  require 'transpec/base_rewriter'
4
- require 'transpec/configuration'
4
+ require 'transpec/config'
5
5
  require 'transpec/report'
6
6
  require 'transpec/rspec_version'
7
7
  require 'transpec/spec_suite'
@@ -13,15 +13,15 @@ module Transpec
13
13
  class Converter < BaseRewriter # rubocop:disable ClassLength
14
14
  include Syntax::Dispatcher
15
15
 
16
- attr_reader :spec_suite, :configuration, :rspec_version, :report
16
+ attr_reader :spec_suite, :config, :rspec_version, :report
17
17
 
18
18
  alias_method :convert_file!, :rewrite_file!
19
19
  alias_method :convert_source, :rewrite_source
20
20
  alias_method :convert, :rewrite
21
21
 
22
- def initialize(spec_suite = nil, configuration = nil, rspec_version = nil)
22
+ def initialize(spec_suite = nil, config = nil, rspec_version = nil)
23
23
  @spec_suite = spec_suite || SpecSuite.new
24
- @configuration = configuration || Configuration.new
24
+ @config = config || Config.new
25
25
  @rspec_version = rspec_version || Transpec.required_rspec_version
26
26
  @report = Report.new
27
27
  end
@@ -44,161 +44,172 @@ module Transpec
44
44
  end
45
45
 
46
46
  def process_should(should)
47
- return unless configuration.convert_should?
48
- should.expectize!(configuration.negative_form_of_to)
47
+ return unless config.convert_should?
48
+ should.expectize!(config.negative_form_of_to)
49
49
  end
50
50
 
51
51
  def process_oneliner_should(oneliner_should)
52
- negative_form = configuration.negative_form_of_to
53
- should_convert_have_items = configuration.convert_have_items? &&
52
+ negative_form = config.negative_form_of_to
53
+ should_convert_have_items = config.convert_have_items? &&
54
54
  oneliner_should.have_matcher.conversion_target?
55
55
 
56
56
  if should_convert_have_items
57
- if configuration.convert_should?
57
+ if config.convert_should?
58
58
  oneliner_should.convert_have_items_to_standard_expect!(negative_form)
59
59
  else
60
60
  oneliner_should.convert_have_items_to_standard_should!
61
61
  end
62
- elsif configuration.convert_oneliner? && rspec_version.oneliner_is_expected_available?
62
+ elsif config.convert_oneliner? && rspec_version.oneliner_is_expected_available?
63
63
  oneliner_should.expectize!(negative_form)
64
64
  end
65
65
  end
66
66
 
67
67
  def process_should_receive(should_receive)
68
68
  if should_receive.useless_expectation?
69
- if configuration.convert_deprecated_method?
70
- if configuration.convert_stub?
71
- should_receive.allowize_useless_expectation!(configuration.negative_form_of_to)
69
+ if config.convert_deprecated_method?
70
+ if config.convert_stub?
71
+ should_receive.allowize_useless_expectation!(config.negative_form_of_to)
72
72
  else
73
73
  should_receive.stubize_useless_expectation!
74
74
  end
75
- elsif configuration.convert_should_receive?
76
- should_receive.expectize!(configuration.negative_form_of_to)
75
+ elsif config.convert_should_receive?
76
+ should_receive.expectize!(config.negative_form_of_to)
77
77
  end
78
- elsif configuration.convert_should_receive?
79
- should_receive.expectize!(configuration.negative_form_of_to)
78
+ elsif config.convert_should_receive?
79
+ should_receive.expectize!(config.negative_form_of_to)
80
80
  end
81
81
  end
82
82
 
83
83
  def process_double(double)
84
- double.convert_to_double! if configuration.convert_deprecated_method?
84
+ double.convert_to_double! if config.convert_deprecated_method?
85
85
  end
86
86
 
87
87
  def process_method_stub(method_stub)
88
- if configuration.convert_stub?
88
+ if config.convert_stub?
89
89
  if !method_stub.hash_arg? ||
90
90
  rspec_version.receive_messages_available? ||
91
- configuration.convert_stub_with_hash_to_allow_to_receive_and_return?
91
+ config.convert_stub_with_hash_to_allow_to_receive_and_return?
92
92
  method_stub.allowize!(rspec_version)
93
- elsif configuration.convert_deprecated_method?
93
+ elsif config.convert_deprecated_method?
94
94
  method_stub.convert_deprecated_method!
95
95
  end
96
- elsif configuration.convert_deprecated_method?
96
+ elsif config.convert_deprecated_method?
97
97
  method_stub.convert_deprecated_method!
98
98
  end
99
99
 
100
- method_stub.remove_no_message_allowance! if configuration.convert_deprecated_method?
100
+ method_stub.remove_no_message_allowance! if config.convert_deprecated_method?
101
101
  end
102
102
 
103
103
  def process_operator(operator)
104
- return unless configuration.convert_should?
104
+ return unless config.convert_should?
105
105
  return if operator.expectation.is_a?(Syntax::OnelinerShould) &&
106
106
  !rspec_version.oneliner_is_expected_available?
107
- operator.convert_operator!(configuration.parenthesize_matcher_arg?)
107
+ operator.convert_operator!(config.parenthesize_matcher_arg?)
108
108
  end
109
109
 
110
110
  def process_be_boolean(be_boolean)
111
111
  return unless rspec_version.be_truthy_available?
112
- return unless configuration.convert_deprecated_method?
112
+ return unless config.convert_deprecated_method?
113
113
 
114
- case configuration.boolean_matcher_type
114
+ case config.boolean_matcher_type
115
115
  when :conditional
116
- be_boolean.convert_to_conditional_matcher!(configuration.form_of_be_falsey)
116
+ be_boolean.convert_to_conditional_matcher!(config.form_of_be_falsey)
117
117
  when :exact
118
118
  be_boolean.convert_to_exact_matcher!
119
119
  end
120
120
  end
121
121
 
122
122
  def process_be_close(be_close)
123
- be_close.convert_to_be_within! if configuration.convert_deprecated_method?
123
+ be_close.convert_to_be_within! if config.convert_deprecated_method?
124
124
  end
125
125
 
126
126
  def process_raise_error(raise_error)
127
127
  return unless raise_error
128
- if configuration.convert_deprecated_method?
128
+ if config.convert_deprecated_method?
129
129
  raise_error.remove_error_specification_with_negative_expectation!
130
130
  end
131
131
  end
132
132
 
133
133
  def process_its(its)
134
- its.convert_to_describe_subject_it! if configuration.convert_its?
134
+ its.convert_to_describe_subject_it! if config.convert_its?
135
135
  end
136
136
 
137
137
  def process_example(example)
138
- return if !rspec_version.rspec_2_99? || !configuration.convert_pending?
138
+ return if !rspec_version.rspec_2_99? || !config.convert_pending?
139
139
  example.convert_pending_to_skip!
140
140
  end
141
141
 
142
142
  def process_pending(pending)
143
- return if !rspec_version.rspec_2_99? || !configuration.convert_pending?
143
+ return if !rspec_version.rspec_2_99? || !config.convert_pending?
144
144
  pending.convert_deprecated_syntax!
145
145
  end
146
146
 
147
147
  def process_current_example(current_example)
148
148
  return unless rspec_version.yielded_example_available?
149
- current_example.convert! if configuration.convert_deprecated_method?
149
+ current_example.convert! if config.convert_deprecated_method?
150
150
  end
151
151
 
152
152
  def process_matcher_definition(matcher_definition)
153
153
  return unless rspec_version.non_should_matcher_protocol_available?
154
- matcher_definition.convert_deprecated_method! if configuration.convert_deprecated_method?
154
+ matcher_definition.convert_deprecated_method! if config.convert_deprecated_method?
155
155
  end
156
156
 
157
157
  def process_example_group(example_group)
158
- return unless rspec_version.non_monkey_patch_example_group_available?
159
- example_group.convert_to_non_monkey_patch! if configuration.convert_example_group?
158
+ if rspec_version.non_monkey_patch_example_group_available? && config.convert_example_group?
159
+ example_group.convert_to_non_monkey_patch!
160
+ end
161
+
162
+ if rspec_version.implicit_spec_type_disablement_available? &&
163
+ config.add_explicit_type_metadata_to_example_group?
164
+ example_group.add_explicit_type_metadata!
165
+ end
160
166
  end
161
167
 
162
168
  def process_rspec_configure(rspec_configure)
163
169
  return unless spec_suite.main_rspec_configure_node?(rspec_configure.node)
164
170
 
165
171
  if rspec_version.non_monkey_patch_example_group_available? &&
166
- configuration.convert_example_group?
172
+ config.convert_example_group?
167
173
  rspec_configure.expose_dsl_globally = false
168
174
  end
169
175
 
170
176
  if need_to_modify_yield_receiver_to_any_instance_implementation_blocks_config?
171
- should_yield = configuration.add_receiver_arg_to_any_instance_implementation_block?
177
+ should_yield = config.add_receiver_arg_to_any_instance_implementation_block?
172
178
  rspec_configure.mocks.yield_receiver_to_any_instance_implementation_blocks = should_yield
173
179
  end
180
+
181
+ if rspec_version.implicit_spec_type_disablement_available? &&
182
+ !config.add_explicit_type_metadata_to_example_group?
183
+ rspec_configure.infer_spec_type_from_file_location!
184
+ end
174
185
  end
175
186
 
176
187
  def process_have(have)
177
- return if !have || !configuration.convert_have_items?
178
- have.convert_to_standard_expectation!(configuration.parenthesize_matcher_arg)
188
+ return if !have || !config.convert_have_items?
189
+ have.convert_to_standard_expectation!(config.parenthesize_matcher_arg)
179
190
  end
180
191
 
181
192
  def process_hook(hook)
182
- return if !configuration.convert_hook_scope? || !rspec_version.hook_scope_alias_available?
193
+ return if !config.convert_hook_scope? || !rspec_version.hook_scope_alias_available?
183
194
  hook.convert_scope_name!
184
195
  end
185
196
 
186
197
  def process_useless_and_return(messaging_host)
187
198
  return unless messaging_host
188
- return unless configuration.convert_deprecated_method?
199
+ return unless config.convert_deprecated_method?
189
200
  messaging_host.remove_useless_and_return!
190
201
  end
191
202
 
192
203
  def process_any_instance_block(messaging_host)
193
204
  return unless messaging_host
194
205
  return unless rspec_version.rspec_2_99?
195
- return unless configuration.convert_deprecated_method?
196
- return unless configuration.add_receiver_arg_to_any_instance_implementation_block?
206
+ return unless config.convert_deprecated_method?
207
+ return unless config.add_receiver_arg_to_any_instance_implementation_block?
197
208
  messaging_host.add_receiver_arg_to_any_instance_implementation_block!
198
209
  end
199
210
 
200
211
  def need_to_modify_yield_receiver_to_any_instance_implementation_blocks_config?
201
- rspec_version.rspec_2_99? && configuration.convert_deprecated_method? &&
212
+ rspec_version.rspec_2_99? && config.convert_deprecated_method? &&
202
213
  spec_suite.need_to_modify_yield_receiver_to_any_instance_implementation_blocks_config?
203
214
  end
204
215
  end
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'transpec/configuration'
3
+ require 'transpec/config'
4
4
  require 'transpec/git'
5
5
  require 'transpec/version'
6
6
  require 'optparse'
@@ -28,14 +28,14 @@ module Transpec
28
28
 
29
29
  VALID_BOOLEAN_MATCHER_TYPES = %w(truthy,falsey truthy,falsy true,false)
30
30
 
31
- attr_reader :configuration
31
+ attr_reader :config
32
32
 
33
33
  def self.available_conversion_types
34
34
  CONFIG_ATTRS_FOR_KEEP_TYPES.keys
35
35
  end
36
36
 
37
- def initialize(configuration = Configuration.new)
38
- @configuration = configuration
37
+ def initialize(config = Config.new)
38
+ @config = config
39
39
  setup_parser
40
40
  end
41
41
 
@@ -55,11 +55,11 @@ module Transpec
55
55
  @parser = create_parser
56
56
 
57
57
  define_option('-f', '--force') do
58
- configuration.forced = true
58
+ config.forced = true
59
59
  end
60
60
 
61
61
  define_option('-c', '--rspec-command COMMAND') do |command|
62
- configuration.rspec_command = command
62
+ config.rspec_command = command
63
63
  end
64
64
 
65
65
  define_option('-k', '--keep TYPE[,TYPE...]') do |types|
@@ -71,11 +71,11 @@ module Transpec
71
71
  end
72
72
 
73
73
  define_option('-s', '--skip-dynamic-analysis') do
74
- configuration.skip_dynamic_analysis = true
74
+ config.skip_dynamic_analysis = true
75
75
  end
76
76
 
77
77
  define_option('-n', '--negative-form FORM') do |form|
78
- configuration.negative_form_of_to = form
78
+ config.negative_form_of_to = form
79
79
  end
80
80
 
81
81
  define_option('-b', '--boolean-matcher TYPE') do |type|
@@ -83,16 +83,20 @@ module Transpec
83
83
  types = VALID_BOOLEAN_MATCHER_TYPES.map(&:inspect).join(', ')
84
84
  fail ArgumentError, "Boolean matcher type must be any of #{types}"
85
85
  end
86
- configuration.boolean_matcher_type = type.include?('truthy') ? :conditional : :exact
87
- configuration.form_of_be_falsey = type.include?('falsy') ? 'be_falsy' : 'be_falsey'
86
+ config.boolean_matcher_type = type.include?('truthy') ? :conditional : :exact
87
+ config.form_of_be_falsey = type.include?('falsy') ? 'be_falsy' : 'be_falsey'
88
88
  end
89
89
 
90
90
  define_option('-a', '--no-yield-any-instance') do
91
- configuration.add_receiver_arg_to_any_instance_implementation_block = false
91
+ config.add_receiver_arg_to_any_instance_implementation_block = false
92
+ end
93
+
94
+ define_option('-t', '--no-explicit-spec-type') do
95
+ config.add_explicit_type_metadata_to_example_group = false
92
96
  end
93
97
 
94
98
  define_option('-p', '--no-parentheses-matcher-arg') do
95
- configuration.parenthesize_matcher_arg = false
99
+ config.parenthesize_matcher_arg = false
96
100
  end
97
101
 
98
102
  define_option('--no-color') do
@@ -144,7 +148,7 @@ module Transpec
144
148
  " *its* (to `describe '#attr' { subject { }; it { } }`)",
145
149
  ' *pending* (to `skip`)',
146
150
  ' *deprecated* (all other deprecated syntaxes to latest syntaxes)',
147
- 'These are all converted by default.'
151
+ 'These conversions are enabled by default.'
148
152
  ],
149
153
  '-v' => [
150
154
  'Enable specific conversions that are disabled by default.',
@@ -172,6 +176,10 @@ module Transpec
172
176
  'Suppress yielding receiver instances to `any_instance`',
173
177
  'implementation blocks as the first block argument.'
174
178
  ],
179
+ '-t' => [
180
+ 'Suppress adding explicit `:type` metadata to example groups in a',
181
+ 'project using rspec-rails.'
182
+ ],
175
183
  '-p' => [
176
184
  'Suppress parenthesizing arguments of matchers when converting',
177
185
  '`should` with operator matcher to `expect` with non-operator matcher.',
@@ -199,17 +207,7 @@ module Transpec
199
207
  end
200
208
 
201
209
  def convert_deprecated_options(raw_args)
202
- raw_args.each_with_object([]) do |arg, args|
203
- case arg
204
- when '-m', '--generate-commit-message'
205
- deprecate('-m/--generate-commit-message option')
206
- when '-t', '--convert-stub-with-hash'
207
- deprecate('-t/--convert-stub-with-hash', '`--convert stub_with_hash`')
208
- args.concat(%w(--convert stub_with_hash))
209
- else
210
- args << arg
211
- end
212
- end
210
+ raw_args.dup
213
211
  end
214
212
 
215
213
  def deprecate(subject, alternative = nil)
@@ -222,7 +220,7 @@ module Transpec
222
220
  inputted_types.split(',').each do |type|
223
221
  config_attr = type_to_attr_map[type.to_sym]
224
222
  fail ArgumentError, "Unknown syntax type #{type.inspect}" unless config_attr
225
- configuration.send(config_attr, boolean)
223
+ config.send(config_attr, boolean)
226
224
  end
227
225
  end
228
226
  end
@@ -44,9 +44,15 @@ module Transpec
44
44
  define_feature :be_truthy, '2.99.0.beta1'
45
45
  define_feature :yielded_example, '2.99.0.beta1'
46
46
  define_feature :yielding_receiver_to_any_instance_implementation_block, '2.99.0.beta1'
47
+
47
48
  define_feature :oneliner_is_expected, '2.99.0.beta2', except: '3.0.0.beta1'
48
49
  define_feature :skip, '2.99.0.beta2', except: '3.0.0.beta1'
50
+
51
+ define_feature :implicit_spec_type_disablement, '2.99.0.rc1',
52
+ except: ['3.0.0.beta1', '3.0.0.beta2']
53
+
49
54
  define_feature :receive_messages, '3.0.0.beta1'
55
+
50
56
  define_feature :receive_message_chain, '3.0.0.beta2'
51
57
  define_feature :non_should_matcher_protocol, '3.0.0.beta2'
52
58
  define_feature :non_monkey_patch_example_group, '3.0.0.beta2'
@@ -10,8 +10,6 @@ module Transpec
10
10
  class SpecSuite
11
11
  include Syntax::Dispatcher
12
12
 
13
- ANALYSIS_TARGET_CLASSES = [Syntax::Mixin::AnyInstanceBlock]
14
-
15
13
  attr_reader :runtime_data
16
14
 
17
15
  def initialize(base_paths = [], runtime_data = nil)
@@ -21,10 +19,8 @@ module Transpec
21
19
  end
22
20
 
23
21
  def specs
24
- @specs ||= begin
25
- FileFinder.find(@base_paths).map do |path|
26
- ProcessedSource.parse_file(path)
27
- end
22
+ @specs ||= FileFinder.find(@base_paths).map do |path|
23
+ ProcessedSource.parse_file(path)
28
24
  end
29
25
  end
30
26
 
@@ -2,12 +2,13 @@
2
2
 
3
3
  require 'transpec/syntax'
4
4
  require 'transpec/syntax/mixin/context_sensitive'
5
+ require 'transpec/syntax/mixin/metadata'
5
6
  require 'transpec/rspec_dsl'
6
7
 
7
8
  module Transpec
8
9
  class Syntax
9
10
  class Example < Syntax
10
- include Mixin::ContextSensitive, RSpecDSL
11
+ include Mixin::ContextSensitive, Mixin::Metadata, RSpecDSL
11
12
 
12
13
  def dynamic_analysis_target?
13
14
  super && receiver_node.nil? && EXAMPLE_METHODS.include?(method_name)
@@ -22,16 +23,6 @@ module Transpec
22
23
  convert_pending_metadata_to_skip!
23
24
  end
24
25
 
25
- def metadata_key_nodes
26
- metadata_nodes.each_with_object([]) do |node, key_nodes|
27
- if node.hash_type?
28
- key_nodes.concat(node.children.map { |pair_node| pair_node.children.first })
29
- else
30
- key_nodes << node
31
- end
32
- end
33
- end
34
-
35
26
  private
36
27
 
37
28
  def convert_pending_selector_to_skip!
@@ -69,10 +60,6 @@ module Transpec
69
60
  end
70
61
  end
71
62
 
72
- def metadata_nodes
73
- arg_nodes[1..-1] || []
74
- end
75
-
76
63
  def register_record(original_syntax, converted_syntax)
77
64
  report.records << Record.new(original_syntax, converted_syntax)
78
65
  end