transpec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +6 -0
- data/Gemfile +9 -0
- data/Guardfile +14 -0
- data/LICENSE.txt +22 -0
- data/README.md +37 -0
- data/Rakefile +27 -0
- data/bin/transpec +8 -0
- data/lib/transpec/ast/scanner.rb +51 -0
- data/lib/transpec/ast/scope_stack.rb +76 -0
- data/lib/transpec/cli.rb +162 -0
- data/lib/transpec/configuration.rb +40 -0
- data/lib/transpec/git.rb +24 -0
- data/lib/transpec/rewriter.rb +109 -0
- data/lib/transpec/syntax/double.rb +21 -0
- data/lib/transpec/syntax/matcher.rb +60 -0
- data/lib/transpec/syntax/method_stub.rb +142 -0
- data/lib/transpec/syntax/send_node_syntax.rb +39 -0
- data/lib/transpec/syntax/should.rb +49 -0
- data/lib/transpec/syntax/should_receive.rb +120 -0
- data/lib/transpec/syntax.rb +58 -0
- data/lib/transpec/util.rb +50 -0
- data/lib/transpec/version.rb +14 -0
- data/lib/transpec.rb +17 -0
- data/spec/.rubocop.yml +19 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/spec_spec.rb +54 -0
- data/spec/support/file_helper.rb +25 -0
- data/spec/support/shared_context.rb +63 -0
- data/spec/transpec/ast/scanner_spec.rb +177 -0
- data/spec/transpec/ast/scope_stack_spec.rb +94 -0
- data/spec/transpec/cli_spec.rb +290 -0
- data/spec/transpec/configuration_spec.rb +52 -0
- data/spec/transpec/git_spec.rb +85 -0
- data/spec/transpec/rewriter_spec.rb +203 -0
- data/spec/transpec/syntax/double_spec.rb +88 -0
- data/spec/transpec/syntax/matcher_spec.rb +407 -0
- data/spec/transpec/syntax/method_stub_spec.rb +386 -0
- data/spec/transpec/syntax/should_receive_spec.rb +286 -0
- data/spec/transpec/syntax/should_spec.rb +262 -0
- data/spec/transpec/util_spec.rb +48 -0
- data/transpec.gemspec +32 -0
- metadata +233 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Syntax
|
5
|
+
class Matcher < Syntax
|
6
|
+
include SendNodeSyntax, Util
|
7
|
+
|
8
|
+
def initialize(node, in_example_group_context, source_rewriter)
|
9
|
+
@node = node
|
10
|
+
@in_example_group_context = in_example_group_context
|
11
|
+
@source_rewriter = source_rewriter
|
12
|
+
end
|
13
|
+
|
14
|
+
def correct_operator!(parenthesize_arg = true)
|
15
|
+
case method_name
|
16
|
+
when :==
|
17
|
+
@source_rewriter.replace(selector_range, 'eq')
|
18
|
+
parenthesize!(parenthesize_arg)
|
19
|
+
when :===, :<, :<=, :>, :>=
|
20
|
+
@source_rewriter.insert_before(selector_range, 'be ')
|
21
|
+
when :=~
|
22
|
+
if arg_node.type == :array
|
23
|
+
@source_rewriter.replace(selector_range, 'match_array')
|
24
|
+
else
|
25
|
+
@source_rewriter.replace(selector_range, 'match')
|
26
|
+
end
|
27
|
+
parenthesize!(parenthesize_arg)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def parenthesize!(always = true)
|
32
|
+
return if here_document?(arg_node)
|
33
|
+
|
34
|
+
case left_parenthesis_range.source
|
35
|
+
when ' '
|
36
|
+
if always || arg_node.type == :hash
|
37
|
+
@source_rewriter.replace(left_parenthesis_range, '(')
|
38
|
+
@source_rewriter.insert_after(expression_range, ')')
|
39
|
+
end
|
40
|
+
when "\n", "\r"
|
41
|
+
@source_rewriter.insert_before(left_parenthesis_range, '(')
|
42
|
+
linefeed = left_parenthesis_range.source
|
43
|
+
matcher_line_indentation = indentation_of_line(@node)
|
44
|
+
right_parenthesis = "#{linefeed}#{matcher_line_indentation})"
|
45
|
+
@source_rewriter.insert_after(expression_range, right_parenthesis)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def left_parenthesis_range
|
52
|
+
Parser::Source::Range.new(
|
53
|
+
selector_range.source_buffer,
|
54
|
+
selector_range.end_pos,
|
55
|
+
selector_range.end_pos + 1
|
56
|
+
)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'English'
|
4
|
+
|
5
|
+
module Transpec
|
6
|
+
class Syntax
|
7
|
+
class MethodStub < Syntax
|
8
|
+
include SendNodeSyntax, Util
|
9
|
+
|
10
|
+
def self.target_node?(node)
|
11
|
+
return false unless node.type == :send
|
12
|
+
receiver_node, method_name, *_ = *node
|
13
|
+
return false unless receiver_node
|
14
|
+
[:stub, :unstub, :stub!, :unstub!].include?(method_name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def allowize!
|
18
|
+
# There's no way of unstubbing in #allow syntax.
|
19
|
+
return unless [:stub, :stub!].include?(method_name)
|
20
|
+
|
21
|
+
if @replaced_deprecated_method
|
22
|
+
fail 'Already replaced deprecated method, cannot allowize.'
|
23
|
+
end
|
24
|
+
|
25
|
+
unless in_example_group_context?
|
26
|
+
fail NotInExampleGroupContextError.new(expression_range, "##{method_name}", '#allow')
|
27
|
+
end
|
28
|
+
|
29
|
+
if arg_node.type == :hash
|
30
|
+
expressions = build_allow_expressions_from_hash_node(arg_node)
|
31
|
+
@source_rewriter.replace(expression_range, expressions)
|
32
|
+
else
|
33
|
+
expression = build_allow_expression(arg_node)
|
34
|
+
@source_rewriter.replace(expression_range, expression)
|
35
|
+
end
|
36
|
+
|
37
|
+
@allowized = true
|
38
|
+
end
|
39
|
+
|
40
|
+
def replace_deprecated_method!
|
41
|
+
replacement_method_name = case method_name
|
42
|
+
when :stub! then 'stub'
|
43
|
+
when :unstub! then 'unstub'
|
44
|
+
end
|
45
|
+
|
46
|
+
return unless replacement_method_name
|
47
|
+
|
48
|
+
if @allowized
|
49
|
+
fail 'Already allowized, cannot replace deprecated method.'
|
50
|
+
end
|
51
|
+
|
52
|
+
@source_rewriter.replace(selector_range, replacement_method_name)
|
53
|
+
|
54
|
+
@replaced_deprecated_method = true
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def build_allow_expressions_from_hash_node(hash_node)
|
60
|
+
expressions = []
|
61
|
+
|
62
|
+
hash_node.children.each_with_index do |pair_node, index|
|
63
|
+
key_node, value_node = *pair_node
|
64
|
+
expression = build_allow_expression(key_node, value_node, false)
|
65
|
+
expression.prepend(indentation_of_line(@node)) if index > 0
|
66
|
+
expressions << expression
|
67
|
+
end
|
68
|
+
|
69
|
+
expressions.join($RS)
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_allow_expression(message_node, return_value_node = nil, keep_form_around_arg = true)
|
73
|
+
expression = ''
|
74
|
+
|
75
|
+
expression << if any_instance?
|
76
|
+
class_source = class_node_of_any_instance.loc.expression.source
|
77
|
+
"allow_any_instance_of(#{class_source})"
|
78
|
+
else
|
79
|
+
"allow(#{subject_range.source})"
|
80
|
+
end
|
81
|
+
|
82
|
+
expression << range_in_between_subject_and_selector.source
|
83
|
+
expression << 'to receive'
|
84
|
+
expression << (keep_form_around_arg ? range_in_between_selector_and_arg.source : '(')
|
85
|
+
expression << message_source(message_node)
|
86
|
+
expression << (keep_form_around_arg ? range_after_arg.source : ')')
|
87
|
+
|
88
|
+
if return_value_node
|
89
|
+
return_value_source = return_value_node.loc.expression.source
|
90
|
+
expression << ".and_return(#{return_value_source})"
|
91
|
+
end
|
92
|
+
|
93
|
+
expression
|
94
|
+
end
|
95
|
+
|
96
|
+
def class_node_of_any_instance
|
97
|
+
return nil unless subject_node.type == :send
|
98
|
+
return nil unless subject_node.children.count == 2
|
99
|
+
receiver_node, method_name = *subject_node
|
100
|
+
return nil unless method_name == :any_instance
|
101
|
+
return nil unless receiver_node.type == :const
|
102
|
+
receiver_node
|
103
|
+
end
|
104
|
+
|
105
|
+
def any_instance?
|
106
|
+
!class_node_of_any_instance.nil?
|
107
|
+
end
|
108
|
+
|
109
|
+
def message_source(node)
|
110
|
+
message_source = node.loc.expression.source
|
111
|
+
if node.type == :sym && !message_source.start_with?(':')
|
112
|
+
message_source.prepend(':')
|
113
|
+
end
|
114
|
+
message_source
|
115
|
+
end
|
116
|
+
|
117
|
+
def range_in_between_subject_and_selector
|
118
|
+
Parser::Source::Range.new(
|
119
|
+
subject_range.source_buffer,
|
120
|
+
subject_range.end_pos,
|
121
|
+
selector_range.begin_pos
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
def range_in_between_selector_and_arg
|
126
|
+
Parser::Source::Range.new(
|
127
|
+
selector_range.source_buffer,
|
128
|
+
selector_range.end_pos,
|
129
|
+
arg_range.begin_pos
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
def range_after_arg
|
134
|
+
Parser::Source::Range.new(
|
135
|
+
arg_range.source_buffer,
|
136
|
+
arg_range.end_pos,
|
137
|
+
expression_range.end_pos
|
138
|
+
)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Syntax
|
5
|
+
module SendNodeSyntax
|
6
|
+
def receiver_node
|
7
|
+
@node.children[0]
|
8
|
+
end
|
9
|
+
|
10
|
+
alias_method :subject_node, :receiver_node
|
11
|
+
|
12
|
+
def method_name
|
13
|
+
@node.children[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def arg_node
|
17
|
+
@node.children[2]
|
18
|
+
end
|
19
|
+
|
20
|
+
def expression_range
|
21
|
+
@node.loc.expression
|
22
|
+
end
|
23
|
+
|
24
|
+
def selector_range
|
25
|
+
@node.loc.selector
|
26
|
+
end
|
27
|
+
|
28
|
+
def receiver_range
|
29
|
+
receiver_node.loc.expression
|
30
|
+
end
|
31
|
+
|
32
|
+
alias_method :subject_range, :receiver_range
|
33
|
+
|
34
|
+
def arg_range
|
35
|
+
arg_node.loc.expression
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Syntax
|
5
|
+
class Should < Syntax
|
6
|
+
include SendNodeSyntax, Util
|
7
|
+
|
8
|
+
def self.target_node?(node)
|
9
|
+
return false unless node.type == :send
|
10
|
+
receiver_node, method_name, *_ = *node
|
11
|
+
return false unless receiver_node
|
12
|
+
[:should, :should_not].include?(method_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def positive?
|
16
|
+
method_name == :should
|
17
|
+
end
|
18
|
+
|
19
|
+
def expectize!(negative_form = 'not_to', parenthesize_matcher_arg = true)
|
20
|
+
unless in_example_group_context?
|
21
|
+
fail NotInExampleGroupContextError.new(expression_range, "##{method_name}", '#expect')
|
22
|
+
end
|
23
|
+
|
24
|
+
if proc_literal?(subject_node)
|
25
|
+
send_node = subject_node.children.first
|
26
|
+
range_of_subject_method_taking_block = send_node.loc.expression
|
27
|
+
@source_rewriter.replace(range_of_subject_method_taking_block, 'expect')
|
28
|
+
elsif subject_range.source[0] == '('
|
29
|
+
@source_rewriter.insert_before(subject_range, 'expect')
|
30
|
+
else
|
31
|
+
@source_rewriter.insert_before(subject_range, 'expect(')
|
32
|
+
@source_rewriter.insert_after(subject_range, ')')
|
33
|
+
end
|
34
|
+
|
35
|
+
@source_rewriter.replace(selector_range, positive? ? 'to' : negative_form)
|
36
|
+
|
37
|
+
matcher.correct_operator!(parenthesize_matcher_arg)
|
38
|
+
end
|
39
|
+
|
40
|
+
def matcher
|
41
|
+
@matcher ||= Matcher.new(matcher_node, in_example_group_context?, @source_rewriter)
|
42
|
+
end
|
43
|
+
|
44
|
+
def matcher_node
|
45
|
+
arg_node || parent_node
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Syntax
|
5
|
+
class ShouldReceive < Syntax
|
6
|
+
include SendNodeSyntax
|
7
|
+
|
8
|
+
def self.target_node?(node)
|
9
|
+
return false unless node.type == :send
|
10
|
+
receiver_node, method_name, *_ = *node
|
11
|
+
return false unless receiver_node
|
12
|
+
[:should_receive, :should_not_receive].include?(method_name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def positive?
|
16
|
+
method_name == :should_receive
|
17
|
+
end
|
18
|
+
|
19
|
+
def expectize!(negative_form = 'not_to')
|
20
|
+
unless in_example_group_context?
|
21
|
+
fail NotInExampleGroupContextError.new(expression_range, "##{method_name}", '#expect')
|
22
|
+
end
|
23
|
+
|
24
|
+
if any_instance?(subject_node)
|
25
|
+
@source_rewriter.insert_before(subject_range, 'expect_any_instance_of(')
|
26
|
+
map = subject_node.loc
|
27
|
+
dot_any_instance_range = map.dot.join(map.selector)
|
28
|
+
@source_rewriter.replace(dot_any_instance_range, ')')
|
29
|
+
else
|
30
|
+
@source_rewriter.insert_before(subject_range, 'expect(')
|
31
|
+
@source_rewriter.insert_after(subject_range, ')')
|
32
|
+
end
|
33
|
+
|
34
|
+
to_receive = "#{positive? ? 'to' : negative_form} receive"
|
35
|
+
@source_rewriter.replace(selector_range, to_receive)
|
36
|
+
|
37
|
+
correct_block_style!
|
38
|
+
end
|
39
|
+
|
40
|
+
def correct_block_style!
|
41
|
+
broken_block_nodes = [
|
42
|
+
block_node_taken_by_with_method_with_no_normal_args,
|
43
|
+
block_node_followed_by_message_expectation_method
|
44
|
+
].compact.uniq
|
45
|
+
|
46
|
+
return if broken_block_nodes.empty?
|
47
|
+
|
48
|
+
broken_block_nodes.each do |block_node|
|
49
|
+
map = block_node.loc
|
50
|
+
next if map.begin.source == '{'
|
51
|
+
@source_rewriter.replace(map.begin, '{')
|
52
|
+
@source_rewriter.replace(map.end, '}')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def any_instance?(node)
|
59
|
+
return false unless node.type == :send
|
60
|
+
return false unless node.children.count == 2
|
61
|
+
receiver_node, method_name = *node
|
62
|
+
return false unless method_name == :any_instance
|
63
|
+
receiver_node.type == :const
|
64
|
+
end
|
65
|
+
|
66
|
+
# subject.should_receive(:method_name).once.with do |block_arg|
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# (block
|
70
|
+
# (send
|
71
|
+
# (send
|
72
|
+
# (send
|
73
|
+
# (send nil :subject) :should_receive
|
74
|
+
# (sym :method_name)) :once) :with)
|
75
|
+
# (args
|
76
|
+
# (arg :block_arg)) nil)
|
77
|
+
def block_node_taken_by_with_method_with_no_normal_args
|
78
|
+
@ancestor_nodes.reverse.reduce(@node) do |child_node, parent_node|
|
79
|
+
return nil unless [:send, :block].include?(parent_node.type)
|
80
|
+
return nil unless parent_node.children.first == child_node
|
81
|
+
|
82
|
+
if parent_node.type == :block
|
83
|
+
return nil unless child_node.children[1] == :with
|
84
|
+
return nil if child_node.children[2]
|
85
|
+
return parent_node
|
86
|
+
end
|
87
|
+
|
88
|
+
parent_node
|
89
|
+
end
|
90
|
+
|
91
|
+
nil
|
92
|
+
end
|
93
|
+
|
94
|
+
# subject.should_receive(:method_name) do |block_arg|
|
95
|
+
# end.once
|
96
|
+
#
|
97
|
+
# (send
|
98
|
+
# (block
|
99
|
+
# (send
|
100
|
+
# (send nil :subject) :should_receive
|
101
|
+
# (sym :method_name))
|
102
|
+
# (args
|
103
|
+
# (arg :block_arg)) nil) :once)
|
104
|
+
def block_node_followed_by_message_expectation_method
|
105
|
+
@ancestor_nodes.reverse.reduce(@node) do |child_node, parent_node|
|
106
|
+
return nil unless [:send, :block].include?(parent_node.type)
|
107
|
+
return nil unless parent_node.children.first == child_node
|
108
|
+
|
109
|
+
if child_node.type == :block && parent_node.type == :send
|
110
|
+
return child_node
|
111
|
+
end
|
112
|
+
|
113
|
+
parent_node
|
114
|
+
end
|
115
|
+
|
116
|
+
nil
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
class Syntax
|
5
|
+
class NotInExampleGroupContextError < StandardError
|
6
|
+
attr_reader :message, :source_range
|
7
|
+
|
8
|
+
def initialize(source_range, original_syntax, target_syntax)
|
9
|
+
@source_range = source_range
|
10
|
+
@message = build_message(original_syntax, target_syntax)
|
11
|
+
end
|
12
|
+
|
13
|
+
def source_buffer
|
14
|
+
@source_range.source_buffer
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def build_message(original_syntax, target_syntax)
|
20
|
+
"Cannot convert #{original_syntax} into #{target_syntax} " +
|
21
|
+
"since #{target_syntax} is not available in the context."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
attr_reader :node, :ancestor_nodes, :in_example_group_context, :source_rewriter
|
26
|
+
alias_method :in_example_group_context?, :in_example_group_context
|
27
|
+
|
28
|
+
def self.all
|
29
|
+
@subclasses ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.inherited(subclass)
|
33
|
+
all << subclass
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.snake_case_name
|
37
|
+
@snake_cake_name ||= begin
|
38
|
+
class_name = name.split('::').last
|
39
|
+
class_name.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.target_node?(node)
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(node, ancestor_nodes, in_example_group_context, source_rewriter)
|
48
|
+
@node = node
|
49
|
+
@ancestor_nodes = ancestor_nodes
|
50
|
+
@in_example_group_context = in_example_group_context
|
51
|
+
@source_rewriter = source_rewriter
|
52
|
+
end
|
53
|
+
|
54
|
+
def parent_node
|
55
|
+
@ancestor_nodes.last
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Transpec
|
4
|
+
module Util
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def proc_literal?(node)
|
8
|
+
return false unless node.type == :block
|
9
|
+
|
10
|
+
send_node = node.children.first
|
11
|
+
receiver_node, method_name, *_ = *send_node
|
12
|
+
|
13
|
+
if receiver_node.nil? || const_name(receiver_node) == 'Kernel'
|
14
|
+
[:lambda, :proc].include?(method_name)
|
15
|
+
elsif const_name(receiver_node) == 'Proc'
|
16
|
+
method_name == :new
|
17
|
+
else
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def const_name(node)
|
23
|
+
return nil if node.nil? || node.type != :const
|
24
|
+
|
25
|
+
const_names = []
|
26
|
+
const_node = node
|
27
|
+
|
28
|
+
loop do
|
29
|
+
namespace_node, name = *const_node
|
30
|
+
const_names << name
|
31
|
+
break unless namespace_node
|
32
|
+
break if namespace_node.type == :cbase
|
33
|
+
const_node = namespace_node
|
34
|
+
end
|
35
|
+
|
36
|
+
const_names.reverse.join('::')
|
37
|
+
end
|
38
|
+
|
39
|
+
def here_document?(node)
|
40
|
+
return false unless [:str, :dstr].include?(node.type)
|
41
|
+
node.loc.begin.source.start_with?('<<')
|
42
|
+
end
|
43
|
+
|
44
|
+
def indentation_of_line(node)
|
45
|
+
line = node.loc.expression.source_line
|
46
|
+
/^(?<indentation>\s*)\S/ =~ line
|
47
|
+
indentation
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/transpec.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'transpec/configuration'
|
4
|
+
require 'transpec/cli'
|
5
|
+
require 'transpec/git'
|
6
|
+
require 'transpec/rewriter'
|
7
|
+
require 'transpec/util'
|
8
|
+
require 'transpec/version'
|
9
|
+
require 'transpec/ast/scanner'
|
10
|
+
require 'transpec/ast/scope_stack'
|
11
|
+
require 'transpec/syntax'
|
12
|
+
require 'transpec/syntax/send_node_syntax'
|
13
|
+
require 'transpec/syntax/double'
|
14
|
+
require 'transpec/syntax/matcher'
|
15
|
+
require 'transpec/syntax/method_stub'
|
16
|
+
require 'transpec/syntax/should'
|
17
|
+
require 'transpec/syntax/should_receive'
|
data/spec/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
inherit_from: ../.rubocop.yml
|
3
|
+
|
4
|
+
# Avoid warning "Possibly useless use of == in void context"
|
5
|
+
# for `should ==`
|
6
|
+
Void:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
# Lengthen for long descriptions.
|
10
|
+
LineLength:
|
11
|
+
Max: 110
|
12
|
+
|
13
|
+
# raise_error matcher always requires {} form block.
|
14
|
+
Blocks:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
# Sometimes block alignment does not suit RSpec syntax.
|
18
|
+
BlockAlignment:
|
19
|
+
Enabled: false
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
RSpec.configure do |config|
|
4
|
+
config.expect_with :rspec do |c|
|
5
|
+
# Yes, I'm writing specs in should syntax intentionally!
|
6
|
+
c.syntax = :should
|
7
|
+
end
|
8
|
+
|
9
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
config.filter_run_excluding do_not_run_in_transpeced_spec: ENV['TRANSPECED_SPEC']
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir[File.join(File.dirname(__FILE__), 'support', '*')].each do |path|
|
14
|
+
require path
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'simplecov'
|
18
|
+
SimpleCov.coverage_dir(File.join('spec', 'coverage'))
|
19
|
+
|
20
|
+
if ENV['TRAVIS']
|
21
|
+
require 'coveralls'
|
22
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
23
|
+
elsif ENV['CI']
|
24
|
+
require 'simplecov-rcov'
|
25
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
26
|
+
end
|
27
|
+
|
28
|
+
SimpleCov.start do
|
29
|
+
add_filter '/spec/'
|
30
|
+
add_filter '/vendor/bundle/'
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'transpec'
|
data/spec/spec_spec.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'tmpdir'
|
5
|
+
require 'English'
|
6
|
+
|
7
|
+
describe 'Transpec project spec', :do_not_run_in_transpeced_spec do
|
8
|
+
around do |example|
|
9
|
+
Dir.chdir(project_root) do
|
10
|
+
example.run
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:project_root) do
|
15
|
+
File.expand_path('..', File.dirname(__FILE__))
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:spec_dir) do
|
19
|
+
File.join(project_root, 'spec')
|
20
|
+
end
|
21
|
+
|
22
|
+
TRANSPECED_SPEC_DIR = File.join(Dir.mktmpdir, 'transpeced_spec')
|
23
|
+
|
24
|
+
def silent_system(*args)
|
25
|
+
original_env = ENV.to_hash
|
26
|
+
|
27
|
+
if args.first.is_a?(Hash)
|
28
|
+
custom_env = args.shift
|
29
|
+
ENV.update(custom_env)
|
30
|
+
end
|
31
|
+
|
32
|
+
command = args.shelljoin
|
33
|
+
`#{command}`
|
34
|
+
|
35
|
+
ENV.replace(original_env)
|
36
|
+
$CHILD_STATUS.success?
|
37
|
+
rescue
|
38
|
+
ENV.replace(original_env)
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can be converted by Transpec itself without error' do
|
43
|
+
FileUtils.cp_r(spec_dir, TRANSPECED_SPEC_DIR)
|
44
|
+
silent_system('./bin/transpec', '--force', TRANSPECED_SPEC_DIR).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'converted spec' do
|
48
|
+
it 'passes all' do
|
49
|
+
pending 'Need to rewrite syntax configuration in RSpec.configure'
|
50
|
+
env = { 'TRANSPECED_SPEC' => 'true' }
|
51
|
+
silent_system(env, 'rspec', TRANSPECED_SPEC_DIR).should be_true
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module FileHelper
|
6
|
+
module_function
|
7
|
+
|
8
|
+
def create_file(file_path, content)
|
9
|
+
file_path = File.expand_path(file_path)
|
10
|
+
|
11
|
+
dir_path = File.dirname(file_path)
|
12
|
+
FileUtils.makedirs(dir_path) unless File.exists?(dir_path)
|
13
|
+
|
14
|
+
File.open(file_path, 'w') do |file|
|
15
|
+
case content
|
16
|
+
when String
|
17
|
+
file.puts content
|
18
|
+
when Array
|
19
|
+
file.puts content.join("\n")
|
20
|
+
else
|
21
|
+
fail 'Unsupported type!'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|