transpec 1.13.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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