transpec 1.5.0 → 1.5.1

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