transpec 0.0.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 +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
|