transpec 1.5.0 → 1.5.1

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Guardfile +18 -14
  4. data/README.md +1 -1
  5. data/README.md.erb +1 -1
  6. data/lib/transpec/cli.rb +2 -2
  7. data/lib/transpec/context_error.rb +23 -0
  8. data/lib/transpec/converter.rb +5 -5
  9. data/lib/transpec/dynamic_analyzer/rewriter.rb +1 -2
  10. data/lib/transpec/report.rb +5 -5
  11. data/lib/transpec/rspec_version.rb +10 -7
  12. data/lib/transpec/syntax.rb +76 -49
  13. data/lib/transpec/syntax/expect.rb +2 -6
  14. data/lib/transpec/syntax/have.rb +1 -2
  15. data/lib/transpec/syntax/its.rb +1 -1
  16. data/lib/transpec/syntax/method_stub.rb +29 -3
  17. data/lib/transpec/syntax/mixin/any_instance.rb +19 -18
  18. data/lib/transpec/syntax/mixin/have_matcher_owner.rb +35 -0
  19. data/lib/transpec/syntax/mixin/send.rb +33 -33
  20. data/lib/transpec/syntax/mixin/should_base.rb +22 -8
  21. data/lib/transpec/syntax/oneliner_should.rb +2 -7
  22. data/lib/transpec/syntax/operator_matcher.rb +4 -3
  23. data/lib/transpec/syntax/should.rb +4 -9
  24. data/lib/transpec/syntax/should_receive.rb +3 -5
  25. data/lib/transpec/version.rb +1 -1
  26. data/spec/support/shared_context.rb +2 -3
  27. data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +1 -1
  28. data/spec/transpec/report_spec.rb +1 -2
  29. data/spec/transpec/rspec_version_spec.rb +7 -1
  30. data/spec/transpec/syntax/double_spec.rb +4 -4
  31. data/spec/transpec/syntax/example_spec.rb +1 -1
  32. data/spec/transpec/syntax/method_stub_spec.rb +65 -11
  33. data/spec/transpec/syntax/should_receive_spec.rb +14 -14
  34. data/spec/transpec/syntax/should_spec.rb +10 -10
  35. data/transpec.gemspec +2 -2
  36. metadata +6 -5
  37. data/lib/transpec/syntax/mixin/have_matcher.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cb53fd56a9663b6ac60c9fcb539aa9f08ce4ef48
4
- data.tar.gz: 483a8e18c082daa89c45a80a67397c5fab6dc7df
3
+ metadata.gz: c05b59c4946002626da61b3c8dc7fc4737ea3eda
4
+ data.tar.gz: e2b2eb1465049948c5e47ccb634b670fca2335b3
5
5
  SHA512:
6
- metadata.gz: 29bdf20766286e22243e0d615b2cb934d86272ad6fec7b2a67d3e53fdb6c19d19f732c95ad3ff7fd6f7bf6732b9665c99d7f9e79a490af3ee4c2ba6a2812afe2
7
- data.tar.gz: eeee1c1f55c9dfa1893be85c04a576f62286a35a60ce0359acbc91c1bf530a334cf6b47345525aa70ce2ec2730f05b20eb29f0159e3ecf700a22b0296a2dd014
6
+ metadata.gz: bb867b7c564d1e49c04677cc2fca28c7627b70fe8357122943be7584f340d0e58390f5859fc0d2250db878bae455ba0461826fd29d46367c0504ac40a5d6949a
7
+ data.tar.gz: d0930196ec951ab8bb0fce1ec44da5758ed0e6fa9c8711d315ef58a3c05680b394988032fb9d785b4ae9dac22b9c8b26bad7544f70bb7410594f770ec9d9605d
data/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## Development
4
4
 
5
+ ## v1.5.1
6
+
7
+ * Check whether a `stub` is RSpec's one or not with a static whitelist when there's no runtime data ([#33](https://github.com/yujinakayama/transpec/issues/33))
8
+ * Fix a bug where one-liner `should` was converted to `is_expected.to` on RSpec 3.0.0.beta1 (available since 2.99.0.beta2 and 3.0.0.beta2)
9
+
5
10
  ## v1.5.0
6
11
 
7
12
  * Mention the project's RSpec version in the auto-generated commit message
data/Guardfile CHANGED
@@ -1,21 +1,25 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard :rspec, all_after_pass: true, all_on_start: true, cmd: 'bundle exec rspec' do
5
- watch(%r{^spec/.+_spec\.rb$})
6
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
8
- watch(%r{^spec/support/.+\.rb$}) { "spec" }
9
- end
4
+ # This group allows to skip running RuboCop if RSpec failed,
5
+ # like Red > Green (RSpec) > Refactor (RuboCop).
6
+ group :red_green_refactor, halt_on_fail: true do
7
+ guard :rspec, all_after_pass: true, all_on_start: true, cmd: 'bundle exec rspec' do
8
+ watch(%r{^spec/.+_spec\.rb$})
9
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
10
+ watch('spec/spec_helper.rb') { "spec" }
11
+ watch(%r{^spec/support/.+\.rb$}) { "spec" }
12
+ end
10
13
 
11
- guard :rubocop do
12
- watch(%r{.+\.rb$})
13
- watch(%r{.+\.rake$})
14
- watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
15
- end
14
+ guard :rubocop do
15
+ watch(%r{.+\.rb$})
16
+ watch(%r{.+\.rake$})
17
+ watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
18
+ end
16
19
 
17
- guard :shell do
18
- watch('README.md.erb') do
19
- system('rake', 'readme') || n('Failed to build README.md', 'README Build Result', :failed)
20
+ guard :shell do
21
+ watch('README.md.erb') do
22
+ system('rake', 'readme') || n('Failed to build README.md', 'README Build Result', :failed)
23
+ end
20
24
  end
21
25
  end
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Transpec
4
4
 
5
- **Transpec** automatically converts your specs to the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
5
+ **Transpec** is a tool for converting your specs to the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
7
  This aims to facilitate smooth transition to RSpec 3, and it's now ready for RSpec 2.99 and 3.0 beta!
8
8
 
data/README.md.erb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Transpec
4
4
 
5
- **Transpec** automatically converts your specs to the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
5
+ **Transpec** is a tool for converting your specs to the latest [RSpec](http://rspec.info/) syntax with static and dynamic code analysis.
6
6
 
7
7
  This aims to facilitate smooth transition to RSpec 3, and it's now ready for RSpec 2.99 and 3.0 beta!
8
8
 
data/lib/transpec/cli.rb CHANGED
@@ -65,9 +65,9 @@ module Transpec
65
65
  converter = Converter.new(@configuration, @project.rspec_version, runtime_data, @report)
66
66
  converter.convert_file!(file_path)
67
67
 
68
- @report.invalid_context_errors.concat(converter.invalid_context_errors)
68
+ @report.context_errors.concat(converter.context_errors)
69
69
 
70
- converter.invalid_context_errors.each do |error|
70
+ converter.context_errors.each do |error|
71
71
  warn_invalid_context_error(error)
72
72
  end
73
73
  rescue Parser::SyntaxError => error
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+
3
+ module Transpec
4
+ class ContextError < StandardError
5
+ attr_reader :message, :source_range
6
+
7
+ def initialize(source_range, original_syntax, target_syntax)
8
+ @source_range = source_range
9
+ @message = build_message(original_syntax, target_syntax)
10
+ end
11
+
12
+ def source_buffer
13
+ @source_range.source_buffer
14
+ end
15
+
16
+ private
17
+
18
+ def build_message(original_syntax, target_syntax)
19
+ "Cannot convert #{original_syntax} into #{target_syntax} " +
20
+ "since #{target_syntax} is not available in the context."
21
+ end
22
+ end
23
+ end
@@ -20,7 +20,7 @@ require 'transpec/syntax/should_receive'
20
20
 
21
21
  module Transpec
22
22
  class Converter < BaseRewriter
23
- attr_reader :configuration, :rspec_version, :runtime_data, :report, :invalid_context_errors
23
+ attr_reader :configuration, :rspec_version, :runtime_data, :report, :context_errors
24
24
 
25
25
  alias_method :convert_file!, :rewrite_file!
26
26
  alias_method :convert, :rewrite
@@ -30,7 +30,7 @@ module Transpec
30
30
  @rspec_version = rspec_version || Transpec.current_rspec_version
31
31
  @runtime_data = runtime_data
32
32
  @report = report || Report.new
33
- @invalid_context_errors = []
33
+ @context_errors = []
34
34
  end
35
35
 
36
36
  def process(ast, source_rewriter)
@@ -42,7 +42,7 @@ module Transpec
42
42
 
43
43
  def dispatch_node(node, source_rewriter)
44
44
  Syntax.standalone_syntaxes.each do |syntax_class|
45
- next unless syntax_class.target_node?(node, @runtime_data)
45
+ next unless syntax_class.conversion_target_node?(node, @runtime_data)
46
46
 
47
47
  syntax = syntax_class.new(node, source_rewriter, @runtime_data, @report)
48
48
 
@@ -52,8 +52,8 @@ module Transpec
52
52
  break
53
53
  end
54
54
  rescue OverlappedRewriteError # rubocop:disable HandleExceptions
55
- rescue Syntax::InvalidContextError => error
56
- @invalid_context_errors << error
55
+ rescue ContextError => error
56
+ @context_errors << error
57
57
  end
58
58
 
59
59
  def process_should(should)
@@ -39,8 +39,7 @@ module Transpec
39
39
 
40
40
  ast.each_node do |node|
41
41
  Syntax.standalone_syntaxes.each do |syntax_class|
42
- syntax_class.register_request_for_dynamic_analysis(node, self)
43
- next unless syntax_class.target_node?(node)
42
+ next unless syntax_class.dynamic_analysis_target_node?(node)
44
43
  syntax = syntax_class.new(node)
45
44
  syntax.register_request_for_dynamic_analysis(self)
46
45
  end
@@ -4,11 +4,11 @@ require 'rainbow'
4
4
 
5
5
  module Transpec
6
6
  class Report
7
- attr_reader :records, :invalid_context_errors, :syntax_errors
7
+ attr_reader :records, :context_errors, :syntax_errors
8
8
 
9
9
  def initialize
10
10
  @records = []
11
- @invalid_context_errors = []
11
+ @context_errors = []
12
12
  @syntax_errors = []
13
13
  end
14
14
 
@@ -72,17 +72,17 @@ module Transpec
72
72
  end
73
73
 
74
74
  def convertion_and_incomplete_stats
75
- color = invalid_context_errors.empty? ? :green : :yellow
75
+ color = context_errors.empty? ? :green : :yellow
76
76
 
77
77
  text = pluralize(records.count, 'conversion') + ', '
78
- text << pluralize(invalid_context_errors.count, 'incomplete') + ', '
78
+ text << pluralize(context_errors.count, 'incomplete') + ', '
79
79
  text.color(color)
80
80
  end
81
81
 
82
82
  def error_stats
83
83
  color = if !syntax_errors.empty?
84
84
  :red
85
- elsif invalid_context_errors.empty?
85
+ elsif context_errors.empty?
86
86
  :green
87
87
  else
88
88
  :yellow
@@ -10,15 +10,18 @@ module Transpec
10
10
 
11
11
  attr_reader :gem_version
12
12
 
13
- def self.define_feature_availability(feature, version_string)
13
+ def self.define_feature(feature, version_string, options = {})
14
14
  available_version = new(version_string)
15
15
 
16
+ exception_version_strings = Array(options[:except])
17
+ exception_versions = exception_version_strings.map { |s| new(s) }
18
+
16
19
  define_singleton_method("#{feature}_available_version") do
17
20
  available_version
18
21
  end
19
22
 
20
23
  define_method("#{feature}_available?") do
21
- self >= available_version
24
+ self >= available_version && !exception_versions.include?(self)
22
25
  end
23
26
  end
24
27
 
@@ -38,10 +41,10 @@ module Transpec
38
41
  @gem_version.to_s
39
42
  end
40
43
 
41
- define_feature_availability :be_truthy, '2.99.0.beta1'
42
- define_feature_availability :yielded_example, '2.99.0.beta1'
43
- define_feature_availability :one_liner_is_expected, '2.99.0.beta2'
44
- define_feature_availability :receive_messages, '3.0.0.beta1'
45
- define_feature_availability :receive_message_chain, '3.0.0.beta2'
44
+ define_feature :be_truthy, '2.99.0.beta1'
45
+ define_feature :yielded_example, '2.99.0.beta1'
46
+ define_feature :one_liner_is_expected, '2.99.0.beta2', except: '3.0.0.beta1'
47
+ define_feature :receive_messages, '3.0.0.beta1'
48
+ define_feature :receive_message_chain, '3.0.0.beta2'
46
49
  end
47
50
  end
@@ -1,24 +1,87 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/context_error'
3
4
  require 'transpec/static_context_inspector'
4
5
  require 'transpec/record'
5
6
  require 'transpec/report'
7
+ require 'active_support/concern'
6
8
 
7
9
  module Transpec
8
10
  class Syntax
9
- attr_reader :node, :source_rewriter, :runtime_data, :report
11
+ module Collection
12
+ def inherited(subclass)
13
+ all_syntaxes << subclass
14
+ end
15
+
16
+ def all_syntaxes
17
+ @subclasses ||= []
18
+ end
10
19
 
11
- def self.inherited(subclass)
12
- all_syntaxes << subclass
20
+ def standalone_syntaxes
21
+ @standalone_syntaxes ||= all_syntaxes.select(&:standalone?)
22
+ end
13
23
  end
24
+ end
25
+ end
26
+
27
+ module Transpec
28
+ class Syntax
29
+ module Rewritable
30
+ private
31
+
32
+ def remove(range)
33
+ @source_rewriter.remove(range)
34
+ end
35
+
36
+ def insert_before(range, content)
37
+ @source_rewriter.insert_before(range, content)
38
+ end
14
39
 
15
- def self.all_syntaxes
16
- @subclasses ||= []
40
+ def insert_after(range, content)
41
+ @source_rewriter.insert_after(range, content)
42
+ end
43
+
44
+ def replace(range, content)
45
+ @source_rewriter.replace(range, content)
46
+ end
17
47
  end
48
+ end
49
+ end
50
+
51
+ module Transpec
52
+ class Syntax
53
+ module DynamicAnalysis
54
+ extend ActiveSupport::Concern
18
55
 
19
- def self.standalone_syntaxes
20
- @standalone_syntaxes ||= all_syntaxes.select(&:standalone?)
56
+ module ClassMethods
57
+ def add_dynamic_analysis_request(&block)
58
+ dynamic_analysis_requests << block
59
+ end
60
+
61
+ def dynamic_analysis_requests
62
+ @dynamic_analysis_requests ||= []
63
+ end
64
+
65
+ def dynamic_analysis_target_node?(node)
66
+ target_node?(node)
67
+ end
68
+ end
69
+
70
+ def register_request_for_dynamic_analysis(rewriter)
71
+ self.class.dynamic_analysis_requests.each do |request|
72
+ instance_exec(rewriter, &request)
73
+ end
74
+ end
21
75
  end
76
+ end
77
+ end
78
+
79
+ module Transpec
80
+ class Syntax
81
+ extend Collection
82
+ include Rewritable, DynamicAnalysis
83
+
84
+ attr_reader :node, :source_rewriter, :runtime_data, :report
22
85
 
23
86
  def self.standalone?
24
87
  true
@@ -31,13 +94,16 @@ module Transpec
31
94
  end
32
95
  end
33
96
 
34
- def self.register_request_for_dynamic_analysis(node, rewriter)
35
- end
36
-
97
+ # The default common method for .conversion_target_node? and .dynamic_analysis_target_node?.
98
+ # If they should behave differently, override either or both.
37
99
  def self.target_node?(node, runtime_data = nil)
38
100
  false
39
101
  end
40
102
 
103
+ def self.conversion_target_node?(node, runtime_data = nil)
104
+ target_node?(node, runtime_data)
105
+ end
106
+
41
107
  def initialize(node, source_rewriter = nil, runtime_data = nil, report = nil)
42
108
  @node = node
43
109
  @source_rewriter = source_rewriter
@@ -45,9 +111,6 @@ module Transpec
45
111
  @report = report || Report.new
46
112
  end
47
113
 
48
- def register_request_for_dynamic_analysis(rewriter)
49
- end
50
-
51
114
  def static_context_inspector
52
115
  @static_context_inspector ||= StaticContextInspector.new(@node)
53
116
  end
@@ -65,41 +128,5 @@ module Transpec
65
128
  def runtime_node_data(node)
66
129
  @runtime_data && @runtime_data[node]
67
130
  end
68
-
69
- def remove(range)
70
- @source_rewriter.remove(range)
71
- end
72
-
73
- def insert_before(range, content)
74
- @source_rewriter.insert_before(range, content)
75
- end
76
-
77
- def insert_after(range, content)
78
- @source_rewriter.insert_after(range, content)
79
- end
80
-
81
- def replace(range, content)
82
- @source_rewriter.replace(range, content)
83
- end
84
-
85
- class InvalidContextError < StandardError
86
- attr_reader :message, :source_range
87
-
88
- def initialize(source_range, original_syntax, target_syntax)
89
- @source_range = source_range
90
- @message = build_message(original_syntax, target_syntax)
91
- end
92
-
93
- def source_buffer
94
- @source_range.source_buffer
95
- end
96
-
97
- private
98
-
99
- def build_message(original_syntax, target_syntax)
100
- "Cannot convert #{original_syntax} into #{target_syntax} " +
101
- "since #{target_syntax} is not available in the context."
102
- end
103
- end
104
131
  end
105
132
  end
@@ -2,21 +2,17 @@
2
2
 
3
3
  require 'transpec/syntax'
4
4
  require 'transpec/syntax/mixin/send'
5
- require 'transpec/syntax/mixin/have_matcher'
5
+ require 'transpec/syntax/mixin/have_matcher_owner'
6
6
 
7
7
  module Transpec
8
8
  class Syntax
9
9
  class Expect < Syntax
10
- include Mixin::Send, Mixin::HaveMatcher
10
+ include Mixin::Send, Mixin::HaveMatcherOwner
11
11
 
12
12
  def self.target_method?(receiver_node, method_name)
13
13
  receiver_node.nil? && method_name == :expect
14
14
  end
15
15
 
16
- def register_request_for_dynamic_analysis(rewriter)
17
- have_matcher.register_request_for_dynamic_analysis(rewriter) if have_matcher
18
- end
19
-
20
16
  def current_syntax_type
21
17
  :expect
22
18
  end
@@ -38,7 +38,7 @@ module Transpec
38
38
  @report = report || Report.new
39
39
  end
40
40
 
41
- def register_request_for_dynamic_analysis(rewriter)
41
+ add_dynamic_analysis_request do |rewriter|
42
42
  DynamicInspector.register_request(self, rewriter)
43
43
  end
44
44
 
@@ -128,7 +128,6 @@ module Transpec
128
128
  end
129
129
 
130
130
  def replacement_matcher_source(parenthesize_arg)
131
- size_source = size_node.loc.expression.source
132
131
  build_replacement_matcher_source(size_source, parenthesize_arg)
133
132
  end
134
133