transpec 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Guardfile +18 -14
- data/README.md +1 -1
- data/README.md.erb +1 -1
- data/lib/transpec/cli.rb +2 -2
- data/lib/transpec/context_error.rb +23 -0
- data/lib/transpec/converter.rb +5 -5
- data/lib/transpec/dynamic_analyzer/rewriter.rb +1 -2
- data/lib/transpec/report.rb +5 -5
- data/lib/transpec/rspec_version.rb +10 -7
- data/lib/transpec/syntax.rb +76 -49
- data/lib/transpec/syntax/expect.rb +2 -6
- data/lib/transpec/syntax/have.rb +1 -2
- data/lib/transpec/syntax/its.rb +1 -1
- data/lib/transpec/syntax/method_stub.rb +29 -3
- data/lib/transpec/syntax/mixin/any_instance.rb +19 -18
- data/lib/transpec/syntax/mixin/have_matcher_owner.rb +35 -0
- data/lib/transpec/syntax/mixin/send.rb +33 -33
- data/lib/transpec/syntax/mixin/should_base.rb +22 -8
- data/lib/transpec/syntax/oneliner_should.rb +2 -7
- data/lib/transpec/syntax/operator_matcher.rb +4 -3
- data/lib/transpec/syntax/should.rb +4 -9
- data/lib/transpec/syntax/should_receive.rb +3 -5
- data/lib/transpec/version.rb +1 -1
- data/spec/support/shared_context.rb +2 -3
- data/spec/transpec/dynamic_analyzer/rewriter_spec.rb +1 -1
- data/spec/transpec/report_spec.rb +1 -2
- data/spec/transpec/rspec_version_spec.rb +7 -1
- data/spec/transpec/syntax/double_spec.rb +4 -4
- data/spec/transpec/syntax/example_spec.rb +1 -1
- data/spec/transpec/syntax/method_stub_spec.rb +65 -11
- data/spec/transpec/syntax/should_receive_spec.rb +14 -14
- data/spec/transpec/syntax/should_spec.rb +10 -10
- data/transpec.gemspec +2 -2
- metadata +6 -5
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c05b59c4946002626da61b3c8dc7fc4737ea3eda
|
4
|
+
data.tar.gz: e2b2eb1465049948c5e47ccb634b670fca2335b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
19
|
-
|
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**
|
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**
|
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.
|
68
|
+
@report.context_errors.concat(converter.context_errors)
|
69
69
|
|
70
|
-
converter.
|
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
|
data/lib/transpec/converter.rb
CHANGED
@@ -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, :
|
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
|
-
@
|
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.
|
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
|
56
|
-
@
|
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.
|
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
|
data/lib/transpec/report.rb
CHANGED
@@ -4,11 +4,11 @@ require 'rainbow'
|
|
4
4
|
|
5
5
|
module Transpec
|
6
6
|
class Report
|
7
|
-
attr_reader :records, :
|
7
|
+
attr_reader :records, :context_errors, :syntax_errors
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@records = []
|
11
|
-
@
|
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 =
|
75
|
+
color = context_errors.empty? ? :green : :yellow
|
76
76
|
|
77
77
|
text = pluralize(records.count, 'conversion') + ', '
|
78
|
-
text << pluralize(
|
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
|
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.
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
data/lib/transpec/syntax.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
12
|
-
|
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
|
-
|
16
|
-
|
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
|
-
|
20
|
-
|
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
|
-
|
35
|
-
|
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/
|
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::
|
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
|
data/lib/transpec/syntax/have.rb
CHANGED
@@ -38,7 +38,7 @@ module Transpec
|
|
38
38
|
@report = report || Report.new
|
39
39
|
end
|
40
40
|
|
41
|
-
|
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
|
|