mrspec 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.travis.yml +7 -0
- data/Gemfile +2 -0
- data/Readme.md +256 -0
- data/bin/mrspec +18 -0
- data/features/mrspec.feature +475 -0
- data/features/support/env.rb +31 -0
- data/lib/mrspec/configuration.rb +18 -0
- data/lib/mrspec/declare_minitests.rb +64 -0
- data/lib/mrspec/minitest_assertion_for_rspec.rb +15 -0
- data/lib/mrspec/minitest_metadata.rb +35 -0
- data/lib/mrspec/option_parser.rb +30 -0
- data/lib/mrspec/runner.rb +12 -0
- data/lib/mrspec/version.rb +3 -0
- data/lib/mrspec.rb +4 -0
- data/mrspec.gemspec +24 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6cbbcda0055d2073b1bc987184afd21145c4a527
|
4
|
+
data.tar.gz: 6131f41d4ffd68a89a00b1ba92f70f1e6b87bccb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4f1e700ae9c81848aede3a469920d55685152b22e2d68bc65b9c65592a97f99c229af26c3d1adaa5035e7577cc8073696d0997fe42bca983f271c3d2b49ea283
|
7
|
+
data.tar.gz: b9cd655c7c06136b3abd010c66a4b70e2525a21f458971e2d5b6b6c2f3a9938ef39b02892b185217809d733edbd90ec762eb2f00b1d13dcc2c9e0dd56fa56253
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,256 @@
|
|
1
|
+
[![Build Status](https://secure.travis-ci.org/JoshCheek/mrspec.png?branch=master)](http://travis-ci.org/JoshCheek/mrspec)
|
2
|
+
|
3
|
+
mrspec
|
4
|
+
======
|
5
|
+
|
6
|
+
Minitest and RSpec, sitting in a tree...
|
7
|
+
|
8
|
+
Runs Minitest tests using RSpec's runner.
|
9
|
+
Also runs RSpec's tests, so if you want to use them side-by-side,
|
10
|
+
this will do it.
|
11
|
+
|
12
|
+
|
13
|
+
Examples
|
14
|
+
--------
|
15
|
+
|
16
|
+
|
17
|
+
### Run specs and tests in tandem
|
18
|
+
|
19
|
+
It matches `test/*_test.rb`, `test/test_*.rb`, `spec/*_spec.rb`.
|
20
|
+
The RSpec group description is the class name without `Test` prefix/suffix.
|
21
|
+
The example name is the method name without the `test_` prefix,
|
22
|
+
and with underscores switched to spaces.
|
23
|
+
It finds test classes and test methods by asking Minitest what it is tracking.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# file: spec/a_spec.rb
|
27
|
+
RSpec.describe 'An RSpec test' do
|
28
|
+
it('does rspec things') { }
|
29
|
+
end
|
30
|
+
|
31
|
+
# file: test/b_test.rb
|
32
|
+
class AMinitestTest < Minitest::Test
|
33
|
+
def test_it_does_minitesty_things
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# file: test/test_c.rb
|
38
|
+
class TestSomethingElse < Minitest::Test
|
39
|
+
def some_helper_method # won't show up
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_this_also_does_minitesty_things
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Added because Minitest::Runnable knows about it
|
47
|
+
class AnotherTestWithNeitherThePrefixNorTheSuffix < Minitest::Test
|
48
|
+
# This causes Minitest to consider it a test, so we consider it one
|
49
|
+
def self.runnables
|
50
|
+
['is_this_a_test_yes_it_is']
|
51
|
+
end
|
52
|
+
|
53
|
+
def is_this_a_test_yes_it_is
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Ignored b/c Minitest::Runnable doesn't know about it
|
58
|
+
class NotATest
|
59
|
+
def test_whatevz
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# file: test/d_spec.rb
|
64
|
+
require 'minitest/spec'
|
65
|
+
describe 'I am a minitest spec' do
|
66
|
+
it 'does minitesty things' do
|
67
|
+
assert_includes self.class.ancestors, Minitest::Spec
|
68
|
+
end
|
69
|
+
end
|
70
|
+
```
|
71
|
+
|
72
|
+
![file patterns](https://s3.amazonaws.com/josh.cheek/mrspec/file-patterns.png)
|
73
|
+
|
74
|
+
|
75
|
+
### Failures, Errors, Skips
|
76
|
+
|
77
|
+
It understands Minitest skips and errors/failures.
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
# file: various_errors.rb
|
81
|
+
class VariousErrors < Minitest::Test
|
82
|
+
def test_this_passes() assert true end
|
83
|
+
def test_they_arent_equal() assert_equal 1, 2 end
|
84
|
+
def test_is_not_included() assert_includes %w[a b c], 'd' end
|
85
|
+
def test_skipped_because…_reasons() skip end
|
86
|
+
end
|
87
|
+
```
|
88
|
+
|
89
|
+
I used `--format progress` here, because there's enough errors that my default documentation
|
90
|
+
formatter makes it spammy >.<
|
91
|
+
|
92
|
+
![various errors](https://s3.amazonaws.com/josh.cheek/mrspec/various-errors2.png)
|
93
|
+
|
94
|
+
|
95
|
+
### Fail Fast and filtering
|
96
|
+
|
97
|
+
The `--fail-fast` flag is a favourite of mine. It continues running tests until it sees a failure, then it stops.
|
98
|
+
|
99
|
+
We can also use tags to filter which tests to run.
|
100
|
+
Mrspec adds RSpec metadata to Minitest classes and tests,
|
101
|
+
the metadata behaves as a tag.
|
102
|
+
|
103
|
+
The best thing about tags is they're easy to add,
|
104
|
+
and they continue to apply to the same test, when it moves around
|
105
|
+
(line numbers change), They stay correct even if I rename it!
|
106
|
+
I won't have to tweak my command-line invocation until I've got the test passing!
|
107
|
+
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# file: test.rb
|
111
|
+
|
112
|
+
# Here, we tag the `NoFailures` class with `them_passing_tests`
|
113
|
+
# And the `TwoFailures` class with `them_failing_tests`
|
114
|
+
class NoFailures < Minitest::Test
|
115
|
+
classmeta them_passing_tests: true
|
116
|
+
|
117
|
+
def test_1() end
|
118
|
+
def test_2() end
|
119
|
+
end
|
120
|
+
|
121
|
+
class TwoFailures < Minitest::Test
|
122
|
+
classmeta them_failing_tests: true
|
123
|
+
|
124
|
+
# I like short tagnames, b/c usually my use is transient.
|
125
|
+
# I just keep them around until they're fixed.
|
126
|
+
meta f1: true
|
127
|
+
def test_3
|
128
|
+
raise 'first failure'
|
129
|
+
end
|
130
|
+
|
131
|
+
meta f2: true
|
132
|
+
def test_4
|
133
|
+
raise 'second failure'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
![Examples of Tagging](https://s3.amazonaws.com/josh.cheek/mrspec/tagging.png)
|
139
|
+
|
140
|
+
|
141
|
+
|
142
|
+
Why?
|
143
|
+
----
|
144
|
+
|
145
|
+
The default way to run minitest tests is with Rake.
|
146
|
+
And if you have multiple suites, that can be nice,
|
147
|
+
or if you already use Rake, then it's not adding a new dependency.
|
148
|
+
But here are some frustrations I have with it as a test runner:
|
149
|
+
|
150
|
+
1. It's not a test runner, it's a build tool. As such, it's not well suited to this task.
|
151
|
+
1. I shouldn't have to add a dependency on Rake just to run my tests.
|
152
|
+
1. The `Rake::TestTask` is confoundingly opaque (I rant about it [here](https://github.com/stripe/stripe-ruby/pull/144#issuecomment-48810307))
|
153
|
+
1. It ultimately just [shells out](https://github.com/rspec/rspec-core/blob/3145e2544e1825bc754d0986e893664afe19abf5/lib/rspec/core/rake_task.rb#L70)
|
154
|
+
(as does the [RSpec one](https://github.com/ruby/rake/blob/e644af3a09659c7e04245186607091324d8816e9/lib/rake/testtask.rb#L104),
|
155
|
+
so why do I need layers of translation and abstraction between me and a command-line invocation?
|
156
|
+
And what's the value of adding an entire process between me and my tests?
|
157
|
+
Think how long Rails takes to start up, now imagine paying that twice every time you want to run your tests!
|
158
|
+
1. It makes it incredibly difficult to dynamically alter my test invoation.
|
159
|
+
With Minitest, you can pass `-n test_something` and it will only run the test named `test_something`,
|
160
|
+
but now I have to edit code tomake that happen (or write code to uese
|
161
|
+
environment variables, which is better, but still cumbersome,
|
162
|
+
and doesn't fail noisily if I mistype it)
|
163
|
+
|
164
|
+
Furthermore, if someone doesn't know about the test task, or it seems formidable, as it often does to new students
|
165
|
+
(I'm a [teacher](http://turing.io/team)), then they won't use it. They instead run files one at a time.
|
166
|
+
When I go to run the tests, there's just no way built in to run them all. I wind up having to craft clever command-line invocations
|
167
|
+
using custom tools ([1](https://github.com/JoshCheek/dotfiles/blob/master/bin/ff),
|
168
|
+
[2](https://github.com/JoshCheek/dotfiles/blob/master/bin/prepend)).
|
169
|
+
|
170
|
+
```sh
|
171
|
+
$ ff test '\.rb' | prepend -r | xargs ruby -e ''
|
172
|
+
```
|
173
|
+
|
174
|
+
Oftentimes, this is the first time they've all been run together, and we find out they haven't run a test in a long time,
|
175
|
+
because it's too cumbersome for them (they're not good with their tools yet), it's failing or worse, syntactically invalid.
|
176
|
+
Maybe they even know it, but they run them one at a time, so it hasn't been a problem for them yet.
|
177
|
+
|
178
|
+
Anyway, all of this is to say that Minitest needs a runner.
|
179
|
+
I hear Rails is working on one, but I don't know when that'll be available,
|
180
|
+
and who knows if they'll write it well enough to be used outside of Rails.
|
181
|
+
|
182
|
+
But the RSpec runner is very nice, it has a lot of features that I use frequently.
|
183
|
+
Someone suggested running Minitest with the RSpec runner (see attribution section),
|
184
|
+
and I thought that was an interesting idea that could have value if it worked.
|
185
|
+
...so, here we are.
|
186
|
+
|
187
|
+
Nuances
|
188
|
+
-------
|
189
|
+
|
190
|
+
Changes the default pattern to look for any files suffixed with `_test.rb` or `_spec.rb`, or prefixed with `test_`
|
191
|
+
(RSpec, by itself, only looks for suffixes of `_spec.rb`).
|
192
|
+
|
193
|
+
Changes the default search directories to be `test` and `spec`
|
194
|
+
(RSpec, by itself, only looks in `spec`).
|
195
|
+
|
196
|
+
Turns off monkey patching, so you cannot use RSPec's toplevel describe, or `should`.
|
197
|
+
There are 2 reasons for this:
|
198
|
+
|
199
|
+
1. It conflicts with `Minitest::Spec`'s definition of `Kernel#describe`
|
200
|
+
([here](https://github.com/seattlerb/minitest/blob/f1081566ec6e9e391628bde3a26fb057ad2576a8/lib/minitest/spec.rb#L71)).
|
201
|
+
And must be preemptively turned off, because after-the-fact disabling
|
202
|
+
causes it to be undefined on both `main` and `Module` ([here](https://github.com/rspec/rspec-core/blob/3145e2544e1825bc754d0986e893664afe19abf5/lib/rspec/core/dsl.rb#L72)),
|
203
|
+
which means that even if you don't use it, it will still interfere with `Minitest::Spec`
|
204
|
+
(removing methods allows method lookup to find superclass definitions,
|
205
|
+
but undefining them ends method lookup.)
|
206
|
+
2. You should just not do that in general. Monkey patching is a bad plan, all around,
|
207
|
+
just use the namespaced methods, or create your own methods to wrap the assertion syntax.
|
208
|
+
I'm looking forward to when this feature is removed altogether.
|
209
|
+
|
210
|
+
|
211
|
+
Running the tests
|
212
|
+
-----------------
|
213
|
+
|
214
|
+
```sh
|
215
|
+
$ bundle
|
216
|
+
$ bundle exec cucumber
|
217
|
+
```
|
218
|
+
|
219
|
+
Why are all the tests written in Cucumber?
|
220
|
+
Well... mostly just b/c I initially wrote this as a script for my dotfiles,
|
221
|
+
which I mostly test with Cucumber and [Haiti](https://github.com/JoshCheek/haiti),
|
222
|
+
as they are usually heavily oriented towards integration,
|
223
|
+
and often not written in Ruby.
|
224
|
+
|
225
|
+
|
226
|
+
Attribution
|
227
|
+
-----------
|
228
|
+
|
229
|
+
Idea from [e2](https://github.com/e2), proposed [here](https://github.com/rspec/rspec-core/issues/1786).
|
230
|
+
Iniitial code was based off of [this gist](https://gist.github.com/e2/bcd2be81b4ac28c85ea0)
|
231
|
+
|
232
|
+
|
233
|
+
MIT License
|
234
|
+
-----------
|
235
|
+
|
236
|
+
```
|
237
|
+
Copyright (c) 2015 Josh Cheek
|
238
|
+
|
239
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
240
|
+
of this software and associated documentation files (the "Software"), to deal
|
241
|
+
in the Software without restriction, including without limitation the rights
|
242
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
243
|
+
copies of the Software, and to permit persons to whom the Software is
|
244
|
+
furnished to do so, subject to the following conditions:
|
245
|
+
|
246
|
+
The above copyright notice and this permission notice shall be included in
|
247
|
+
all copies or substantial portions of the Software.
|
248
|
+
|
249
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
250
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
251
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
252
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
253
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
254
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
255
|
+
THE SOFTWARE.
|
256
|
+
```
|
data/bin/mrspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
|
4
|
+
require 'mrspec'
|
5
|
+
|
6
|
+
# All your config are belong to us
|
7
|
+
RSpec.configuration = MRspec::Configuration.new
|
8
|
+
|
9
|
+
# Use our option parser instead of RSpec's
|
10
|
+
RSpec::Core::Parser.parser_method = RSpec::Core::Parser.instance_method :mrspec_parser
|
11
|
+
|
12
|
+
# Run tests with our runner at program exit
|
13
|
+
MRspec::Runner.autorun
|
14
|
+
|
15
|
+
# Disable RSpec and Minitest's autorun methods
|
16
|
+
# so that loading tests doesn't lead to multiple runners
|
17
|
+
RSpec::Core::Runner.define_singleton_method(:autorun) { }
|
18
|
+
Minitest.define_singleton_method(:autorun) { }
|
@@ -0,0 +1,475 @@
|
|
1
|
+
Feature: mrspec
|
2
|
+
Minitest doesn't have a runner, but a runner would be really nice.
|
3
|
+
RSpec has a nice runner... so lets join them together!
|
4
|
+
|
5
|
+
Scenario: Finds spec/**/*_spec.rb and test/**/*_test.rb and test/**/test_*.rb
|
6
|
+
Given the file "spec/a_spec.rb":
|
7
|
+
"""
|
8
|
+
RSpec.describe 'a' do
|
9
|
+
it('passes') { }
|
10
|
+
end
|
11
|
+
"""
|
12
|
+
And the file "spec/dir/b_spec.rb":
|
13
|
+
"""
|
14
|
+
RSpec.describe 'b' do
|
15
|
+
it('passes') { }
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
And the file "test/c_test.rb":
|
19
|
+
"""
|
20
|
+
class CTest < Minitest::Test
|
21
|
+
def test_passes
|
22
|
+
end
|
23
|
+
end
|
24
|
+
"""
|
25
|
+
And the file "test/dir/d_test.rb":
|
26
|
+
"""
|
27
|
+
class DTest < Minitest::Test
|
28
|
+
def test_passes
|
29
|
+
end
|
30
|
+
end
|
31
|
+
"""
|
32
|
+
And the file "test/dir/test_e.rb":
|
33
|
+
"""
|
34
|
+
class ETest < Minitest::Test
|
35
|
+
def test_passes
|
36
|
+
end
|
37
|
+
end
|
38
|
+
"""
|
39
|
+
And the file "test/a_test_file.rb":
|
40
|
+
"""
|
41
|
+
raise "I should not be loaded!"
|
42
|
+
"""
|
43
|
+
And the file "spec/a_spec_file.rb":
|
44
|
+
"""
|
45
|
+
raise "I should not be loaded!"
|
46
|
+
"""
|
47
|
+
When I run 'mrspec -f json'
|
48
|
+
Then the program ran successfully
|
49
|
+
And stdout includes "5 examples"
|
50
|
+
And stdout includes "0 failures"
|
51
|
+
|
52
|
+
|
53
|
+
Scenario: Registers minitest tests as RSpec tests, recording skips, passes, errors, failures
|
54
|
+
Given the file "some_test.rb":
|
55
|
+
"""
|
56
|
+
class LotaStuffsTest < Minitest::Test
|
57
|
+
def test_passes
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_fails
|
61
|
+
assert_equal 1, 2
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_errors
|
65
|
+
raise 'omg'
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_skips
|
69
|
+
skip
|
70
|
+
end
|
71
|
+
end
|
72
|
+
"""
|
73
|
+
When I run "mrspec some_test.rb --no-color --format progress"
|
74
|
+
|
75
|
+
# counts correctly
|
76
|
+
Then stdout includes "4 examples"
|
77
|
+
And stdout includes "2 failures"
|
78
|
+
And stdout includes "1 pending"
|
79
|
+
And stdout does not include "No examples found"
|
80
|
+
|
81
|
+
# displays the failed assertion, not an error
|
82
|
+
And stdout includes "Expected: 1"
|
83
|
+
And stdout includes "Actual: 2"
|
84
|
+
|
85
|
+
# displays the test's code, not the integration code
|
86
|
+
And stdout includes "raise 'omg'"
|
87
|
+
And stdout includes "assert_equal 1, 2"
|
88
|
+
And stdout does not include "Minitest.run_one_method"
|
89
|
+
|
90
|
+
|
91
|
+
Scenario: Works with Minitest::Test, choosing intelligent names
|
92
|
+
Given the file "some_test.rb":
|
93
|
+
"""
|
94
|
+
class MyClass1Test < Minitest::Test
|
95
|
+
def test_it_does_stuff
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class TestMyClass2 < Minitest::Test
|
100
|
+
def test_it_does_stuff
|
101
|
+
end
|
102
|
+
end
|
103
|
+
"""
|
104
|
+
When I run "mrspec some_test.rb -f json"
|
105
|
+
Then the program ran successfully
|
106
|
+
And stdout includes '"full_description":"MyClass1 it does stuff"'
|
107
|
+
And stdout includes '"full_description":"MyClass2 it does stuff"'
|
108
|
+
|
109
|
+
|
110
|
+
Scenario: Works with Minitest::Spec, choosing intelligent names
|
111
|
+
Given the file "some_spec.rb":
|
112
|
+
"""
|
113
|
+
require 'minitest/spec'
|
114
|
+
describe 'the description' do
|
115
|
+
it 'the example' do
|
116
|
+
assert true
|
117
|
+
if kind_of? Minitest::Spec
|
118
|
+
puts "I am defined by Minitest::Spec"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
"""
|
123
|
+
When I run "mrspec some_spec.rb -f json"
|
124
|
+
Then stdout includes "1 example"
|
125
|
+
And stdout includes "0 failures"
|
126
|
+
And stdout includes "I am defined by Minitest::Spec"
|
127
|
+
And stdout includes '"description":"the example"'
|
128
|
+
And stdout includes '"full_description":"the description the example"'
|
129
|
+
|
130
|
+
|
131
|
+
Scenario: Filters the runner and minitest code out of the backtrace do
|
132
|
+
Given the file "some_test.rb":
|
133
|
+
"""
|
134
|
+
class LotaStuffsTest < Minitest::Test
|
135
|
+
def test_errors
|
136
|
+
raise "zomg"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
"""
|
140
|
+
When I run "mrspec some_test.rb"
|
141
|
+
Then stdout does not include "minitest"
|
142
|
+
And stdout does not include "mrspec.rb"
|
143
|
+
And stdout does not include "bin/mrspec"
|
144
|
+
|
145
|
+
|
146
|
+
Scenario: --fail-fast flag
|
147
|
+
Given the file "fails_fast_test.rb":
|
148
|
+
"""
|
149
|
+
class TwoFailures < Minitest::Test
|
150
|
+
i_suck_and_my_tests_are_order_dependent!
|
151
|
+
def test_1
|
152
|
+
raise
|
153
|
+
end
|
154
|
+
def test_2
|
155
|
+
raise
|
156
|
+
end
|
157
|
+
end
|
158
|
+
"""
|
159
|
+
When I run 'mrspec fails_fast_test.rb --fail-fast'
|
160
|
+
Then stdout includes "1 example"
|
161
|
+
|
162
|
+
|
163
|
+
Scenario: -e flag
|
164
|
+
Given the file "spec/first_spec.rb":
|
165
|
+
"""
|
166
|
+
RSpec.describe 'a' do
|
167
|
+
example('b') { }
|
168
|
+
end
|
169
|
+
"""
|
170
|
+
Given the file "test/first_test.rb":
|
171
|
+
"""
|
172
|
+
class FirstTest < Minitest::Test
|
173
|
+
def test_1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
"""
|
177
|
+
And the file "test/second_test.rb":
|
178
|
+
"""
|
179
|
+
class SecondTest < Minitest::Test
|
180
|
+
def test_2
|
181
|
+
end
|
182
|
+
end
|
183
|
+
"""
|
184
|
+
When I run 'mrspec -e Second'
|
185
|
+
Then stdout includes "1 example"
|
186
|
+
And stdout does not include "2 examples"
|
187
|
+
|
188
|
+
|
189
|
+
Scenario: Passing a filename overrides the default pattern
|
190
|
+
Given the file "spec/first_spec.rb":
|
191
|
+
"""
|
192
|
+
RSpec.describe 'first spec' do
|
193
|
+
example('rspec 1') { }
|
194
|
+
end
|
195
|
+
"""
|
196
|
+
Given the file "test/first_test.rb":
|
197
|
+
"""
|
198
|
+
class FirstTest < Minitest::Test
|
199
|
+
def test_minitest_1
|
200
|
+
end
|
201
|
+
end
|
202
|
+
"""
|
203
|
+
And the file "test/second_test.rb":
|
204
|
+
"""
|
205
|
+
class SecondTest < Minitest::Test
|
206
|
+
def test_minitest_2
|
207
|
+
end
|
208
|
+
end
|
209
|
+
"""
|
210
|
+
When I run 'mrspec -f d test/second_test.rb'
|
211
|
+
Then stdout includes "1 example"
|
212
|
+
And stdout includes "minitest 2"
|
213
|
+
And stdout does not include "rspec 1"
|
214
|
+
And stdout does not include "minitest 1"
|
215
|
+
|
216
|
+
|
217
|
+
Scenario: Can add metadata to examples, ie run only tagged tests
|
218
|
+
Given the file "test/tag_test.rb":
|
219
|
+
"""
|
220
|
+
class TagTest < Minitest::Test
|
221
|
+
meta first: true
|
222
|
+
def test_1
|
223
|
+
puts "ran test 1"
|
224
|
+
end
|
225
|
+
|
226
|
+
# multiple tags in meta, and aggregated across metas
|
227
|
+
meta second: true, second2: true
|
228
|
+
meta second3: true
|
229
|
+
def test_2
|
230
|
+
puts "ran test 2"
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_3
|
234
|
+
puts "ran test 3"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
"""
|
238
|
+
|
239
|
+
# only test_1 is tagged w/ first
|
240
|
+
When I run 'mrspec test/tag_test.rb -t first'
|
241
|
+
Then the program ran successfully
|
242
|
+
Then stdout includes "1 example"
|
243
|
+
And stdout includes "ran test 1"
|
244
|
+
And stdout does not include "ran test 2"
|
245
|
+
And stdout does not include "ran test 3"
|
246
|
+
|
247
|
+
# test_2 is tagged w/ second, and second2 (multiple tags in 1 meta)
|
248
|
+
When I run 'mrspec test/tag_test.rb -t second'
|
249
|
+
Then stdout includes "1 example"
|
250
|
+
And stdout includes "ran test 2"
|
251
|
+
And stdout does not include "ran test 1"
|
252
|
+
And stdout does not include "ran test 3"
|
253
|
+
|
254
|
+
When I run 'mrspec test/tag_test.rb -t second2'
|
255
|
+
Then stdout includes "1 example"
|
256
|
+
And stdout includes "ran test 2"
|
257
|
+
And stdout does not include "ran test 1"
|
258
|
+
And stdout does not include "ran test 3"
|
259
|
+
|
260
|
+
# test_2 is tagged with second3 (consolidates metadata until they are used)
|
261
|
+
When I run 'mrspec test/tag_test.rb -t second3'
|
262
|
+
Then stdout includes "1 example"
|
263
|
+
And stdout includes "ran test 2"
|
264
|
+
And stdout does not include "ran test 1"
|
265
|
+
And stdout does not include "ran test 3"
|
266
|
+
|
267
|
+
# for sanity, show that test_3 is actually a test, just not tagged (metadata gets cleared)
|
268
|
+
When I run 'mrspec test/tag_test.rb'
|
269
|
+
Then stdout includes "3 examples"
|
270
|
+
And stdout includes "ran test 1"
|
271
|
+
And stdout includes "ran test 2"
|
272
|
+
And stdout includes "ran test 3"
|
273
|
+
|
274
|
+
|
275
|
+
Scenario: Can add metadata to groups
|
276
|
+
Given the file "tag_groups.rb":
|
277
|
+
"""
|
278
|
+
class Tag1Test < Minitest::Test
|
279
|
+
classmeta tag1: true
|
280
|
+
|
281
|
+
meta tag2: true
|
282
|
+
def test_tagged_with_1_and_2
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_tagged_with_1_only
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
class UntaggedTest < Minitest::Test
|
290
|
+
def test_untagged
|
291
|
+
end
|
292
|
+
end
|
293
|
+
"""
|
294
|
+
|
295
|
+
# tag1 runs all tests in Tag1Test (b/c the tag is on the class)
|
296
|
+
When I run 'mrspec -f d -t tag1 tag_groups.rb'
|
297
|
+
Then the program ran successfully
|
298
|
+
And stdout includes "tagged with 1 and 2"
|
299
|
+
And stdout includes "tagged with 1 only"
|
300
|
+
And stdout does not include "untagged"
|
301
|
+
|
302
|
+
# tag2 runs only Tag1Test#test_tagged_with_1_and_2 (b/c the tag is on the method)
|
303
|
+
When I run 'mrspec -f d -t tag2 tag_groups.rb'
|
304
|
+
Then the program ran successfully
|
305
|
+
And stdout includes "tagged with 1 and 2"
|
306
|
+
And stdout does not include "tagged with 1 only"
|
307
|
+
And stdout does not include "untagged"
|
308
|
+
|
309
|
+
# no tags runs all tests (ignores all tagging)
|
310
|
+
When I run 'mrspec -f d tag_groups.rb'
|
311
|
+
Then the program ran successfully
|
312
|
+
And stdout includes "tagged with 1 and 2"
|
313
|
+
And stdout includes "tagged with 1 only"
|
314
|
+
And stdout includes "untagged"
|
315
|
+
|
316
|
+
Scenario: Intelligently formats Minitest's assertions
|
317
|
+
Given the file "test/some_assertions.rb":
|
318
|
+
"""
|
319
|
+
RSpec.describe 'a' do
|
320
|
+
it('fails1') { expect('rspec-1').to eq 'rspec-2' }
|
321
|
+
it('fails2') { expect(%w[rspec a b c]).to include 'd' }
|
322
|
+
end
|
323
|
+
|
324
|
+
class A < Minitest::Test
|
325
|
+
def test_fails1() assert_equal 'minitest-1', 'minitest-2' end
|
326
|
+
def test_fails2() assert_includes %w[minitest a b c], 'd' end
|
327
|
+
end
|
328
|
+
"""
|
329
|
+
When I run 'mrspec --no-color test/some_assertions.rb'
|
330
|
+
# RSpec eq
|
331
|
+
Then stdout includes 'expected: "rspec-2"'
|
332
|
+
And stdout includes ' got: "rspec-1"'
|
333
|
+
# Minitest assert_equal
|
334
|
+
And stdout includes 'Expected: "minitest-1"'
|
335
|
+
And stdout includes ' Actual: "minitest-2"'
|
336
|
+
|
337
|
+
# RSpec includes
|
338
|
+
And stdout includes 'expected ["rspec", "a", "b", "c"] to include "d"'
|
339
|
+
# Minitest assert_includes
|
340
|
+
And stdout includes 'Expected ["minitest", "a", "b", "c"] to include "d"'
|
341
|
+
|
342
|
+
# Doesn't print Minitest::Assertion class, as if it's an exception
|
343
|
+
And stdout does not include "Minitest::Assertion"
|
344
|
+
|
345
|
+
Scenario: Respects Minitest's lifecycle hooks
|
346
|
+
Given the file "test/lifecycle_test.rb":
|
347
|
+
"""
|
348
|
+
class A < Minitest::Test
|
349
|
+
%w(before_teardown teardown after_teardown before_setup setup after_setup).shuffle.each do |methodname|
|
350
|
+
define_method methodname do
|
351
|
+
@order ||= []
|
352
|
+
@order << methodname
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_1
|
357
|
+
@order << :test_1
|
358
|
+
at_exit { puts "[#{@order.join " "}]" }
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_2
|
362
|
+
@order << :test_2
|
363
|
+
at_exit { puts "[#{@order.join " "}]" }
|
364
|
+
end
|
365
|
+
end
|
366
|
+
"""
|
367
|
+
When I run "mrspec test/lifecycle_test.rb"
|
368
|
+
Then the program ran successfully
|
369
|
+
And stdout includes "[before_setup setup after_setup test_1 before_teardown teardown after_teardown]"
|
370
|
+
And stdout includes "[before_setup setup after_setup test_2 before_teardown teardown after_teardown]"
|
371
|
+
|
372
|
+
|
373
|
+
Scenario: Doesn't get fucked up by Minitest autorunning
|
374
|
+
Given the file "requires_minitest_autorun.rb":
|
375
|
+
"""
|
376
|
+
require 'minitest/autorun'
|
377
|
+
class A < Minitest::Test
|
378
|
+
def test_a
|
379
|
+
p caller.last # will tell us which lib is running this test
|
380
|
+
end
|
381
|
+
end
|
382
|
+
"""
|
383
|
+
When I run "mrspec requires_minitest_autorun.rb"
|
384
|
+
Then stdout includes "rspec/core/runner.rb"
|
385
|
+
And stdout does not include "lib/minitest.rb"
|
386
|
+
|
387
|
+
|
388
|
+
Scenario: Doesn't get fucked up by RSpec autorunning
|
389
|
+
Given the file "requires_rspec_autorun.rb":
|
390
|
+
"""
|
391
|
+
require 'rspec/autorun'
|
392
|
+
|
393
|
+
$load_count ||= 0
|
394
|
+
$load_count += 1
|
395
|
+
|
396
|
+
RSpec.describe 'something' do
|
397
|
+
it 'does whatever' do
|
398
|
+
$run_count ||= 0
|
399
|
+
$run_count += 1
|
400
|
+
puts "load count: #{$load_count}"
|
401
|
+
puts "run count: #{$run_count}"
|
402
|
+
end
|
403
|
+
end
|
404
|
+
"""
|
405
|
+
When I run "mrspec requires_rspec_autorun.rb"
|
406
|
+
Then stdout includes "load count: 1"
|
407
|
+
And stdout includes "run count: 1"
|
408
|
+
And stdout does not include "load count: 2"
|
409
|
+
And stdout does not include "run count: 2"
|
410
|
+
|
411
|
+
|
412
|
+
Scenario: Doesn't depend on RSpec::Mocks or RSpec::Expectations
|
413
|
+
Given the file "no_dev_deps/Gemfile":
|
414
|
+
"""
|
415
|
+
source 'https://rubygems.org'
|
416
|
+
gem 'mrspec', path: "{{root_dir}}"
|
417
|
+
"""
|
418
|
+
When I run "env BUNDLE_GEMFILE=no_dev_deps/Gemfile bundle install"
|
419
|
+
Then the program ran successfully
|
420
|
+
|
421
|
+
Given the file "no_dev_deps/print_results.rb":
|
422
|
+
"""
|
423
|
+
at_exit do
|
424
|
+
exception = $!
|
425
|
+
if exception.kind_of? SystemExit
|
426
|
+
puts "ERROR: SYSTEM EXIT (RSpec raises this if there's a failure)"
|
427
|
+
elsif exception
|
428
|
+
puts "AN ERROR: #{$!.inspect}"
|
429
|
+
else
|
430
|
+
puts "NO ERROR"
|
431
|
+
end
|
432
|
+
|
433
|
+
unexpected_deps = $LOADED_FEATURES.grep(/rspec/).grep(/mocks|expectations/)
|
434
|
+
if unexpected_deps.any?
|
435
|
+
puts "UNEXPECTED DEPS: #{unexpected_deps}"
|
436
|
+
else
|
437
|
+
puts "NO UNEXPECTED DEPS"
|
438
|
+
end
|
439
|
+
end
|
440
|
+
"""
|
441
|
+
And the file "no_dev_deps/test_with_failures.rb":
|
442
|
+
"""
|
443
|
+
require_relative 'print_results'
|
444
|
+
class A < Minitest::Test
|
445
|
+
def test_that_passes() assert_equal 1, 1 end
|
446
|
+
def test_that_fails() assert_equal 1, 2 end
|
447
|
+
def test_that_errors() raise "wat" end
|
448
|
+
def test_that_skips() skip end
|
449
|
+
end
|
450
|
+
"""
|
451
|
+
|
452
|
+
When I run "env BUNDLE_GEMFILE=no_dev_deps/Gemfile bundle exec mrspec no_dev_deps/test_with_failures.rb"
|
453
|
+
Then stderr is empty
|
454
|
+
And stdout includes "4 examples"
|
455
|
+
And stdout includes "2 failures"
|
456
|
+
And stdout includes "1 pending"
|
457
|
+
And stdout includes "ERROR: SYSTEM EXIT"
|
458
|
+
And stdout includes "NO UNEXPECTED DEPS"
|
459
|
+
|
460
|
+
Given the file "no_dev_deps/test_that_passes.rb":
|
461
|
+
"""
|
462
|
+
require_relative 'print_results'
|
463
|
+
class A < Minitest::Test
|
464
|
+
def test_that_passes() assert true end
|
465
|
+
end
|
466
|
+
"""
|
467
|
+
When I run "env BUNDLE_GEMFILE=no_dev_deps/Gemfile bundle exec mrspec -f p no_dev_deps/test_that_passes.rb"
|
468
|
+
Then the program ran successfully
|
469
|
+
And stdout includes "NO ERROR"
|
470
|
+
And stdout includes "NO UNEXPECTED DEPS"
|
471
|
+
|
472
|
+
Scenario: The help screen is custom to mrspec
|
473
|
+
When I run "mrspec -h"
|
474
|
+
Then stdout includes "Usage: mrspec"
|
475
|
+
# Probably add more later
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'haiti'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
proving_grounds_dir = Dir.mktmpdir
|
6
|
+
After { FileUtils.remove_entry proving_grounds_dir }
|
7
|
+
|
8
|
+
Haiti.configure do |config|
|
9
|
+
config.proving_grounds_dir = proving_grounds_dir
|
10
|
+
config.bin_dir = File.expand_path('../../../bin', __FILE__)
|
11
|
+
end
|
12
|
+
|
13
|
+
module GeneralHelpers
|
14
|
+
def pwd
|
15
|
+
Haiti.config.proving_grounds_dir
|
16
|
+
end
|
17
|
+
|
18
|
+
def root_dir
|
19
|
+
@root_dir ||= File.expand_path '../../..', __FILE__
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
When 'I pry' do
|
24
|
+
require "pry"
|
25
|
+
binding.pry
|
26
|
+
end
|
27
|
+
|
28
|
+
Then 'the program ran successfully' do
|
29
|
+
expect(@last_executed.stderr).to eq ""
|
30
|
+
expect(@last_executed.exitstatus).to eq 0
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'mrspec/declare_minitests'
|
2
|
+
require 'rspec/core'
|
3
|
+
|
4
|
+
module MRspec
|
5
|
+
class Configuration < RSpec::Core::Configuration
|
6
|
+
def initialize(*)
|
7
|
+
super
|
8
|
+
disable_monkey_patching!
|
9
|
+
filter_gems_from_backtrace 'mrspec', 'minitest'
|
10
|
+
self.pattern = pattern.sub '*_spec.rb', '{*_spec,*_test,test_*}.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_spec_files(*)
|
14
|
+
super
|
15
|
+
MRspec::DeclareMinitests.call
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'minitest'
|
2
|
+
require 'mrspec/minitest_assertion_for_rspec'
|
3
|
+
|
4
|
+
module MRspec
|
5
|
+
module DeclareMinitests
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def self.call
|
9
|
+
init_minitest
|
10
|
+
wrap_classes Minitest::Runnable.runnables
|
11
|
+
end
|
12
|
+
|
13
|
+
def group_name(klass)
|
14
|
+
klass.name.sub(/^Test/, '').sub(/Test$/, '')
|
15
|
+
end
|
16
|
+
|
17
|
+
def example_name(method_name)
|
18
|
+
# remove test_, and turn underscores into spaces
|
19
|
+
# https://github.com/seattlerb/minitest/blob/f1081566ec6e9e391628bde3a26fb057ad2576a8/lib/minitest/test.rb#L62
|
20
|
+
# remove test_0001_, where the number increments
|
21
|
+
# https://github.com/seattlerb/minitest/blob/f1081566ec6e9e391628bde3a26fb057ad2576a8/lib/minitest/spec.rb#L218-222
|
22
|
+
method_name.sub(/^test_(?:\d{4}_)?/, '').tr('_', ' ')
|
23
|
+
end
|
24
|
+
|
25
|
+
def init_minitest
|
26
|
+
Minitest.reporter = Minitest::CompositeReporter.new # we're not using the reporter, but some plugins, (eg minitest/pride) expect it to be there
|
27
|
+
Minitest.load_plugins
|
28
|
+
Minitest.init_plugins Minitest.process_args([])
|
29
|
+
end
|
30
|
+
|
31
|
+
def wrap_classes(klasses)
|
32
|
+
klasses.each { |klass| wrap_class klass }
|
33
|
+
end
|
34
|
+
|
35
|
+
def wrap_class(klass)
|
36
|
+
example_group = RSpec.describe group_name(klass), klass.class_metadata
|
37
|
+
klass.runnable_methods.each do |method_name|
|
38
|
+
wrap_test example_group, klass, method_name
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def wrap_test(example_group, klass, mname)
|
43
|
+
metadata = klass.example_metadata[mname.intern]
|
44
|
+
example = example_group.example example_name(mname), metadata do
|
45
|
+
instance = Minitest.run_one_method klass, mname
|
46
|
+
next if instance.passed?
|
47
|
+
pending 'skipped' if instance.skipped?
|
48
|
+
error = instance.failure.error
|
49
|
+
raise error unless error.kind_of? Minitest::Assertion
|
50
|
+
raise MinitestAssertionForRSpec.new error
|
51
|
+
end
|
52
|
+
fix_metadata example.metadata, klass.instance_method(mname)
|
53
|
+
end
|
54
|
+
|
55
|
+
def fix_metadata(metadata, method)
|
56
|
+
file, line = method.source_location
|
57
|
+
return unless file && line # not sure when this wouldn't be true, so no tests on it, but hypothetically it could happen
|
58
|
+
metadata[:file_path] = file
|
59
|
+
metadata[:line_number] = line
|
60
|
+
metadata[:location] = "#{file}:#{line}"
|
61
|
+
metadata[:absolute_file_path] = File.expand_path(file)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MRspec
|
2
|
+
# With assertions, we must wrap it in a class that has "RSpec" in the name
|
3
|
+
# https://github.com/rspec/rspec-core/blob/3145e2544e1825bc754d0986e893664afe19abf5/lib/rspec/core/formatters/exception_presenter.rb#L94
|
4
|
+
# This is how RSpec differentiates failures from exceptions (errors get their class printed, failures do not)
|
5
|
+
# We could wrap it in an ExpectationNotMetError, as all their errors seem to be,
|
6
|
+
# but that is defined in rspec-expectations, which we otherwise don't depend on.
|
7
|
+
#
|
8
|
+
# We'll keep the Minitest error messages, though, as they were on par with RSpec's for all the examples I tried
|
9
|
+
class MinitestAssertionForRSpec < Exception
|
10
|
+
def initialize(assertion)
|
11
|
+
super assertion.message
|
12
|
+
set_backtrace assertion.backtrace
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'minitest'
|
2
|
+
|
3
|
+
# Allow Minitest to support RSpec's metadata (eg tagging)
|
4
|
+
# Thus you can tag a test or a class, and then pass `-t mytag` to mrspec,
|
5
|
+
# and it will only run the tagged code.
|
6
|
+
class << Minitest::Runnable
|
7
|
+
# Add metadata to the current class
|
8
|
+
def classmeta(metadata)
|
9
|
+
class_metadata.merge! metadata
|
10
|
+
end
|
11
|
+
|
12
|
+
# Add metadata to the next defined test
|
13
|
+
def meta(metadata)
|
14
|
+
pending_metadata.merge! metadata
|
15
|
+
end
|
16
|
+
|
17
|
+
def class_metadata
|
18
|
+
@selfmetadata ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def example_metadata
|
22
|
+
@metadata ||= Hash.new { |metadata, mname| metadata[mname] = {} }
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def method_added(manme)
|
28
|
+
example_metadata[manme.intern].merge! pending_metadata
|
29
|
+
pending_metadata.clear
|
30
|
+
end
|
31
|
+
|
32
|
+
def pending_metadata
|
33
|
+
@pending_metadata ||= {}
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rspec/core/option_parser'
|
2
|
+
|
3
|
+
class RSpec::Core::Parser
|
4
|
+
# Trying to mitigate the invasiveness of this code.
|
5
|
+
# It's not great, but it's better than unconditionally overriding the method.
|
6
|
+
# We have to do this, b/c OptionParser will print directly to stdout/err
|
7
|
+
# and call `exit`: https://gist.github.com/JoshCheek/7adc25a46e735510558d
|
8
|
+
# The RSpec portion does this, too https://github.com/rspec/rspec-core/blob/3145e2544e1825bc754d0986e893664afe19abf5/lib/rspec/core/option_parser.rb#L267-299
|
9
|
+
# so we need to get between the definition and the parsing to make any changes
|
10
|
+
|
11
|
+
# Save RSpec's parser
|
12
|
+
alias rspec_parser parser
|
13
|
+
|
14
|
+
# Ours calls RSpec's, then modifies values on the returned parser
|
15
|
+
def mrspec_parser(*args, &b)
|
16
|
+
rspec_parser(*args, &b).tap { |parser| parser.banner.gsub! /\brspec\b/, 'mrspec' }
|
17
|
+
end
|
18
|
+
|
19
|
+
# A place to store which method `parser` actually resolves to
|
20
|
+
singleton_class.class_eval { attr_accessor :parser_method }
|
21
|
+
|
22
|
+
# Default it to RSpec's, because requiring this file shouldn't fuck up your environment,
|
23
|
+
# We'll swap the value in the binary, that decision belongs as high in the callstack as we can get it.
|
24
|
+
self.parser_method = instance_method :rspec_parser
|
25
|
+
|
26
|
+
# The actual parser method just delegates to the saved one (ultra-late binding :P)
|
27
|
+
define_method :parser do |*args, &b|
|
28
|
+
self.class.parser_method.bind(self).call(*args, &b)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rspec/core/runner'
|
2
|
+
|
3
|
+
module MRspec
|
4
|
+
class Runner < RSpec::Core::Runner
|
5
|
+
def initialize(*)
|
6
|
+
super
|
7
|
+
# seems like there should be a better way, but I can't figure out what it is
|
8
|
+
files_and_dirs = @options.options[:files_or_directories_to_run]
|
9
|
+
files_and_dirs << 'spec' << 'test' if files_and_dirs.empty?
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/mrspec.rb
ADDED
data/mrspec.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "mrspec/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "mrspec"
|
6
|
+
s.version = MRspec::VERSION
|
7
|
+
s.authors = ["Josh Cheek"]
|
8
|
+
s.email = ["josh.cheek@gmail.com"]
|
9
|
+
s.homepage = "https://github.com/JoshCheek/mrspec"
|
10
|
+
s.summary = %q{Minitest tests + RSpec's test runner}
|
11
|
+
s.description = %q{Allows you to run Minitest tests and specs with RSpec's runner, thus you can write both Minitest and RSpec, side-by-side, and take advantage of the many incredibly helpful features it supports (primarily: better formatters, --colour, --fail-fast, and tagging).}
|
12
|
+
s.license = "MIT"
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = ['mrspec']
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.add_dependency "rspec-core", "~> 3.0"
|
20
|
+
s.add_dependency "minitest", "~> 5.0"
|
21
|
+
|
22
|
+
s.add_development_dependency "haiti", ">= 0.2.2", "< 0.3"
|
23
|
+
s.add_development_dependency "cucumber", "~> 2.0"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mrspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Cheek
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec-core
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: haiti
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.2.2
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0.3'
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 0.2.2
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.3'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: cucumber
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '2.0'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '2.0'
|
75
|
+
description: 'Allows you to run Minitest tests and specs with RSpec''s runner, thus
|
76
|
+
you can write both Minitest and RSpec, side-by-side, and take advantage of the many
|
77
|
+
incredibly helpful features it supports (primarily: better formatters, --colour,
|
78
|
+
--fail-fast, and tagging).'
|
79
|
+
email:
|
80
|
+
- josh.cheek@gmail.com
|
81
|
+
executables:
|
82
|
+
- mrspec
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- ".gitignore"
|
87
|
+
- ".travis.yml"
|
88
|
+
- Gemfile
|
89
|
+
- Readme.md
|
90
|
+
- bin/mrspec
|
91
|
+
- features/mrspec.feature
|
92
|
+
- features/support/env.rb
|
93
|
+
- lib/mrspec.rb
|
94
|
+
- lib/mrspec/configuration.rb
|
95
|
+
- lib/mrspec/declare_minitests.rb
|
96
|
+
- lib/mrspec/minitest_assertion_for_rspec.rb
|
97
|
+
- lib/mrspec/minitest_metadata.rb
|
98
|
+
- lib/mrspec/option_parser.rb
|
99
|
+
- lib/mrspec/runner.rb
|
100
|
+
- lib/mrspec/version.rb
|
101
|
+
- mrspec.gemspec
|
102
|
+
homepage: https://github.com/JoshCheek/mrspec
|
103
|
+
licenses:
|
104
|
+
- MIT
|
105
|
+
metadata: {}
|
106
|
+
post_install_message:
|
107
|
+
rdoc_options: []
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 2.4.1
|
123
|
+
signing_key:
|
124
|
+
specification_version: 4
|
125
|
+
summary: Minitest tests + RSpec's test runner
|
126
|
+
test_files:
|
127
|
+
- features/mrspec.feature
|
128
|
+
- features/support/env.rb
|
129
|
+
has_rdoc:
|