From 58573c33e4720315ed27491e31dcc22892e1ce95 Mon Sep 17 00:00:00 2001 From: eregon Date: Sun, 20 Jan 2019 20:38:27 +0000 Subject: [PATCH] Update to ruby/mspec@e9a482d git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- spec/mspec/README.md | 29 ++++++------- spec/mspec/lib/mspec/matchers/complain.rb | 19 ++++++--- spec/mspec/lib/mspec/matchers/raise_error.rb | 7 +-- spec/mspec/lib/mspec/utils/warnings.rb | 2 +- spec/mspec/spec/matchers/complain_spec.rb | 45 ++++++++++++++++++++ spec/mspec/spec/matchers/raise_error_spec.rb | 12 ++++++ 6 files changed, 88 insertions(+), 26 deletions(-) diff --git a/spec/mspec/README.md b/spec/mspec/README.md index 23986c92e4..a53ebb4336 100644 --- a/spec/mspec/README.md +++ b/spec/mspec/README.md @@ -2,13 +2,14 @@ ## Overview -MSpec is a specialized framework that is syntax-compatible with RSpec for -basic things like 'describe', 'it' blocks and 'before', 'after' actions. MSpec -contains additional features that assist in writing the RubySpecs used by -multiple Ruby implementations. +MSpec is a specialized framework that is syntax-compatible with RSpec 2 for +basic things like `describe`, `it` blocks and `before`, `after` actions. +MSpec contains additional features that assist in writing specs for +Ruby implementations in [ruby/spec](https://github.com/ruby/spec). MSpec attempts to use the simplest Ruby language features so that beginning -Ruby implementations can run the Ruby specs. +Ruby implementations can run the Ruby specs. For example, no file from the +standard library or RubyGems is necessary to run MSpec. MSpec is not intended as a replacement for RSpec. MSpec attempts to provide a subset of RSpec's features in some cases and a superset in others. It does not @@ -23,8 +24,6 @@ specs in a manner compatible with multiple Ruby implementations. 2. MSpec provides a different shared spec implementation specifically designed to ease writing specs for the numerous aliased methods in Ruby. - The MSpec shared spec implementation should not conflict with RSpec's own - shared behavior facility. 3. MSpec provides various helper methods to simplify some specs, for example, creating temporary file names. @@ -33,6 +32,10 @@ specs in a manner compatible with multiple Ruby implementations. configuration facility with a default project file and user-specific overrides. + 5. MSpec support "tagging", that is excluding specs known as failing on + a particular Ruby implementation, and automatically adding and removing tags + while running the specs. + ## Requirements MSpec requires Ruby 2.3 or more recent. @@ -63,29 +66,21 @@ After installing the gem dependencies, the specs can be run as follows: ruby -S bundle exec rspec ``` -Or - -```bash -ruby -S rake -``` - To run an individual spec file, use the following example: ```bash ruby -S bundle exec rspec spec/helpers/ruby_exe_spec.rb ``` - ## Documentation -See http://ruby.github.io/rubyspec.github.io/ - +See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) in ruby/spec +for a list of matchers and how to use `mspec`. ## Source Code See https://github.com/ruby/mspec - ## License See the LICENSE in the source code. diff --git a/spec/mspec/lib/mspec/matchers/complain.rb b/spec/mspec/lib/mspec/matchers/complain.rb index 4bcb255040..22b8be17e1 100644 --- a/spec/mspec/lib/mspec/matchers/complain.rb +++ b/spec/mspec/lib/mspec/matchers/complain.rb @@ -1,8 +1,17 @@ require 'mspec/helpers/io' class ComplainMatcher - def initialize(complaint) - @complaint = complaint + def initialize(complaint = nil, options = nil) + # the proper solution is to use double splat operator e.g. + # def initialize(complaint = nil, **options) + # but we are trying to minimize language features required to run MSpec + if complaint.is_a?(Hash) + @complaint = nil + @options = complaint + else + @complaint = complaint + @options = options || {} + end end def matches?(proc) @@ -10,7 +19,7 @@ class ComplainMatcher @verbose = $VERBOSE begin err = $stderr = IOStub.new - $VERBOSE = false + $VERBOSE = @options.key?(:verbose) ? @options[:verbose] : false Thread.current[:in_mspec_complain_matcher] = true proc.call ensure @@ -54,7 +63,7 @@ class ComplainMatcher end module MSpecMatchers - private def complain(complaint=nil) - ComplainMatcher.new(complaint) + private def complain(complaint = nil, options = nil) + ComplainMatcher.new(complaint, options) end end diff --git a/spec/mspec/lib/mspec/matchers/raise_error.rb b/spec/mspec/lib/mspec/matchers/raise_error.rb index a051ea12f7..8350e25794 100644 --- a/spec/mspec/lib/mspec/matchers/raise_error.rb +++ b/spec/mspec/lib/mspec/matchers/raise_error.rb @@ -12,6 +12,9 @@ class RaiseErrorMatcher rescue Exception => actual @actual = actual if matching_exception?(actual) + # The block has its own expectations and will throw an exception if it fails + @block[actual] if @block + return true else raise actual @@ -20,6 +23,7 @@ class RaiseErrorMatcher def matching_exception?(exc) return false unless @exception === exc + if @message then case @message when String @@ -29,9 +33,6 @@ class RaiseErrorMatcher end end - # The block has its own expectations and will throw an exception if it fails - @block[exc] if @block - return true end diff --git a/spec/mspec/lib/mspec/utils/warnings.rb b/spec/mspec/lib/mspec/utils/warnings.rb index 4d23474236..7c2bc6fe88 100644 --- a/spec/mspec/lib/mspec/utils/warnings.rb +++ b/spec/mspec/lib/mspec/utils/warnings.rb @@ -51,7 +51,7 @@ if RUBY_ENGINE == "ruby" and ruby_version_is("2.4") when /hash\/shared\/index\.rb:\d+: warning: Hash#index is deprecated; use Hash#key/ when /env\/shared\/key\.rb:\d+: warning: ENV\.index is deprecated; use ENV\.key/ when /exponent(_spec)?\.rb:\d+: warning: in a\*\*b, b may be too big/ - when /enumerator\/(new|initialize_spec)\.rb:\d+: warning: Enumerator\.new without a block is deprecated/ + when /enumerator\/(new_spec|initialize_spec)\.rb:\d+: warning: Enumerator\.new without a block is deprecated/ else $stderr.write message end diff --git a/spec/mspec/spec/matchers/complain_spec.rb b/spec/mspec/spec/matchers/complain_spec.rb index 709b57be6c..83ecb70622 100644 --- a/spec/mspec/spec/matchers/complain_spec.rb +++ b/spec/mspec/spec/matchers/complain_spec.rb @@ -49,4 +49,49 @@ describe ComplainMatcher do matcher.negative_failure_message.should == ["Expected warning not to match: /ou/", "but got: \"ouch\""] end + + context "`verbose` option specified" do + before do + $VERBOSE, @verbose = nil, $VERBOSE + end + + after do + $VERBOSE = @verbose + end + + it "sets $VERBOSE with specified second optional parameter" do + verbose = nil + proc = lambda { verbose = $VERBOSE } + + ComplainMatcher.new(nil, verbose: true).matches?(proc) + verbose.should == true + + ComplainMatcher.new(nil, verbose: false).matches?(proc) + verbose.should == false + end + + it "sets $VERBOSE with false by default" do + verbose = nil + proc = lambda { verbose = $VERBOSE } + + ComplainMatcher.new(nil).matches?(proc) + verbose.should == false + end + + it "does not have side effect" do + proc = lambda { safe_value = $VERBOSE } + + lambda do + ComplainMatcher.new(nil, verbose: true).matches?(proc) + end.should_not change { $VERBOSE } + end + + it "accepts a verbose level as single argument" do + verbose = nil + proc = lambda { verbose = $VERBOSE } + + ComplainMatcher.new(verbose: true).matches?(proc) + verbose.should == true + end + end end diff --git a/spec/mspec/spec/matchers/raise_error_spec.rb b/spec/mspec/spec/matchers/raise_error_spec.rb index 7c93f0f64c..28e1ea69a7 100644 --- a/spec/mspec/spec/matchers/raise_error_spec.rb +++ b/spec/mspec/spec/matchers/raise_error_spec.rb @@ -74,6 +74,18 @@ describe RaiseErrorMatcher do ["Expected ExpectedException (expected)", "but got UnexpectedException (unexpected)"] end + it "provides a useful failure message when the proc raises the expected exception with an unexpected message" do + exc = ExpectedException.new("unexpected") + matcher = RaiseErrorMatcher.new(ExpectedException, "expected") + + matcher.matching_exception?(exc).should == false + lambda { + matcher.matches?(Proc.new { raise exc }) + }.should raise_error(ExpectedException) + matcher.failure_message.should == + ["Expected ExpectedException (expected)", "but got ExpectedException (unexpected)"] + end + it "provides a useful failure message when no exception is raised" do proc = Proc.new { 120 } matcher = RaiseErrorMatcher.new(ExpectedException, "expected")