1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2019-01-20 20:38:27 +00:00
parent 1c53f86bd9
commit 58573c33e4
6 changed files with 88 additions and 26 deletions

View file

@ -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.

View file

@ -1,8 +1,17 @@
require 'mspec/helpers/io'
class ComplainMatcher
def initialize(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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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")