mrspec 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e3716393cd836e1e228ee410a752fa456251a14a
4
- data.tar.gz: db2dd4b64131c69a5e515553851200758f07b7d9
3
+ metadata.gz: cdd22bb539e153f142c4077fdce46540ceee9a7f
4
+ data.tar.gz: b4452df608986b9ffea6c42c4d04c32309f30e43
5
5
  SHA512:
6
- metadata.gz: 2a337f4dff9c32fe226680d45d3168a5de4ccd22dc133d9f99c77e49d9fe14806a0634df8b0633840bb7ba3cc0d3a04b3ff99edb5663f9a9da742bf5f72b8663
7
- data.tar.gz: bb1f71b60212884a1bebc4e591fbd2e820f79dd7285365ebccadff6f2a19c9b424a59d3f4ac389c2da8724282409f92bbb5cdfe2b9bd212d9acfacebaf199bce
6
+ metadata.gz: ca074f1e8fccb7bc5d7a16c66f37b9587294b97859655dab04c003923cfb6f52a21b4df80eca30df1c402a3e62a318e67bcb56f75163953575b4703e20e814d8
7
+ data.tar.gz: b1a4c586ffe977c060fd0e2d4a653e2496582b19e598ec2b06d8c5282c07e6c471e791a39707396165a06b101d447a567908aa964b86e3a8e5794f0f6a7de190
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
  script: bin/mrspec --colour --format documentation && cucumber
3
3
  rvm:
4
- - 1.9.3
5
4
  - 2.0.0
6
5
  - 2.1.2
7
6
  - 2.2.2
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
  -----------
@@ -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
- require 'rspec/core/option_parser'
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
- $stdout.puts "mrspec #{MRspec::VERSION}\n"\
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
- example_group = rspec.describe group_name(klass), klass.class_metadata
43
- klass.runnable_methods.each do |method_name|
44
- wrap_test example_group, klass, method_name
45
- end
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 = klass.example_metadata[mname.intern]
50
- example = example_group.example example_name(mname), metadata do
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 fix_metadata(metadata, method)
62
- file, line = method.source_location
63
- return unless file && line # not sure when this wouldn't be true, so no tests on it, but hypothetically it could happen
64
- metadata[:file_path] = file
65
- metadata[:line_number] = line
66
- metadata[:location] = "#{file}:#{line}"
67
- metadata[:absolute_file_path] = File.expand_path(file)
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
@@ -1,3 +1,3 @@
1
1
  module MRspec
2
- VERSION = '0.3.1'
2
+ VERSION = '0.3.2'
3
3
  end
@@ -16,7 +16,11 @@ Gem::Specification.new do |s|
16
16
  s.executables = ['mrspec']
17
17
  s.require_paths = ['lib']
18
18
 
19
- s.add_dependency "rspec-core", "~> 3.2"
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(option_parser, flag)
30
- stdout, stderr, *rest = capture_io do
31
- begin option_parser.parse([flag])
32
- rescue SystemExit
33
- end
34
- end
35
- assert_empty rest
36
- assert_empty stderr
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 Parser.new([]).rspec_parser({}), '--version'
54
- rspec_v = record_hostile_parsing Parser.new([]).rspec_parser({}), '-v'
55
- mrspec_version = record_hostile_parsing Parser.new([]).mrspec_parser({}), '--version'
56
- mrspec_v = record_hostile_parsing Parser.new([]).mrspec_parser({}), '-v'
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
- parser = Parser.new([]).mrspec_parser({})
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.1
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: 2016-02-17 00:00:00.000000000 Z
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.2'
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.2'
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.4.8
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: