Skip to content

Commit

Permalink
Update to ruby/spec@41bf282
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Feb 28, 2020
1 parent 5d21050 commit a0f5ff4
Show file tree
Hide file tree
Showing 75 changed files with 851 additions and 143 deletions.
54 changes: 46 additions & 8 deletions spec/ruby/CONTRIBUTING.md
Expand Up @@ -53,6 +53,8 @@ which indicates the file was generated but the method unspecified.
Here is a list of frequently-used matchers, which should be enough for most specs.
There are a few extra specific matchers used in the couple specs that need it.

#### Comparison matchers

```ruby
(1 + 2).should == 3 # Calls #==
(1 + 2).should_not == 5
Expand All @@ -66,7 +68,11 @@ File.should equal(File) # Calls #equal? (tests identity)
4.should > 3

"Hello".should =~ /l{2}/ # Calls #=~ (Regexp match)
```

#### Predicate matchers

```ruby
[].should be_empty # Calls #empty?
[1,2,3].should include(2) # Calls #include?

Expand All @@ -82,8 +88,13 @@ Numeric.should be_ancestor_of(Float) # Float.ancestors.include?(Numeric)
3.14.should respond_to(:to_i) # Calls #respond_to?
Fixnum.should have_instance_method(:+)
Array.should have_method(:new)
# Also have_constant, have_private_instance_method, have_singleton_method, etc
```

Also `have_constant`, `have_private_instance_method`, `have_singleton_method`, etc.

#### Exception matchers

```ruby
-> {
raise "oops"
}.should raise_error(RuntimeError, /oops/)
Expand All @@ -95,11 +106,20 @@ Array.should have_method(:new)
e.message.should include("oops")
e.cause.should == nil
}
```

##### should_not raise_error

# To avoid! Instead, use an expectation testing what the code in the lambda does.
# If an exception is raised, it will fail the example anyway.
**To avoid!** Instead, use an expectation testing what the code in the lambda does.
If an exception is raised, it will fail the example anyway.

```ruby
-> { ... }.should_not raise_error
```

#### Warning matcher

```ruby
-> {
Fixnum
}.should complain(/constant ::Fixnum is deprecated/) # Expect a warning
Expand All @@ -110,6 +130,8 @@ Array.should have_method(:new)
Different guards are available as defined by mspec.
Here is a list of the most commonly-used guards:

#### Version guards

```ruby
ruby_version_is ""..."2.4" do
# Specs for RUBY_VERSION < 2.4
Expand All @@ -118,7 +140,11 @@ end
ruby_version_is "2.4" do
# Specs for RUBY_VERSION >= 2.4
end
```

#### Platform guards

```ruby
platform_is :windows do
# Specs only valid on Windows
end
Expand All @@ -140,34 +166,46 @@ end
big_endian do
# Big-endian platform
end
```

#### Guard for bug

In case there is a bug in MRI but the expected behavior is obvious.
First, file a bug at https://bugs.ruby-lang.org/.
It is better to use a `ruby_version_is` guard if there was a release with the fix.

# In case there is a bug in MRI but the expected behavior is obvious
# First file a bug at https://bugs.ruby-lang.org/
# It is better to use a ruby_version_is guard if there was a release with the fix
```ruby
ruby_bug '#13669', ''...'2.5' do
it "works like this" do
# Specify the expected behavior here, not the bug
end
end
```

#### Combining guards

# Combining guards
```ruby
guard -> { platform_is :windows and ruby_version_is ""..."2.5" } do
# Windows and RUBY_VERSION < 2.5
end

guard_not -> { platform_is :windows and ruby_version_is ""..."2.5" } do
# The opposite
end
```

# Custom guard
#### Custom guard

```ruby
max_uint = (1 << 32) - 1
guard -> { max_uint <= fixnum_max } do
end
```

Custom guards are better than a simple `if` as they allow [mspec commands](https://github.com/ruby/mspec/issues/30#issuecomment-312487779) to work properly.

#### Implementation-specific behaviors

In general, the usage of guards should be minimized as possible.

There are no guards to define implementation-specific behavior because
Expand Down
3 changes: 1 addition & 2 deletions spec/ruby/README.md
@@ -1,7 +1,6 @@
# The Ruby Spec Suite

[![Actions Build Status](https://github.com/ruby/spec/workflows/CI/badge.svg?branch=master)](https://github.com/ruby/spec/actions)
[![Windows Actions Build Status](https://github.com/ruby/spec/workflows/Windows/badge.svg?branch=master)](https://github.com/ruby/spec/actions)
[![Actions Build Status](https://github.com/ruby/spec/workflows/CI/badge.svg)](https://github.com/ruby/spec/actions)
[![Gitter](https://badges.gitter.im/ruby/spec.svg)](https://gitter.im/ruby/spec)

The Ruby Spec Suite, abbreviated `ruby/spec`, is a test suite for the behavior of the Ruby programming language.
Expand Down
33 changes: 33 additions & 0 deletions spec/ruby/command_line/dash_l_spec.rb
@@ -0,0 +1,33 @@
require_relative '../spec_helper'

describe "The -l command line option" do
before :each do
@names = fixture __FILE__, "full_names.txt"
end

it "chomps lines with default separator" do
ruby_exe('puts $_.end_with?("\n")', options: "-n -l", escape: true,
args: " < #{@names}").should ==
"false\nfalse\nfalse\n"
end

ruby_version_is "2.5" do
it "chomps last line based on $/" do
ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"alice j\nbob field\njames grey\n"
end
end

it "sets $\\ to the value of $/" do
ruby_exe("puts $\\ == $/", options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"true\ntrue\ntrue\n"
end

it "sets $-l" do
ruby_exe("puts $-l", options: "-n -l", escape: true,
args: " < #{@names}").should ==
"true\ntrue\ntrue\n"
end
end
13 changes: 11 additions & 2 deletions spec/ruby/core/array/shared/slice.rb
Expand Up @@ -461,7 +461,7 @@ def to.to_int() -2 end
it "raises a RangeError when the start index is out of range of Fixnum" do
array = [1, 2, 3, 4, 5, 6]
obj = mock('large value')
obj.should_receive(:to_int).and_return(0x8000_0000_0000_0000_0000)
obj.should_receive(:to_int).and_return(bignum_value)
-> { array.send(@method, obj) }.should raise_error(RangeError)

obj = 8e19
Expand All @@ -471,10 +471,19 @@ def to.to_int() -2 end
it "raises a RangeError when the length is out of range of Fixnum" do
array = [1, 2, 3, 4, 5, 6]
obj = mock('large value')
obj.should_receive(:to_int).and_return(0x8000_0000_0000_0000_0000)
obj.should_receive(:to_int).and_return(bignum_value)
-> { array.send(@method, 1, obj) }.should raise_error(RangeError)

obj = 8e19
-> { array.send(@method, 1, obj) }.should raise_error(RangeError)
end

it "raises a type error if a range is passed with a length" do
->{ [1, 2, 3].send(@method, 1..2, 1) }.should raise_error(TypeError)
end

it "raises a RangeError if passed a range with a bound that is too large" do
-> { "hello".send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError)
-> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError)
end
end
6 changes: 6 additions & 0 deletions spec/ruby/core/binding/eval_spec.rb
Expand Up @@ -131,4 +131,10 @@
bind, meth = obj.get_binding_with_send_and_method
bind.eval("__method__").should == meth
end

it "reflects refinements activated in the binding scope" do
bind = BindingSpecs::Refined.refined_binding

bind.eval("'bar'.foo").should == "foo"
end
end
14 changes: 14 additions & 0 deletions spec/ruby/core/binding/fixtures/classes.rb
Expand Up @@ -49,4 +49,18 @@ def get_binding_in_block
end
end
end

module AddFooToString
refine(String) do
def foo
"foo"
end
end
end
class Refined
using AddFooToString
def self.refined_binding
binding
end
end
end
6 changes: 6 additions & 0 deletions spec/ruby/core/file/realpath_spec.rb
Expand Up @@ -67,6 +67,12 @@
it "raises Errno::ENOENT if the symlink points to an absent file" do
-> { File.realpath(@fake_link) }.should raise_error(Errno::ENOENT)
end

it "converts the argument with #to_path" do
path = mock("path")
path.should_receive(:to_path).and_return(__FILE__)
File.realpath(path).should == File.realpath(__FILE__ )
end
end
end

Expand Down
9 changes: 9 additions & 0 deletions spec/ruby/core/file/stat_spec.rb
Expand Up @@ -41,5 +41,14 @@
st.file?.should == true
st.symlink?.should == false
end

it "returns an error when given missing non-ASCII path" do
missing_path = "/missingfilepath\xE3E4".force_encoding("ASCII-8BIT")
-> {
File.stat(missing_path)
}.should raise_error(Errno::ENOENT) { |e|
e.message.should include(missing_path)
}
end
end
end
5 changes: 5 additions & 0 deletions spec/ruby/core/integer/lte_spec.rb
Expand Up @@ -46,6 +46,11 @@
(@bignum <= (@bignum + 0.5)).should == false
end

it "returns true for bignums compare to a bigger float" do
(18446744073709551616 <= 1.8446744073709552e+19).should == true
(@bignum <= (@bignum + 9999.0)).should == true
end

it "raises an ArgumentError when given a non-Integer" do
-> { @bignum <= "4" }.should raise_error(ArgumentError)
-> { @bignum <= mock('str') }.should raise_error(ArgumentError)
Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/core/kernel/caller_locations_spec.rb
Expand Up @@ -28,6 +28,14 @@
locations1[2..4].map(&:to_s).should == locations2.map(&:to_s)
end

ruby_version_is "2.6" do
it "works with endless ranges" do
locations1 = caller_locations(0)
locations2 = caller_locations(eval("(2..)"))
locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s)
end
end

it "can be called with a range whose end is negative" do
locations1 = caller_locations(0)
locations2 = caller_locations(2..-1)
Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/core/kernel/caller_spec.rb
Expand Up @@ -43,4 +43,12 @@
"#{path}:2:in `block in <main>'\n"
]
end

ruby_version_is "2.6" do
it "works with endless ranges" do
locations1 = KernelSpecs::CallerTest.locations(0)
locations2 = KernelSpecs::CallerTest.locations(eval("(2..)"))
locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s)
end
end
end
40 changes: 40 additions & 0 deletions spec/ruby/core/kernel/eval_spec.rb
Expand Up @@ -373,4 +373,44 @@ class EvalSpecs
EvalSpecs.send :remove_const, :Vπstring_not_frozen
end
end

it "activates refinements from the eval scope" do
refinery = Module.new do
refine EvalSpecs::A do
def foo
"bar"
end
end
end

result = nil

Module.new do
using refinery

result = eval "EvalSpecs::A.new.foo"
end

result.should == "bar"
end

it "activates refinements from the binding" do
refinery = Module.new do
refine EvalSpecs::A do
def foo
"bar"
end
end
end

b = nil
m = Module.new do
using refinery
b = binding
end

result = eval "EvalSpecs::A.new.foo", b

result.should == "bar"
end
end
6 changes: 6 additions & 0 deletions spec/ruby/core/module/name_spec.rb
Expand Up @@ -18,6 +18,12 @@ module m::N; end
m::N.name.should =~ /\A#<Module:0x[0-9a-f]+>::N\z/
end

it "returns nil for a singleton class" do
Module.new.singleton_class.name.should be_nil
String.singleton_class.name.should be_nil
Object.new.singleton_class.name.should be_nil
end

it "changes when the module is reachable through a constant path" do
m = Module.new
module m::N; end
Expand Down

0 comments on commit a0f5ff4

Please sign in to comment.