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.
- 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
|
|