minitest_to_rspec 0.11.0 → 0.12.0

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 (36) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +3 -2
  3. data/CHANGELOG.md +19 -0
  4. data/README.md +3 -0
  5. data/lib/minitest_to_rspec/converter.rb +2 -2
  6. data/lib/minitest_to_rspec/input/model/base.rb +15 -0
  7. data/lib/minitest_to_rspec/input/model/call.rb +185 -0
  8. data/lib/minitest_to_rspec/input/model/defn.rb +37 -0
  9. data/lib/minitest_to_rspec/input/model/hash_exp.rb +24 -0
  10. data/lib/minitest_to_rspec/input/model/iter.rb +89 -0
  11. data/lib/minitest_to_rspec/input/model/klass.rb +102 -0
  12. data/lib/minitest_to_rspec/input/processor.rb +40 -0
  13. data/lib/minitest_to_rspec/input/subprocessors/base.rb +91 -0
  14. data/lib/minitest_to_rspec/input/subprocessors/call.rb +279 -0
  15. data/lib/minitest_to_rspec/input/subprocessors/defn.rb +64 -0
  16. data/lib/minitest_to_rspec/input/subprocessors/iter.rb +148 -0
  17. data/lib/minitest_to_rspec/input/subprocessors/klass.rb +101 -0
  18. data/lib/minitest_to_rspec/minitest/stub.rb +85 -0
  19. data/lib/minitest_to_rspec/{expression_builders → rspec}/stub.rb +3 -2
  20. data/lib/minitest_to_rspec/type.rb +1 -1
  21. data/lib/minitest_to_rspec/version.rb +1 -1
  22. metadata +17 -18
  23. data/lib/minitest_to_rspec/model/base.rb +0 -13
  24. data/lib/minitest_to_rspec/model/call.rb +0 -165
  25. data/lib/minitest_to_rspec/model/calls/once.rb +0 -13
  26. data/lib/minitest_to_rspec/model/calls/twice.rb +0 -13
  27. data/lib/minitest_to_rspec/model/defn.rb +0 -27
  28. data/lib/minitest_to_rspec/model/hash_exp.rb +0 -20
  29. data/lib/minitest_to_rspec/model/iter.rb +0 -79
  30. data/lib/minitest_to_rspec/model/klass.rb +0 -100
  31. data/lib/minitest_to_rspec/processor.rb +0 -38
  32. data/lib/minitest_to_rspec/subprocessors/base.rb +0 -89
  33. data/lib/minitest_to_rspec/subprocessors/call.rb +0 -391
  34. data/lib/minitest_to_rspec/subprocessors/defn.rb +0 -49
  35. data/lib/minitest_to_rspec/subprocessors/iter.rb +0 -138
  36. data/lib/minitest_to_rspec/subprocessors/klass.rb +0 -99
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: be2fe63a020fb7a38b10551341162eb978a0b84c
4
- data.tar.gz: '0696d05d0c95b8cb6afbe1865ae224b2e8066e86'
2
+ SHA256:
3
+ metadata.gz: e8f9207756131c32b3622da37695b0da546d38749df1d22ae1f7d1daa1f1f1a5
4
+ data.tar.gz: dfb8bb34cd541ed7172822c98ce84db91bb7b99af0bd3f01d907da50a0472af1
5
5
  SHA512:
6
- metadata.gz: 1f44130fe3b150666829ff09abd348e92dffa6104f70678412ea1ef9e9e7cb363280549930796062d4c346590f634584cab18cd9db92f1c16f5a876b3ae88833
7
- data.tar.gz: ef3a2361df027ddb59c33f858c49641f295298fa60d6a140bc63b60408e9706c2ec4d57cba346ed964d1eb7de5aa017b016b1bf151f403dfac5046f618b49c5b
6
+ metadata.gz: 45025ed9cdf045697a49d0571811fa14919ba91868044630de17f4436a0f1ffa32c6f172a9b8518eb7139dadce949798caa6a37828101303892d1055c3522001
7
+ data.tar.gz: 3ea95cd4da9200505c5c23bf072d084aa37d4994add74f8689e9766061046aa8a68ce6f66adb5c10d325143b3e73a878a86bafc5693088e5016fc4a4d01c7385
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
- - "2.3.5"
4
- - "2.4.2"
3
+ - "2.3.6"
4
+ - "2.4.3"
5
+ - "2.5.0"
5
6
  script: bundle exec rake
6
7
  sudo: false
7
8
  notifications:
@@ -17,6 +17,25 @@ of [keepachangelog.com][2].
17
17
 
18
18
  - None
19
19
 
20
+ ## 0.12.0 (2018-03-11)
21
+
22
+ ### Breaking Changes
23
+
24
+ - None
25
+
26
+ ### Added
27
+
28
+ - [#21](https://github.com/jaredbeck/minitest_to_rspec/pull/21) -
29
+ convert `setup`/`teardown` methods to `before`/`after` blocks
30
+ - [#20](https://github.com/jaredbeck/minitest_to_rspec/pull/20) -
31
+ Support `refute_raise[s]`
32
+ - [#18](https://github.com/jaredbeck/minitest_to_rspec/pull/18) -
33
+ Support namespaced exceptions for assert_raise[s]
34
+
35
+ ### Fixed
36
+
37
+ - None
38
+
20
39
  ## 0.11.0 (2017-11-10)
21
40
 
22
41
  ### Breaking Changes
data/README.md CHANGED
@@ -97,6 +97,8 @@ assert_not_nil | |
97
97
  [assert_raises][13] | 0..2 | Minitest
98
98
  refute | |
99
99
  refute_equal | |
100
+ [refute_raise][39] | |
101
+ [refute_raises][39] | |
100
102
 
101
103
  ## Supported Mocha
102
104
 
@@ -160,3 +162,4 @@ This project would not be possible without [ruby_parser][14],
160
162
  [36]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/ClassMethods#context-instance_method
161
163
  [37]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/Context#setup-instance_method
162
164
  [38]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/ClassMethods#should-instance_method
165
+ [39]: https://github.com/jaredbeck/minitest_to_rspec/pull/20
@@ -2,14 +2,14 @@
2
2
 
3
3
  require 'ruby_parser'
4
4
  require 'ruby2ruby'
5
- require_relative 'processor'
5
+ require 'minitest_to_rspec/input/processor'
6
6
  require_relative 'errors'
7
7
 
8
8
  module MinitestToRspec
9
9
  # Converts strings of minitest code. Does not read or write files.
10
10
  class Converter
11
11
  def initialize(rails: false, mocha: false)
12
- @processor = Processor.new(rails, mocha)
12
+ @processor = Input::Processor.new(rails, mocha)
13
13
  end
14
14
 
15
15
  # - `input` - Contents of a ruby file.
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/sexp_assertions'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Input models are simple data objects
9
+ # representing the S-expressions they are named after.
10
+ class Base
11
+ include SexpAssertions
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/input/model/base'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Data object. Represents a `:call` s-expression.
9
+ class Call < Base
10
+ attr_reader :original
11
+
12
+ def initialize(exp)
13
+ assert_sexp_type(:call, exp)
14
+ @exp = exp.dup
15
+ @original = exp.dup
16
+ end
17
+
18
+ class << self
19
+ def assert_difference?(exp)
20
+ exp.sexp_type == :call && new(exp).assert_difference?
21
+ end
22
+
23
+ def assert_no_difference?(exp)
24
+ exp.sexp_type == :call && new(exp).assert_no_difference?
25
+ end
26
+
27
+ def assert_nothing_raised?(exp)
28
+ exp.sexp_type == :call && new(exp).assert_nothing_raised?
29
+ end
30
+
31
+ def assert_raise?(exp)
32
+ exp.sexp_type == :call && new(exp).assert_raise?
33
+ end
34
+
35
+ def assert_raises?(exp)
36
+ exp.sexp_type == :call && new(exp).assert_raises?
37
+ end
38
+
39
+ def refute_raise?(exp)
40
+ exp.sexp_type == :call && new(exp).refute_raise?
41
+ end
42
+
43
+ def refute_raises?(exp)
44
+ exp.sexp_type == :call && new(exp).refute_raises?
45
+ end
46
+
47
+ def method_name?(exp, name)
48
+ exp.sexp_type == :call && new(exp).method_name.to_s == name.to_s
49
+ end
50
+ end
51
+
52
+ def arguments
53
+ @exp[3..-1] || []
54
+ end
55
+
56
+ def argument_types
57
+ arguments.map(&:sexp_type)
58
+ end
59
+
60
+ def assert_difference?
61
+ return false unless method_name == :assert_difference
62
+ [[:str], %i[str lit]].include?(argument_types)
63
+ end
64
+
65
+ def assert_no_difference?
66
+ method_name == :assert_no_difference &&
67
+ arguments.length == 1 &&
68
+ arguments[0].sexp_type == :str
69
+ end
70
+
71
+ def assert_nothing_raised?
72
+ method_name == :assert_nothing_raised && arguments.empty?
73
+ end
74
+
75
+ def assert_raise?
76
+ method_name == :assert_raise && raise_error_args?
77
+ end
78
+
79
+ def assert_raises?
80
+ method_name == :assert_raises && raise_error_args?
81
+ end
82
+
83
+ def refute_raise?
84
+ method_name == :refute_raise && raise_error_args?
85
+ end
86
+
87
+ def refute_raises?
88
+ method_name == :refute_raises && raise_error_args?
89
+ end
90
+
91
+ def calls_in_receiver_chain
92
+ receiver_chain.each_with_object([]) do |e, a|
93
+ next unless sexp_type?(:call, e)
94
+ a << self.class.new(e)
95
+ end
96
+ end
97
+
98
+ def find_call_in_receiver_chain(method_names)
99
+ name_array = [method_names].flatten
100
+ calls_in_receiver_chain.find { |i|
101
+ name_array.include?(i.method_name)
102
+ }
103
+ end
104
+
105
+ def method_name
106
+ @exp[2]
107
+ end
108
+
109
+ def num_arguments
110
+ arguments.length
111
+ end
112
+
113
+ def one_string_argument?
114
+ arguments.length == 1 && string?(arguments[0])
115
+ end
116
+
117
+ # Returns true if arguments can be processed into RSpec's `raise_error`
118
+ # matcher. When the last argument is a string, it represents the
119
+ # assertion failure message, which will be discarded later.
120
+ def raise_error_args?
121
+ arg_types = arguments.map(&:sexp_type)
122
+ [[], [:str], [:const], %i[const str], [:colon2]].include?(arg_types)
123
+ end
124
+
125
+ def receiver
126
+ @exp[1]
127
+ end
128
+
129
+ # Consider the following chain of method calls:
130
+ #
131
+ # @a.b.c
132
+ #
133
+ # whose S-expression is
134
+ #
135
+ # s(:call, s(:call, s(:call, nil, :a), :b), :c)
136
+ #
137
+ # the "receiver chain" is
138
+ #
139
+ # [
140
+ # s(:call, s(:call, nil, :a), :b),
141
+ # s(:call, nil, :a),
142
+ # nil
143
+ # ]
144
+ #
145
+ # The order of the returned array matches the order in which
146
+ # messages are received, i.e. the order of execution.
147
+ #
148
+ # Note that the final receiver `nil` is included. This `nil`
149
+ # represents the implicit receiver, e.g. `self` or `main`.
150
+ #
151
+ def receiver_chain
152
+ receivers = []
153
+ ptr = @exp
154
+ while sexp_type?(:call, ptr)
155
+ receivers << ptr[1]
156
+ ptr = ptr[1]
157
+ end
158
+ receivers
159
+ end
160
+
161
+ def receiver_chain_include?(method_name)
162
+ receiver_chain.compact.any? { |r|
163
+ self.class.method_name?(r, method_name)
164
+ }
165
+ end
166
+
167
+ def require_test_helper?
168
+ method_name == :require &&
169
+ one_string_argument? &&
170
+ arguments[0][1] == 'test_helper'
171
+ end
172
+
173
+ def question_mark_method?
174
+ method_name.to_s.end_with?('?')
175
+ end
176
+
177
+ private
178
+
179
+ def string?(exp)
180
+ exp.sexp_type == :str
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/input/model/base'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Data object. Represents a `:defn` s-expression.
9
+ class Defn < Base
10
+ def initialize(exp)
11
+ assert_sexp_type(:defn, exp)
12
+ @exp = exp.dup
13
+ end
14
+
15
+ def body
16
+ @exp[3..-1]
17
+ end
18
+
19
+ def method_name
20
+ @exp[1].to_s
21
+ end
22
+
23
+ def test_method?
24
+ method_name.start_with?('test_')
25
+ end
26
+
27
+ def setup?
28
+ method_name == 'setup'
29
+ end
30
+
31
+ def teardown?
32
+ method_name == 'teardown'
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/input/model/base'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Data object. Represents a `:hash` S-expression.
9
+ class HashExp < Base
10
+ def initialize(sexp)
11
+ assert_sexp_type(:hash, sexp)
12
+ @exp = sexp.dup
13
+ end
14
+
15
+ # A slightly nicer implementation would be:
16
+ # `@exp[1..-1].each_slice(2).to_h`
17
+ # but that would require ruby >= 2.1
18
+ def to_h
19
+ Hash[@exp[1..-1].each_slice(2).to_a]
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/input/model/base'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Data object. Represents an `:iter` s-expression.
9
+ class Iter < Base
10
+ def initialize(exp)
11
+ assert_sexp_type(:iter, exp)
12
+ @exp = exp.dup
13
+ end
14
+
15
+ def [](*args)
16
+ @exp[*args]
17
+ end
18
+
19
+ def assert_difference?
20
+ !empty? && Model::Call.assert_difference?(@exp[1])
21
+ end
22
+
23
+ def assert_no_difference?
24
+ !empty? && Model::Call.assert_no_difference?(@exp[1])
25
+ end
26
+
27
+ def assert_nothing_raised?
28
+ !empty? && Model::Call.assert_nothing_raised?(@exp[1])
29
+ end
30
+
31
+ def assert_raise?
32
+ !empty? && Model::Call.assert_raise?(@exp[1])
33
+ end
34
+
35
+ def assert_raises?
36
+ !empty? && Model::Call.assert_raises?(@exp[1])
37
+ end
38
+
39
+ def refute_raise?
40
+ !empty? && Model::Call.refute_raise?(@exp[1])
41
+ end
42
+
43
+ def refute_raises?
44
+ !empty? && Model::Call.refute_raises?(@exp[1])
45
+ end
46
+
47
+ def block
48
+ @exp[3]
49
+ end
50
+
51
+ def call
52
+ @exp[1]
53
+ end
54
+
55
+ # Not to be confused with block arguments.
56
+ def call_arguments
57
+ call_obj.arguments
58
+ end
59
+
60
+ def call_obj
61
+ Model::Call.new(call)
62
+ end
63
+
64
+ # Enumerates children, skipping the base `call` and
65
+ # starting with the block arguments, then each `:call` in
66
+ # the block.
67
+ def each
68
+ @exp[2..-1].each do |e| yield(e) end
69
+ end
70
+
71
+ def empty?
72
+ @exp.length == 1 # just the sexp_type
73
+ end
74
+
75
+ def setup?
76
+ !empty? && Model::Call.method_name?(@exp[1], :setup)
77
+ end
78
+
79
+ def teardown?
80
+ !empty? && Model::Call.method_name?(@exp[1], :teardown)
81
+ end
82
+
83
+ def sexp
84
+ @exp
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'minitest_to_rspec/input/model/base'
4
+
5
+ module MinitestToRspec
6
+ module Input
7
+ module Model
8
+ # Data object. Represents a `:class` S-expression.
9
+ class Klass < Base
10
+ def initialize(exp)
11
+ assert_sexp_type(:class, exp)
12
+ @exp = exp.dup
13
+ assert_valid_name
14
+ end
15
+
16
+ def action_controller_test_case?
17
+ lineage?(parent, %i[ActionController TestCase])
18
+ end
19
+
20
+ def action_mailer_test_case?
21
+ lineage?(parent, %i[ActionMailer TestCase])
22
+ end
23
+
24
+ def active_support_test_case?
25
+ lineage?(parent, %i[ActiveSupport TestCase])
26
+ end
27
+
28
+ # Raise an error if we don't know now to process the name
29
+ # of this class. Specifically, classes with module-shorthand.
30
+ def assert_valid_name
31
+ if name.is_a?(Symbol)
32
+ # Valid
33
+ elsif name.respond_to?(:sexp_type) && name.sexp_type == :colon2
34
+ raise ModuleShorthandError
35
+ else
36
+ raise ProcessingError, "Unexpected class expression: #{name}"
37
+ end
38
+ end
39
+
40
+ def block?
41
+ !block.empty?
42
+ end
43
+
44
+ def block
45
+ @_block ||= @exp[3..-1] || []
46
+ end
47
+
48
+ def draper_test_case?
49
+ lineage?(parent, %i[Draper TestCase])
50
+ end
51
+
52
+ # Returns the name of the class. Examples:
53
+ #
54
+ # - Banana #=> :Banana
55
+ # - Fruit::Banana #=> s(:colon2, s(:const, :Fruit), :Banana)
56
+ #
57
+ # Note that the latter (module shorthand) is not supported
58
+ # by MinitestToRspec. See `#assert_valid_name`.
59
+ #
60
+ def name
61
+ @exp[1]
62
+ end
63
+
64
+ # Returns the "inheritance". Examples:
65
+ #
66
+ # - Inherit nothing #=> nil
67
+ # - Inherit Foo #=> s(:const, :Foo)
68
+ # - Inherit Bar::Foo #=> s(:colon2, s(:const, :Bar), :Foo)
69
+ #
70
+ def parent
71
+ @_parent ||= @exp[2]
72
+ end
73
+
74
+ # Returns true if `@exp` inherits from, e.g. ActiveSupport::TestCase.
75
+ # TODO: Other test case parent classes.
76
+ def test_case?
77
+ return false unless sexp_type?(:colon2, parent)
78
+ active_support_test_case? ||
79
+ action_controller_test_case? ||
80
+ action_mailer_test_case? ||
81
+ draper_test_case?
82
+ end
83
+
84
+ private
85
+
86
+ def ancestor_name(exp, index)
87
+ assert_sexp_type(:colon2, exp)
88
+ ancestor = exp[index + 1]
89
+ sexp_type?(:const, ancestor) ? ancestor[1] : ancestor
90
+ end
91
+
92
+ def lineage?(exp, names)
93
+ assert_sexp_type(:colon2, exp)
94
+ exp.length == names.length + 1 &&
95
+ names.each_with_index.all? { |name, ix|
96
+ name.to_sym == ancestor_name(exp, ix).to_sym
97
+ }
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end