transpec 0.0.1 → 0.0.2

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Guardfile +4 -0
  5. data/README.md +102 -5
  6. data/README.md.erb +107 -0
  7. data/Rakefile +26 -5
  8. data/bin/transpec +1 -1
  9. data/lib/transpec/ast/scanner.rb +3 -0
  10. data/lib/transpec/ast/scope_stack.rb +2 -0
  11. data/lib/transpec/cli.rb +4 -0
  12. data/lib/transpec/rewriter.rb +14 -2
  13. data/lib/transpec/syntax.rb +36 -1
  14. data/lib/transpec/syntax/any_instanceable.rb +24 -0
  15. data/lib/transpec/syntax/be_close.rb +32 -0
  16. data/lib/transpec/syntax/double.rb +14 -8
  17. data/lib/transpec/syntax/expectizable.rb +20 -0
  18. data/lib/transpec/syntax/matcher.rb +16 -8
  19. data/lib/transpec/syntax/method_stub.rb +26 -40
  20. data/lib/transpec/syntax/send_node_syntax.rb +2 -4
  21. data/lib/transpec/syntax/should.rb +25 -16
  22. data/lib/transpec/syntax/should_receive.rb +32 -35
  23. data/lib/transpec/version.rb +1 -1
  24. data/spec/spec_helper.rb +8 -6
  25. data/spec/support/shared_context.rb +4 -0
  26. data/spec/transpec/ast/scanner_spec.rb +1 -1
  27. data/spec/transpec/ast/scope_stack_spec.rb +1 -0
  28. data/spec/transpec/cli_spec.rb +1 -0
  29. data/spec/transpec/configuration_spec.rb +1 -0
  30. data/spec/transpec/git_spec.rb +8 -0
  31. data/spec/transpec/rewriter_spec.rb +30 -0
  32. data/spec/transpec/syntax/be_close_spec.rb +50 -0
  33. data/spec/transpec/syntax/double_spec.rb +3 -2
  34. data/spec/transpec/syntax/matcher_spec.rb +1 -0
  35. data/spec/transpec/syntax/method_stub_spec.rb +1 -0
  36. data/spec/transpec/syntax/should_receive_spec.rb +1 -0
  37. data/spec/transpec/syntax/should_spec.rb +1 -0
  38. data/spec/transpec/util_spec.rb +1 -0
  39. data/transpec.gemspec +1 -0
  40. metadata +23 -3
  41. data/lib/transpec.rb +0 -17
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax/send_node_syntax'
4
+
5
+ module Transpec
6
+ class Syntax
7
+ module AnyInstanceable
8
+ include SendNodeSyntax
9
+
10
+ def any_instance?
11
+ !class_node_of_any_instance.nil?
12
+ end
13
+
14
+ def class_node_of_any_instance
15
+ return nil unless subject_node.type == :send
16
+ return nil unless subject_node.children.count == 2
17
+ receiver_node, method_name = *subject_node
18
+ return nil unless method_name == :any_instance
19
+ return nil unless receiver_node.type == :const
20
+ receiver_node
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/send_node_syntax'
5
+
6
+ module Transpec
7
+ class Syntax
8
+ class BeClose < Syntax
9
+ def convert_to_be_within!
10
+ _receiver_node, _method_name, expected_node, delta_node = *node
11
+
12
+ be_within_source = 'be_within('
13
+ be_within_source << delta_node.loc.expression.source
14
+ be_within_source << ').of('
15
+ be_within_source << expected_node.loc.expression.source
16
+ be_within_source << ')'
17
+
18
+ replace(expression_range, be_within_source)
19
+ end
20
+
21
+ private
22
+
23
+ def self.target_receiver_node?(node)
24
+ node.nil?
25
+ end
26
+
27
+ def self.target_method_names
28
+ [:be_close]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,20 +1,26 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/send_node_syntax'
5
+
3
6
  module Transpec
4
7
  class Syntax
5
8
  class Double < Syntax
6
9
  include SendNodeSyntax
7
10
 
8
- def self.target_node?(node)
9
- return false unless node.type == :send
10
- receiver_node, method_name, *_ = *node
11
- return false if receiver_node
12
- [:double, :mock, :stub].include?(method_name)
11
+ def convert_to_double!
12
+ return if method_name == :double
13
+ replace(selector_range, 'double')
13
14
  end
14
15
 
15
- def replace_deprecated_method!
16
- return if method_name == :double
17
- @source_rewriter.replace(selector_range, 'double')
16
+ private
17
+
18
+ def self.target_receiver_node?(node)
19
+ node.nil?
20
+ end
21
+
22
+ def self.target_method_names
23
+ [:double, :mock, :stub]
18
24
  end
19
25
  end
20
26
  end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+
3
+ require 'transpec/syntax/send_node_syntax'
4
+
5
+ module Transpec
6
+ class Syntax
7
+ module Expectizable
8
+ include SendNodeSyntax
9
+
10
+ def wrap_subject_in_expect!
11
+ if subject_range.source[0] == '('
12
+ insert_before(subject_range, 'expect')
13
+ else
14
+ insert_before(subject_range, 'expect(')
15
+ insert_after(subject_range, ')')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,10 +1,18 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/send_node_syntax'
5
+ require 'transpec/util'
6
+
3
7
  module Transpec
4
8
  class Syntax
5
9
  class Matcher < Syntax
6
10
  include SendNodeSyntax, Util
7
11
 
12
+ def self.target_node?(node)
13
+ false
14
+ end
15
+
8
16
  def initialize(node, in_example_group_context, source_rewriter)
9
17
  @node = node
10
18
  @in_example_group_context = in_example_group_context
@@ -14,15 +22,15 @@ module Transpec
14
22
  def correct_operator!(parenthesize_arg = true)
15
23
  case method_name
16
24
  when :==
17
- @source_rewriter.replace(selector_range, 'eq')
25
+ replace(selector_range, 'eq')
18
26
  parenthesize!(parenthesize_arg)
19
27
  when :===, :<, :<=, :>, :>=
20
- @source_rewriter.insert_before(selector_range, 'be ')
28
+ insert_before(selector_range, 'be ')
21
29
  when :=~
22
30
  if arg_node.type == :array
23
- @source_rewriter.replace(selector_range, 'match_array')
31
+ replace(selector_range, 'match_array')
24
32
  else
25
- @source_rewriter.replace(selector_range, 'match')
33
+ replace(selector_range, 'match')
26
34
  end
27
35
  parenthesize!(parenthesize_arg)
28
36
  end
@@ -34,15 +42,15 @@ module Transpec
34
42
  case left_parenthesis_range.source
35
43
  when ' '
36
44
  if always || arg_node.type == :hash
37
- @source_rewriter.replace(left_parenthesis_range, '(')
38
- @source_rewriter.insert_after(expression_range, ')')
45
+ replace(left_parenthesis_range, '(')
46
+ insert_after(expression_range, ')')
39
47
  end
40
48
  when "\n", "\r"
41
- @source_rewriter.insert_before(left_parenthesis_range, '(')
49
+ insert_before(left_parenthesis_range, '(')
42
50
  linefeed = left_parenthesis_range.source
43
51
  matcher_line_indentation = indentation_of_line(@node)
44
52
  right_parenthesis = "#{linefeed}#{matcher_line_indentation})"
45
- @source_rewriter.insert_after(expression_range, right_parenthesis)
53
+ insert_after(expression_range, right_parenthesis)
46
54
  end
47
55
  end
48
56
 
@@ -1,26 +1,20 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/any_instanceable'
5
+ require 'transpec/util'
3
6
  require 'English'
4
7
 
5
8
  module Transpec
6
9
  class Syntax
7
10
  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
11
+ include AnyInstanceable, Util
16
12
 
17
13
  def allowize!
18
14
  # There's no way of unstubbing in #allow syntax.
19
15
  return unless [:stub, :stub!].include?(method_name)
20
16
 
21
- if @replaced_deprecated_method
22
- fail 'Already replaced deprecated method, cannot allowize.'
23
- end
17
+ fail 'Already replaced deprecated method, cannot allowize.' if @replaced_deprecated_method
24
18
 
25
19
  unless in_example_group_context?
26
20
  fail NotInExampleGroupContextError.new(expression_range, "##{method_name}", '#allow')
@@ -28,10 +22,10 @@ module Transpec
28
22
 
29
23
  if arg_node.type == :hash
30
24
  expressions = build_allow_expressions_from_hash_node(arg_node)
31
- @source_rewriter.replace(expression_range, expressions)
25
+ replace(expression_range, expressions)
32
26
  else
33
27
  expression = build_allow_expression(arg_node)
34
- @source_rewriter.replace(expression_range, expression)
28
+ replace(expression_range, expression)
35
29
  end
36
30
 
37
31
  @allowized = true
@@ -45,17 +39,23 @@ module Transpec
45
39
 
46
40
  return unless replacement_method_name
47
41
 
48
- if @allowized
49
- fail 'Already allowized, cannot replace deprecated method.'
50
- end
42
+ fail 'Already allowized, cannot replace deprecated method.' if @allowized
51
43
 
52
- @source_rewriter.replace(selector_range, replacement_method_name)
44
+ replace(selector_range, replacement_method_name)
53
45
 
54
46
  @replaced_deprecated_method = true
55
47
  end
56
48
 
57
49
  private
58
50
 
51
+ def self.target_receiver_node?(node)
52
+ !node.nil?
53
+ end
54
+
55
+ def self.target_method_names
56
+ [:stub, :unstub, :stub!, :unstub!]
57
+ end
58
+
59
59
  def build_allow_expressions_from_hash_node(hash_node)
60
60
  expressions = []
61
61
 
@@ -70,15 +70,7 @@ module Transpec
70
70
  end
71
71
 
72
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
-
73
+ expression = allow_source
82
74
  expression << range_in_between_subject_and_selector.source
83
75
  expression << 'to receive'
84
76
  expression << (keep_form_around_arg ? range_in_between_selector_and_arg.source : '(')
@@ -93,24 +85,18 @@ module Transpec
93
85
  expression
94
86
  end
95
87
 
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?
88
+ def allow_source
89
+ if any_instance?
90
+ class_source = class_node_of_any_instance.loc.expression.source
91
+ "allow_any_instance_of(#{class_source})"
92
+ else
93
+ "allow(#{subject_range.source})"
94
+ end
107
95
  end
108
96
 
109
97
  def message_source(node)
110
98
  message_source = node.loc.expression.source
111
- if node.type == :sym && !message_source.start_with?(':')
112
- message_source.prepend(':')
113
- end
99
+ message_source.prepend(':') if node.type == :sym && !message_source.start_with?(':')
114
100
  message_source
115
101
  end
116
102
 
@@ -1,5 +1,7 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+
3
5
  module Transpec
4
6
  class Syntax
5
7
  module SendNodeSyntax
@@ -17,10 +19,6 @@ module Transpec
17
19
  @node.children[2]
18
20
  end
19
21
 
20
- def expression_range
21
- @node.loc.expression
22
- end
23
-
24
22
  def selector_range
25
23
  @node.loc.selector
26
24
  end
@@ -1,16 +1,14 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/expectizable'
5
+ require 'transpec/syntax/matcher'
6
+ require 'transpec/util'
7
+
3
8
  module Transpec
4
9
  class Syntax
5
10
  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
11
+ include Expectizable, Util
14
12
 
15
13
  def positive?
16
14
  method_name == :should
@@ -22,17 +20,12 @@ module Transpec
22
20
  end
23
21
 
24
22
  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')
23
+ replace_proc_selector_with_expect!
30
24
  else
31
- @source_rewriter.insert_before(subject_range, 'expect(')
32
- @source_rewriter.insert_after(subject_range, ')')
25
+ wrap_subject_in_expect!
33
26
  end
34
27
 
35
- @source_rewriter.replace(selector_range, positive? ? 'to' : negative_form)
28
+ replace(selector_range, positive? ? 'to' : negative_form)
36
29
 
37
30
  matcher.correct_operator!(parenthesize_matcher_arg)
38
31
  end
@@ -44,6 +37,22 @@ module Transpec
44
37
  def matcher_node
45
38
  arg_node || parent_node
46
39
  end
40
+
41
+ private
42
+
43
+ def self.target_receiver_node?(node)
44
+ !node.nil?
45
+ end
46
+
47
+ def self.target_method_names
48
+ [:should, :should_not]
49
+ end
50
+
51
+ def replace_proc_selector_with_expect!
52
+ send_node = subject_node.children.first
53
+ range_of_subject_method_taking_block = send_node.loc.expression
54
+ replace(range_of_subject_method_taking_block, 'expect')
55
+ end
47
56
  end
48
57
  end
49
58
  end
@@ -1,16 +1,13 @@
1
1
  # coding: utf-8
2
2
 
3
+ require 'transpec/syntax'
4
+ require 'transpec/syntax/expectizable'
5
+ require 'transpec/syntax/any_instanceable'
6
+
3
7
  module Transpec
4
8
  class Syntax
5
9
  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
10
+ include Expectizable, AnyInstanceable
14
11
 
15
12
  def positive?
16
13
  method_name == :should_receive
@@ -21,46 +18,50 @@ module Transpec
21
18
  fail NotInExampleGroupContextError.new(expression_range, "##{method_name}", '#expect')
22
19
  end
23
20
 
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, ')')
21
+ if any_instance?
22
+ wrap_class_in_expect_any_instance_of!
29
23
  else
30
- @source_rewriter.insert_before(subject_range, 'expect(')
31
- @source_rewriter.insert_after(subject_range, ')')
24
+ wrap_subject_in_expect!
32
25
  end
33
26
 
34
- to_receive = "#{positive? ? 'to' : negative_form} receive"
35
- @source_rewriter.replace(selector_range, to_receive)
27
+ replace(selector_range, "#{positive? ? 'to' : negative_form} receive")
36
28
 
37
29
  correct_block_style!
38
30
  end
39
31
 
40
32
  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
33
  return if broken_block_nodes.empty?
47
34
 
48
35
  broken_block_nodes.each do |block_node|
49
36
  map = block_node.loc
50
37
  next if map.begin.source == '{'
51
- @source_rewriter.replace(map.begin, '{')
52
- @source_rewriter.replace(map.end, '}')
38
+ replace(map.begin, '{')
39
+ replace(map.end, '}')
53
40
  end
54
41
  end
55
42
 
56
43
  private
57
44
 
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
45
+ def self.target_receiver_node?(node)
46
+ !node.nil?
47
+ end
48
+
49
+ def self.target_method_names
50
+ [:should_receive, :should_not_receive]
51
+ end
52
+
53
+ def wrap_class_in_expect_any_instance_of!
54
+ insert_before(subject_range, 'expect_any_instance_of(')
55
+ map = subject_node.loc
56
+ dot_any_instance_range = map.dot.join(map.selector)
57
+ replace(dot_any_instance_range, ')')
58
+ end
59
+
60
+ def broken_block_nodes
61
+ @broken_block_nodes ||= [
62
+ block_node_taken_by_with_method_with_no_normal_args,
63
+ block_node_followed_by_message_expectation_method
64
+ ].compact.uniq
64
65
  end
65
66
 
66
67
  # subject.should_receive(:method_name).once.with do |block_arg|
@@ -105,11 +106,7 @@ module Transpec
105
106
  @ancestor_nodes.reverse.reduce(@node) do |child_node, parent_node|
106
107
  return nil unless [:send, :block].include?(parent_node.type)
107
108
  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
-
109
+ return child_node if child_node.type == :block && parent_node.type == :send
113
110
  parent_node
114
111
  end
115
112