minitest_to_rspec 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +11 -2
- data/CHANGELOG.md +17 -0
- data/README.md +13 -0
- data/Rakefile +1 -1
- data/bin/console +4 -4
- data/bin/mt2rspec +1 -1
- data/doc/mocha/mocha_test.rb +50 -0
- data/lib/minitest_to_rspec/cli.rb +19 -19
- data/lib/minitest_to_rspec/converter.rb +4 -4
- data/lib/minitest_to_rspec/expression_builders/stub.rb +62 -0
- data/lib/minitest_to_rspec/model/base.rb +1 -1
- data/lib/minitest_to_rspec/model/call.rb +17 -27
- data/lib/minitest_to_rspec/model/calls/once.rb +2 -2
- data/lib/minitest_to_rspec/model/calls/twice.rb +2 -2
- data/lib/minitest_to_rspec/model/defn.rb +1 -1
- data/lib/minitest_to_rspec/model/iter.rb +1 -1
- data/lib/minitest_to_rspec/model/klass.rb +5 -5
- data/lib/minitest_to_rspec/processor.rb +6 -6
- data/lib/minitest_to_rspec/subprocessors/base.rb +1 -1
- data/lib/minitest_to_rspec/subprocessors/call.rb +68 -36
- data/lib/minitest_to_rspec/subprocessors/defn.rb +2 -2
- data/lib/minitest_to_rspec/subprocessors/iter.rb +2 -2
- data/lib/minitest_to_rspec/subprocessors/klass.rb +4 -4
- data/lib/minitest_to_rspec/type.rb +33 -0
- data/lib/minitest_to_rspec/version.rb +1 -1
- data/lib/minitest_to_rspec.rb +2 -2
- data/minitest_to_rspec.gemspec +16 -16
- metadata +5 -4
- data/.rubocop_todo.yml +0 -57
- data/lib/minitest_to_rspec/model/calls/returns.rb +0 -87
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be2fe63a020fb7a38b10551341162eb978a0b84c
|
4
|
+
data.tar.gz: '0696d05d0c95b8cb6afbe1865ae224b2e8066e86'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f44130fe3b150666829ff09abd348e92dffa6104f70678412ea1ef9e9e7cb363280549930796062d4c346590f634584cab18cd9db92f1c16f5a876b3ae88833
|
7
|
+
data.tar.gz: ef3a2361df027ddb59c33f858c49641f295298fa60d6a140bc63b60408e9706c2ec4d57cba346ed964d1eb7de5aa017b016b1bf151f403dfac5046f618b49c5b
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
inherit_from: .rubocop_todo.yml
|
2
|
-
|
3
1
|
AllCops:
|
4
2
|
Exclude:
|
5
3
|
- spec/fixtures/**/*
|
@@ -40,6 +38,9 @@ Metrics/MethodLength:
|
|
40
38
|
Metrics/ModuleLength:
|
41
39
|
Enabled: false
|
42
40
|
|
41
|
+
Metrics/ParameterLists:
|
42
|
+
Max: 6
|
43
|
+
|
43
44
|
# EOS is a well-known delimiter and thus satisfactory.
|
44
45
|
Naming/HeredocDelimiterNaming:
|
45
46
|
Enabled: false
|
@@ -52,6 +53,14 @@ Style/Documentation:
|
|
52
53
|
Exclude:
|
53
54
|
- 'spec/**/*'
|
54
55
|
|
56
|
+
# Too subtle to lint. Avoid postfix operators unless line is very simple.
|
57
|
+
Style/IfUnlessModifier:
|
58
|
+
Enabled: false
|
59
|
+
|
55
60
|
# Guard clauses are great, but this is too subtle to lint.
|
56
61
|
Style/GuardClause:
|
57
62
|
Enabled: false
|
63
|
+
|
64
|
+
# Too subtle to lint. Avoid postfix operators unless line is very simple.
|
65
|
+
Style/WhileUntilModifier:
|
66
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -17,6 +17,23 @@ of [keepachangelog.com][2].
|
|
17
17
|
|
18
18
|
- None
|
19
19
|
|
20
|
+
## 0.11.0 (2017-11-10)
|
21
|
+
|
22
|
+
### Breaking Changes
|
23
|
+
|
24
|
+
- None
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- [#15](https://github.com/jaredbeck/minitest_to_rspec/pull/15) -
|
29
|
+
Support mocha stubs without returns
|
30
|
+
- [#16](https://github.com/jaredbeck/minitest_to_rspec/pull/16) -
|
31
|
+
Convert `should` to `it`
|
32
|
+
|
33
|
+
### Fixed
|
34
|
+
|
35
|
+
- None
|
36
|
+
|
20
37
|
## 0.10.2 (2017-11-09)
|
21
38
|
|
22
39
|
### Breaking Changes
|
data/README.md
CHANGED
@@ -8,6 +8,7 @@ Converts [minitest][8] files to [rspec][9].
|
|
8
8
|
and [ActiveSupport][27] are converted to [rspec-expectations][25].
|
9
9
|
- Selected methods from [mocha][28] are converted to [rspec-mocks][24].
|
10
10
|
(Experimental)
|
11
|
+
- Selected methods from [shoulda-context][36]
|
11
12
|
|
12
13
|
## Example
|
13
14
|
|
@@ -111,6 +112,14 @@ Mocha | Arity | Block | Notes
|
|
111
112
|
|
112
113
|
To do: [at_least, never, raises, etc.][30]
|
113
114
|
|
115
|
+
## Supported shoulda-context methods
|
116
|
+
|
117
|
+
Mocha | Arity | Block | Notes
|
118
|
+
--------------------- | ----- | ----- | -------
|
119
|
+
[context][36] | 1 | yes |
|
120
|
+
[setup][37] | 1,2 | no |
|
121
|
+
[should][38] | 1,2 | yes |
|
122
|
+
|
114
123
|
## Acknowledgements
|
115
124
|
|
116
125
|
This project would not be possible without [ruby_parser][14],
|
@@ -147,3 +156,7 @@ This project would not be possible without [ruby_parser][14],
|
|
147
156
|
[32]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation#twice-instance_method
|
148
157
|
[34]: https://github.com/bbatsov/ruby-style-guide
|
149
158
|
[35]: https://github.com/bbatsov/rubocop
|
159
|
+
[35]: https://github.com/thoughtbot/shoulda-context
|
160
|
+
[36]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/ClassMethods#context-instance_method
|
161
|
+
[37]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/Context#setup-instance_method
|
162
|
+
[38]: http://www.rubydoc.info/github/thoughtbot/shoulda-context/master/Shoulda/Context/ClassMethods#should-instance_method
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/bin/mt2rspec
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
gem 'mocha'
|
5
|
+
require 'minitest/unit'
|
6
|
+
require 'mocha/mini_test'
|
7
|
+
require 'minitest/autorun'
|
8
|
+
|
9
|
+
# Reverse engineering mocha, to clarify some things missing in the mocha docs.
|
10
|
+
class TestDerp < Minitest::Test
|
11
|
+
def test_expects_return_value
|
12
|
+
x = Object.new
|
13
|
+
x.define_singleton_method(:y) { :z } # this won't get called
|
14
|
+
x.expects(:y)
|
15
|
+
assert_nil x.y
|
16
|
+
# passes
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_stubs_only
|
20
|
+
x = Object.new
|
21
|
+
x.stubs(:y)
|
22
|
+
# passes
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_stubs_returns
|
26
|
+
x = Object.new
|
27
|
+
x.stubs(:y).returns(:z)
|
28
|
+
# passes
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_stubs_once
|
32
|
+
x = Object.new
|
33
|
+
x.stubs(:y).once
|
34
|
+
# fails: expected exactly once, not yet invoked
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_stubs_twice
|
38
|
+
x = Object.new
|
39
|
+
x.stubs(:y).twice
|
40
|
+
# fails: expected exactly twice, not yet invoked
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_stubs_return_value
|
44
|
+
x = Object.new
|
45
|
+
x.define_singleton_method(:y) { :z } # this won't get called
|
46
|
+
x.stubs(:y)
|
47
|
+
assert_nil x.y
|
48
|
+
# passes
|
49
|
+
end
|
50
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'fileutils'
|
4
|
+
require 'minitest_to_rspec'
|
5
|
+
require 'trollop'
|
6
6
|
|
7
7
|
module MinitestToRspec
|
8
8
|
# Command-Line Interface (CLI) instantiated by `bin/mt2rspec`
|
9
9
|
class CLI
|
10
|
-
E_USAGE = 1
|
11
|
-
E_FILE_NOT_FOUND = 2
|
12
|
-
E_FILE_ALREADY_EXISTS = 3
|
13
|
-
E_CONVERT_FAIL = 4
|
14
|
-
E_CANNOT_CREATE_TARGET_DIR = 5
|
10
|
+
E_USAGE = 1
|
11
|
+
E_FILE_NOT_FOUND = 2
|
12
|
+
E_FILE_ALREADY_EXISTS = 3
|
13
|
+
E_CONVERT_FAIL = 4
|
14
|
+
E_CANNOT_CREATE_TARGET_DIR = 5
|
15
15
|
|
16
|
-
BANNER = <<~EOS
|
16
|
+
BANNER = <<~EOS
|
17
17
|
Usage: mt2rspec [--rails] [--mocha] source_file [target_file]
|
18
18
|
|
19
19
|
Reads source_file, writes target_file. If target_file is omitted,
|
@@ -23,8 +23,8 @@ module MinitestToRspec
|
|
23
23
|
|
24
24
|
Options:
|
25
25
|
EOS
|
26
|
-
OPT_MOCHA =
|
27
|
-
OPT_RAILS = <<~EOS.tr("\n",
|
26
|
+
OPT_MOCHA = 'Convert mocha to rspec-mocks. (Experimental)'
|
27
|
+
OPT_RAILS = <<~EOS.tr("\n", ' ').freeze
|
28
28
|
Requires rails_helper instead of spec_helper.
|
29
29
|
Passes :type metadatum to RSpec.describe.
|
30
30
|
EOS
|
@@ -48,7 +48,7 @@ module MinitestToRspec
|
|
48
48
|
@source = args[0]
|
49
49
|
@target = infer_target_from @source
|
50
50
|
else
|
51
|
-
warn
|
51
|
+
warn 'Please specify source file'
|
52
52
|
exit E_USAGE
|
53
53
|
end
|
54
54
|
end
|
@@ -59,7 +59,7 @@ module MinitestToRspec
|
|
59
59
|
ensure_target_directory(target)
|
60
60
|
write_target(converter.convert(read_source, source))
|
61
61
|
rescue Error => e
|
62
|
-
|
62
|
+
warn "Failed to convert: #{e}"
|
63
63
|
exit E_CONVERT_FAIL
|
64
64
|
end
|
65
65
|
|
@@ -67,14 +67,14 @@ module MinitestToRspec
|
|
67
67
|
|
68
68
|
def assert_file_exists(file)
|
69
69
|
unless File.exist?(file)
|
70
|
-
|
70
|
+
warn "File not found: #{file}"
|
71
71
|
exit(E_FILE_NOT_FOUND)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
75
|
def assert_file_does_not_exist(file)
|
76
76
|
if File.exist?(file)
|
77
|
-
|
77
|
+
warn "File already exists: #{file}"
|
78
78
|
exit(E_FILE_ALREADY_EXISTS)
|
79
79
|
end
|
80
80
|
end
|
@@ -89,16 +89,16 @@ module MinitestToRspec
|
|
89
89
|
begin
|
90
90
|
FileUtils.mkdir_p(dir)
|
91
91
|
rescue SystemCallError => e
|
92
|
-
|
93
|
-
|
92
|
+
warn "Cannot create target dir: #{dir}"
|
93
|
+
warn e.message
|
94
94
|
exit E_CANNOT_CREATE_TARGET_DIR
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
98
|
def infer_target_from(source)
|
99
99
|
source
|
100
|
-
.gsub(/\Atest/,
|
101
|
-
.gsub(/_test.rb\Z/,
|
100
|
+
.gsub(/\Atest/, 'spec')
|
101
|
+
.gsub(/_test.rb\Z/, '_spec.rb')
|
102
102
|
end
|
103
103
|
|
104
104
|
def read_source
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require_relative
|
6
|
-
require_relative
|
3
|
+
require 'ruby_parser'
|
4
|
+
require 'ruby2ruby'
|
5
|
+
require_relative 'processor'
|
6
|
+
require_relative 'errors'
|
7
7
|
|
8
8
|
module MinitestToRspec
|
9
9
|
# Converts strings of minitest code. Does not read or write files.
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest_to_rspec/type'
|
4
|
+
|
5
|
+
module MinitestToRspec
|
6
|
+
module ExpressionBuilders
|
7
|
+
# Represents an `expects` or a `stubs`
|
8
|
+
class Stub
|
9
|
+
def initialize(receiver, any_instance, message, with, returns, count)
|
10
|
+
Type.assert(Sexp, receiver)
|
11
|
+
Type.bool(any_instance)
|
12
|
+
Type.assert(Sexp, message)
|
13
|
+
Type.assert([NilClass, Sexp], with)
|
14
|
+
Type.assert([NilClass, Sexp], returns)
|
15
|
+
Type.assert([NilClass, Integer], count)
|
16
|
+
@receiver = receiver
|
17
|
+
@any_instance = any_instance
|
18
|
+
@message = message
|
19
|
+
@with = with
|
20
|
+
@returns = returns
|
21
|
+
@count = count
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a Sexp representing an RSpec stub (allow) or message
|
25
|
+
# expectation (expect)
|
26
|
+
def to_rspec_exp
|
27
|
+
stub_chain = s(:call, nil, :receive, @message)
|
28
|
+
unless @with.nil?
|
29
|
+
stub_chain = s(:call, stub_chain, :with, @with)
|
30
|
+
end
|
31
|
+
unless @returns.nil?
|
32
|
+
stub_chain = s(:call, stub_chain, :and_return, @returns)
|
33
|
+
end
|
34
|
+
unless @count.nil?
|
35
|
+
stub_chain = s(:call, stub_chain, receive_count_method)
|
36
|
+
end
|
37
|
+
expect_allow = s(:call, nil, rspec_mocks_method, @receiver.dup)
|
38
|
+
s(:call, expect_allow, :to, stub_chain)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def receive_count_method
|
44
|
+
case @count
|
45
|
+
when 1
|
46
|
+
:once
|
47
|
+
when 2
|
48
|
+
:twice
|
49
|
+
else
|
50
|
+
raise "Unsupported message receive count: #{@count}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns :expect or :allow
|
55
|
+
def rspec_mocks_method
|
56
|
+
prefix = @count.nil? ? 'allow' : 'expect'
|
57
|
+
suffix = @any_instance ? '_any_instance_of' : ''
|
58
|
+
(prefix + suffix).to_sym
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module MinitestToRspec
|
6
6
|
module Model
|
@@ -50,7 +50,7 @@ module MinitestToRspec
|
|
50
50
|
|
51
51
|
def assert_difference?
|
52
52
|
return false unless method_name == :assert_difference
|
53
|
-
[[:str], [
|
53
|
+
[[:str], %i[str lit]].include?(argument_types)
|
54
54
|
end
|
55
55
|
|
56
56
|
def assert_no_difference?
|
@@ -72,10 +72,15 @@ module MinitestToRspec
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def calls_in_receiver_chain
|
75
|
-
receiver_chain
|
76
|
-
|
77
|
-
|
78
|
-
|
75
|
+
receiver_chain.each_with_object([]) do |e, a|
|
76
|
+
next unless sexp_type?(:call, e)
|
77
|
+
a << self.class.new(e)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def find_call_in_receiver_chain(method_names)
|
82
|
+
name_array = [method_names].flatten
|
83
|
+
calls_in_receiver_chain.find { |i| name_array.include?(i.method_name) }
|
79
84
|
end
|
80
85
|
|
81
86
|
def method_name
|
@@ -95,30 +100,13 @@ module MinitestToRspec
|
|
95
100
|
# assertion failure message, which will be discarded later.
|
96
101
|
def raise_error_args?
|
97
102
|
arg_types = arguments.map(&:sexp_type)
|
98
|
-
[[], [:str], [:const], [
|
103
|
+
[[], [:str], [:const], %i[const str]].include?(arg_types)
|
99
104
|
end
|
100
105
|
|
101
106
|
def receiver
|
102
107
|
@exp[1]
|
103
108
|
end
|
104
109
|
|
105
|
-
# While `#receiver` returns a `Sexp`, `#receiver_call`
|
106
|
-
# returns a `Model::Call`.
|
107
|
-
def receiver_call
|
108
|
-
if sexp_type?(:call, receiver)
|
109
|
-
rvc = Model::Call.new(receiver)
|
110
|
-
|
111
|
-
# TODO: Seems like a factory pattern
|
112
|
-
if rvc.method_name == :returns
|
113
|
-
Model::Calls::Returns.new(receiver)
|
114
|
-
else
|
115
|
-
rvc
|
116
|
-
end
|
117
|
-
else
|
118
|
-
raise TypeError
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
110
|
# Consider the following chain of method calls:
|
123
111
|
#
|
124
112
|
# @a.b.c
|
@@ -152,17 +140,19 @@ module MinitestToRspec
|
|
152
140
|
end
|
153
141
|
|
154
142
|
def receiver_chain_include?(method_name)
|
155
|
-
receiver_chain.compact.any? { |r|
|
143
|
+
receiver_chain.compact.any? { |r|
|
144
|
+
self.class.method_name?(r, method_name)
|
145
|
+
}
|
156
146
|
end
|
157
147
|
|
158
148
|
def require_test_helper?
|
159
149
|
method_name == :require &&
|
160
150
|
one_string_argument? &&
|
161
|
-
arguments[0][1] ==
|
151
|
+
arguments[0][1] == 'test_helper'
|
162
152
|
end
|
163
153
|
|
164
154
|
def question_mark_method?
|
165
|
-
method_name.to_s.end_with?(
|
155
|
+
method_name.to_s.end_with?('?')
|
166
156
|
end
|
167
157
|
|
168
158
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative 'base'
|
4
4
|
|
5
5
|
module MinitestToRspec
|
6
6
|
module Model
|
@@ -13,15 +13,15 @@ module MinitestToRspec
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def action_controller_test_case?
|
16
|
-
lineage?(parent, [
|
16
|
+
lineage?(parent, %i[ActionController TestCase])
|
17
17
|
end
|
18
18
|
|
19
19
|
def action_mailer_test_case?
|
20
|
-
lineage?(parent, [
|
20
|
+
lineage?(parent, %i[ActionMailer TestCase])
|
21
21
|
end
|
22
22
|
|
23
23
|
def active_support_test_case?
|
24
|
-
lineage?(parent, [
|
24
|
+
lineage?(parent, %i[ActiveSupport TestCase])
|
25
25
|
end
|
26
26
|
|
27
27
|
# Raise an error if we don't know now to process the name
|
@@ -45,7 +45,7 @@ module MinitestToRspec
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def draper_test_case?
|
48
|
-
lineage?(parent, [
|
48
|
+
lineage?(parent, %i[Draper TestCase])
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns the name of the class. Examples:
|
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require_relative
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
3
|
+
require 'ruby_parser'
|
4
|
+
require 'sexp_processor'
|
5
|
+
require_relative 'subprocessors/call'
|
6
|
+
require_relative 'subprocessors/defn'
|
7
|
+
require_relative 'subprocessors/klass'
|
8
|
+
require_relative 'subprocessors/iter'
|
9
9
|
|
10
10
|
module MinitestToRspec
|
11
11
|
# Consumes a `String` of minitest code and returns an S-expression
|
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require_relative
|
6
|
-
require_relative
|
3
|
+
require 'minitest_to_rspec/type'
|
4
|
+
require 'minitest_to_rspec/expression_builders/stub'
|
5
|
+
require_relative '../model/call'
|
6
|
+
require_relative '../model/hash_exp'
|
7
|
+
require_relative 'base'
|
7
8
|
|
8
9
|
module MinitestToRspec
|
9
10
|
module Subprocessors
|
@@ -166,9 +167,21 @@ module MinitestToRspec
|
|
166
167
|
expect_to_not(eq(unexpected), calculated, true)
|
167
168
|
end
|
168
169
|
|
170
|
+
# Processes an entire line of code that ends in `.returns`
|
169
171
|
def method_returns
|
170
|
-
|
171
|
-
|
172
|
+
receiver = mocha_stub_receiver(@exp)
|
173
|
+
any_instance = rspec_any_instance?(@exp)
|
174
|
+
message_call = mocha_stub_expects(@exp)
|
175
|
+
message = message_call.arguments.first
|
176
|
+
with = mocha_stub_with(@exp)
|
177
|
+
returns = @exp.arguments.first
|
178
|
+
count = message_call.method_name == :expects ? 1 : nil
|
179
|
+
ExpressionBuilders::Stub.new(
|
180
|
+
receiver, any_instance, message, with, returns, count
|
181
|
+
).to_rspec_exp
|
182
|
+
rescue StandardError
|
183
|
+
# TODO: We used to have an `UnknownVariant` error.
|
184
|
+
# That was nice and specific.
|
172
185
|
@exp.original
|
173
186
|
end
|
174
187
|
|
@@ -180,6 +193,10 @@ module MinitestToRspec
|
|
180
193
|
end
|
181
194
|
end
|
182
195
|
|
196
|
+
def method_should
|
197
|
+
s(:call, nil, :it, *@exp.arguments)
|
198
|
+
end
|
199
|
+
|
183
200
|
# Happily, the no-block signatures of [stub][3] are the
|
184
201
|
# same as [double][2].
|
185
202
|
#
|
@@ -200,7 +217,7 @@ module MinitestToRspec
|
|
200
217
|
def method_stub_everything
|
201
218
|
if @exp.receiver.nil?
|
202
219
|
d = s(:call, nil, :double, *@exp.arguments)
|
203
|
-
s(:call, d, :as_null_object
|
220
|
+
s(:call, d, :as_null_object)
|
204
221
|
else
|
205
222
|
@exp.original
|
206
223
|
end
|
@@ -236,35 +253,50 @@ module MinitestToRspec
|
|
236
253
|
expect_to(receive_and_call_original(lit_sexp), exp.receiver, true)
|
237
254
|
end
|
238
255
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
256
|
+
# TODO: add support for
|
257
|
+
# - at_least
|
258
|
+
# - at_least_once
|
259
|
+
# - at_most
|
260
|
+
# - at_most_once
|
261
|
+
# - never
|
262
|
+
def mocha_expectation_count(exp, count)
|
263
|
+
Type.assert(Model::Call, exp)
|
264
|
+
Type.assert(Integer, count)
|
265
|
+
receiver = mocha_stub_receiver(exp)
|
266
|
+
any_instance = rspec_any_instance?(exp)
|
267
|
+
message = mocha_stub_expects(exp).arguments.first
|
268
|
+
with = mocha_stub_with(exp)
|
269
|
+
returns = exp.find_call_in_receiver_chain(:returns)&.arguments&.first
|
270
|
+
ExpressionBuilders::Stub.new(
|
271
|
+
receiver, any_instance, message, with, returns, count
|
272
|
+
).to_rspec_exp
|
273
|
+
end
|
274
|
+
|
275
|
+
# Given a mocha stub, e.g. `X.any_instance.expects(:y)`, returns `X`.
|
276
|
+
def mocha_stub_receiver(exp)
|
277
|
+
chain = exp.receiver_chain
|
278
|
+
last = chain[-1]
|
279
|
+
last.nil? ? chain[-2] : last
|
280
|
+
end
|
281
|
+
|
282
|
+
# Given an `exp` representing a chain of calls, like
|
283
|
+
# `stubs(x).returns(y).once`, finds the call to `stubs` or `expects`.
|
284
|
+
def mocha_stub_expects(exp)
|
285
|
+
exp.find_call_in_receiver_chain(%i[stubs expects])
|
286
|
+
end
|
287
|
+
|
288
|
+
def mocha_stub_with(exp)
|
289
|
+
exp.find_call_in_receiver_chain(:with)&.arguments&.first
|
290
|
+
end
|
291
|
+
|
292
|
+
def rspec_any_instance?(exp)
|
293
|
+
exp.calls_in_receiver_chain.any? { |i|
|
294
|
+
i.method_name.to_s.include?('any_instance')
|
295
|
+
}
|
250
296
|
end
|
251
297
|
|
252
298
|
def mocha_once(exp)
|
253
|
-
mocha_expectation_count(exp,
|
254
|
-
end
|
255
|
-
|
256
|
-
# Given `r`, a `Model::Calls::Returns`, return a `Sexp` representing
|
257
|
-
# the equivalent stub or message expectation in RSpec.
|
258
|
-
def mocha_returns(r)
|
259
|
-
raise ArgumentError unless r.is_a?(Model::Calls::Returns)
|
260
|
-
subprocessor_method = "#{r.rspec_mocks_method}_receive_and_return"
|
261
|
-
send(subprocessor_method,
|
262
|
-
r.rspec_msg_recipient,
|
263
|
-
r.message,
|
264
|
-
r.values,
|
265
|
-
r.any_instance?,
|
266
|
-
r.with
|
267
|
-
)
|
299
|
+
mocha_expectation_count(exp, 1)
|
268
300
|
end
|
269
301
|
|
270
302
|
def mocha_stub(exp)
|
@@ -277,7 +309,7 @@ module MinitestToRspec
|
|
277
309
|
end
|
278
310
|
|
279
311
|
def mocha_twice(exp)
|
280
|
-
mocha_expectation_count(exp,
|
312
|
+
mocha_expectation_count(exp, 2)
|
281
313
|
end
|
282
314
|
|
283
315
|
def name_of_processing_method
|
@@ -307,7 +339,7 @@ module MinitestToRspec
|
|
307
339
|
s(:call, nil, :lambda),
|
308
340
|
0,
|
309
341
|
s(:block,
|
310
|
-
s(:str,
|
342
|
+
s(:str, 'Sorry for the pointless lambda here.'),
|
311
343
|
*array_of_calls
|
312
344
|
)
|
313
345
|
),
|
@@ -341,7 +373,7 @@ module MinitestToRspec
|
|
341
373
|
end
|
342
374
|
|
343
375
|
def require_spec_helper
|
344
|
-
prefix = @rails ?
|
376
|
+
prefix = @rails ? 'rails' : 'spec'
|
345
377
|
s(:call, nil, :require, s(:str, "#{prefix}_helper"))
|
346
378
|
end
|
347
379
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
5
|
-
require_relative
|
3
|
+
require_relative '../errors'
|
4
|
+
require_relative '../model/klass'
|
5
|
+
require_relative 'base'
|
6
6
|
|
7
7
|
module MinitestToRspec
|
8
8
|
module Subprocessors
|
@@ -39,7 +39,7 @@ module MinitestToRspec
|
|
39
39
|
# Given a `test_class_name` like `BananaTest`, returns the
|
40
40
|
# described class, like `Banana`.
|
41
41
|
def described_class(test_class_name)
|
42
|
-
test_class_name.to_s.gsub(/Test\Z/,
|
42
|
+
test_class_name.to_s.gsub(/Test\Z/, '').to_sym
|
43
43
|
end
|
44
44
|
|
45
45
|
# Returns the head of the output Sexp. If it's a test case,
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MinitestToRspec
|
4
|
+
# Runtime type assertion function.
|
5
|
+
module Type
|
6
|
+
class << self
|
7
|
+
def assert(types, value)
|
8
|
+
unless array_wrap(types).any? { |t| value.is_a?(t) }
|
9
|
+
raise TypeError, "Expected #{types}, got #{value}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def bool(value)
|
14
|
+
unless [false, true].include?(value)
|
15
|
+
raise TypeError, "Expected Boolean, got #{value}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Implementation copied from Array.wrap in ActiveSupport 5
|
22
|
+
def array_wrap(object)
|
23
|
+
if object.nil?
|
24
|
+
[]
|
25
|
+
elsif object.respond_to?(:to_ary)
|
26
|
+
object.to_ary || [object]
|
27
|
+
else
|
28
|
+
[object]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/minitest_to_rspec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'minitest_to_rspec/version'
|
4
|
+
require 'minitest_to_rspec/converter'
|
5
5
|
|
6
6
|
# A command-line tool for converting minitest files to rspec.
|
7
7
|
module MinitestToRspec
|
data/minitest_to_rspec.gemspec
CHANGED
@@ -5,32 +5,32 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'minitest_to_rspec/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
8
|
+
spec.name = 'minitest_to_rspec'
|
9
9
|
spec.version = MinitestToRspec::VERSION
|
10
10
|
spec.executables << 'mt2rspec'
|
11
|
-
spec.authors = [
|
12
|
-
spec.email = [
|
11
|
+
spec.authors = ['Jared Beck']
|
12
|
+
spec.email = ['jared@jaredbeck.com']
|
13
13
|
|
14
|
-
spec.summary =
|
14
|
+
spec.summary = 'Converts minitest files to rspec'
|
15
15
|
spec.description = <<~EOS
|
16
16
|
A command-line tool for converting minitest files to rspec.
|
17
17
|
EOS
|
18
|
-
spec.homepage =
|
19
|
-
spec.license =
|
18
|
+
spec.homepage = 'https://github.com/jaredbeck/minitest_to_rspec'
|
19
|
+
spec.license = 'MIT'
|
20
20
|
|
21
21
|
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
22
22
|
f.match(%r{^(test|spec|features)/})
|
23
23
|
}
|
24
|
-
spec.require_paths = [
|
25
|
-
spec.required_ruby_version =
|
24
|
+
spec.require_paths = ['lib']
|
25
|
+
spec.required_ruby_version = '>= 2.3.0'
|
26
26
|
|
27
|
-
spec.add_runtime_dependency
|
28
|
-
spec.add_runtime_dependency
|
29
|
-
spec.add_runtime_dependency
|
27
|
+
spec.add_runtime_dependency 'ruby2ruby', '~> 2.3'
|
28
|
+
spec.add_runtime_dependency 'ruby_parser', '~> 3.8'
|
29
|
+
spec.add_runtime_dependency 'trollop', '~> 2.1'
|
30
30
|
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
32
|
+
spec.add_development_dependency 'byebug', '~> 9.1'
|
33
|
+
spec.add_development_dependency 'rake', '~> 12.1'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.5'
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.51.0'
|
36
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest_to_rspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jared Beck
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby2ruby
|
@@ -134,7 +134,6 @@ extra_rdoc_files: []
|
|
134
134
|
files:
|
135
135
|
- ".gitignore"
|
136
136
|
- ".rubocop.yml"
|
137
|
-
- ".rubocop_todo.yml"
|
138
137
|
- ".travis.yml"
|
139
138
|
- CHANGELOG.md
|
140
139
|
- CODE_OF_CONDUCT.md
|
@@ -145,16 +144,17 @@ files:
|
|
145
144
|
- bin/console
|
146
145
|
- bin/mt2rspec
|
147
146
|
- doc/minitest.md
|
147
|
+
- doc/mocha/mocha_test.rb
|
148
148
|
- doc/rspec.md
|
149
149
|
- doc/supported_assertions.md
|
150
150
|
- lib/minitest_to_rspec.rb
|
151
151
|
- lib/minitest_to_rspec/cli.rb
|
152
152
|
- lib/minitest_to_rspec/converter.rb
|
153
153
|
- lib/minitest_to_rspec/errors.rb
|
154
|
+
- lib/minitest_to_rspec/expression_builders/stub.rb
|
154
155
|
- lib/minitest_to_rspec/model/base.rb
|
155
156
|
- lib/minitest_to_rspec/model/call.rb
|
156
157
|
- lib/minitest_to_rspec/model/calls/once.rb
|
157
|
-
- lib/minitest_to_rspec/model/calls/returns.rb
|
158
158
|
- lib/minitest_to_rspec/model/calls/twice.rb
|
159
159
|
- lib/minitest_to_rspec/model/defn.rb
|
160
160
|
- lib/minitest_to_rspec/model/hash_exp.rb
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- lib/minitest_to_rspec/subprocessors/defn.rb
|
168
168
|
- lib/minitest_to_rspec/subprocessors/iter.rb
|
169
169
|
- lib/minitest_to_rspec/subprocessors/klass.rb
|
170
|
+
- lib/minitest_to_rspec/type.rb
|
170
171
|
- lib/minitest_to_rspec/version.rb
|
171
172
|
- minitest_to_rspec.gemspec
|
172
173
|
homepage: https://github.com/jaredbeck/minitest_to_rspec
|
data/.rubocop_todo.yml
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
# `rubocop --auto-gen-config`
|
3
|
-
# on 2017-11-01 23:47:55 -0400 using RuboCop version 0.51.0.
|
4
|
-
# The point is for the user to remove these configuration records
|
5
|
-
# one by one as the offenses are removed from the code base.
|
6
|
-
# Note that changes in the inspected code, or installation of new
|
7
|
-
# versions of RuboCop, may require this file to be generated again.
|
8
|
-
|
9
|
-
# Offense count: 5
|
10
|
-
# Cop supports --auto-correct.
|
11
|
-
Style/RedundantFreeze:
|
12
|
-
Exclude:
|
13
|
-
- 'lib/minitest_to_rspec/cli.rb'
|
14
|
-
|
15
|
-
# Offense count: 1
|
16
|
-
# Cop supports --auto-correct.
|
17
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
18
|
-
# SupportedStyles: only_raise, only_fail, semantic
|
19
|
-
Style/SignalException:
|
20
|
-
Exclude:
|
21
|
-
- 'spec/lib/cli_spec.rb'
|
22
|
-
|
23
|
-
# Offense count: 5
|
24
|
-
# Cop supports --auto-correct.
|
25
|
-
Style/StderrPuts:
|
26
|
-
Exclude:
|
27
|
-
- 'lib/minitest_to_rspec/cli.rb'
|
28
|
-
|
29
|
-
# Offense count: 340
|
30
|
-
# Cop supports --auto-correct.
|
31
|
-
# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline.
|
32
|
-
# SupportedStyles: single_quotes, double_quotes
|
33
|
-
Style/StringLiterals:
|
34
|
-
Enabled: false
|
35
|
-
|
36
|
-
# Offense count: 8
|
37
|
-
# Cop supports --auto-correct.
|
38
|
-
# Configuration parameters: SupportedStyles.
|
39
|
-
# SupportedStyles: percent, brackets
|
40
|
-
Style/SymbolArray:
|
41
|
-
EnforcedStyle: percent
|
42
|
-
MinSize: 3
|
43
|
-
|
44
|
-
# Offense count: 1
|
45
|
-
# Cop supports --auto-correct.
|
46
|
-
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
|
47
|
-
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
|
48
|
-
Style/TrailingCommaInArguments:
|
49
|
-
Exclude:
|
50
|
-
- 'lib/minitest_to_rspec/subprocessors/call.rb'
|
51
|
-
|
52
|
-
# Offense count: 1
|
53
|
-
# Cop supports --auto-correct.
|
54
|
-
# Configuration parameters: MaxLineLength.
|
55
|
-
Style/WhileUntilModifier:
|
56
|
-
Exclude:
|
57
|
-
- 'lib/minitest_to_rspec/subprocessors/iter.rb'
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "../call"
|
4
|
-
require_relative "../../errors"
|
5
|
-
|
6
|
-
module MinitestToRspec
|
7
|
-
module Model
|
8
|
-
module Calls
|
9
|
-
# Represents a call to `returns`, the stubbing method
|
10
|
-
# from `mocha`.
|
11
|
-
class Returns < Call
|
12
|
-
KNOWN_RECEIVERS = %i[stubs expects with].freeze
|
13
|
-
|
14
|
-
def initialize(exp)
|
15
|
-
@exp = exp
|
16
|
-
raise UnknownVariant unless known_variant?
|
17
|
-
end
|
18
|
-
|
19
|
-
def stub?
|
20
|
-
receiver_chain_include?(:stubs)
|
21
|
-
end
|
22
|
-
|
23
|
-
def any_instance?
|
24
|
-
receiver_chain_include?(:any_instance)
|
25
|
-
end
|
26
|
-
|
27
|
-
def expectation?
|
28
|
-
receiver_chain_include?(:expects)
|
29
|
-
end
|
30
|
-
|
31
|
-
def known_variant?
|
32
|
-
r = receiver
|
33
|
-
!r.nil? &&
|
34
|
-
r.sexp_type == :call &&
|
35
|
-
KNOWN_RECEIVERS.include?(Call.new(r).method_name) &&
|
36
|
-
!values.empty? &&
|
37
|
-
message.sexp_type == :lit
|
38
|
-
end
|
39
|
-
|
40
|
-
def message
|
41
|
-
calls_in_receiver_chain
|
42
|
-
.find { |c| [:stubs, :expects].include? c.method_name }
|
43
|
-
.arguments[0]
|
44
|
-
end
|
45
|
-
|
46
|
-
# To avoid a `ProcessingError` please check `known_variant?`
|
47
|
-
# before calling `rspec_mocks_method`.
|
48
|
-
def rspec_mocks_method
|
49
|
-
s = stub?
|
50
|
-
e = expectation?
|
51
|
-
if s && e
|
52
|
-
raise ProcessingError, "Method chain contains stubs and expects"
|
53
|
-
elsif s
|
54
|
-
:allow
|
55
|
-
elsif e
|
56
|
-
:expect
|
57
|
-
else
|
58
|
-
raise ProcessingError, "Found returns without stubs or expects"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
# Returns `Sexp` representing the object that will receive
|
63
|
-
# the stubbed message. Examples:
|
64
|
-
#
|
65
|
-
# banana.stubs(:delicious?).returns(true)
|
66
|
-
# Kiwi.any_instance.stubs(:delicious?).returns(false)
|
67
|
-
#
|
68
|
-
# On the first line, the `rspec_msg_recipient` is `banana`. On the
|
69
|
-
# second, `Kiwi`.
|
70
|
-
#
|
71
|
-
def rspec_msg_recipient
|
72
|
-
receiver_chain.compact.last
|
73
|
-
end
|
74
|
-
|
75
|
-
# The return values
|
76
|
-
def values
|
77
|
-
arguments
|
78
|
-
end
|
79
|
-
|
80
|
-
def with
|
81
|
-
w = calls_in_receiver_chain.find { |c| c.method_name == :with }
|
82
|
-
w.nil? ? [] : w.arguments
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|