mrspec 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/Readme.md +20 -0
- data/features/mrspec.feature +25 -0
- data/lib/mrspec/add_options_to_rspec_parser.rb +17 -8
- data/lib/mrspec/declare_minitests.rb +40 -15
- data/lib/mrspec/version.rb +1 -1
- data/mrspec.gemspec +5 -1
- data/test/test_parser_monkey_patches.rb +19 -15
- metadata +5 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cdd22bb539e153f142c4077fdce46540ceee9a7f
|
4
|
+
data.tar.gz: b4452df608986b9ffea6c42c4d04c32309f30e43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca074f1e8fccb7bc5d7a16c66f37b9587294b97859655dab04c003923cfb6f52a21b4df80eca30df1c402a3e62a318e67bcb56f75163953575b4703e20e814d8
|
7
|
+
data.tar.gz: b1a4c586ffe977c060fd0e2d4a653e2496582b19e598ec2b06d8c5282c07e6c471e791a39707396165a06b101d447a567908aa964b86e3a8e5794f0f6a7de190
|
data/.travis.yml
CHANGED
data/Readme.md
CHANGED
@@ -235,6 +235,26 @@ because I don't currently have any features I'm trying to add.
|
|
235
235
|
As I maintain this, though, I'll begin implementing them,
|
236
236
|
as it will be easier in the end :)
|
237
237
|
|
238
|
+
Run mrpsec as the Rake Test Task
|
239
|
+
-------------------------------
|
240
|
+
Add this to your `Rakefile` in your Rails App Root Dir
|
241
|
+
below`Rails.application.load_tasks`
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
# ----- To run minitest is the bit that I added -----
|
245
|
+
# I know it's ridiculous, but there isn't a better way, it's what RSpec does, too:
|
246
|
+
# https://github.com/rspec/rspec-rails/blob/682a12067eab233c646057f984692e3b70749f32/lib/rspec/rails/tasks/rspec.rake#L2-L4
|
247
|
+
tasks = Rake.application.instance_variable_get('@tasks')
|
248
|
+
tasks['test'].clear_actions if tasks['test']
|
249
|
+
tasks['spec'].clear_actions if tasks['spec']
|
250
|
+
|
251
|
+
mrspec = Proc.new do
|
252
|
+
sh 'mrspec', '--fail-fast'
|
253
|
+
end
|
254
|
+
|
255
|
+
task :test, &mrspec
|
256
|
+
task :spec, &mrspec
|
257
|
+
```
|
238
258
|
|
239
259
|
Attribution
|
240
260
|
-----------
|
data/features/mrspec.feature
CHANGED
@@ -592,6 +592,7 @@ Feature: mrspec
|
|
592
592
|
Then the program ran successfully
|
593
593
|
And stdout includes "I got loaded!"
|
594
594
|
|
595
|
+
|
595
596
|
Scenario: Correctly hooks up everything up to enable advanced analysis features
|
596
597
|
Given the file "whatev.rb":
|
597
598
|
"""
|
@@ -611,3 +612,27 @@ Feature: mrspec
|
|
611
612
|
"""
|
612
613
|
When I run 'mrspec whatev.rb'
|
613
614
|
Then stdout includes "misspell"
|
615
|
+
|
616
|
+
|
617
|
+
Scenario: Can invoke Minitest::Spec with line numbers (#21)
|
618
|
+
Given the file "line_nums_spec.rb":
|
619
|
+
"""
|
620
|
+
require 'minitest/spec'
|
621
|
+
describe "group" do
|
622
|
+
it "passing-example" do
|
623
|
+
assert_equal true, true
|
624
|
+
end
|
625
|
+
it "failing-example" do
|
626
|
+
assert_equal true, false
|
627
|
+
end
|
628
|
+
end
|
629
|
+
"""
|
630
|
+
|
631
|
+
When I run "mrspec line_nums_spec.rb --format progress"
|
632
|
+
Then stdout includes "2 examples, 1 failure"
|
633
|
+
|
634
|
+
When I run "mrspec line_nums_spec.rb:3 --format progress"
|
635
|
+
Then stdout includes "1 example, 0 failures"
|
636
|
+
|
637
|
+
When I run "mrspec line_nums_spec.rb:6 --format progress"
|
638
|
+
Then stdout includes "1 example, 1 failure"
|
@@ -1,5 +1,10 @@
|
|
1
|
-
|
1
|
+
# Since 3.5, it's worth checking to see if we can get rid of this class and just
|
2
|
+
# hijack it in the runner or something. Essentially, they moved away from having
|
3
|
+
# the parser calling exit and printing directly, so we might be able to sit above
|
4
|
+
# it and compose it rather than going into its guts and guerilla patching it.
|
5
|
+
# But not going to do that now b/c got shit to do w/ my life, yo.
|
2
6
|
|
7
|
+
require 'rspec/core/option_parser'
|
3
8
|
class RSpec::Core::Parser
|
4
9
|
# Trying to mitigate the invasiveness of this code.
|
5
10
|
# It's not great, but it's better than unconditionally overriding the method.
|
@@ -13,8 +18,8 @@ class RSpec::Core::Parser
|
|
13
18
|
public :rspec_parser
|
14
19
|
|
15
20
|
# Ours calls RSpec's, then modifies values on the returned parser
|
16
|
-
def mrspec_parser(*args, &b)
|
17
|
-
option_parser = rspec_parser(*args, &b)
|
21
|
+
def mrspec_parser(options, *args, &b)
|
22
|
+
option_parser = rspec_parser(options, *args, &b)
|
18
23
|
|
19
24
|
# update the program name
|
20
25
|
option_parser.banner.gsub! /\brspec\b/, 'mrspec'
|
@@ -23,11 +28,7 @@ class RSpec::Core::Parser
|
|
23
28
|
# calling exit and toplevel puts, b/c that's what RSpec's does https://github.com/rspec/rspec-core/blob/c7c1154934c42b5f6905bb7bd22025fe6c8a816c/lib/rspec/core/option_parser.rb#L290
|
24
29
|
# and I don't feel like figuring out how to work around it.
|
25
30
|
option_parser.on('-v', '--version', 'Display the version.') do
|
26
|
-
|
27
|
-
"rspec-core #{RSpec::Core::Version::STRING}\n"\
|
28
|
-
"minitest #{Minitest::VERSION}\n"\
|
29
|
-
"wwhhiae2c #{ErrorToCommunicate::VERSION}\n"
|
30
|
-
exit
|
31
|
+
options[:runner] = method :print_mrspec_version
|
31
32
|
end
|
32
33
|
|
33
34
|
format_description = option_parser.top.short['f'].desc
|
@@ -50,4 +51,12 @@ class RSpec::Core::Parser
|
|
50
51
|
define_method :parser do |*args, &b|
|
51
52
|
self.class.parser_method.bind(self).call(*args, &b)
|
52
53
|
end
|
54
|
+
|
55
|
+
def print_mrspec_version(_opts, _err, out)
|
56
|
+
out.puts "mrspec #{MRspec::VERSION}\n"\
|
57
|
+
"rspec-core #{RSpec::Core::Version::STRING}\n"\
|
58
|
+
"minitest #{Minitest::VERSION}\n"\
|
59
|
+
"wwhhiae2c #{ErrorToCommunicate::VERSION}\n"
|
60
|
+
end
|
53
61
|
end
|
62
|
+
|
@@ -39,15 +39,18 @@ module MRspec
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def wrap_class(rspec, klass)
|
42
|
-
|
43
|
-
klass.
|
44
|
-
|
45
|
-
|
42
|
+
tests = get_tests(klass)
|
43
|
+
metadata = initial_metadata tests, klass.class_metadata, -1
|
44
|
+
group = rspec.describe group_name(klass), metadata
|
45
|
+
tests.each { |mname, file, line| wrap_test group, klass, mname, file, line }
|
46
46
|
end
|
47
47
|
|
48
|
-
def wrap_test(example_group, klass, mname)
|
49
|
-
metadata =
|
50
|
-
|
48
|
+
def wrap_test(example_group, klass, mname, file, line)
|
49
|
+
metadata = initial_metadata [[mname, file, line]],
|
50
|
+
klass.example_metadata[mname.intern],
|
51
|
+
0
|
52
|
+
|
53
|
+
example = example_group.example example_name(mname), metadata do
|
51
54
|
instance = Minitest.run_one_method klass, mname
|
52
55
|
next if instance.passed?
|
53
56
|
pending 'skipped' if instance.skipped?
|
@@ -55,16 +58,38 @@ module MRspec
|
|
55
58
|
raise error unless error.kind_of? Minitest::Assertion
|
56
59
|
raise MinitestAssertionForRSpec.new error
|
57
60
|
end
|
58
|
-
fix_metadata example.metadata, klass.instance_method(mname)
|
59
61
|
end
|
60
62
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
def get_tests(klass)
|
64
|
+
klass.runnable_methods
|
65
|
+
.map { |mname| [mname, *klass.instance_method(mname).source_location] }
|
66
|
+
.sort_by { |name, file, line| line }
|
67
|
+
end
|
68
|
+
|
69
|
+
def initial_metadata(tests, existing_metadat, offset)
|
70
|
+
# There is a disagreement here:
|
71
|
+
# In RSpec, each describe block is its own example group, so the group will
|
72
|
+
# all be defined in the same file. In Minitest, the example group is a class,
|
73
|
+
# which can be reopened, thus the group can exist in multiple files.
|
74
|
+
# I'm just going to ignore it for now, but prob the right thing to do is
|
75
|
+
# to split the test methods into groups based on what file they are defined
|
76
|
+
# in, and then what class they are defined in (currently, it is only what
|
77
|
+
# class they are defined in)
|
78
|
+
#
|
79
|
+
# Leaving mrspec stuff in the backtrace, though, that way if we can't
|
80
|
+
# successfully guess the caller, then it's more helpful as someone tries
|
81
|
+
# to figure out wtf happened
|
82
|
+
guessed_caller_entry = nil
|
83
|
+
tests
|
84
|
+
.select { |name, file, line| file && line }
|
85
|
+
.take(1)
|
86
|
+
.each { |_, file, line| guessed_caller_entry = "#{file}:#{line+offset}" }
|
87
|
+
|
88
|
+
metadata = {}
|
89
|
+
metadata[:caller] = [guessed_caller_entry, *caller] if guessed_caller_entry
|
90
|
+
metadata.merge! existing_metadat
|
91
|
+
|
92
|
+
metadata
|
68
93
|
end
|
69
94
|
end
|
70
95
|
end
|
data/lib/mrspec/version.rb
CHANGED
data/mrspec.gemspec
CHANGED
@@ -16,7 +16,11 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.executables = ['mrspec']
|
17
17
|
s.require_paths = ['lib']
|
18
18
|
|
19
|
-
|
19
|
+
# b/c we go into the guts of RSpec, we're sensitive to private API changes,
|
20
|
+
# in this case, we need https://github.com/rspec/rspec-core/commit/d52c969
|
21
|
+
# which was released as part of v3.5.0
|
22
|
+
s.add_dependency "rspec-core", "~> 3.5"
|
23
|
+
|
20
24
|
s.add_dependency "minitest", "~> 5.0"
|
21
25
|
s.add_dependency "what_weve_got_here_is_an_error_to_communicate", "~> 0.0.8"
|
22
26
|
|
@@ -3,6 +3,7 @@ require 'support/helper'
|
|
3
3
|
|
4
4
|
class TestParserMonkeyPatches < Minitest::Spec
|
5
5
|
Parser = RSpec::Core::Parser
|
6
|
+
ConfigurationOptions = RSpec::Core::ConfigurationOptions
|
6
7
|
|
7
8
|
def rspec_parser
|
8
9
|
Parser.instance_method :rspec_parser
|
@@ -26,15 +27,19 @@ class TestParserMonkeyPatches < Minitest::Spec
|
|
26
27
|
end
|
27
28
|
|
28
29
|
describe '#mrspec_parser' do
|
29
|
-
def record_hostile_parsing(
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
stdout
|
30
|
+
def record_hostile_parsing(parser_method_name, flag)
|
31
|
+
# This is performed by Runner.run
|
32
|
+
original_parser_method = Parser.parser_method
|
33
|
+
Parser.parser_method = Parser.instance_method parser_method_name
|
34
|
+
options = ConfigurationOptions.new([])
|
35
|
+
result = Parser.parse([flag])
|
36
|
+
stderr = StringIO.new
|
37
|
+
stdout = StringIO.new
|
38
|
+
result[:runner].call(options, stderr, stdout)
|
39
|
+
assert_empty stderr.string
|
40
|
+
stdout.string
|
41
|
+
ensure
|
42
|
+
Parser.parser_method = original_parser_method
|
38
43
|
end
|
39
44
|
|
40
45
|
it 'returns the original #rspec_parser' do
|
@@ -50,10 +55,10 @@ class TestParserMonkeyPatches < Minitest::Spec
|
|
50
55
|
end
|
51
56
|
|
52
57
|
it 'overrides -v and --version includes the Mrspec version, the RSpec::Core version, the Minitest version, and the ErrorToCommunicate version' do
|
53
|
-
rspec_version = record_hostile_parsing
|
54
|
-
rspec_v = record_hostile_parsing
|
55
|
-
mrspec_version = record_hostile_parsing
|
56
|
-
mrspec_v = record_hostile_parsing
|
58
|
+
rspec_version = record_hostile_parsing :rspec_parser, '--version'
|
59
|
+
rspec_v = record_hostile_parsing :rspec_parser, '-v'
|
60
|
+
mrspec_version = record_hostile_parsing :mrspec_parser, '--version'
|
61
|
+
mrspec_v = record_hostile_parsing :mrspec_parser, '-v'
|
57
62
|
|
58
63
|
# RSpec version parser defines both of these flags to return its version
|
59
64
|
assert_equal rspec_version, rspec_v
|
@@ -73,8 +78,7 @@ class TestParserMonkeyPatches < Minitest::Spec
|
|
73
78
|
it 'sets the correct description for the versions'
|
74
79
|
|
75
80
|
it 'includes the what_weve_got_here_is_an_error_to_communicate formatter in the help screen' do
|
76
|
-
|
77
|
-
help = record_hostile_parsing parser, '--help'
|
81
|
+
help = record_hostile_parsing :mrspec_parser, '--help'
|
78
82
|
formatters = help.lines
|
79
83
|
.drop_while { |l| l !~ /--format/ }
|
80
84
|
.drop(1)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mrspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Cheek
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec-core
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '3.
|
19
|
+
version: '3.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '3.
|
26
|
+
version: '3.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
version: '0'
|
142
142
|
requirements: []
|
143
143
|
rubyforge_project:
|
144
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.8
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Minitest and RSpec, sitting in a tree, T. E. S. T. I. N. G!
|
@@ -153,4 +153,3 @@ test_files:
|
|
153
153
|
- test/test_configuration.rb
|
154
154
|
- test/test_mrspec.rb
|
155
155
|
- test/test_parser_monkey_patches.rb
|
156
|
-
has_rdoc:
|