minitest_to_rspec 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +25 -15
- data/lib/minitest_to_rspec/cli.rb +25 -20
- data/lib/minitest_to_rspec/converter.rb +10 -7
- data/lib/minitest_to_rspec/{exp → model}/base.rb +1 -1
- data/lib/minitest_to_rspec/{exp → model}/call.rb +52 -5
- data/lib/minitest_to_rspec/{exp → model}/calls/once.rb +1 -1
- data/lib/minitest_to_rspec/{exp → model}/calls/returns.rb +31 -16
- data/lib/minitest_to_rspec/{exp → model}/calls/twice.rb +1 -1
- data/lib/minitest_to_rspec/{exp → model}/hash_exp.rb +1 -1
- data/lib/minitest_to_rspec/{exp → model}/iter.rb +9 -9
- data/lib/minitest_to_rspec/{exp → model}/klass.rb +1 -1
- data/lib/minitest_to_rspec/processor.rb +5 -4
- data/lib/minitest_to_rspec/subprocessors/base.rb +6 -1
- data/lib/minitest_to_rspec/subprocessors/call.rb +78 -27
- data/lib/minitest_to_rspec/subprocessors/iter.rb +5 -4
- data/lib/minitest_to_rspec/subprocessors/klass.rb +4 -4
- data/lib/minitest_to_rspec/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5b86085638913b9300eac531234df1080da30f8
|
4
|
+
data.tar.gz: 25716e1fa38dd1770ecf4d6af06d1ae17e83f9b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f77f05e827b8a7ccf6670bd10f3ff595199b19be8398035377c3efad2ded7f251b188a5ba0a0d443abc7d78debcfab986a17b001afc2b653a9ee7ee9d1a51ba
|
7
|
+
data.tar.gz: 602e936f4681ccb800f950185d8fb970299531a5616346a72b7f2a49c80e21aedf8168aa1aff1f87e36e2eafee9c45a59e54919a8e2985178236e853d63d858e
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,27 @@ Change Log
|
|
4
4
|
This project follows [semver 2.0.0][1] and the recommendations
|
5
5
|
of [keepachangelog.com][2].
|
6
6
|
|
7
|
+
0.7.0
|
8
|
+
-----
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
- `assert` on a question-mark method converts to `eq(true)` instead
|
12
|
+
of `be_truthy`. Likewise, `refute` converts to `eq(false)`. This is not
|
13
|
+
guaranteed to be the same as minitest's fuzzy `assert`, but the convention of
|
14
|
+
question-mark methods returning real booleans is strong.
|
15
|
+
|
16
|
+
### Added
|
17
|
+
- Converts assert_not_nil
|
18
|
+
- CLI
|
19
|
+
- Added `--mocha` flag. If present, converts mocha to
|
20
|
+
rspec-mocks. (Experimental)
|
21
|
+
- Creates `target_file` directory if it does not exist
|
22
|
+
- Experimental
|
23
|
+
- mocha: with
|
24
|
+
|
25
|
+
### Fixed
|
26
|
+
- `__FILE__` keyword in input
|
27
|
+
|
7
28
|
0.6.2
|
8
29
|
-----
|
9
30
|
|
data/README.md
CHANGED
@@ -7,6 +7,7 @@ Converts [minitest][8] files to [rspec][9].
|
|
7
7
|
- Selected assertions from [Test::Unit][26], [minitest][8],
|
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
|
+
(Experimental)
|
10
11
|
|
11
12
|
Example
|
12
13
|
-------
|
@@ -28,26 +29,22 @@ end
|
|
28
29
|
Output:
|
29
30
|
|
30
31
|
```ruby
|
31
|
-
require
|
32
|
-
RSpec.describe
|
33
|
-
it
|
32
|
+
require "spec_helper"
|
33
|
+
RSpec.describe Array do
|
34
|
+
it "changes length" do
|
34
35
|
ary = []
|
35
|
-
expect { ary.push(:x) }.to
|
36
|
+
expect { ary.push(:x) }.to change { ary.length }
|
36
37
|
end
|
37
38
|
end
|
38
39
|
```
|
39
40
|
|
40
|
-
The code style is whatever [ruby2ruby][6] feels like printing,
|
41
|
-
and is not configurable. Comments are discarded.
|
42
|
-
|
43
41
|
Usage
|
44
42
|
-----
|
45
43
|
|
46
44
|
### CLI
|
47
45
|
|
48
46
|
```bash
|
49
|
-
|
50
|
-
bundle exec mt2rspec [--rails] source_file [target_file]
|
47
|
+
bundle exec mt2rspec [--rails] [--mocha] source_file [target_file]
|
51
48
|
bundle exec mt2rspec --help
|
52
49
|
```
|
53
50
|
|
@@ -55,16 +52,28 @@ bundle exec mt2rspec --help
|
|
55
52
|
|
56
53
|
```ruby
|
57
54
|
require 'minitest_to_rspec'
|
58
|
-
MinitestToRspec::Converter.new
|
55
|
+
converter = MinitestToRspec::Converter.new(rails: false, mocha: false)
|
56
|
+
converter.convert("assert('banana')")
|
59
57
|
#=> "expect(\"banana\").to(be_truthy)"
|
60
58
|
```
|
61
59
|
|
60
|
+
Output
|
61
|
+
------
|
62
|
+
|
63
|
+
The primary goal is correctness, but [code style][34] is also important. To
|
64
|
+
allow us to configure our output, we use [sexp2ruby][33] instead of
|
65
|
+
[ruby2ruby][6]. As [sexp2ruby][33] adds more configuration options, we'll make
|
66
|
+
use of them.
|
67
|
+
|
68
|
+
Comments are discarded by [ruby_parser][14], so we have no way of
|
69
|
+
preserving them.
|
70
|
+
|
62
71
|
Supported Assertions
|
63
72
|
--------------------
|
64
73
|
|
65
|
-
Selected assertions from minitest, Test::Unit, and
|
66
|
-
See [doc/supported_assertions.md][5] for rationale.
|
67
|
-
are welcome.
|
74
|
+
Selected assertions from [minitest][8], [Test::Unit][26], and
|
75
|
+
[ActiveSupport][27]. See [doc/supported_assertions.md][5] for rationale.
|
76
|
+
Contributions are welcome.
|
68
77
|
|
69
78
|
Assertion | Arity | Source
|
70
79
|
--------------------------- | ----- | ------
|
@@ -74,6 +83,7 @@ assert_difference | 1,2 |
|
|
74
83
|
[assert_not_equal][22] | 2,3 | Test::Unit
|
75
84
|
assert_match | |
|
76
85
|
assert_nil | |
|
86
|
+
assert_not_nil | |
|
77
87
|
[assert_no_difference][12] | | ActiveSupport
|
78
88
|
[assert_nothing_raised][10] | | Test::Unit
|
79
89
|
[assert_raise][11] | 0..2 | Test::Unit
|
@@ -81,8 +91,6 @@ assert_nil | |
|
|
81
91
|
refute | |
|
82
92
|
refute_equal | |
|
83
93
|
|
84
|
-
To do: assert_not_nil
|
85
|
-
|
86
94
|
Supported Mocha
|
87
95
|
---------------
|
88
96
|
|
@@ -136,3 +144,5 @@ This project would not be possible without [ruby_parser][14],
|
|
136
144
|
[30]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation
|
137
145
|
[31]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation#once-instance_method
|
138
146
|
[32]: http://www.rubydoc.info/github/floehopper/mocha/Mocha/Expectation#twice-instance_method
|
147
|
+
[33]: https://github.com/jaredbeck/sexp2ruby
|
148
|
+
[34]: https://github.com/bbatsov/ruby-style-guide
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "fileutils"
|
1
2
|
require "minitest_to_rspec"
|
2
3
|
require "trollop"
|
3
4
|
|
@@ -7,34 +8,36 @@ module MinitestToRspec
|
|
7
8
|
E_FILE_NOT_FOUND = 2.freeze
|
8
9
|
E_FILE_ALREADY_EXISTS = 3.freeze
|
9
10
|
E_CONVERT_FAIL = 4.freeze
|
11
|
+
E_CANNOT_CREATE_TARGET_DIR = 5.freeze
|
10
12
|
|
11
13
|
BANNER = <<EOS.freeze
|
12
|
-
Usage: mt2rspec --rails source_file [target_file]
|
14
|
+
Usage: mt2rspec [--rails] [--mocha] source_file [target_file]
|
13
15
|
|
14
|
-
Reads source_file, writes target_file.
|
15
|
-
its location will be inferred.
|
16
|
-
implies spec/fruit/banana_spec.rb.
|
16
|
+
Reads source_file, writes target_file. If target_file is omitted,
|
17
|
+
its location will be inferred. For example, test/fruit/banana_test.rb
|
18
|
+
implies spec/fruit/banana_spec.rb. If the target directory doesn't
|
19
|
+
exist, it will be created.
|
17
20
|
|
18
21
|
Options:
|
19
22
|
EOS
|
20
|
-
|
23
|
+
OPT_MOCHA = "Convert mocha to rspec-mocks. (Experimental)"
|
21
24
|
OPT_RAILS = <<EOS.gsub(/\n/, " ").freeze
|
22
25
|
Requires rails_helper instead of spec_helper.
|
23
26
|
Passes :type metadatum to RSpec.describe.
|
24
27
|
EOS
|
25
28
|
|
26
|
-
attr_reader :
|
29
|
+
attr_reader :source, :target
|
27
30
|
|
28
31
|
def initialize(args)
|
29
|
-
assert_trollop_version
|
30
|
-
|
31
32
|
opts = Trollop.options(args) do
|
32
33
|
version MinitestToRspec::VERSION
|
33
34
|
banner BANNER
|
34
35
|
opt :rails, OPT_RAILS, short: :none
|
36
|
+
opt :mocha, OPT_MOCHA, short: :none
|
35
37
|
end
|
36
38
|
|
37
39
|
@rails = opts[:rails]
|
40
|
+
@mocha = opts[:mocha]
|
38
41
|
case args.length
|
39
42
|
when 2
|
40
43
|
@source, @target = args
|
@@ -50,7 +53,8 @@ EOS
|
|
50
53
|
def run
|
51
54
|
assert_file_exists(source)
|
52
55
|
assert_file_does_not_exist(target)
|
53
|
-
|
56
|
+
ensure_target_directory(target)
|
57
|
+
write_target(converter.convert(read_source, source))
|
54
58
|
rescue Error => e
|
55
59
|
$stderr.puts "Failed to convert: #{e}"
|
56
60
|
exit E_CONVERT_FAIL
|
@@ -72,19 +76,20 @@ EOS
|
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
75
|
-
|
76
|
-
|
77
|
-
unless Trollop.method(:die).arity == -2
|
78
|
-
warn "Please use trollop version f7009b45 or greater."
|
79
|
-
warn "This manual version constraint will be removed when"
|
80
|
-
warn "https://github.com/ManageIQ/trollop/pull/63"
|
81
|
-
warn "is included in an official trollop release."
|
82
|
-
exit(-1)
|
83
|
-
end
|
79
|
+
def converter
|
80
|
+
Converter.new(mocha: @mocha, rails: @rails)
|
84
81
|
end
|
85
82
|
|
86
|
-
def
|
87
|
-
|
83
|
+
def ensure_target_directory(target)
|
84
|
+
dir = File.dirname(target)
|
85
|
+
return if Dir.exist?(dir)
|
86
|
+
begin
|
87
|
+
FileUtils.mkdir_p(dir)
|
88
|
+
rescue SystemCallError => e
|
89
|
+
$stderr.puts "Cannot create target dir: #{dir}"
|
90
|
+
$stderr.puts e.message
|
91
|
+
exit E_CANNOT_CREATE_TARGET_DIR
|
92
|
+
end
|
88
93
|
end
|
89
94
|
|
90
95
|
def infer_target_from(source)
|
@@ -19,21 +19,24 @@ module MinitestToRspec
|
|
19
19
|
to_not
|
20
20
|
]
|
21
21
|
|
22
|
-
def initialize(
|
23
|
-
@
|
24
|
-
@processor = Processor.new(@options[:rails])
|
22
|
+
def initialize(rails: false, mocha: false)
|
23
|
+
@processor = Processor.new(rails, mocha)
|
25
24
|
end
|
26
25
|
|
27
|
-
|
28
|
-
|
26
|
+
# - `input` - Contents of a ruby file.
|
27
|
+
# - `file_path` - Optional. Value will replace any `__FILE__`
|
28
|
+
# keywords in the input.
|
29
|
+
def convert(input, file_path = nil)
|
30
|
+
render process parse(input, file_path)
|
29
31
|
end
|
30
32
|
|
31
33
|
private
|
32
34
|
|
33
35
|
# Parses input string and returns Abstract Syntax Tree (AST)
|
34
36
|
# as an S-expression.
|
35
|
-
def parse(input)
|
36
|
-
|
37
|
+
def parse(input, file_path)
|
38
|
+
file_path ||= "No file path provided to #{self.class}#convert"
|
39
|
+
RubyParser.new.parse(input, file_path)
|
37
40
|
end
|
38
41
|
|
39
42
|
# Processes an AST (S-expressions) representing a minitest
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "base"
|
2
2
|
|
3
3
|
module MinitestToRspec
|
4
|
-
module
|
4
|
+
module Model
|
5
5
|
|
6
6
|
# Data object. Represents a `:call` s-expression.
|
7
7
|
class Call < Base
|
@@ -35,7 +35,7 @@ module MinitestToRspec
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def method_name?(exp, name)
|
38
|
-
exp.sexp_type == :call && new(exp).method_name == name
|
38
|
+
exp.sexp_type == :call && new(exp).method_name.to_s == name.to_s
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -70,6 +70,13 @@ module MinitestToRspec
|
|
70
70
|
method_name == :assert_raises && raise_error_args?
|
71
71
|
end
|
72
72
|
|
73
|
+
def calls_in_receiver_chain
|
74
|
+
receiver_chain.
|
75
|
+
compact.
|
76
|
+
select { |r| sexp_type?(:call, r) }.
|
77
|
+
map { |r| Call.new(r) }
|
78
|
+
end
|
79
|
+
|
73
80
|
def method_name
|
74
81
|
@exp[2]
|
75
82
|
end
|
@@ -95,14 +102,14 @@ module MinitestToRspec
|
|
95
102
|
end
|
96
103
|
|
97
104
|
# While `#receiver` returns a `Sexp`, `#receiver_call`
|
98
|
-
# returns a `
|
105
|
+
# returns a `Model::Call`.
|
99
106
|
def receiver_call
|
100
107
|
if sexp_type?(:call, receiver)
|
101
|
-
rvc =
|
108
|
+
rvc = Model::Call.new(receiver)
|
102
109
|
|
103
110
|
# TODO: Seems like a factory pattern
|
104
111
|
if rvc.method_name == :returns
|
105
|
-
|
112
|
+
Model::Calls::Returns.new(receiver)
|
106
113
|
else
|
107
114
|
rvc
|
108
115
|
end
|
@@ -111,12 +118,52 @@ module MinitestToRspec
|
|
111
118
|
end
|
112
119
|
end
|
113
120
|
|
121
|
+
# Consider the following chain of method calls:
|
122
|
+
#
|
123
|
+
# @a.b.c
|
124
|
+
#
|
125
|
+
# whose S-expression is
|
126
|
+
#
|
127
|
+
# s(:call, s(:call, s(:call, nil, :a), :b), :c)
|
128
|
+
#
|
129
|
+
# the "receiver chain" is
|
130
|
+
#
|
131
|
+
# [
|
132
|
+
# s(:call, s(:call, nil, :a), :b),
|
133
|
+
# s(:call, nil, :a),
|
134
|
+
# nil
|
135
|
+
# ]
|
136
|
+
#
|
137
|
+
# The order of the returned array matches the order in which
|
138
|
+
# messages are received, i.e. the order of execution.
|
139
|
+
#
|
140
|
+
# Note that the final receiver `nil` is included. This `nil`
|
141
|
+
# represents the implicit receiver, e.g. `self` or `main`.
|
142
|
+
#
|
143
|
+
def receiver_chain
|
144
|
+
receivers = []
|
145
|
+
ptr = @exp
|
146
|
+
while sexp_type?(:call, ptr)
|
147
|
+
receivers << ptr[1]
|
148
|
+
ptr = ptr[1]
|
149
|
+
end
|
150
|
+
receivers
|
151
|
+
end
|
152
|
+
|
153
|
+
def receiver_chain_include?(method_name)
|
154
|
+
receiver_chain.compact.any? { |r| Call.method_name?(r, method_name) }
|
155
|
+
end
|
156
|
+
|
114
157
|
def require_test_helper?
|
115
158
|
method_name == :require &&
|
116
159
|
one_string_argument? &&
|
117
160
|
arguments[0][1] == "test_helper"
|
118
161
|
end
|
119
162
|
|
163
|
+
def question_mark_method?
|
164
|
+
method_name.to_s.end_with?("?")
|
165
|
+
end
|
166
|
+
|
120
167
|
private
|
121
168
|
|
122
169
|
def string?(exp)
|
@@ -2,32 +2,29 @@ require_relative "../call"
|
|
2
2
|
require_relative "../../errors"
|
3
3
|
|
4
4
|
module MinitestToRspec
|
5
|
-
module
|
5
|
+
module Model
|
6
6
|
module Calls
|
7
7
|
|
8
8
|
# Represents a call to `returns`, the stubbing method
|
9
9
|
# from `mocha`.
|
10
10
|
class Returns < Call
|
11
|
-
KNOWN_RECEIVERS = %i[stubs expects]
|
12
|
-
RSPEC_MOCK_METHODS = { expects: :expect, stubs: :allow }
|
11
|
+
KNOWN_RECEIVERS = %i[stubs expects with]
|
13
12
|
|
14
13
|
def initialize(exp)
|
15
14
|
@exp = exp
|
16
15
|
raise UnknownVariant unless known_variant?
|
17
16
|
end
|
18
17
|
|
18
|
+
def stub?
|
19
|
+
receiver_chain_include?(:stubs)
|
20
|
+
end
|
21
|
+
|
19
22
|
def any_instance?
|
20
|
-
|
21
|
-
if !rcr.nil? && sexp_type?(:call, rcr)
|
22
|
-
Call.new(rcr).method_name == :any_instance
|
23
|
-
else
|
24
|
-
false
|
25
|
-
end
|
23
|
+
receiver_chain_include?(:any_instance)
|
26
24
|
end
|
27
25
|
|
28
|
-
|
29
|
-
|
30
|
-
receiver_call.receiver
|
26
|
+
def expectation?
|
27
|
+
receiver_chain_include?(:expects)
|
31
28
|
end
|
32
29
|
|
33
30
|
def known_variant?
|
@@ -40,13 +37,25 @@ module MinitestToRspec
|
|
40
37
|
end
|
41
38
|
|
42
39
|
def message
|
43
|
-
|
40
|
+
calls_in_receiver_chain.
|
41
|
+
find { |c| [:stubs, :expects].include? c.method_name }.
|
42
|
+
arguments[0]
|
44
43
|
end
|
45
44
|
|
46
45
|
# To avoid a `ProcessingError` please check `known_variant?`
|
47
46
|
# before calling `rspec_mocks_method`.
|
48
47
|
def rspec_mocks_method
|
49
|
-
|
48
|
+
s = stub?
|
49
|
+
e = expectation?
|
50
|
+
if s && e
|
51
|
+
raise ProcessingError, "Method chain contains stubs and expects"
|
52
|
+
elsif s
|
53
|
+
:allow
|
54
|
+
elsif e
|
55
|
+
:expect
|
56
|
+
else
|
57
|
+
raise ProcessingError, "Found returns without stubs or expects"
|
58
|
+
end
|
50
59
|
end
|
51
60
|
|
52
61
|
# Returns `Sexp` representing the object that will receive
|
@@ -55,16 +64,22 @@ module MinitestToRspec
|
|
55
64
|
# banana.stubs(:delicious?).returns(true)
|
56
65
|
# Kiwi.any_instance.stubs(:delicious?).returns(false)
|
57
66
|
#
|
58
|
-
#
|
67
|
+
# On the first line, the `rspec_msg_recipient` is `banana`. On the
|
68
|
+
# second, `Kiwi`.
|
59
69
|
#
|
60
70
|
def rspec_msg_recipient
|
61
|
-
|
71
|
+
receiver_chain.compact.last
|
62
72
|
end
|
63
73
|
|
64
74
|
# The return values
|
65
75
|
def values
|
66
76
|
arguments
|
67
77
|
end
|
78
|
+
|
79
|
+
def with
|
80
|
+
w = calls_in_receiver_chain.find { |c| c.method_name == :with }
|
81
|
+
w.nil? ? [] : w.arguments
|
82
|
+
end
|
68
83
|
end
|
69
84
|
end
|
70
85
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require_relative "base"
|
2
2
|
|
3
3
|
module MinitestToRspec
|
4
|
-
module
|
4
|
+
module Model
|
5
5
|
|
6
6
|
# Data object. Represents an `:iter` s-expression.
|
7
7
|
class Iter < Base
|
@@ -15,23 +15,23 @@ module MinitestToRspec
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def assert_difference?
|
18
|
-
!empty? &&
|
18
|
+
!empty? && Model::Call.assert_difference?(@exp[1])
|
19
19
|
end
|
20
20
|
|
21
21
|
def assert_no_difference?
|
22
|
-
!empty? &&
|
22
|
+
!empty? && Model::Call.assert_no_difference?(@exp[1])
|
23
23
|
end
|
24
24
|
|
25
25
|
def assert_nothing_raised?
|
26
|
-
!empty? &&
|
26
|
+
!empty? && Model::Call.assert_nothing_raised?(@exp[1])
|
27
27
|
end
|
28
28
|
|
29
29
|
def assert_raise?
|
30
|
-
!empty? &&
|
30
|
+
!empty? && Model::Call.assert_raise?(@exp[1])
|
31
31
|
end
|
32
32
|
|
33
33
|
def assert_raises?
|
34
|
-
!empty? &&
|
34
|
+
!empty? && Model::Call.assert_raises?(@exp[1])
|
35
35
|
end
|
36
36
|
|
37
37
|
def block
|
@@ -48,7 +48,7 @@ module MinitestToRspec
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def call_obj
|
51
|
-
|
51
|
+
Model::Call.new(call)
|
52
52
|
end
|
53
53
|
|
54
54
|
# Enumerates children, skipping the base `call` and
|
@@ -63,11 +63,11 @@ module MinitestToRspec
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def setup?
|
66
|
-
!empty? &&
|
66
|
+
!empty? && Model::Call.method_name?(@exp[1], :setup)
|
67
67
|
end
|
68
68
|
|
69
69
|
def teardown?
|
70
|
-
!empty? &&
|
70
|
+
!empty? && Model::Call.method_name?(@exp[1], :teardown)
|
71
71
|
end
|
72
72
|
|
73
73
|
def sexp
|
@@ -6,22 +6,23 @@ require_relative "subprocessors/iter"
|
|
6
6
|
|
7
7
|
module MinitestToRspec
|
8
8
|
class Processor < SexpProcessor
|
9
|
-
def initialize(rails)
|
9
|
+
def initialize(rails, mocha)
|
10
10
|
super()
|
11
11
|
self.strict = false
|
12
|
+
@mocha = mocha
|
12
13
|
@rails = rails
|
13
14
|
end
|
14
15
|
|
15
16
|
def process_call(exp)
|
16
|
-
Subprocessors::Call.new(exp, @rails).process
|
17
|
+
Subprocessors::Call.new(exp, @rails, @mocha).process
|
17
18
|
end
|
18
19
|
|
19
20
|
def process_class(exp)
|
20
|
-
Subprocessors::Klass.new(exp, @rails).process
|
21
|
+
Subprocessors::Klass.new(exp, @rails, @mocha).process
|
21
22
|
end
|
22
23
|
|
23
24
|
def process_iter(exp)
|
24
|
-
Subprocessors::Iter.new(exp).process
|
25
|
+
Subprocessors::Iter.new(exp, @rails, @mocha).process
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
@@ -5,6 +5,11 @@ module MinitestToRspec
|
|
5
5
|
class Base
|
6
6
|
include SexpAssertions
|
7
7
|
|
8
|
+
def initialize(rails, mocha)
|
9
|
+
@rails = rails
|
10
|
+
@mocha = mocha
|
11
|
+
end
|
12
|
+
|
8
13
|
# Returns a s-expression representing an rspec-mocks stub.
|
9
14
|
def allow_to(msg_recipient, matcher, any_instance = false)
|
10
15
|
allow_method = any_instance ? :allow_any_instance_of : :allow
|
@@ -64,7 +69,7 @@ module MinitestToRspec
|
|
64
69
|
#
|
65
70
|
# TODO: `full_process` may not be the best name.
|
66
71
|
def full_process(obj)
|
67
|
-
obj.is_a?(Sexp) ? Processor.new(
|
72
|
+
obj.is_a?(Sexp) ? Processor.new(@rails, @mocha).process(obj) : obj
|
68
73
|
end
|
69
74
|
|
70
75
|
def matcher(name, *args)
|
@@ -1,34 +1,57 @@
|
|
1
|
-
require_relative "../
|
2
|
-
require_relative "../
|
3
|
-
require_relative "../
|
1
|
+
require_relative "../model/call"
|
2
|
+
require_relative "../model/calls/returns"
|
3
|
+
require_relative "../model/hash_exp"
|
4
4
|
require_relative "base"
|
5
5
|
|
6
6
|
module MinitestToRspec
|
7
7
|
module Subprocessors
|
8
8
|
class Call < Base
|
9
|
-
|
10
|
-
|
9
|
+
|
10
|
+
# Mocha methods will only be processed if `--mocha` flag was given,
|
11
|
+
# i.e. `mocha` argument in constructor is true.
|
12
|
+
MOCHA_METHODS = %i[
|
13
|
+
expects
|
14
|
+
once
|
15
|
+
returns
|
16
|
+
stub
|
17
|
+
stubs
|
18
|
+
stub_everything
|
19
|
+
twice
|
20
|
+
]
|
21
|
+
|
22
|
+
def initialize(sexp, rails, mocha)
|
23
|
+
super(rails, mocha)
|
24
|
+
@exp = Model::Call.new(sexp)
|
11
25
|
sexp.clear
|
12
|
-
@rails = rails
|
13
26
|
end
|
14
27
|
|
15
|
-
# Given a `
|
28
|
+
# Given a `Model::Call`, returns a `Sexp`
|
16
29
|
def process
|
17
|
-
if
|
30
|
+
if process?
|
18
31
|
send(name_of_processing_method)
|
19
32
|
else
|
20
33
|
@exp.original
|
21
34
|
end
|
22
35
|
end
|
23
36
|
|
37
|
+
def process?
|
38
|
+
respond_to?(name_of_processing_method, true) &&
|
39
|
+
(@mocha || !MOCHA_METHODS.include?(@exp.method_name))
|
40
|
+
end
|
41
|
+
|
24
42
|
private
|
25
43
|
|
26
44
|
# - msg_rcp. Message recipient. The object to be stubbed.
|
27
45
|
# - msg. Message. The name of the stubbed method.
|
28
46
|
# - ret_vals. Return values.
|
29
47
|
# - any_ins. Any instance? True if this is an `any_instance` stub.
|
30
|
-
|
31
|
-
|
48
|
+
# - with. Allowed arguments.
|
49
|
+
def allow_receive_and_return(msg_rcp, msg, ret_vals, any_ins, with)
|
50
|
+
allow_to(
|
51
|
+
msg_rcp,
|
52
|
+
receive_and_return(msg, ret_vals, with),
|
53
|
+
any_ins
|
54
|
+
)
|
32
55
|
end
|
33
56
|
|
34
57
|
# Given `exp`, an S-expression representing an rspec-mocks statement
|
@@ -52,6 +75,10 @@ module MinitestToRspec
|
|
52
75
|
matcher(:be_truthy)
|
53
76
|
end
|
54
77
|
|
78
|
+
def call_to_question_mark?(exp)
|
79
|
+
sexp_type?(:call, exp) && Model::Call.new(exp).question_mark_method?
|
80
|
+
end
|
81
|
+
|
55
82
|
def eq(exp)
|
56
83
|
matcher(:eq, exp)
|
57
84
|
end
|
@@ -60,17 +87,23 @@ module MinitestToRspec
|
|
60
87
|
# - msg. Message. The name of the stubbed method.
|
61
88
|
# - ret_vals. Return values.
|
62
89
|
# - any_ins. Any instance? True if this is an `any_instance` stub.
|
63
|
-
|
64
|
-
|
90
|
+
# - with. Allowed arguments.
|
91
|
+
def expect_receive_and_return(msg_rcp, msg, ret_vals, any_ins, with)
|
92
|
+
expect_to(
|
93
|
+
receive_and_return(msg, ret_vals, with),
|
94
|
+
msg_rcp,
|
95
|
+
true,
|
96
|
+
any_ins
|
97
|
+
)
|
65
98
|
end
|
66
99
|
|
67
100
|
# Given a `Sexp` representing a `Hash` of message expectations,
|
68
101
|
# return an array of `Sexp`, each representing an expectation
|
69
102
|
# in rspec-mocks syntax.
|
70
103
|
def hash_to_expectations(sexp, receiver)
|
71
|
-
|
104
|
+
Model::HashExp.new(sexp).to_h.map { |msg, ret_val|
|
72
105
|
expect_receive_and_return(
|
73
|
-
receiver.deep_clone, msg, wrap_sexp(ret_val)
|
106
|
+
receiver.deep_clone, msg, wrap_sexp(ret_val), false, []
|
74
107
|
)
|
75
108
|
}
|
76
109
|
end
|
@@ -80,7 +113,7 @@ module MinitestToRspec
|
|
80
113
|
end
|
81
114
|
|
82
115
|
def method_assert
|
83
|
-
|
116
|
+
refsert eq(s(:true)), be_truthy
|
84
117
|
end
|
85
118
|
|
86
119
|
def method_assert_equal
|
@@ -99,6 +132,10 @@ module MinitestToRspec
|
|
99
132
|
expect_to(be_nil, @exp.arguments[0], true)
|
100
133
|
end
|
101
134
|
|
135
|
+
def method_assert_not_nil
|
136
|
+
expect_to_not(be_nil, @exp.arguments[0], true)
|
137
|
+
end
|
138
|
+
|
102
139
|
def method_assert_not_equal
|
103
140
|
expected = @exp.arguments[0]
|
104
141
|
calculated = @exp.arguments[1]
|
@@ -118,7 +155,7 @@ module MinitestToRspec
|
|
118
155
|
end
|
119
156
|
|
120
157
|
def method_refute
|
121
|
-
|
158
|
+
refsert eq(s(:false)), be_falsey
|
122
159
|
end
|
123
160
|
|
124
161
|
def method_refute_equal
|
@@ -128,7 +165,7 @@ module MinitestToRspec
|
|
128
165
|
end
|
129
166
|
|
130
167
|
def method_returns
|
131
|
-
mocha_returns(
|
168
|
+
mocha_returns(Model::Calls::Returns.new(@exp.original))
|
132
169
|
rescue UnknownVariant
|
133
170
|
@exp.original
|
134
171
|
end
|
@@ -176,7 +213,7 @@ module MinitestToRspec
|
|
176
213
|
end
|
177
214
|
|
178
215
|
def mocha_expects(exp)
|
179
|
-
raise ArgumentError unless exp.is_a?(
|
216
|
+
raise ArgumentError unless exp.is_a?(Model::Call)
|
180
217
|
arg = exp.arguments.first
|
181
218
|
if sexp_type?(:hash, arg)
|
182
219
|
mocha_expects_hash(exp, arg)
|
@@ -198,7 +235,7 @@ module MinitestToRspec
|
|
198
235
|
end
|
199
236
|
|
200
237
|
def mocha_expectation_count(exp, ordinal)
|
201
|
-
raise ArgumentError unless exp.is_a?(
|
238
|
+
raise ArgumentError unless exp.is_a?(Model::Call)
|
202
239
|
raise ArgumentError unless %i[once twice].include?(ordinal)
|
203
240
|
rvc = exp.receiver_call
|
204
241
|
receiver_processing_method = "mocha_#{rvc.method_name}".to_sym
|
@@ -214,21 +251,22 @@ module MinitestToRspec
|
|
214
251
|
mocha_expectation_count(exp, :once)
|
215
252
|
end
|
216
253
|
|
217
|
-
# Given `r`, a `
|
254
|
+
# Given `r`, a `Model::Calls::Returns`, return a `Sexp` representing
|
218
255
|
# the equivalent stub or message expectation in RSpec.
|
219
256
|
def mocha_returns(r)
|
220
|
-
raise ArgumentError unless r.is_a?(
|
257
|
+
raise ArgumentError unless r.is_a?(Model::Calls::Returns)
|
221
258
|
subprocessor_method = "#{r.rspec_mocks_method}_receive_and_return"
|
222
259
|
send(subprocessor_method,
|
223
260
|
r.rspec_msg_recipient,
|
224
261
|
r.message,
|
225
262
|
r.values,
|
226
|
-
r.any_instance
|
263
|
+
r.any_instance?,
|
264
|
+
r.with
|
227
265
|
)
|
228
266
|
end
|
229
267
|
|
230
268
|
def mocha_stub(exp)
|
231
|
-
raise ArgumentError unless exp.is_a?(
|
269
|
+
raise ArgumentError unless exp.is_a?(Model::Call)
|
232
270
|
if exp.receiver.nil?
|
233
271
|
s(:call, nil, :double, *exp.arguments)
|
234
272
|
else
|
@@ -275,16 +313,29 @@ module MinitestToRspec
|
|
275
313
|
)
|
276
314
|
end
|
277
315
|
|
278
|
-
def receive(message)
|
279
|
-
s(:call, nil, :receive, message)
|
316
|
+
def receive(message, with = [])
|
317
|
+
r = s(:call, nil, :receive, message)
|
318
|
+
if with.empty?
|
319
|
+
r
|
320
|
+
else
|
321
|
+
s(:call, r, :with, *with)
|
322
|
+
end
|
280
323
|
end
|
281
324
|
|
282
325
|
def receive_and_call_original(message)
|
283
326
|
s(:call, s(:call, nil, :receive, message), :and_call_original)
|
284
327
|
end
|
285
328
|
|
286
|
-
def receive_and_return(message, return_values)
|
287
|
-
s(:call, receive(message), :and_return, *return_values)
|
329
|
+
def receive_and_return(message, return_values, with = [])
|
330
|
+
s(:call, receive(message, with), :and_return, *return_values)
|
331
|
+
end
|
332
|
+
|
333
|
+
# `refsert` - Code shared by refute and assert. I could also have gone
|
334
|
+
# with `assfute`. Wooo .. time for bed.
|
335
|
+
def refsert(exact, fuzzy)
|
336
|
+
actual = @exp.arguments[0]
|
337
|
+
matcher = call_to_question_mark?(actual) ? exact : fuzzy
|
338
|
+
expect_to(matcher, actual, true)
|
288
339
|
end
|
289
340
|
|
290
341
|
def require_spec_helper
|
@@ -1,11 +1,12 @@
|
|
1
1
|
require_relative "base"
|
2
|
-
require_relative "../
|
2
|
+
require_relative "../model/iter"
|
3
3
|
|
4
4
|
module MinitestToRspec
|
5
5
|
module Subprocessors
|
6
6
|
class Iter < Base
|
7
|
-
def initialize(sexp)
|
8
|
-
|
7
|
+
def initialize(sexp, rails, mocha)
|
8
|
+
super(rails, mocha)
|
9
|
+
@exp = Model::Iter.new(sexp)
|
9
10
|
sexp.clear
|
10
11
|
end
|
11
12
|
|
@@ -84,7 +85,7 @@ module MinitestToRspec
|
|
84
85
|
RubyParser.new.parse(str)
|
85
86
|
end
|
86
87
|
|
87
|
-
# Given a `
|
88
|
+
# Given a `Model::Iter`, returns a `Sexp`
|
88
89
|
def process_exp(exp)
|
89
90
|
if processable?(exp)
|
90
91
|
send_to_processing_method(exp)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative "../errors"
|
2
|
-
require_relative "../
|
2
|
+
require_relative "../model/klass"
|
3
3
|
require_relative "base"
|
4
4
|
|
5
5
|
module MinitestToRspec
|
@@ -9,10 +9,10 @@ module MinitestToRspec
|
|
9
9
|
# Takes `sexp`, a `:class` s-expression, and `rails`, a
|
10
10
|
# boolean indicating that `rspec-rails` conventions (like
|
11
11
|
# `:type` metadata) should be used.
|
12
|
-
def initialize(sexp, rails)
|
13
|
-
|
12
|
+
def initialize(sexp, rails, mocha)
|
13
|
+
super(rails, mocha)
|
14
|
+
@exp = Model::Klass.new(sexp)
|
14
15
|
sexp.clear
|
15
|
-
@rails = rails
|
16
16
|
end
|
17
17
|
|
18
18
|
def process
|
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.7.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: 2015-
|
11
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby_parser
|
@@ -180,14 +180,14 @@ files:
|
|
180
180
|
- lib/minitest_to_rspec/cli.rb
|
181
181
|
- lib/minitest_to_rspec/converter.rb
|
182
182
|
- lib/minitest_to_rspec/errors.rb
|
183
|
-
- lib/minitest_to_rspec/
|
184
|
-
- lib/minitest_to_rspec/
|
185
|
-
- lib/minitest_to_rspec/
|
186
|
-
- lib/minitest_to_rspec/
|
187
|
-
- lib/minitest_to_rspec/
|
188
|
-
- lib/minitest_to_rspec/
|
189
|
-
- lib/minitest_to_rspec/
|
190
|
-
- lib/minitest_to_rspec/
|
183
|
+
- lib/minitest_to_rspec/model/base.rb
|
184
|
+
- lib/minitest_to_rspec/model/call.rb
|
185
|
+
- lib/minitest_to_rspec/model/calls/once.rb
|
186
|
+
- lib/minitest_to_rspec/model/calls/returns.rb
|
187
|
+
- lib/minitest_to_rspec/model/calls/twice.rb
|
188
|
+
- lib/minitest_to_rspec/model/hash_exp.rb
|
189
|
+
- lib/minitest_to_rspec/model/iter.rb
|
190
|
+
- lib/minitest_to_rspec/model/klass.rb
|
191
191
|
- lib/minitest_to_rspec/processor.rb
|
192
192
|
- lib/minitest_to_rspec/sexp_assertions.rb
|
193
193
|
- lib/minitest_to_rspec/subprocessors/base.rb
|