minitest_to_rspec 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +21 -0
- data/CODE_OF_CONDUCT.md +28 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +75 -0
- data/Rakefile +19 -0
- data/bin/console +11 -0
- data/doc/minitest.md +29 -0
- data/doc/rspec.md +5 -0
- data/doc/supported_assertions.md +60 -0
- data/lib/minitest_to_rspec.rb +5 -0
- data/lib/minitest_to_rspec/converter.rb +57 -0
- data/lib/minitest_to_rspec/errors.rb +3 -0
- data/lib/minitest_to_rspec/exp/call.rb +84 -0
- data/lib/minitest_to_rspec/exp/iter.rb +43 -0
- data/lib/minitest_to_rspec/processor.rb +26 -0
- data/lib/minitest_to_rspec/subprocessors/base.rb +58 -0
- data/lib/minitest_to_rspec/subprocessors/call.rb +109 -0
- data/lib/minitest_to_rspec/subprocessors/class.rb +105 -0
- data/lib/minitest_to_rspec/subprocessors/iter.rb +107 -0
- data/lib/minitest_to_rspec/version.rb +3 -0
- data/minitest_to_rspec.gemspec +31 -0
- metadata +195 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c0b2d69b30e206e341a4bd6a5b036ae70469f96e
|
4
|
+
data.tar.gz: f101b5c2b968434081eff2574abda02c01c73eec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7574bec7773f8e050aae8326b63d699146feed31abc91abb9eac7d7ce5d609c1a11a6d9705c7bf1ce5600f936abcbe02325ba35b453a083750d2f5d22e15b5c1
|
7
|
+
data.tar.gz: 718febe6a17d6495f56423fc288131ebdc0725723cd5900512204feac01d173e515f0e947cf0bdbe946d42e1ea11ce5975356548df8722e0b52dfc3f7fe5b71f
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.2.1
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Change Log
|
2
|
+
==========
|
3
|
+
|
4
|
+
This project follows [semver 2.0.0][1] and the recommendations
|
5
|
+
of [keepachangelog.com][2].
|
6
|
+
|
7
|
+
Road Map
|
8
|
+
--------
|
9
|
+
|
10
|
+
- CLI
|
11
|
+
- More assertions
|
12
|
+
|
13
|
+
Contributions welcome.
|
14
|
+
|
15
|
+
0.1.0
|
16
|
+
-----
|
17
|
+
|
18
|
+
Initial release. 11 assertions are supported.
|
19
|
+
|
20
|
+
[1]: http://semver.org/spec/v2.0.0.html
|
21
|
+
[2]: http://keepachangelog.com/
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people
|
4
|
+
who contribute through reporting issues, posting feature requests, updating
|
5
|
+
documentation, submitting pull requests or patches, and other activities.
|
6
|
+
|
7
|
+
We are committed to making participation in this project a harassment-free
|
8
|
+
experience for everyone, regardless of level of experience, gender, gender
|
9
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
10
|
+
body size, race, age, or religion.
|
11
|
+
|
12
|
+
Examples of unacceptable behavior by participants include the use of sexual
|
13
|
+
language or imagery, derogatory comments or personal attacks, trolling, public
|
14
|
+
or private harassment, insults, or other unprofessional conduct.
|
15
|
+
|
16
|
+
Project maintainers have the right and responsibility to remove, edit, or reject
|
17
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
18
|
+
not aligned to this Code of Conduct. Project maintainers who do not follow the
|
19
|
+
Code of Conduct may be removed from the project team.
|
20
|
+
|
21
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
22
|
+
reported by opening an issue or contacting one or more of the project
|
23
|
+
maintainers.
|
24
|
+
|
25
|
+
This Code of Conduct is adapted from the [Contributor
|
26
|
+
Covenant](http:contributor-covenant.org), version 1.0.0, available at
|
27
|
+
[http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org
|
28
|
+
/version/1/0/0/)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Jared Beck
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# MinitestToRspec
|
2
|
+
|
3
|
+
Converts [minitest][8] files to [rspec][9].
|
4
|
+
|
5
|
+
[![Build Status][1]][2] [![Code Climate][3]][4] [![Test Coverage][7]][4]
|
6
|
+
|
7
|
+
Example
|
8
|
+
-------
|
9
|
+
|
10
|
+
Input:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
require 'test_helper'
|
14
|
+
class BananaTest < ActiveSupport::TestCase
|
15
|
+
test "is delicious" do
|
16
|
+
assert Banana.new.delicious?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
Output:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require("spec_helper")
|
25
|
+
RSpec.describe(Banana) do
|
26
|
+
it("is delicious") { expect(Banana.new.delicious?).to(be_truthy) }
|
27
|
+
end
|
28
|
+
```
|
29
|
+
|
30
|
+
The code style is whatever [ruby2ruby][6] feels like printing,
|
31
|
+
and is not configurable. The goal is not style, but to get to
|
32
|
+
rspec quickly.
|
33
|
+
|
34
|
+
Usage
|
35
|
+
-----
|
36
|
+
|
37
|
+
No CLI executable is provided yet, but ruby usage is simple.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
require 'minitest_to_rspec'
|
41
|
+
MinitestToRspec::Converter.new.convert("assert('banana')")
|
42
|
+
#=> "expect(\"banana\").to(be_truthy)"
|
43
|
+
```
|
44
|
+
|
45
|
+
Supported Assertions
|
46
|
+
--------------------
|
47
|
+
|
48
|
+
Selected assertions from minitest, Test::Unit, and ActiveSupport.
|
49
|
+
See [doc/supported_assertions.md][5] for rationale. Contributions
|
50
|
+
are welcome.
|
51
|
+
|
52
|
+
Assertion | Arity
|
53
|
+
--------------------------- | -----
|
54
|
+
assert |
|
55
|
+
assert_difference | 1
|
56
|
+
assert_difference | 2
|
57
|
+
assert_equal |
|
58
|
+
assert_match |
|
59
|
+
assert_nil |
|
60
|
+
assert_no_difference |
|
61
|
+
[assert_nothing_raised][10] |
|
62
|
+
assert_raises |
|
63
|
+
refute |
|
64
|
+
refute_equal |
|
65
|
+
|
66
|
+
[1]: https://travis-ci.org/jaredbeck/minitest_to_rspec.svg
|
67
|
+
[2]: https://travis-ci.org/jaredbeck/minitest_to_rspec
|
68
|
+
[3]: https://codeclimate.com/github/jaredbeck/minitest_to_rspec/badges/gpa.svg
|
69
|
+
[4]: https://codeclimate.com/github/jaredbeck/minitest_to_rspec
|
70
|
+
[5]: https://github.com/jaredbeck/minitest_to_rspec/blob/master/doc/supported_assertions.md
|
71
|
+
[6]: https://github.com/seattlerb/ruby2ruby
|
72
|
+
[7]: https://codeclimate.com/github/jaredbeck/minitest_to_rspec/badges/coverage.svg
|
73
|
+
[8]: https://github.com/jaredbeck/minitest_to_rspec/blob/master/doc/minitest.md
|
74
|
+
[9]: https://github.com/jaredbeck/minitest_to_rspec/blob/master/doc/rspec.md
|
75
|
+
[10]: http://www.rubydoc.info/gems/test-unit/3.0.9/Test/Unit/Assertions#assert_nothing_raised-instance_method
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cane/rake_task'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
desc 'Check quality metrics'
|
5
|
+
Cane::RakeTask.new(:quality) do |cane|
|
6
|
+
cane.max_violations = 0
|
7
|
+
cane.abc_glob = 'lib/**/*.rb'
|
8
|
+
cane.abc_max = 10
|
9
|
+
cane.no_doc = true
|
10
|
+
cane.style_glob = 'lib/**/*.rb'
|
11
|
+
cane.style_measure = 80
|
12
|
+
end
|
13
|
+
|
14
|
+
task(:spec).clear
|
15
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
16
|
+
t.verbose = false
|
17
|
+
end
|
18
|
+
|
19
|
+
task :default => [:quality, :spec]
|
data/bin/console
ADDED
data/doc/minitest.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Minitest
|
2
|
+
========
|
3
|
+
|
4
|
+
Gem | https://rubygems.org/gems/minitest
|
5
|
+
Docs | http://www.rubydoc.info/gems/minitest/5.5.1
|
6
|
+
|
7
|
+
ActiveSupport
|
8
|
+
-------------
|
9
|
+
|
10
|
+
Rails adds some assertions to minitest.
|
11
|
+
|
12
|
+
- http://guides.rubyonrails.org/testing.html
|
13
|
+
- [active_support/testing/assertions.rb][3]
|
14
|
+
|
15
|
+
Test::Unit
|
16
|
+
----------
|
17
|
+
|
18
|
+
- https://github.com/test-unit/test-unit
|
19
|
+
- http://www.rubydoc.info/gems/test-unit/3.0.9/Test/Unit/Assertions
|
20
|
+
|
21
|
+
Selected History
|
22
|
+
----------------
|
23
|
+
|
24
|
+
[Minitest was removed from ruby stdlib][1] in ruby 2.2, but it is
|
25
|
+
still [packaged with ruby][2] somehow.
|
26
|
+
|
27
|
+
[1]: https://bugs.ruby-lang.org/issues/9711
|
28
|
+
[2]: https://bugs.ruby-lang.org/issues/9852
|
29
|
+
[3]: https://github.com/rails/rails/blob/master/activesupport/lib/active_support/testing/assertions.rb
|
data/doc/rspec.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
Supported Assertions
|
2
|
+
====================
|
3
|
+
|
4
|
+
A quick survey of one mid-sized test suite (14 kilolines) found
|
5
|
+
the following assertions in use.
|
6
|
+
|
7
|
+
```bash
|
8
|
+
find test -type f -name '*.rb' | xargs cat > all_tests;
|
9
|
+
for a in $( cat ~/Desktop/assertions ); do
|
10
|
+
echo -n $a
|
11
|
+
ggrep -E "\\b$a\\b" all_tests | wc -l
|
12
|
+
done |
|
13
|
+
awk '{print $2 " " $1}' |
|
14
|
+
sort -nr
|
15
|
+
```
|
16
|
+
|
17
|
+
```
|
18
|
+
625 assert
|
19
|
+
530 assert_equal
|
20
|
+
84 assert_difference
|
21
|
+
38 assert_no_difference
|
22
|
+
10 refute
|
23
|
+
10 assert_nil
|
24
|
+
5 assert_nothing_raised
|
25
|
+
4 assert_match
|
26
|
+
2 assert_raises
|
27
|
+
1 refute_equal
|
28
|
+
0 refute_same
|
29
|
+
0 refute_respond_to
|
30
|
+
0 refute_predicate
|
31
|
+
0 refute_operator
|
32
|
+
0 refute_nil
|
33
|
+
0 refute_match
|
34
|
+
0 refute_kind_of
|
35
|
+
0 refute_instance_of
|
36
|
+
0 refute_includes
|
37
|
+
0 refute_in_epsilon
|
38
|
+
0 refute_in_delta
|
39
|
+
0 refute_empty
|
40
|
+
0 assert_throws
|
41
|
+
0 assert_silent
|
42
|
+
0 assert_send
|
43
|
+
0 assert_same
|
44
|
+
0 assert_respond_to
|
45
|
+
0 assert_present
|
46
|
+
0 assert_predicate
|
47
|
+
0 assert_output
|
48
|
+
0 assert_operator
|
49
|
+
0 assert_not
|
50
|
+
0 assert_kind_of
|
51
|
+
0 assert_instance_of
|
52
|
+
0 assert_includes
|
53
|
+
0 assert_in_epsilon
|
54
|
+
0 assert_in_delta
|
55
|
+
0 assert_empty
|
56
|
+
0 assert_blank
|
57
|
+
```
|
58
|
+
|
59
|
+
Assertions which are not used in the targeted test suite
|
60
|
+
are not yet supported, but contributions are welcome.
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "ruby_parser"
|
2
|
+
require "ruby2ruby"
|
3
|
+
require_relative "processor"
|
4
|
+
|
5
|
+
module MinitestToRspec
|
6
|
+
class Converter
|
7
|
+
def initialize
|
8
|
+
@processor = Processor.new
|
9
|
+
@ruby2ruby = Ruby2Ruby.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def convert(input)
|
13
|
+
render process parse input
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Parses an input string using the `ruby_parser` gem, and
|
19
|
+
# returns an Abstract Syntax Tree (AST) in the form of
|
20
|
+
# S-expressions.
|
21
|
+
#
|
22
|
+
# Example of AST
|
23
|
+
# --------------
|
24
|
+
#
|
25
|
+
# s(:block,
|
26
|
+
# s(:call, nil, :require, s(:str, "test_helper")),
|
27
|
+
# s(:class,
|
28
|
+
# :BananaTest,
|
29
|
+
# s(:colon2, s(:const, :ActiveSupport), :TestCase),
|
30
|
+
# s(:iter,
|
31
|
+
# s(:call, nil, :test, s(:str, "is delicious")),
|
32
|
+
# s(:args),
|
33
|
+
# s(:call, nil, :assert,
|
34
|
+
# s(:call, s(:call, s(:const, :Banana), :new), :delicious?)
|
35
|
+
# )
|
36
|
+
# )
|
37
|
+
# )
|
38
|
+
# )
|
39
|
+
#
|
40
|
+
def parse(input)
|
41
|
+
RubyParser.new.parse(input)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Processes an AST (S-expressions) representing a minitest
|
45
|
+
# file, and returns an AST (still S-expressions) representing
|
46
|
+
# an rspec file.
|
47
|
+
def process(exp)
|
48
|
+
@processor.process(exp)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Given an AST representing an rspec file, returns a string
|
52
|
+
# of ruby code.
|
53
|
+
def render(exp)
|
54
|
+
@ruby2ruby.process(exp)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module MinitestToRspec
|
2
|
+
module Exp
|
3
|
+
|
4
|
+
# Data object. Represents a `:call` s-expression.
|
5
|
+
class Call
|
6
|
+
attr_reader :original
|
7
|
+
|
8
|
+
def initialize(exp)
|
9
|
+
unless exp.sexp_type == :call
|
10
|
+
raise ArgumentError, "Expected call, got #{exp.sexp_type}"
|
11
|
+
end
|
12
|
+
@exp = exp.dup
|
13
|
+
@original = exp.dup
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def assert_difference?(exp)
|
18
|
+
exp.sexp_type == :call && new(exp).assert_difference?
|
19
|
+
end
|
20
|
+
|
21
|
+
def assert_no_difference?(exp)
|
22
|
+
exp.sexp_type == :call && new(exp).assert_no_difference?
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_nothing_raised?(exp)
|
26
|
+
exp.sexp_type == :call && new(exp).assert_nothing_raised?
|
27
|
+
end
|
28
|
+
|
29
|
+
def assert_raises?(exp)
|
30
|
+
exp.sexp_type == :call && new(exp).assert_raises?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def arguments
|
35
|
+
@exp[3..-1]
|
36
|
+
end
|
37
|
+
|
38
|
+
def argument_types
|
39
|
+
arguments.map(&:sexp_type)
|
40
|
+
end
|
41
|
+
|
42
|
+
def assert_difference?
|
43
|
+
return false unless method_name == :assert_difference
|
44
|
+
[[:str], [:str, :lit]].include?(argument_types)
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_no_difference?
|
48
|
+
method_name == :assert_no_difference &&
|
49
|
+
arguments.length == 1 &&
|
50
|
+
arguments[0].sexp_type == :str
|
51
|
+
end
|
52
|
+
|
53
|
+
def assert_nothing_raised?
|
54
|
+
method_name == :assert_nothing_raised && arguments.empty?
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_raises?
|
58
|
+
method_name == :assert_raises &&
|
59
|
+
arguments.length == 1 &&
|
60
|
+
arguments[0].sexp_type == :const
|
61
|
+
end
|
62
|
+
|
63
|
+
def method_name
|
64
|
+
@exp[2]
|
65
|
+
end
|
66
|
+
|
67
|
+
def one_string_argument?
|
68
|
+
arguments.length == 1 && string?(arguments[0])
|
69
|
+
end
|
70
|
+
|
71
|
+
def require_test_helper?
|
72
|
+
method_name == :require &&
|
73
|
+
one_string_argument? &&
|
74
|
+
arguments[0][1] == "test_helper"
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
def string?(exp)
|
80
|
+
exp.sexp_type == :str
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module MinitestToRspec
|
2
|
+
module Exp
|
3
|
+
|
4
|
+
# Data object. Represents an `:iter` s-expression.
|
5
|
+
class Iter
|
6
|
+
|
7
|
+
def initialize(exp)
|
8
|
+
unless exp.sexp_type == :iter
|
9
|
+
raise ArgumentError, "Expected iter, got #{exp.sexp_type}"
|
10
|
+
end
|
11
|
+
@exp = exp.dup
|
12
|
+
end
|
13
|
+
|
14
|
+
def [](*args)
|
15
|
+
@exp[*args]
|
16
|
+
end
|
17
|
+
|
18
|
+
def assert_difference?
|
19
|
+
!empty? && Exp::Call.assert_difference?(@exp[1])
|
20
|
+
end
|
21
|
+
|
22
|
+
def assert_no_difference?
|
23
|
+
!empty? && Exp::Call.assert_no_difference?(@exp[1])
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_nothing_raised?
|
27
|
+
!empty? && Exp::Call.assert_nothing_raised?(@exp[1])
|
28
|
+
end
|
29
|
+
|
30
|
+
def assert_raises?
|
31
|
+
!empty? && Exp::Call.assert_raises?(@exp[1])
|
32
|
+
end
|
33
|
+
|
34
|
+
def empty?
|
35
|
+
@exp.length == 1 # just the sexp_type
|
36
|
+
end
|
37
|
+
|
38
|
+
def sexp
|
39
|
+
@exp
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "ruby_parser"
|
2
|
+
require "sexp_processor"
|
3
|
+
require_relative "subprocessors/call"
|
4
|
+
require_relative "subprocessors/class"
|
5
|
+
require_relative "subprocessors/iter"
|
6
|
+
|
7
|
+
module MinitestToRspec
|
8
|
+
class Processor < SexpProcessor
|
9
|
+
def initialize
|
10
|
+
super
|
11
|
+
self.strict = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_call(exp)
|
15
|
+
Subprocessors::Call.process(exp)
|
16
|
+
end
|
17
|
+
|
18
|
+
def process_class(exp)
|
19
|
+
Subprocessors::Class.process(exp)
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_iter(exp)
|
23
|
+
Subprocessors::Iter.process(exp)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module MinitestToRspec
|
2
|
+
module Subprocessors
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
|
6
|
+
# Returns a s-expression representing an RSpec expectation, i.e. the
|
7
|
+
# combination of an "expectation target" and a matcher.
|
8
|
+
def expect(target, eager, phase, matcher)
|
9
|
+
s(:call, expectation_target(target, eager), phase, matcher)
|
10
|
+
end
|
11
|
+
|
12
|
+
def expect_to(matcher, target, eager)
|
13
|
+
expect(target, eager, :to, matcher)
|
14
|
+
end
|
15
|
+
|
16
|
+
def expect_to_not(matcher, target, eager)
|
17
|
+
expect(target, eager, :to_not, matcher)
|
18
|
+
end
|
19
|
+
|
20
|
+
# In RSpec, `expect` returns an "expectation target". This
|
21
|
+
# can be based on an expression, as in `expect(1 + 1)` or it
|
22
|
+
# can be based on a block, as in `expect { raise }`. Either
|
23
|
+
# way, it's called an "expectation target".
|
24
|
+
def expectation_target(exp, eager = true)
|
25
|
+
m = "expectation_target_%s" % [eager ? "eager" : "lazy"]
|
26
|
+
send(m, exp)
|
27
|
+
end
|
28
|
+
|
29
|
+
def expectation_target_eager(exp)
|
30
|
+
s(:call, nil, :expect, exp)
|
31
|
+
end
|
32
|
+
|
33
|
+
def expectation_target_lazy(block)
|
34
|
+
s(:iter,
|
35
|
+
s(:call, nil, :expect),
|
36
|
+
s(:args),
|
37
|
+
full_process(block)
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Run `exp` through a new `Processor`. This is useful for expressions
|
42
|
+
# that cannot be fully understood by a single subprocessor. For
|
43
|
+
# example, we process :iter expressions, because we're interested in
|
44
|
+
# :iter that contain e.g. an `assert_difference`. However, if the :iter
|
45
|
+
# turns out to be uninteresting, we still want to fully process its
|
46
|
+
# sub-expressions. TODO: `full_process` may not be the best name.
|
47
|
+
def full_process(exp)
|
48
|
+
Processor.new.process(exp)
|
49
|
+
end
|
50
|
+
|
51
|
+
def matcher(name, *args)
|
52
|
+
exp = s(:call, nil, name)
|
53
|
+
exp.concat(args)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative "../exp/call"
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module MinitestToRspec
|
5
|
+
module Subprocessors
|
6
|
+
class Call < Base
|
7
|
+
|
8
|
+
ASSERTIONS = %i[
|
9
|
+
assert
|
10
|
+
assert_equal
|
11
|
+
assert_match
|
12
|
+
assert_nil
|
13
|
+
refute
|
14
|
+
refute_equal
|
15
|
+
]
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def process(sexp)
|
19
|
+
exp = Exp::Call.new(sexp)
|
20
|
+
sexp.clear
|
21
|
+
process_exp(exp)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def assertion?(exp)
|
27
|
+
ASSERTIONS.include?(exp.method_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def be_falsey
|
31
|
+
matcher(:be_falsey)
|
32
|
+
end
|
33
|
+
|
34
|
+
def be_nil
|
35
|
+
matcher(:be_nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
def be_truthy
|
39
|
+
matcher(:be_truthy)
|
40
|
+
end
|
41
|
+
|
42
|
+
def eq(exp)
|
43
|
+
matcher(:eq, exp)
|
44
|
+
end
|
45
|
+
|
46
|
+
def match(pattern)
|
47
|
+
matcher(:match, pattern)
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_assert(exp)
|
51
|
+
expect_to(be_truthy, exp.arguments[0], true)
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_assert_equal(exp)
|
55
|
+
expected = exp.arguments[0]
|
56
|
+
calculated = exp.arguments[1]
|
57
|
+
expect_to(eq(expected), calculated, true)
|
58
|
+
end
|
59
|
+
|
60
|
+
def method_assert_match(exp)
|
61
|
+
pattern = exp.arguments[0]
|
62
|
+
string = exp.arguments[1]
|
63
|
+
expect_to(match(pattern), string, true)
|
64
|
+
end
|
65
|
+
|
66
|
+
def method_assert_nil(exp)
|
67
|
+
expect_to(be_nil, exp.arguments[0], true)
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_refute(exp)
|
71
|
+
expect_to(be_falsey, exp.arguments[0], true)
|
72
|
+
end
|
73
|
+
|
74
|
+
def method_refute_equal(exp)
|
75
|
+
unexpected = exp.arguments[0]
|
76
|
+
calculated = exp.arguments[1]
|
77
|
+
expect_to_not(eq(unexpected), calculated, true)
|
78
|
+
end
|
79
|
+
|
80
|
+
def method_test(exp)
|
81
|
+
s(:call, nil, :it, *exp.arguments)
|
82
|
+
end
|
83
|
+
|
84
|
+
def processable?(exp)
|
85
|
+
exp.method_name == :test || assertion?(exp)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Given a `Exp::Call`, returns a `Sexp`
|
89
|
+
def process_exp(exp)
|
90
|
+
if exp.require_test_helper?
|
91
|
+
require_spec_helper
|
92
|
+
elsif processable?(exp)
|
93
|
+
process_method(exp)
|
94
|
+
else
|
95
|
+
exp.original
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def process_method(exp)
|
100
|
+
send("method_#{exp.method_name}".to_sym, exp)
|
101
|
+
end
|
102
|
+
|
103
|
+
def require_spec_helper
|
104
|
+
s(:call, nil, :require, s(:str, "spec_helper"))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative "../errors"
|
2
|
+
require_relative "base"
|
3
|
+
|
4
|
+
module MinitestToRspec
|
5
|
+
module Subprocessors
|
6
|
+
class Class < Base
|
7
|
+
class << self
|
8
|
+
|
9
|
+
# Examples of S-expressions
|
10
|
+
# -------------------------
|
11
|
+
#
|
12
|
+
# An empty class
|
13
|
+
#
|
14
|
+
# class Derp; end
|
15
|
+
# s(:class, :Derp, nil)
|
16
|
+
#
|
17
|
+
# A trivial class
|
18
|
+
#
|
19
|
+
# class Derp; puts; end
|
20
|
+
# s(:class, :Derp, nil, s(:call, nil, :puts))
|
21
|
+
#
|
22
|
+
# A TestCase
|
23
|
+
#
|
24
|
+
# s(:class,
|
25
|
+
# :BananaTest,
|
26
|
+
# s(:colon2, s(:const, :ActiveSupport), :TestCase),
|
27
|
+
# s(:iter,
|
28
|
+
# s(:call, nil, :test, s(:str, "is delicious")),
|
29
|
+
# s(:args),
|
30
|
+
# s(:call, nil, :assert,
|
31
|
+
# s(:call, s(:call, s(:const, :Banana), :new), :delicious?)
|
32
|
+
# )
|
33
|
+
# )
|
34
|
+
# )
|
35
|
+
#
|
36
|
+
def process(exp)
|
37
|
+
raise ArgumentError unless exp.shift == :class
|
38
|
+
name = exp.shift
|
39
|
+
parent = exp.shift
|
40
|
+
iter = exp.empty? ? nil : exp.shift
|
41
|
+
raise("Unexpected class expression") unless exp.empty?
|
42
|
+
result(name, parent, iter)
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def active_support_test_case?(parent)
|
48
|
+
parent.length == 3 &&
|
49
|
+
parent[1] == s(:const, :ActiveSupport) &&
|
50
|
+
parent[2] == :TestCase
|
51
|
+
end
|
52
|
+
|
53
|
+
# Given a `test_class_name` like `BananaTest`, returns the
|
54
|
+
# described clas, like `Banana`.
|
55
|
+
def described_class(test_class_name)
|
56
|
+
test_class_name.to_s.gsub(/Test\Z/, "").to_sym
|
57
|
+
end
|
58
|
+
|
59
|
+
def inheritance?(exp)
|
60
|
+
exp.sexp_type == :colon2
|
61
|
+
end
|
62
|
+
|
63
|
+
# Run `exp` through a new `Processor`. This is appropriate
|
64
|
+
# for expressions like `:iter` (a block) which we're not
|
65
|
+
# interested in processing. We *are* interested in
|
66
|
+
# processing expressions within an `:iter`, but not the
|
67
|
+
# iter itself. TODO: `full_process` may not be the best name.
|
68
|
+
def full_process(exp)
|
69
|
+
Processor.new.process(exp)
|
70
|
+
end
|
71
|
+
|
72
|
+
def result(name, parent, iter)
|
73
|
+
if parent && test_case?(parent)
|
74
|
+
rspec_describe_block(name, iter)
|
75
|
+
elsif iter.nil?
|
76
|
+
s(:class, name, parent)
|
77
|
+
else
|
78
|
+
s(:class, name, parent, full_process(iter))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def rspec_describe(arg)
|
83
|
+
s(:call, s(:const, :RSpec), :describe, arg)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns a S-expression representing a call to RSpec.describe
|
87
|
+
def rspec_describe_block(name, iter)
|
88
|
+
arg = s(:const, described_class(name))
|
89
|
+
result = s(:iter, rspec_describe(arg), s(:args))
|
90
|
+
unless iter.nil?
|
91
|
+
result << full_process(iter)
|
92
|
+
end
|
93
|
+
result
|
94
|
+
end
|
95
|
+
|
96
|
+
# TODO: Obviously, there are test case parent classes
|
97
|
+
# other than ActiveSupport::TestCase
|
98
|
+
def test_case?(parent)
|
99
|
+
raise ArgumentError unless inheritance?(parent)
|
100
|
+
active_support_test_case?(parent)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
require_relative "../exp/iter"
|
3
|
+
|
4
|
+
module MinitestToRspec
|
5
|
+
module Subprocessors
|
6
|
+
class Iter < Base
|
7
|
+
class << self
|
8
|
+
def process(sexp)
|
9
|
+
exp = Exp::Iter.new(sexp)
|
10
|
+
sexp.clear
|
11
|
+
process_exp(exp)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Returns an expression representing an RSpec `change {}`
|
17
|
+
# matcher. See also `change_by` below.
|
18
|
+
def change(exp)
|
19
|
+
matcher_with_block(:change, exp)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns an expression representing an RSpec `change {}.by()` matcher.
|
23
|
+
def change_by(diff_exp, by_exp)
|
24
|
+
s(:call,
|
25
|
+
change(diff_exp),
|
26
|
+
:by,
|
27
|
+
by_exp
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def matcher_with_block(matcher_name, block)
|
32
|
+
s(:iter,
|
33
|
+
s(:call, nil, matcher_name),
|
34
|
+
s(:args),
|
35
|
+
block
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse(str)
|
40
|
+
RubyParser.new.parse(str)
|
41
|
+
end
|
42
|
+
|
43
|
+
def process_assert_difference(exp)
|
44
|
+
call = exp[1]
|
45
|
+
block = exp[3]
|
46
|
+
by = call[4]
|
47
|
+
what = parse(call[3][1])
|
48
|
+
matcher = by.nil? ? change(what) : change_by(what, by)
|
49
|
+
expect_to(matcher, block, false)
|
50
|
+
end
|
51
|
+
|
52
|
+
def process_assert_no_difference(exp)
|
53
|
+
call = exp[1]
|
54
|
+
block = exp[3]
|
55
|
+
what = parse(call[3][1])
|
56
|
+
expect_to_not(change(what), block, false)
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_assert_nothing_raised(exp)
|
60
|
+
block = exp[3]
|
61
|
+
expect_to_not(raise_error, block, false)
|
62
|
+
end
|
63
|
+
|
64
|
+
def process_assert_raises(exp)
|
65
|
+
block = exp[3]
|
66
|
+
call = Exp::Call.new(exp[1])
|
67
|
+
err = call.arguments.first
|
68
|
+
expect_to(raise_error(err), block, false)
|
69
|
+
end
|
70
|
+
|
71
|
+
# Given a `Exp::Iter`, returns a `Sexp`
|
72
|
+
def process_exp(exp)
|
73
|
+
m = processing_method(exp)
|
74
|
+
if m.nil?
|
75
|
+
process_uninteresting_iter(exp.sexp)
|
76
|
+
else
|
77
|
+
send(m, exp)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def process_uninteresting_iter(exp)
|
82
|
+
iter = s(exp.shift)
|
83
|
+
until exp.empty?
|
84
|
+
iter << full_process(exp.shift)
|
85
|
+
end
|
86
|
+
iter
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the name of a method in this subprocessor, or nil if
|
90
|
+
# this iter is not processable.
|
91
|
+
def processing_method(iter)
|
92
|
+
if !iter.empty? && iter[1].sexp_type == :call
|
93
|
+
method_name = iter[1][2]
|
94
|
+
decision = "#{method_name}?".to_sym
|
95
|
+
if iter.respond_to?(decision) && iter.public_send(decision)
|
96
|
+
"process_#{method_name}".to_sym
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def raise_error(*args)
|
102
|
+
matcher(:raise_error, *args)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'minitest_to_rspec/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "minitest_to_rspec"
|
8
|
+
spec.version = MinitestToRspec::VERSION
|
9
|
+
spec.authors = ["Jared Beck"]
|
10
|
+
spec.email = ["jared@jaredbeck.com"]
|
11
|
+
|
12
|
+
spec.summary = "Converts minitest files to rspec"
|
13
|
+
spec.homepage = "https://github.com/jaredbeck/minitest_to_rspec"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
}
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "ruby_parser"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "cane"
|
25
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "ruby2ruby"
|
29
|
+
spec.add_development_dependency "pry"
|
30
|
+
spec.add_development_dependency "pry-nav"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minitest_to_rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jared Beck
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ruby_parser
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cane
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: codeclimate-test-reporter
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ruby2ruby
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: pry-nav
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
description:
|
140
|
+
email:
|
141
|
+
- jared@jaredbeck.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".ruby-version"
|
148
|
+
- ".travis.yml"
|
149
|
+
- CHANGELOG.md
|
150
|
+
- CODE_OF_CONDUCT.md
|
151
|
+
- Gemfile
|
152
|
+
- LICENSE.txt
|
153
|
+
- README.md
|
154
|
+
- Rakefile
|
155
|
+
- bin/console
|
156
|
+
- doc/minitest.md
|
157
|
+
- doc/rspec.md
|
158
|
+
- doc/supported_assertions.md
|
159
|
+
- lib/minitest_to_rspec.rb
|
160
|
+
- lib/minitest_to_rspec/converter.rb
|
161
|
+
- lib/minitest_to_rspec/errors.rb
|
162
|
+
- lib/minitest_to_rspec/exp/call.rb
|
163
|
+
- lib/minitest_to_rspec/exp/iter.rb
|
164
|
+
- lib/minitest_to_rspec/processor.rb
|
165
|
+
- lib/minitest_to_rspec/subprocessors/base.rb
|
166
|
+
- lib/minitest_to_rspec/subprocessors/call.rb
|
167
|
+
- lib/minitest_to_rspec/subprocessors/class.rb
|
168
|
+
- lib/minitest_to_rspec/subprocessors/iter.rb
|
169
|
+
- lib/minitest_to_rspec/version.rb
|
170
|
+
- minitest_to_rspec.gemspec
|
171
|
+
homepage: https://github.com/jaredbeck/minitest_to_rspec
|
172
|
+
licenses:
|
173
|
+
- MIT
|
174
|
+
metadata: {}
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
require_paths:
|
178
|
+
- lib
|
179
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - ">="
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
requirements:
|
186
|
+
- - ">="
|
187
|
+
- !ruby/object:Gem::Version
|
188
|
+
version: '0'
|
189
|
+
requirements: []
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.4.5
|
192
|
+
signing_key:
|
193
|
+
specification_version: 4
|
194
|
+
summary: Converts minitest files to rspec
|
195
|
+
test_files: []
|