1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2020-12-27 17:35:32 +01:00
parent 267bed0cd9
commit 727c97da19
108 changed files with 1325 additions and 270 deletions

View file

@ -124,8 +124,8 @@ If an exception is raised, it will fail the example anyway.
```ruby
-> {
Integer
}.should complain(/constant ::Integer is deprecated/) # Expect a warning
Fixnum
}.should complain(/constant ::Fixnum is deprecated/) # Expect a warning
```
### Guards

View file

@ -34,7 +34,8 @@ More precisely, every latest stable MRI release should [pass](https://travis-ci.
### Synchronization with Ruby Implementations
The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby.
The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby,
using [this script](https://github.com/ruby/mspec/blob/master/tool/sync/sync-rubyspec.rb).
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
Any of these repositories can be used to add or edit specs, use what is most convenient for you.

View file

@ -3,6 +3,14 @@ require_relative 'shared/each_byte'
ruby_version_is ''...'3.0' do
describe "ARGF.bytes" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :argf_each_byte, :bytes
end
end

View file

@ -3,6 +3,14 @@ require_relative 'shared/each_char'
ruby_version_is ''...'3.0' do
describe "ARGF.chars" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :argf_each_char, :chars
end
end

View file

@ -3,6 +3,14 @@ require_relative 'shared/each_codepoint'
ruby_version_is ''...'3.0' do
describe "ARGF.codepoints" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :argf_each_codepoint, :codepoints
end
end

View file

@ -3,6 +3,14 @@ require_relative 'shared/each_line'
ruby_version_is ''...'3.0' do
describe "ARGF.lines" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :argf_each_line, :lines
end
end

View file

@ -439,7 +439,6 @@ end
ruby_version_is "2.6" do
describe "Array#[]= with [m..]" do
it "just sets the section defined by range to nil even if the rhs is nil" do
a = [1, 2, 3, 4, 5]
a[eval("(2..)")] = nil
@ -476,6 +475,53 @@ ruby_version_is "2.6" do
end
end
ruby_version_is "2.7" do
describe "Array#[]= with [..n] and [...n]" do
it "just sets the section defined by range to nil even if the rhs is nil" do
a = [1, 2, 3, 4, 5]
a[eval("(..2)")] = nil
a.should == [nil, 4, 5]
a[eval("(...2)")] = nil
a.should == [nil, 5]
end
it "just sets the section defined by range to nil if n < 0 and the rhs is nil" do
a = [1, 2, 3, 4, 5]
a[eval("(..-3)")] = nil
a.should == [nil, 4, 5]
a[eval("(...-1)")] = [nil, 5]
end
it "replaces the section defined by range" do
a = [6, 5, 4, 3, 2, 1]
a[eval("(...3)")] = 9
a.should == [9, 3, 2, 1]
a[eval("(..2)")] = [7, 7, 7, 7, 7]
a.should == [7, 7, 7, 7, 7, 1]
end
it "replaces the section if n < 0" do
a = [1, 2, 3, 4, 5]
a[eval("(..-2)")] = [7, 8, 9]
a.should == [7, 8, 9, 5]
end
it "replaces everything if n > the array size" do
a = [1, 2, 3]
a[eval("(...7)")] = [4]
a.should == [4]
end
it "inserts at the beginning if n < negative the array size" do
a = [1, 2, 3]
a[eval("(..-7)")] = [4]
a.should == [4, 1, 2, 3]
a[eval("(...-10)")] = [6]
a.should == [6, 4, 1, 2, 3]
end
end
end
describe "Array#[] after a shift" do
it "works for insertion" do
a = [1,2]

View file

@ -324,4 +324,11 @@ describe "Array#fill with (filler, range)" do
[1, 2, 3, 4].fill(eval("(3...)")) { |x| x + 2 }.should == [1, 2, 3, 5]
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do
[1, 2, 3, 4].fill('x', eval("(..2)")).should == ["x", "x", "x", 4]
[1, 2, 3, 4].fill(eval("(...2)")) { |x| x + 2 }.should == [2, 3, 3, 4]
end
end
end

View file

@ -33,7 +33,7 @@ describe "Array#first" do
-> { [1, 2].first(-1) }.should raise_error(ArgumentError)
end
it "raises a RangeError when count is an Integer" do
it "raises a RangeError when count is a Bignum" do
-> { [].first(bignum_value) }.should raise_error(RangeError)
end

View file

@ -486,7 +486,7 @@ describe :array_slice, shared: true do
end
end
it "raises a RangeError when the start index is out of range of Integer" do
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(bignum_value)
@ -502,7 +502,7 @@ describe :array_slice, shared: true do
array.send(@method, max_long.to_f.prev_float).should == nil
end
it "raises a RangeError when the length is out of range of Integer" do
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(bignum_value)
@ -520,4 +520,41 @@ describe :array_slice, shared: true do
-> { "hello".send(@method, bignum_value..(bignum_value + 1)) }.should raise_error(RangeError)
-> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError)
end
ruby_version_is "2.6" do
it "can accept endless ranges" do
a = [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(2..)")).should == [2, 3, 4, 5]
a.send(@method, eval("(2...)")).should == [2, 3, 4, 5]
a.send(@method, eval("(-2..)")).should == [4, 5]
a.send(@method, eval("(-2...)")).should == [4, 5]
a.send(@method, eval("(9..)")).should == nil
a.send(@method, eval("(9...)")).should == nil
a.send(@method, eval("(-9..)")).should == nil
a.send(@method, eval("(-9...)")).should == nil
end
end
ruby_version_is "2.7" do
it "can accept beginless ranges" do
a = [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(..3)")).should == [0, 1, 2, 3]
a.send(@method, eval("(...3)")).should == [0, 1, 2]
a.send(@method, eval("(..-3)")).should == [0, 1, 2, 3]
a.send(@method, eval("(...-3)")).should == [0, 1, 2]
a.send(@method, eval("(..0)")).should == [0]
a.send(@method, eval("(...0)")).should == []
a.send(@method, eval("(..9)")).should == [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(...9)")).should == [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(..-9)")).should == []
a.send(@method, eval("(...-9)")).should == []
end
it "can accept nil...nil ranges" do
a = [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(nil...nil)")).should == a
a.send(@method, eval("(...nil)")).should == a
a.send(@method, eval("(nil..)")).should == a
end
end
end

View file

@ -163,6 +163,26 @@ describe "Array#slice!" do
a = [1, 2, 3]
a.slice!(eval("(2...)")).should == [3]
a.should == [1, 2]
a = [1, 2, 3]
a.slice!(eval("(-2..)")).should == [2, 3]
a.should == [1]
a = [1, 2, 3]
a.slice!(eval("(-1...)")).should == [3]
a.should == [1, 2]
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do
a = [0,1,2,3,4]
a.slice!(eval("(..3)")).should == [0, 1, 2, 3]
a.should == [4]
a = [0,1,2,3,4]
a.slice!(eval("(...-2)")).should == [0, 1, 2]
a.should == [3, 4]
end
end
end

View file

@ -67,4 +67,11 @@ describe "Array#values_at" do
[1, 2, 3, 4].values_at(eval("(3...)")).should == [4]
end
end
ruby_version_is "2.7" do
it "works when given beginless ranges" do
[1, 2, 3, 4].values_at(eval("(..2)")).should == [1, 2, 3]
[1, 2, 3, 4].values_at(eval("(...2)")).should == [1, 2]
end
end
end

View file

@ -19,7 +19,7 @@ describe "Complex#coerce" do
result.last.should be_kind_of(Complex)
end
it "returns an array containing other and self as Complex when other is an Integer" do
it "returns an array containing other and self as Complex when other is a Bignum" do
result = @one.coerce(4294967296)
result.should == [4294967296, 1]
result.first.should be_kind_of(Complex)

View file

@ -12,7 +12,7 @@ describe :complex_divide, shared: true do
end
end
describe "with Integer" do
describe "with Fixnum" do
it "divides both parts of the Complex number" do
Complex(20, 40).send(@method, 2).should == Complex(10, 20)
Complex(30, 30).send(@method, 10).should == Complex(3, 3)
@ -27,7 +27,7 @@ describe :complex_divide, shared: true do
end
end
describe "with Integer" do
describe "with Bignum" do
it "divides both parts of the Complex number" do
Complex(20, 40).send(@method, 2).should == Complex(10, 20)
Complex(15, 16).send(@method, 2.0).should be_close(Complex(7.5, 8), TOLERANCE)

View file

@ -13,3 +13,11 @@ ruby_version_is ''...'3.0' do
end
end
end
ruby_version_is '3.0' do
describe "Data" do
it "does not exist anymore" do
Object.should_not have_constant(:Data)
end
end
end

View file

@ -17,7 +17,7 @@ describe "Enumerable#first" do
EnumerableSpecs::YieldsMixed2.new.to_enum.first.should == nil
end
it "raises a RangeError when passed an Integer" do
it "raises a RangeError when passed a Bignum" do
enum = EnumerableSpecs::Empty.new
-> { enum.first(bignum_value) }.should raise_error(RangeError)
end

View file

@ -51,7 +51,20 @@ describe :enumerable_collect, shared: true do
ScratchPad.recorded.should == [1]
end
it "yields 2 arguments for a Hash" do
it "yields an Array of 2 elements for a Hash when block arity is 1" do
c = Class.new do
def register(a)
ScratchPad << a
end
end
m = c.new.method(:register)
ScratchPad.record []
{ 1 => 'a', 2 => 'b' }.map(&m)
ScratchPad.recorded.should == [[1, 'a'], [2, 'b']]
end
it "yields 2 arguments for a Hash when block arity is 2" do
c = Class.new do
def register(a, b)
ScratchPad << [a, b]
@ -64,5 +77,17 @@ describe :enumerable_collect, shared: true do
ScratchPad.recorded.should == [[1, 'a'], [2, 'b']]
end
it "raises an error for a Hash when an arity enforcing block of arity >2 is passed in" do
c = Class.new do
def register(a, b, c)
end
end
m = c.new.method(:register)
-> do
{ 1 => 'a', 2 => 'b' }.map(&m)
end.should raise_error(ArgumentError)
end
it_should_behave_like :enumerable_enumeratorized_with_origin_size
end

View file

@ -13,7 +13,9 @@ describe "Enumerator#initialize" do
ruby_version_is ''...'3.0' do
it "returns self when given an object" do
@uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
suppress_warning do
@uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
end
end
end

View file

@ -10,25 +10,26 @@ describe "Enumerator.new" do
ruby_version_is ''...'3.0' do
it "creates a new custom enumerator with the given object, iterator and arguments" do
enum = Enumerator.new(1, :upto, 3)
enum = suppress_warning { Enumerator.new(1, :upto, 3) }
enum.should be_an_instance_of(Enumerator)
end
it "creates a new custom enumerator that responds to #each" do
enum = Enumerator.new(1, :upto, 3)
enum = suppress_warning { Enumerator.new(1, :upto, 3) }
enum.respond_to?(:each).should == true
end
it "creates a new custom enumerator that runs correctly" do
Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
suppress_warning { Enumerator.new(1, :upto, 3) }.map{ |x| x }.should == [1,2,3]
end
it "aliases the second argument to :each" do
Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
suppress_warning { Enumerator.new(1..2) }.to_a.should ==
suppress_warning { Enumerator.new(1..2, :each) }.to_a
end
it "doesn't check for the presence of the iterator method" do
Enumerator.new(nil).should be_an_instance_of(Enumerator)
suppress_warning { Enumerator.new(nil) }.should be_an_instance_of(Enumerator)
end
it "uses the latest define iterator method" do
@ -37,7 +38,7 @@ describe "Enumerator.new" do
yield :foo
end
end
enum = Enumerator.new(StrangeEach.new)
enum = suppress_warning { Enumerator.new(StrangeEach.new) }
enum.to_a.should == [:foo]
class StrangeEach
def each

View file

@ -1,5 +1,6 @@
# -*- encoding: binary -*-
require_relative '../../spec_helper'
require_relative 'fixtures/common'
describe "ENV.[]" do
before :each do
@ -58,8 +59,7 @@ describe "ENV.[]" do
it "uses the locale encoding if Encoding.default_internal is nil" do
Encoding.default_internal = nil
locale = Encoding.find('locale')
locale = Encoding::UTF_8 if platform_is :windows
locale = ENVSpecs.encoding
locale = Encoding::BINARY if locale == Encoding::US_ASCII
ENV[@variable] = "\xC3\xB8"
ENV[@variable].encoding.should == locale

View file

@ -1,5 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/hash/key_error'
require_relative 'fixtures/common'
describe "ENV.fetch" do
before :each do
@ -56,8 +57,7 @@ describe "ENV.fetch" do
end
it "uses the locale encoding" do
encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
ENV["foo"] = "bar"
ENV.fetch("foo").encoding.should == encoding
ENV.fetch("foo").encoding.should == ENVSpecs.encoding
end
end

9
spec/ruby/core/env/fixtures/common.rb vendored Normal file
View file

@ -0,0 +1,9 @@
module ENVSpecs
def self.encoding
locale = Encoding.find('locale')
if ruby_version_is '3' and platform_is :windows
locale = Encoding::UTF_8
end
locale
end
end

View file

@ -1,4 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'
describe "ENV.shift" do
it "returns a pair and deletes it" do
@ -42,10 +43,9 @@ describe "ENV.shift" do
it "uses the locale encoding if Encoding.default_internal is nil" do
Encoding.default_internal = nil
encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
pair = ENV.shift
pair.first.encoding.should equal(encoding)
pair.last.encoding.should equal(encoding)
pair.first.encoding.should equal(ENVSpecs.encoding)
pair.last.encoding.should equal(ENVSpecs.encoding)
end
it "transcodes from the locale encoding to Encoding.default_internal if set" do

View file

@ -1,4 +1,5 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'
describe "ENV.values_at" do
before :each do
@ -28,8 +29,7 @@ describe "ENV.values_at" do
end
it "uses the locale encoding" do
encoding = platform_is(:windows) ? Encoding::UTF_8 : Encoding.find('locale')
ENV.values_at(ENV.keys.first).first.encoding.should == encoding
ENV.values_at(ENV.keys.first).first.encoding.should == ENVSpecs.encoding
end
it "raises TypeError when a key is not coercible to String" do

View file

@ -54,6 +54,27 @@ describe :hash_each, shared: true do
end
end
it "yields an Array of 2 elements when given a callable of arity 1" do
obj = Object.new
def obj.foo(key_value)
ScratchPad << key_value
end
ScratchPad.record([])
{ "a" => 1 }.send(@method, &obj.method(:foo))
ScratchPad.recorded.should == [["a", 1]]
end
it "raises an error for a Hash when an arity enforcing callable of arity >2 is passed in" do
obj = Object.new
def obj.foo(key, value, extra)
end
-> {
{ "a" => 1 }.send(@method, &obj.method(:foo))
}.should raise_error(ArgumentError)
end
it "uses the same order as keys() and values()" do
h = { a: 1, b: 2, c: 3, d: 5 }
keys = []

View file

@ -3,25 +3,35 @@ require_relative '../fixtures/classes'
describe :hash_index, shared: true do
it "returns the corresponding key for value" do
{ 2 => 'a', 1 => 'b' }.send(@method, 'b').should == 1
suppress_warning do # for Hash#index
{ 2 => 'a', 1 => 'b' }.send(@method, 'b').should == 1
end
end
it "returns nil if the value is not found" do
{ a: -1, b: 3.14, c: 2.718 }.send(@method, 1).should be_nil
suppress_warning do # for Hash#index
{ a: -1, b: 3.14, c: 2.718 }.send(@method, 1).should be_nil
end
end
it "doesn't return default value if the value is not found" do
Hash.new(5).send(@method, 5).should be_nil
suppress_warning do # for Hash#index
Hash.new(5).send(@method, 5).should be_nil
end
end
it "compares values using ==" do
{ 1 => 0 }.send(@method, 0.0).should == 1
{ 1 => 0.0 }.send(@method, 0).should == 1
suppress_warning do # for Hash#index
{ 1 => 0 }.send(@method, 0.0).should == 1
{ 1 => 0.0 }.send(@method, 0).should == 1
end
needle = mock('needle')
inhash = mock('inhash')
inhash.should_receive(:==).with(needle).and_return(true)
{ 1 => inhash }.send(@method, needle).should == 1
suppress_warning do # for Hash#index
{ 1 => inhash }.send(@method, needle).should == 1
end
end
end

View file

@ -4,8 +4,8 @@ require 'bigdecimal'
describe "Integer#coerce" do
context "fixnum" do
describe "when given an Integer" do
it "returns an array containing two Integers" do
describe "when given a Fixnum" do
it "returns an array containing two Fixnums" do
1.coerce(2).should == [2, 1]
1.coerce(2).map { |i| i.class }.should == [Integer, Integer]
end
@ -42,7 +42,7 @@ describe "Integer#coerce" do
end
context "bignum" do
it "coerces other to an Integer and returns [other, self] when passed an Integer" do
it "coerces other to a Bignum and returns [other, self] when passed a Fixnum" do
a = bignum_value
ary = a.coerce(2)
@ -51,7 +51,7 @@ describe "Integer#coerce" do
ary.should == [2, a]
end
it "returns [other, self] when passed an Integer" do
it "returns [other, self] when passed a Bignum" do
a = bignum_value
b = bignum_value
ary = a.coerce(b)
@ -61,7 +61,7 @@ describe "Integer#coerce" do
ary.should == [b, a]
end
it "raises a TypeError when not passed an Integer" do
it "raises a TypeError when not passed a Fixnum or Bignum" do
a = bignum_value
-> { a.coerce(nil) }.should raise_error(TypeError)

View file

@ -27,7 +27,7 @@ describe "Integer#<=>" do
end
context "bignum" do
describe "with an Integer" do
describe "with a Fixnum" do
it "returns -1 when other is larger" do
(-bignum_value <=> 2).should == -1
end
@ -37,7 +37,7 @@ describe "Integer#<=>" do
end
end
describe "with an Integer" do
describe "with a Bignum" do
describe "when other is negative" do
it "returns -1 when self is negative and other is larger" do
(-bignum_value(42) <=> -bignum_value).should == -1
@ -158,7 +158,7 @@ describe "Integer#<=>" do
end
# The tests below are taken from matz's revision 23730 for Ruby trunk
it "returns 1 when self is Infinity and other is an Integer" do
it "returns 1 when self is Infinity and other is a Bignum" do
(infinity_value <=> Float::MAX.to_i*2).should == 1
end

View file

@ -1,27 +1,25 @@
require_relative '../../spec_helper'
ruby_version_is ""..."3.0" do
describe "Fixnum" do
it "is unified into Integer" do
suppress_warning do
Fixnum.should equal(Integer)
end
end
it "is deprecated" do
-> { Fixnum }.should complain(/constant ::Fixnum is deprecated/)
describe "Fixnum" do
it "is unified into Integer" do
suppress_warning do
Fixnum.should equal(Integer)
end
end
describe "Bignum" do
it "is unified into Integer" do
suppress_warning do
Bignum.should equal(Integer)
end
end
it "is deprecated" do
-> { Bignum }.should complain(/constant ::Bignum is deprecated/)
end
it "is deprecated" do
-> { Fixnum }.should complain(/constant ::Fixnum is deprecated/)
end
end
describe "Bignum" do
it "is unified into Integer" do
suppress_warning do
Bignum.should equal(Integer)
end
end
it "is deprecated" do
-> { Bignum }.should complain(/constant ::Bignum is deprecated/)
end
end

View file

@ -7,7 +7,7 @@ describe "Integer#denominator" do
@numbers = [
20, # Integer
-2709, # Negative Integer
99999999**99, # Integer
99999999**99, # Bignum
-99999**621, # Negative BigNum
0,
1

View file

@ -68,14 +68,14 @@ describe "Integer#[]" do
-> { 3[obj] }.should raise_error(TypeError)
end
it "calls #to_int to coerce a String to an Integer and returns 0" do
it "calls #to_int to coerce a String to a Bignum and returns 0" do
obj = mock('bignum value')
obj.should_receive(:to_int).and_return(bignum_value)
3[obj].should == 0
end
it "returns 0 when passed a Float in the range of an Integer" do
it "returns 0 when passed a Float in the range of a Bignum" do
3[bignum_value.to_f].should == 0
end
@ -131,16 +131,10 @@ describe "Integer#[]" do
0b000001[-3, 4].should == 0b1000
end
it "ignores negative upper boundary" do
0b101001101[1..-1].should == 0b10100110
0b101001101[1..-2].should == 0b10100110
0b101001101[1..-3].should == 0b10100110
end
it "ignores upper boundary smaller than lower boundary" do
0b101001101[4..1].should == 0b10100
0b101001101[4..2].should == 0b10100
0b101001101[4..3].should == 0b10100
0b101001101[-4..-5].should == 0b1010011010000
end
it "raises FloatDomainError if any boundary is infinity" do

View file

@ -2,7 +2,7 @@ require_relative '../../spec_helper'
describe "Integer#even?" do
context "fixnum" do
it "returns true for an Integer when it is an even number" do
it "returns true for a Fixnum when it is an even number" do
(-2).even?.should be_true
(-1).even?.should be_false
@ -11,7 +11,7 @@ describe "Integer#even?" do
2.even?.should be_true
end
it "returns true for an Integer when it is an even number" do
it "returns true for a Bignum when it is an even number" do
bignum_value(0).even?.should be_true
bignum_value(1).even?.should be_false

View file

@ -31,13 +31,13 @@ describe "Integer#gcd" do
-100.gcd(-100).should == 100
end
it "accepts an Integer argument" do
it "accepts a Bignum argument" do
bignum = 9999**99
bignum.should be_kind_of(Integer)
99.gcd(bignum).should == 99
end
it "works if self is an Integer" do
it "works if self is a Bignum" do
bignum = 9999**99
bignum.should be_kind_of(Integer)
bignum.gcd(99).should == 99

View file

@ -26,13 +26,13 @@ describe "Integer#gcdlcm" do
200.gcdlcm(20)[1].should == 200.lcm(20)
end
it "accepts an Integer argument" do
it "accepts a Bignum argument" do
bignum = 91999**99
bignum.should be_kind_of(Integer)
99.gcdlcm(bignum).should == [99.gcd(bignum), 99.lcm(bignum)]
end
it "works if self is an Integer" do
it "works if self is a Bignum" do
bignum = 9999**89
bignum.should be_kind_of(Integer)
bignum.gcdlcm(99).should == [bignum.gcd(99), bignum.lcm(99)]

View file

@ -31,13 +31,13 @@ describe "Integer#lcm" do
-100.lcm(-100).should == 100
end
it "accepts an Integer argument" do
it "accepts a Bignum argument" do
bignum = 9999**99
bignum.should be_kind_of(Integer)
99.lcm(bignum).should == bignum
end
it "works if self is an Integer" do
it "works if self is a Bignum" do
bignum = 9999**99
bignum.should be_kind_of(Integer)
bignum.lcm(99).should == bignum

View file

@ -52,17 +52,17 @@ describe "Integer#<< (with n << m)" do
(-7 << -64).should == -1
end
it "returns 0 when m < 0 and m is an Integer" do
it "returns 0 when m < 0 and m is a Bignum" do
(3 << -bignum_value).should == 0
end
it "returns an Integer == fixnum_max * 2 when fixnum_max << 1 and n > 0" do
it "returns an Bignum == fixnum_max * 2 when fixnum_max << 1 and n > 0" do
result = fixnum_max << 1
result.should be_an_instance_of(Integer)
result.should == fixnum_max * 2
end
it "returns an Integer == fixnum_min * 2 when fixnum_min << 1 and n < 0" do
it "returns an Bignum == fixnum_min * 2 when fixnum_min << 1 and n < 0" do
result = fixnum_min << 1
result.should be_an_instance_of(Integer)
result.should == fixnum_min * 2
@ -127,17 +127,17 @@ describe "Integer#<< (with n << m)" do
(@bignum << -68).should == 0
end
it "returns 0 when m < 0 and m is an Integer" do
it "returns 0 when m < 0 and m is a Bignum" do
(@bignum << -bignum_value).should == 0
end
it "returns an Integer == fixnum_max when (fixnum_max * 2) << -1 and n > 0" do
it "returns a Fixnum == fixnum_max when (fixnum_max * 2) << -1 and n > 0" do
result = (fixnum_max * 2) << -1
result.should be_an_instance_of(Integer)
result.should == fixnum_max
end
it "returns an Integer == fixnum_min when (fixnum_min * 2) << -1 and n < 0" do
it "returns a Fixnum == fixnum_min when (fixnum_min * 2) << -1 and n < 0" do
result = (fixnum_min * 2) << -1
result.should be_an_instance_of(Integer)
result.should == fixnum_min

View file

@ -56,13 +56,13 @@ describe "Integer#>> (with n >> m)" do
(3 >> bignum_value).should == 0
end
it "returns an Integer == fixnum_max * 2 when fixnum_max >> -1 and n > 0" do
it "returns an Bignum == fixnum_max * 2 when fixnum_max >> -1 and n > 0" do
result = fixnum_max >> -1
result.should be_an_instance_of(Integer)
result.should == fixnum_max * 2
end
it "returns an Integer == fixnum_min * 2 when fixnum_min >> -1 and n < 0" do
it "returns an Bignum == fixnum_min * 2 when fixnum_min >> -1 and n < 0" do
result = fixnum_min >> -1
result.should be_an_instance_of(Integer)
result.should == fixnum_min * 2
@ -153,17 +153,17 @@ describe "Integer#>> (with n >> m)" do
(@bignum >> 68).should == 0
end
it "returns 0 when m is an Integer" do
it "returns 0 when m is a Bignum" do
(@bignum >> bignum_value).should == 0
end
it "returns an Integer == fixnum_max when (fixnum_max * 2) >> 1 and n > 0" do
it "returns a Fixnum == fixnum_max when (fixnum_max * 2) >> 1 and n > 0" do
result = (fixnum_max * 2) >> 1
result.should be_an_instance_of(Integer)
result.should == fixnum_max
end
it "returns an Integer == fixnum_min when (fixnum_min * 2) >> 1 and n < 0" do
it "returns a Fixnum == fixnum_min when (fixnum_min * 2) >> 1 and n < 0" do
result = (fixnum_min * 2) >> 1
result.should be_an_instance_of(Integer)
result.should == fixnum_min

View file

@ -47,7 +47,9 @@ describe :integer_exponent, shared: true do
end
it "returns Float::INFINITY when the number is too big" do
2.send(@method, 427387904).should == Float::INFINITY
-> {
2.send(@method, 427387904).should == Float::INFINITY
}.should complain(/warning: in a\*\*b, b may be too big/)
end
it "raises a ZeroDivisionError for 0 ** -1" do
@ -105,7 +107,10 @@ describe :integer_exponent, shared: true do
end
it "switch to a Float when the values is too big" do
flt = @bignum.send(@method, @bignum)
flt = nil
-> {
flt = @bignum.send(@method, @bignum)
}.should complain(/warning: in a\*\*b, b may be too big/)
flt.should be_kind_of(Float)
flt.infinite?.should == 1
end

View file

@ -1,25 +1,25 @@
describe :integer_next, shared: true do
it "returns the next larger positive Integer" do
it "returns the next larger positive Fixnum" do
2.send(@method).should == 3
end
it "returns the next larger negative Integer" do
it "returns the next larger negative Fixnum" do
(-2).send(@method).should == -1
end
it "returns the next larger positive Integer" do
it "returns the next larger positive Bignum" do
bignum_value.send(@method).should == bignum_value(1)
end
it "returns the next larger negative Integer" do
it "returns the next larger negative Bignum" do
(-bignum_value(1)).send(@method).should == -bignum_value
end
it "overflows an Integer to an Integer" do
it "overflows a Fixnum to a Bignum" do
fixnum_max.send(@method).should == fixnum_max + 1
end
it "underflows an Integer to an Integer" do
it "underflows a Bignum to a Fixnum" do
(fixnum_min - 1).send(@method).should == fixnum_min
end
end

View file

@ -13,7 +13,7 @@ describe "Integer#to_r" do
298.to_r.denominator.should == 1
end
it "works even if self is an Integer" do
it "works even if self is a Bignum" do
bignum = 99999**999
bignum.should be_an_instance_of(Integer)
bignum.to_r.should == Rational(bignum, 1)

View file

@ -10,7 +10,7 @@ describe "Integer#-@" do
-8.send(:-@).should == 8
end
it "negates self at Integer/Integer boundaries" do
it "negates self at Fixnum/Bignum boundaries" do
(-fixnum_max).should == (0 - fixnum_max)
(-fixnum_max).should < 0
(-fixnum_min).should == (0 - fixnum_min)

View file

@ -6,9 +6,11 @@ ruby_version_is ''...'3.0' do
describe "IO#bytes" do
before :each do
@io = IOSpecs.io_fixture "lines.txt"
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
@io.close unless @io.closed?
end

View file

@ -5,10 +5,26 @@ require_relative 'shared/chars'
ruby_version_is ''...'3.0' do
describe "IO#chars" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :io_chars, :chars
end
describe "IO#chars" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :io_chars_empty, :chars
end
end

View file

@ -6,15 +6,25 @@ ruby_version_is ''...'3.0' do
# See redmine #1667
describe "IO#codepoints" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :io_codepoints, :codepoints
end
describe "IO#codepoints" do
before :each do
@io = IOSpecs.io_fixture "lines.txt"
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
@io.close unless @io.closed?
end

View file

@ -6,9 +6,11 @@ ruby_version_is ''...'3.0' do
describe "IO#lines" do
before :each do
@io = IOSpecs.io_fixture "lines.txt"
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
@io.close if @io
end

View file

@ -90,6 +90,12 @@ describe "IO.write" do
IO.write(@filename, 'hi', mode: "w", encoding: Encoding::UTF_32LE).should == 8
end
it "writes the file with the permissions in the :perm parameter" do
rm_r @filename
IO.write(@filename, 'write :perm spec', mode: "w", perm: 0o755).should == 16
(File.stat(@filename).mode & 0o777) == 0o755
end
it "writes binary data if no encoding is given" do
IO.write(@filename, 'Hëllö'.encode('ISO-8859-1'))
xEB = [235].pack('C*')

View file

@ -9,7 +9,7 @@ describe :kernel_float, shared: true do
float2.should equal float
end
it "returns a Float for Integers" do
it "returns a Float for Fixnums" do
@object.send(:Float, 1).should == 1.0
end
@ -17,7 +17,7 @@ describe :kernel_float, shared: true do
@object.send(:Float, Complex(1)).should == 1.0
end
it "returns a Float for Integers" do
it "returns a Float for Bignums" do
@object.send(:Float, 1000000000000).should == 1000000000000.0
end

View file

@ -2,11 +2,11 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe :kernel_integer, shared: true do
it "returns an Integer for an Integer" do
it "returns a Bignum for a Bignum" do
Integer(2e100).should == 2e100
end
it "returns an Integer for an Integer" do
it "returns a Fixnum for a Fixnum" do
Integer(100).should == 100
end
@ -39,7 +39,7 @@ describe :kernel_integer, shared: true do
-> { Integer(nil) }.should raise_error(TypeError)
end
it "returns an Integer or Integer object" do
it "returns an Integer object" do
Integer(2).should be_an_instance_of(Integer)
Integer(9**99).should be_an_instance_of(Integer)
end
@ -54,14 +54,14 @@ describe :kernel_integer, shared: true do
Integer(3.quo(2)).should == 1
end
it "returns the value of to_int if the result is an Integer" do
it "returns the value of to_int if the result is a Fixnum" do
obj = mock("object")
obj.should_receive(:to_int).and_return(1)
obj.should_not_receive(:to_i)
Integer(obj).should == 1
end
it "returns the value of to_int if the result is an Integer" do
it "returns the value of to_int if the result is a Bignum" do
obj = mock("object")
obj.should_receive(:to_int).and_return(2 * 10**100)
obj.should_not_receive(:to_i)

View file

@ -15,8 +15,8 @@ describe "Marshal.dump" do
Marshal.dump(false).should == "\004\bF"
end
describe "with an Integer" do
it "dumps an Integer" do
describe "with a Fixnum" do
it "dumps a Fixnum" do
[ [Marshal, 0, "\004\bi\000"],
[Marshal, 5, "\004\bi\n"],
[Marshal, 8, "\004\bi\r"],
@ -38,11 +38,11 @@ describe "Marshal.dump" do
end
platform_is wordsize: 64 do
it "dumps a positive Integer > 31 bits as an Integer" do
it "dumps a positive Fixnum > 31 bits as a Bignum" do
Marshal.dump(2**31 + 1).should == "\x04\bl+\a\x01\x00\x00\x80"
end
it "dumps a negative Integer > 31 bits as an Integer" do
it "dumps a negative Fixnum > 31 bits as a Bignum" do
Marshal.dump(-2**31 - 1).should == "\x04\bl-\a\x01\x00\x00\x80"
end
end
@ -157,14 +157,14 @@ describe "Marshal.dump" do
end
end
describe "with an Integer" do
it "dumps an Integer" do
describe "with a Bignum" do
it "dumps a Bignum" do
[ [Marshal, -4611686018427387903, "\004\bl-\t\377\377\377\377\377\377\377?"],
[Marshal, -2361183241434822606847, "\004\bl-\n\377\377\377\377\377\377\377\377\177\000"],
].should be_computed_by(:dump)
end
it "dumps an Integer" do
it "dumps a Bignum" do
[ [Marshal, 2**64, "\004\bl+\n\000\000\000\000\000\000\000\000\001\000"],
[Marshal, 2**90, "\004\bl+\v#{"\000" * 11}\004"],
[Marshal, -2**63, "\004\bl-\t\000\000\000\000\000\000\000\200"],

View file

@ -211,14 +211,14 @@ describe :marshal_load, shared: true do
y.first.tainted?.should be_false
end
it "does not taint Integers" do
it "does not taint Fixnums" do
x = [1]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
y.first.tainted?.should be_false
end
it "does not taint Integers" do
it "does not taint Bignums" do
x = [bignum_value]
y = Marshal.send(@method, Marshal.dump(x).taint)
y.tainted?.should be_true
@ -740,16 +740,16 @@ describe :marshal_load, shared: true do
end
end
describe "for an Integer" do
describe "for a Bignum" do
platform_is wordsize: 64 do
context "that is Integer on 32-bit platforms but Integer on 64-bit" do
it "dumps an Integer" do
context "that is Bignum on 32-bit platforms but Fixnum on 64-bit" do
it "dumps a Fixnum" do
val = Marshal.send(@method, "\004\bl+\ab:wU")
val.should == 1433877090
val.class.should == Integer
end
it "dumps an array containing multiple references to the Integer as an array of Integer" do
it "dumps an array containing multiple references to the Bignum as an array of Fixnum" do
arr = Marshal.send(@method, "\004\b[\al+\a\223BwU@\006")
arr.should == [1433879187, 1433879187]
arr.each { |v| v.class.should == Integer }

View file

@ -78,4 +78,12 @@ describe :method_to_s, shared: true do
@string = @m.send(@method).sub(/0x\h+/, '0xXXXXXX')
@string.should.start_with? "#<Method: #<MethodSpecs::MySub:0xXXXXXX>.bar"
end
ruby_version_is '2.7' do
ruby_bug '#17428', '2.7'...'3.0' do
it "shows the metaclass and the owner for a Module instance method retrieved from a class" do
String.method(:include).inspect.should.start_with?("#<Method: #<Class:String>(Module)#include")
end
end
end
end

View file

@ -14,20 +14,29 @@ describe "Method#unbind" do
@normal_um.should be_kind_of(UnboundMethod)
end
it "returns a String containing 'UnboundMethod'" do
@string.should =~ /\bUnboundMethod\b/
describe "#inspect" do
it "returns a String containing 'UnboundMethod'" do
@string.should =~ /\bUnboundMethod\b/
end
it "returns a String containing the method name" do
@string.should =~ /\#bar/
end
it "returns a String containing the Module the method is defined in" do
@string.should =~ /MethodSpecs::MyMod/
end
it "returns a String containing the Module the method is referenced from" do
@string.should =~ /MethodSpecs::MySub/
end
end
it "returns a String containing the method name" do
@string.should =~ /\#bar/
end
it "returns a String containing the Module the method is defined in" do
@string.should =~ /MethodSpecs::MyMod/
end
it "returns a String containing the Module the method is referenced from" do
@string.should =~ /MethodSpecs::MySub/
it "keeps the origin singleton class if there is one" do
obj = Object.new
def obj.foo
end
obj.method(:foo).unbind.inspect.should.start_with?("#<UnboundMethod: #{obj.singleton_class}#foo")
end
specify "rebinding UnboundMethod to Method's obj produces exactly equivalent Methods" do

View file

@ -6,7 +6,7 @@ describe "Numeric#denominator" do
before :each do
@numbers = [
20, # Integer
99999999**99, # Integer
99999999**99, # Bignum
]
end

View file

@ -11,7 +11,7 @@ describe "Numeric#quo" do
2.quo(2.5).should eql(0.8)
end
it "returns the result of self divided by the given Integer as a Float" do
it "returns the result of self divided by the given Bignum as a Float" do
45.quo(bignum_value).should be_close(1.04773789668636e-08, TOLERANCE)
end

View file

@ -7,7 +7,7 @@ describe "Numeric#real" do
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
bignum_value, # Integer
bignum_value, # Bignum
infinity_value,
nan_value
].map{ |n| [n, -n] }.flatten

View file

@ -6,7 +6,7 @@ describe :numeric_imag, shared: true do
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
bignum_value, # Integer
bignum_value, # Bignum
infinity_value,
nan_value
].map{|n| [n,-n]}.flatten

View file

@ -6,7 +6,7 @@ describe :numeric_rect, shared: true do
20, # Integer
398.72, # Float
Rational(3, 4), # Rational
99999999**99, # Integer
99999999**99, # Bignum
infinity_value,
nan_value
]

View file

@ -60,4 +60,26 @@ describe "Process::Constants" do
Process::RLIMIT_AS.should == 10
end
end
platform_is :windows do
it "does not define RLIMIT constants" do
%i[
RLIMIT_CPU
RLIMIT_FSIZE
RLIMIT_DATA
RLIMIT_STACK
RLIMIT_CORE
RLIMIT_RSS
RLIMIT_NPROC
RLIMIT_NOFILE
RLIMIT_MEMLOCK
RLIMIT_AS
RLIM_INFINITY
RLIM_SAVED_MAX
RLIM_SAVED_CUR
].each do |const|
Process.const_defined?(const).should be_false
end
end
end
end

View file

@ -11,8 +11,8 @@ platform_is :aix do
Process.getrlimit(:DATA)
end
platform_is_not :windows do
describe "Process.getrlimit" do
describe "Process.getrlimit" do
platform_is_not :windows do
it "returns a two-element Array of Integers" do
result = Process.getrlimit Process::RLIMIT_CORE
result.size.should == 2
@ -88,4 +88,13 @@ platform_is_not :windows do
end
end
end
platform_is :windows do
it "is not implemented" do
Process.respond_to?(:getrlimit).should be_false
-> do
Process.getrlimit(nil)
end.should raise_error NotImplementedError
end
end
end

View file

@ -1,7 +1,7 @@
require_relative '../../spec_helper'
platform_is_not :windows do
describe "Process.setrlimit" do
describe "Process.setrlimit" do
platform_is_not :windows do
context "when passed an Object" do
before do
@resource = Process::RLIMIT_CORE
@ -229,4 +229,13 @@ platform_is_not :windows do
end
end
end
platform_is :windows do
it "is not implemented" do
Process.respond_to?(:setrlimit).should be_false
-> do
Process.setrlimit(nil, nil)
end.should raise_error NotImplementedError
end
end
end

View file

@ -49,18 +49,18 @@ describe "Random.rand" do
end
end
describe "Random#rand with Integer" do
describe "Random#rand with Fixnum" do
it "returns an Integer" do
Random.new.rand(20).should be_an_instance_of(Integer)
end
it "returns an Integer greater than or equal to 0" do
it "returns a Fixnum greater than or equal to 0" do
prng = Random.new
ints = 20.times.map { prng.rand(5) }
ints.min.should >= 0
end
it "returns an Integer less than the argument" do
it "returns a Fixnum less than the argument" do
prng = Random.new
ints = 20.times.map { prng.rand(5) }
ints.max.should <= 4
@ -92,19 +92,19 @@ describe "Random#rand with Integer" do
end
end
describe "Random#rand with Integer" do
it "typically returns an Integer" do
describe "Random#rand with Bignum" do
it "typically returns a Bignum" do
rnd = Random.new(1)
10.times.map{ rnd.rand(bignum_value*2) }.max.should be_an_instance_of(Integer)
end
it "returns an Integer greater than or equal to 0" do
it "returns a Bignum greater than or equal to 0" do
prng = Random.new
bigs = 20.times.map { prng.rand(bignum_value) }
bigs.min.should >= 0
end
it "returns an Integer less than the argument" do
it "returns a Bignum less than the argument" do
prng = Random.new
bigs = 20.times.map { prng.rand(bignum_value) }
bigs.max.should < bignum_value

View file

@ -126,8 +126,8 @@ describe "Range#bsearch" do
inf = Float::INFINITY
(0..inf).bsearch { |x| x == inf }.should == inf
(0...inf).bsearch { |x| x == inf }.should == nil
(-inf..0).bsearch { |x| x == -inf }.should == nil
(-inf...0).bsearch { |x| x == -inf }.should == nil
(-inf..0).bsearch { |x| x != -inf }.should == -Float::MAX
(-inf...0).bsearch { |x| x != -inf }.should == -Float::MAX
(inf..inf).bsearch { |x| true }.should == inf
(inf...inf).bsearch { |x| true }.should == nil
(-inf..-inf).bsearch { |x| true }.should == -inf
@ -194,10 +194,10 @@ describe "Range#bsearch" do
it "works with infinity bounds" do
inf = Float::INFINITY
(0..inf).bsearch { |x| x == inf ? 0 : -1 }.should == nil
(0...inf).bsearch { |x| x == inf ? 0 : -1 }.should == nil
(-inf...0).bsearch { |x| x == -inf ? 0 : 1 }.should == nil
(-inf..0).bsearch { |x| x == -inf ? 0 : 1 }.should == nil
(0..inf).bsearch { |x| x == inf ? 0 : 1 }.should == inf
(0...inf).bsearch { |x| x == inf ? 0 : 1 }.should == nil
(-inf...0).bsearch { |x| x == -inf ? 0 : -1 }.should == -inf
(-inf..0).bsearch { |x| x == -inf ? 0 : -1 }.should == -inf
(inf..inf).bsearch { 0 }.should == inf
(inf...inf).bsearch { 0 }.should == nil
(-inf..-inf).bsearch { 0 }.should == -inf
@ -248,7 +248,7 @@ describe "Range#bsearch" do
it "returns an element at an index for which block returns 0" do
result = eval("(0..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 }
[1, 2].should include(result)
[1, 2, 3].should include(result)
end
end
end
@ -330,4 +330,111 @@ describe "Range#bsearch" do
end
end
end
ruby_version_is "2.7" do
context "with beginless ranges and Integer values" do
context "with a block returning true or false" do
it "returns the smallest element for which block returns true" do
eval("(..10)").bsearch { |x| x >= 2 }.should == 2
eval("(...-1)").bsearch { |x| x >= -10 }.should == -10
end
end
context "with a block returning negative, zero, positive numbers" do
it "returns nil if the block returns greater than zero for every element" do
eval("(..0)").bsearch { |x| 1 }.should be_nil
end
it "returns nil if the block never returns zero" do
eval("(..0)").bsearch { |x| x > 5 ? -1 : 1 }.should be_nil
end
it "accepts Float::INFINITY from the block" do
eval("(..0)").bsearch { |x| Float::INFINITY }.should be_nil
end
it "returns an element at an index for which block returns 0.0" do
result = eval("(..10)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 }
result.should == 2
end
it "returns an element at an index for which block returns 0" do
result = eval("(...10)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 }
[1, 2, 3].should include(result)
end
end
end
context "with beginless ranges and Float values" do
context "with a block returning true or false" do
it "returns nil if the block returns true for every element" do
eval("(..-0.1)").bsearch { |x| x > 0.0 }.should be_nil
eval("(...-0.1)").bsearch { |x| x > 0.0 }.should be_nil
end
it "returns nil if the block returns nil for every element" do
eval("(..-0.1)").bsearch { |x| nil }.should be_nil
eval("(...-0.1)").bsearch { |x| nil }.should be_nil
end
it "returns the smallest element for which block returns true" do
eval("(..10)").bsearch { |x| x >= 2 }.should == 2
eval("(..10)").bsearch { |x| x >= 1 }.should == 1
end
it "works with infinity bounds" do
inf = Float::INFINITY
eval("(..inf)").bsearch { |x| true }.should == -inf
eval("(...inf)").bsearch { |x| true }.should == -inf
eval("(..-inf)").bsearch { |x| true }.should == -inf
eval("(...-inf)").bsearch { |x| true }.should == nil
end
end
context "with a block returning negative, zero, positive numbers" do
it "returns nil if the block returns less than zero for every element" do
eval("(..5.0)").bsearch { |x| -1 }.should be_nil
eval("(...5.0)").bsearch { |x| -1 }.should be_nil
end
it "returns nil if the block returns greater than zero for every element" do
eval("(..1.1)").bsearch { |x| 1 }.should be_nil
eval("(...1.1)").bsearch { |x| 1 }.should be_nil
end
it "returns nil if the block never returns zero" do
eval("(..6.3)").bsearch { |x| x < 2 ? 1 : -1 }.should be_nil
end
it "accepts (+/-)Float::INFINITY from the block" do
eval("(..5.0)").bsearch { |x| Float::INFINITY }.should be_nil
eval("(..7.0)").bsearch { |x| -Float::INFINITY }.should be_nil
end
it "returns an element at an index for which block returns 0.0" do
result = eval("(..8.0)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 }
result.should == 2
end
it "returns an element at an index for which block returns 0" do
result = eval("(..8.0)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 }
result.should >= 1
result.should <= 3
end
it "works with infinity bounds" do
inf = Float::INFINITY
eval("(..-inf)").bsearch { |x| 1 }.should == nil
eval("(...-inf)").bsearch { |x| 1 }.should == nil
eval("(..inf)").bsearch { |x| x == inf ? 0 : 1 }.should == inf
eval("(...inf)").bsearch { |x| x == inf ? 0 : 1 }.should == nil
eval("(..-inf)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf
eval("(...-inf)").bsearch { |x| x == -inf ? 0 : -1 }.should == nil
eval("(..inf)").bsearch { |x| 3 - x }.should == 3
eval("(...inf)").bsearch { |x| 3 - x }.should == 3
end
end
end
end
end

View file

@ -0,0 +1,14 @@
require_relative '../../spec_helper'
describe "Range#count" do
ruby_version_is "2.7" do
it "returns Infinity for beginless ranges without arguments or blocks" do
inf = Float::INFINITY
eval("('a'...)").count.should == inf
eval("(7..)").count.should == inf
eval("(...'a')").count.should == inf
eval("(...nil)").count.should == inf
eval("(..10.0)").count.should == inf
end
end
end

View file

@ -32,6 +32,12 @@ describe "Range#each" do
a.should == [x, y]
end
it "works for non-ASCII ranges" do
a = []
('Σ'..'Ω').each { |i| a << i }
a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"]
end
ruby_version_is "2.6" do
it "works with endless ranges" do
a = []
@ -54,6 +60,12 @@ describe "Range#each" do
end
end
ruby_version_is "2.7" do
it "raises a TypeError beginless ranges" do
-> { eval("(..2)").each { |x| x } }.should raise_error(TypeError)
end
end
it "raises a TypeError if the first element does not respond to #succ" do
-> { (0.5..2.4).each { |i| i } }.should raise_error(TypeError)

View file

@ -13,4 +13,10 @@ describe "Range#==" do
eval("(1.0..)").should == eval("(1.0..)")
end
end
ruby_version_is "2.7" do
it "returns true if the endpoints are == for beginless ranges" do
eval("(...10)").should == eval("(...10)")
end
end
end

View file

@ -46,4 +46,10 @@ describe "Range#first" do
it "raises a TypeError when passed a String" do
-> { (2..3).first("1") }.should raise_error(TypeError)
end
ruby_version_is "2.7" do
it "raises a RangeError when called on an beginless range" do
-> { eval("(..1)").first }.should raise_error(RangeError)
end
end
end

View file

@ -19,6 +19,18 @@ describe "Range#inspect" do
end
end
ruby_version_is '2.7' do
it "works for beginless ranges" do
eval("(..1)").inspect.should == "..1"
eval("(...0.1)").inspect.should == "...0.1"
end
it "works for nil ... nil ranges" do
eval("(..nil)").inspect.should == "nil..nil"
eval("(nil...)").inspect.should == "nil...nil"
end
end
ruby_version_is ''...'2.7' do
it "returns a tainted string if either end is tainted" do
(("a".taint)..."c").inspect.tainted?.should be_true

View file

@ -51,6 +51,19 @@ describe "Range#max" do
-> { eval("(1..)").max }.should raise_error(RangeError)
end
end
ruby_version_is "3.0" do
it "returns the end point for beginless ranges" do
eval("(..1)").max.should == 1
eval("(..1.0)").max.should == 1.0
end
it "raises for an exclusive beginless range" do
-> {
eval("(...1)").max
}.should raise_error(TypeError, 'cannot exclude end value with non Integer begin value')
end
end
end
describe "Range#max given a block" do
@ -85,4 +98,10 @@ describe "Range#max given a block" do
('z'..'l').max {|x,y| x <=> y}.should be_nil
(5...5).max {|x,y| x <=> y}.should be_nil
end
ruby_version_is "2.7" do
it "raises RangeError when called with custom comparison method on an beginless range" do
-> { eval("(..1)").max {|a, b| a} }.should raise_error(RangeError)
end
end
end

View file

@ -38,6 +38,19 @@ describe "Range#min" do
time_end = Time.now + 1.0
(time_start...time_end).min.should equal(time_start)
end
ruby_version_is "2.6" do
it "returns the start point for endless ranges" do
eval("(1..)").min.should == 1
eval("(1.0...)").min.should == 1.0
end
end
ruby_version_is "2.7" do
it "raises RangeError when called on an beginless range" do
-> { eval("(..1)").min }.should raise_error(RangeError)
end
end
end
describe "Range#min given a block" do
@ -74,9 +87,8 @@ describe "Range#min given a block" do
end
ruby_version_is "2.6" do
it "returns the start point for endless ranges" do
eval("(1..)").min.should == 1
eval("(1.0...)").min.should == 1.0
it "raises RangeError when called with custom comparison method on an endless range" do
-> { eval("(1..)").min {|a, b| a} }.should raise_error(RangeError)
end
end
end

View file

@ -25,10 +25,24 @@ describe "Range#size" do
end
ruby_version_is "2.6" do
it 'returns Float::INFINITY for endless ranges' do
it 'returns Float::INFINITY for endless ranges if the start is numeric' do
eval("(1..)").size.should == Float::INFINITY
eval("(0.5...)").size.should == Float::INFINITY
end
it 'returns nil for endless ranges if the start is not numeric' do
eval("('z'..)").size.should == nil
eval("([]...)").size.should == nil
end
end
ruby_version_is "2.7" do
it 'returns Float::INFINITY for all beginless ranges' do
eval("(..1)").size.should == Float::INFINITY
eval("(...0.5)").size.should == Float::INFINITY
eval("(..nil)").size.should == Float::INFINITY
eval("(...'o')").size.should == Float::INFINITY
end
end
it "returns nil if first and last are not Numeric" do

View file

@ -20,9 +20,19 @@ describe "Range#to_a" do
(:A..:z).to_a.size.should == 58
end
it "works for non-ASCII ranges" do
('Σ'..'Ω').to_a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"]
end
ruby_version_is "2.6" do
it "throws an exception for endless ranges" do
-> { eval("(1..)").to_a }.should raise_error(RangeError)
end
end
ruby_version_is "2.7" do
it "throws an exception for beginless ranges" do
-> { eval("(..1)").to_a }.should raise_error(TypeError)
end
end
end

View file

@ -11,4 +11,46 @@ describe "Regexp.last_match" do
/c(.)t/ =~ 'cat'
Regexp.last_match(1).should == 'a'
end
it "returns nil when there is no match" do
/foo/ =~ "TEST123"
Regexp.last_match(:test).should == nil
Regexp.last_match(1).should == nil
Regexp.last_match(Object.new).should == nil
Regexp.last_match("test").should == nil
end
describe "when given a Symbol" do
it "returns a named capture" do
/(?<test>[A-Z]+.*)/ =~ "TEST123"
Regexp.last_match(:test).should == "TEST123"
end
it "raises an IndexError when given a missing name" do
/(?<test>[A-Z]+.*)/ =~ "TEST123"
-> { Regexp.last_match(:missing) }.should raise_error(IndexError)
end
end
describe "when given a String" do
it "returns a named capture" do
/(?<test>[A-Z]+.*)/ =~ "TEST123"
Regexp.last_match("test").should == "TEST123"
end
end
describe "when given an Object" do
it "coerces argument to an index using #to_int" do
obj = mock("converted to int")
obj.should_receive(:to_int).and_return(1)
/(?<test>[A-Z]+.*)/ =~ "TEST123"
Regexp.last_match(obj).should == "TEST123"
end
it "raises a TypeError when unable to coerce" do
obj = Object.new
/(?<test>[A-Z]+.*)/ =~ "TEST123"
-> { Regexp.last_match(obj) }.should raise_error(TypeError)
end
end
end

View file

@ -74,6 +74,12 @@ describe "String#upto" do
a.should == ["a", "b", "c"]
end
it "works with non-ASCII ranges" do
a = []
'Σ'.upto('Ω') { |s| a << s }
a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"]
end
describe "on sequence of numbers" do
it "calls the block as Integer#upto" do
"8".upto("11").to_a.should == 8.upto(11).map(&:to_s)

View file

@ -43,11 +43,19 @@ ruby_version_is "2.7" do
s.deconstruct_keys([0] ).should == {0 => 10}
end
it "ignores not existing attribute names" do
it "returns an empty hash when there are more keys than attributes" do
struct = Struct.new(:x, :y)
s = struct.new(1, 2)
s.deconstruct_keys([:a, :b, :c]).should == {}
s.deconstruct_keys([:x, :y, :a]).should == {}
end
it "returns at first not existing attribute name" do
struct = Struct.new(:x, :y)
s = struct.new(1, 2)
s.deconstruct_keys([:a, :x]).should == {}
s.deconstruct_keys([:x, :a]).should == {x: 1}
end
it "accepts nil argument and return all the attributes" do

View file

@ -435,11 +435,11 @@ describe "The defined? keyword for an expression" do
end
end
it "returns 'expression' when passed an Integer literal" do
it "returns 'expression' when passed a Fixnum literal" do
defined?(42).should == "expression"
end
it "returns 'expression' when passed an Integer literal" do
it "returns 'expression' when passed a Bignum literal" do
defined?(0xdead_beef_deed_feed).should == "expression"
end

View file

@ -29,7 +29,7 @@ ruby_version_is "2.7" do
it "can not be used in both outer and nested blocks at the same time" do
-> {
eval("-> { _1; -> { _2 } }")
}.should raise_error(SyntaxError, /numbered parameter is already used in.+ outer block here/m)
}.should raise_error(SyntaxError, /numbered parameter is already used in/m)
end
ruby_version_is '2.7'...'3.0' do

View file

@ -5,7 +5,7 @@ ruby_version_is "2.7" do
# TODO: Remove excessive eval calls when support of previous version
# Ruby 2.6 will be dropped
before do
before :each do
ScratchPad.record []
end
@ -41,7 +41,7 @@ ruby_version_is "2.7" do
end
describe "warning" do
before do
before :each do
ruby_version_is ""..."3.0" do
@src = 'case [0, 1]; in [a, b]; end'
end
@ -49,6 +49,12 @@ ruby_version_is "2.7" do
ruby_version_is "3.0" do
@src = '[0, 1] => [a, b]'
end
@experimental, Warning[:experimental] = Warning[:experimental], true
end
after :each do
Warning[:experimental] = @experimental
end
it "warns about pattern matching is experimental feature" do
@ -130,6 +136,19 @@ ruby_version_is "2.7" do
}.should raise_error(SyntaxError, /unexpected/)
end
it "evaluates the case expression once for multiple patterns, caching the result" do
eval(<<~RUBY).should == true
case (ScratchPad << :foo; 1)
in 0
false
in 1
true
end
RUBY
ScratchPad.recorded.should == [:foo]
end
describe "guards" do
it "supports if guard" do
eval(<<~RUBY).should == false
@ -508,6 +527,47 @@ ruby_version_is "2.7" do
RUBY
end
ruby_version_is "3.0" do
it "calls #deconstruct once for multiple patterns, caching the result" do
obj = Object.new
def obj.deconstruct
ScratchPad << :deconstruct
[0, 1]
end
eval(<<~RUBY).should == true
case obj
in [1, 2]
false
in [0, 1]
true
end
RUBY
ScratchPad.recorded.should == [:deconstruct]
end
end
it "calls #deconstruct even on objects that are already an array" do
obj = [1, 2]
def obj.deconstruct
ScratchPad << :deconstruct
[3, 4]
end
eval(<<~RUBY).should == true
case obj
in [3, 4]
true
else
false
end
RUBY
ScratchPad.recorded.should == [:deconstruct]
end
it "does not match object if Constant === object returns false" do
eval(<<~RUBY).should == false
case [0, 1, 2]
@ -521,6 +581,7 @@ ruby_version_is "2.7" do
it "does not match object without #deconstruct method" do
obj = Object.new
obj.should_receive(:respond_to?).with(:deconstruct)
eval(<<~RUBY).should == false
case obj
@ -546,6 +607,26 @@ ruby_version_is "2.7" do
}.should raise_error(TypeError, /deconstruct must return Array/)
end
it "accepts a subclass of Array from #deconstruct" do
obj = Object.new
def obj.deconstruct
subarray = Class.new(Array).new(2)
def subarray.[](n)
n
end
subarray
end
eval(<<~RUBY).should == true
case obj
in [1, 2]
false
in [0, 1]
true
end
RUBY
end
it "does not match object if elements of array returned by #deconstruct method does not match elements in pattern" do
obj = Object.new
def obj.deconstruct; [1] end
@ -778,6 +859,26 @@ ruby_version_is "2.7" do
RUBY
end
it "calls #deconstruct_keys per pattern" do
obj = Object.new
def obj.deconstruct_keys(*)
ScratchPad << :deconstruct_keys
{a: 1}
end
eval(<<~RUBY).should == true
case obj
in {b: 1}
false
in {a: 1}
true
end
RUBY
ScratchPad.recorded.should == [:deconstruct_keys, :deconstruct_keys]
end
it "does not match object if Constant === object returns false" do
eval(<<~RUBY).should == false
case {a: 1}
@ -791,6 +892,7 @@ ruby_version_is "2.7" do
it "does not match object without #deconstruct_keys method" do
obj = Object.new
obj.should_receive(:respond_to?).with(:deconstruct_keys)
eval(<<~RUBY).should == false
case obj

View file

@ -47,7 +47,89 @@ describe "Regexps with back-references" do
/(a\1?){2}/.match("aaaa").to_a.should == ["aa", "a"]
end
it "does not reset enclosed capture groups" do
/((a)|(b))+/.match("ab").captures.should == [ "b", "a", "b" ]
end
it "can match an optional quote, followed by content, followed by a matching quote, as the whole string" do
/^("|)(.*)\1$/.match('x').to_a.should == ["x", "", "x"]
end
it "allows forward references" do
/(?:(\2)|(.))+/.match("aa").to_a.should == [ "aa", "a", "a" ]
end
it "disallows forward references >= 10" do
(/\10()()()()()()()()()()/ =~ "\x08").should == 0
end
it "ignores backreferences > 1000" do
/\99999/.match("99999")[0].should == "99999"
end
it "0 is not a valid backreference" do
-> { Regexp.new("\\k<0>") }.should raise_error(RegexpError)
end
it "allows numeric conditional backreferences" do
/(a)(?(1)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?(<1>)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?('1')a|b)/.match("aa").to_a.should == [ "aa", "a" ]
end
it "allows either <> or '' in named conditional backreferences" do
-> { Regexp.new("(?<a>a)(?(a)a|b)") }.should raise_error(RegexpError)
/(?<a>a)(?(<a>)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a>a)(?('a')a|b)/.match("aa").to_a.should == [ "aa", "a" ]
end
it "allows negative numeric backreferences" do
/(a)\k<-1>/.match("aa").to_a.should == [ "aa", "a" ]
/(a)\g<-1>/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?(<-1>)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?('-1')a|b)/.match("aa").to_a.should == [ "aa", "a" ]
end
it "delimited numeric backreferences can start with 0" do
/(a)\k<01>/.match("aa").to_a.should == [ "aa", "a" ]
/(a)\g<01>/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?(01)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?(<01>)a|b)/.match("aa").to_a.should == [ "aa", "a" ]
/(a)(?('01')a|b)/.match("aa").to_a.should == [ "aa", "a" ]
end
it "regular numeric backreferences cannot start with 0" do
/(a)\01/.match("aa").should == nil
/(a)\01/.match("a\x01").to_a.should == [ "a\x01", "a" ]
end
it "named capture groups invalidate numeric backreferences" do
-> { Regexp.new("(?<a>a)\\1") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a>a)\\k<1>") }.should raise_error(RegexpError)
-> { Regexp.new("(a)(?<a>a)\\1") }.should raise_error(RegexpError)
-> { Regexp.new("(a)(?<a>a)\\k<1>") }.should raise_error(RegexpError)
end
it "treats + or - as the beginning of a level specifier in \\k<> backreferences and (?(...)...|...) conditional backreferences" do
-> { Regexp.new("(?<a+>a)\\k<a+>") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+b>a)\\k<a+b>") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+1>a)\\k<a+1>") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a->a)\\k<a->") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-b>a)\\k<a-b>") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-1>a)\\k<a-1>") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+>a)(?(<a+>)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+b>a)(?(<a+b>)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+1>a)(?(<a+1>)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a->a)(?(<a->)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-b>a)(?(<a-b>)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-1>a)(?(<a-1>)a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+>a)(?('a+')a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+b>a)(?('a+b')a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a+1>a)(?('a+1')a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a->a)(?('a-')a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-b>a)(?('a-b')a|b)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<a-1>a)(?('a-1')a|b)") }.should raise_error(RegexpError)
end
end

View file

@ -78,4 +78,20 @@ describe "Regexps with escape characters" do
# \M-x meta (x|0x80) (character code point value)
# \M-\C-x meta control char (character code point value)
end
it "handles three digit octal escapes starting with 0" do
/[\000-\b]/.match("\x00")[0].should == "\x00"
end
it "handles control escapes with \\C-x syntax" do
/\C-*\C-J\C-j/.match("\n\n\n")[0].should == "\n\n\n"
end
it "supports the \\K keep operator" do
/a\Kb/.match("ab")[0].should == "b"
end
it "supports the \\R line break escape" do
/\R/.match("\n")[0].should == "\n"
end
end

View file

@ -20,4 +20,9 @@ describe "Regexps with grouping" do
# Parsing precedence
/(?:xdigit:)/.match("xdigit:").to_a.should == ["xdigit:"]
end
it "group names cannot start with digits or minus" do
-> { Regexp.new("(?<1a>a)") }.should raise_error(RegexpError)
-> { Regexp.new("(?<-a>a)") }.should raise_error(RegexpError)
end
end

View file

@ -45,4 +45,87 @@ describe "Regexps with repetition" do
/a?/.match("aaa").to_a.should == ["a"]
/a?/.match("bbb").to_a.should == [""]
end
it "handles incomplete range quantifiers" do
/a{}/.match("a{}")[0].should == "a{}"
/a{,}/.match("a{,}")[0].should == "a{,}"
/a{1/.match("a{1")[0].should == "a{1"
/a{1,2/.match("a{1,2")[0].should == "a{1,2"
/a{,5}/.match("aaa")[0].should == "aaa"
end
it "lets us use quantifiers on assertions" do
/a^?b/.match("ab")[0].should == "ab"
/a$?b/.match("ab")[0].should == "ab"
/a\A?b/.match("ab")[0].should == "ab"
/a\Z?b/.match("ab")[0].should == "ab"
/a\z?b/.match("ab")[0].should == "ab"
/a\G?b/.match("ab")[0].should == "ab"
/a\b?b/.match("ab")[0].should == "ab"
/a\B?b/.match("ab")[0].should == "ab"
/a(?=c)?b/.match("ab")[0].should == "ab"
/a(?!=b)?b/.match("ab")[0].should == "ab"
/a(?<=c)?b/.match("ab")[0].should == "ab"
/a(?<!a)?b/.match("ab")[0].should == "ab"
end
it "does not delete optional assertions" do
/(?=(a))?/.match("a").to_a.should == [ "", "a" ]
end
it "supports nested quantifiers" do
suppress_warning do
eval <<-RUBY
/a***/.match("aaa")[0].should == "aaa"
# a+?* should not be reduced, it should be equivalent to (a+?)*
# NB: the capture group prevents regex engines from reducing the two quantifiers
# https://bugs.ruby-lang.org/issues/17341
/a+?*/.match("")[0].should == ""
/(a+?)*/.match("")[0].should == ""
/a+?*/.match("a")[0].should == "a"
/(a+?)*/.match("a")[0].should == "a"
ruby_bug '#17341', ''...'3.0' do
/a+?*/.match("aa")[0].should == "aa"
end
/(a+?)*/.match("aa")[0].should == "aa"
# a+?+ should not be reduced, it should be equivalent to (a+?)+
# https://bugs.ruby-lang.org/issues/17341
/a+?+/.match("").should == nil
/(a+?)+/.match("").should == nil
/a+?+/.match("a")[0].should == "a"
/(a+?)+/.match("a")[0].should == "a"
ruby_bug '#17341', ''...'3.0' do
/a+?+/.match("aa")[0].should == "aa"
end
/(a+?)+/.match("aa")[0].should == "aa"
# both a**? and a+*? should be equivalent to (a+)??
# this quantifier would rather match nothing, but if that's not possible,
# it will greedily take everything
/a**?/.match("")[0].should == ""
/(a*)*?/.match("")[0].should == ""
/a+*?/.match("")[0].should == ""
/(a+)*?/.match("")[0].should == ""
/(a+)??/.match("")[0].should == ""
/a**?/.match("aaa")[0].should == ""
/(a*)*?/.match("aaa")[0].should == ""
/a+*?/.match("aaa")[0].should == ""
/(a+)*?/.match("aaa")[0].should == ""
/(a+)??/.match("aaa")[0].should == ""
/b.**?b/.match("baaabaaab")[0].should == "baaabaaab"
/b(.*)*?b/.match("baaabaaab")[0].should == "baaabaaab"
/b.+*?b/.match("baaabaaab")[0].should == "baaabaaab"
/b(.+)*?b/.match("baaabaaab")[0].should == "baaabaaab"
/b(.+)??b/.match("baaabaaab")[0].should == "baaabaaab"
RUBY
end
end
end

View file

@ -0,0 +1,50 @@
require_relative '../../spec_helper'
require_relative '../fixtures/classes'
describe "Regexps with subexpression calls" do
it "allows numeric subexpression calls" do
/(a)\g<1>/.match("aa").to_a.should == [ "aa", "a" ]
end
it "treats subexpression calls as distinct from simple back-references" do
# Back-references only match a string which is equal to the original captured string.
/(?<three_digits>[0-9]{3})-\k<three_digits>/.match("123-123")[0].should == "123-123"
/(?<three_digits>[0-9]{3})-\k<three_digits>/.match("123-456").should == nil
# However, subexpression calls reuse the previous expression and can match a different
# string.
/(?<three_digits>[0-9]{3})-\g<three_digits>/.match("123-456")[0].should == "123-456"
end
it "allows recursive subexpression calls" do
# This pattern matches well-nested parenthesized expression.
parens = /^ (?<parens> (?: \( \g<parens> \) | [^()] )* ) $/x
parens.match("((a)(b))c(d)")[0].should == "((a)(b))c(d)"
parens.match("((a)(b)c(d)").should == nil
end
it "allows access to back-references from the current level" do
# Using \\k<first_char-0> accesses the last value captured in first_char
# on the current stack level.
mirror = /^ (?<mirror> (?: (?<first_char>.) \g<mirror> \k<first_char-0> )? ) $/x
mirror.match("abccba")[0].should == "abccba"
mirror.match("abccbd").should == nil
# OTOH, using \\k<first_char> accesses the last value captured in first_char,
# regardless of the stack level. Therefore, it can't be used to implement
# the mirror language.
broken_mirror = /^ (?<mirror> (?: (?<first_char>.) \g<mirror> \k<first_char> )? ) $/x
broken_mirror.match("abccba").should == nil
# This matches because the 'c' is captured in first_char and that value is
# then used for all subsequent back-references, regardless of nesting.
broken_mirror.match("abcccc")[0].should == "abcccc"
end
it "allows + and - in group names and referential constructs that don't use levels, i.e. subexpression calls" do
/(?<a+>a)\g<a+>/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a+b>a)\g<a+b>/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a+1>a)\g<a+1>/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a->a)\g<a->/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a-b>a)\g<a-b>/.match("aa").to_a.should == [ "aa", "a" ]
/(?<a-1>a)\g<a-1>/.match("aa").to_a.should == [ "aa", "a" ]
end
end

View file

@ -74,7 +74,7 @@ describe "A singleton class" do
end
it "doesn't have singleton class" do
-> { bignum_value.singleton_class.superclass.should == Integer }.should raise_error(TypeError)
-> { bignum_value.singleton_class }.should raise_error(TypeError)
end
end

View file

@ -30,15 +30,17 @@ describe "Kernel#BigDecimal" do
BigDecimal(rational, 100).to_s.should == "0.99999999999999999999e18"
end
ruby_version_is ""..."3.0" do
it "accepts significant digits >= given precision" do
it "accepts significant digits >= given precision" do
suppress_warning do
BigDecimal("3.1415923", 10).precs[1].should >= 10
end
end
it "determines precision from initial value" do
pi_string = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593014782083152134043"
BigDecimal(pi_string).precs[1].should >= pi_string.size-1
end
it "determines precision from initial value" do
pi_string = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593014782083152134043"
suppress_warning {
BigDecimal(pi_string).precs[1]
}.should >= pi_string.size-1
end
it "ignores leading and trailing whitespace" do
@ -225,14 +227,12 @@ describe "Kernel#BigDecimal" do
Float(@b).to_s.should == "166.66666666666666"
end
ruby_version_is ""..."3.0" do
it "has the expected precision on the LHS" do
@a.precs[0].should == 18
end
it "has the expected precision on the LHS" do
suppress_warning { @a.precs[0] }.should == 18
end
it "has the expected maximum precision on the LHS" do
@a.precs[1].should == 27
end
it "has the expected maximum precision on the LHS" do
suppress_warning { @a.precs[1] }.should == 27
end
it "produces the expected result when done via Float" do
@ -245,36 +245,32 @@ describe "Kernel#BigDecimal" do
# Check underlying methods work as we understand
ruby_version_is ""..."3.0" do
it "BigDecimal precision is the number of digits rounded up to a multiple of nine" do
1.upto(100) do |n|
b = BigDecimal('4' * n)
precs, _ = b.precs
(precs >= 9).should be_true
(precs >= n).should be_true
(precs % 9).should == 0
end
BigDecimal('NaN').precs[0].should == 9
it "BigDecimal precision is the number of digits rounded up to a multiple of nine" do
1.upto(100) do |n|
b = BigDecimal('4' * n)
precs, _ = suppress_warning { b.precs }
(precs >= 9).should be_true
(precs >= n).should be_true
(precs % 9).should == 0
end
suppress_warning { BigDecimal('NaN').precs[0] }.should == 9
end
it "BigDecimal maximum precision is nine more than precision except for abnormals" do
1.upto(100) do |n|
b = BigDecimal('4' * n)
precs, max = b.precs
max.should == precs + 9
end
BigDecimal('NaN').precs[1].should == 9
it "BigDecimal maximum precision is nine more than precision except for abnormals" do
1.upto(100) do |n|
b = BigDecimal('4' * n)
precs, max = suppress_warning { b.precs }
max.should == precs + 9
end
suppress_warning { BigDecimal('NaN').precs[1] }.should == 9
end
it "BigDecimal(Rational, 18) produces the result we expect" do
BigDecimal(@b, 18).to_s.should == "0.166666666666666667e3"
end
ruby_version_is ""..."3.0" do
it "BigDecimal(Rational, BigDecimal.precs[0]) produces the result we expect" do
BigDecimal(@b, @a.precs[0]).to_s.should == "0.166666666666666667e3"
end
it "BigDecimal(Rational, BigDecimal.precs[0]) produces the result we expect" do
BigDecimal(@b, suppress_warning { @a.precs[0] }).to_s.should == "0.166666666666666667e3"
end
# Check the top-level expression works as we expect

View file

@ -41,14 +41,14 @@ describe "BigDecimal#add" do
@frac_3.add(@frac_4, 6).should == BigDecimal("0.11111E16")
end
it "returns a + [Integer value] with given precision" do
it "returns a + [Fixnum value] with given precision" do
(1..10).each {|precision|
@dot_ones.add(0, precision).should == BigDecimal("0." + "1" * precision)
}
BigDecimal("0.88").add(0, 1).should == BigDecimal("0.9")
end
it "returns a + [Integer value] with given precision" do
it "returns a + [Bignum value] with given precision" do
bignum = 10000000000000000000
(1..20).each {|precision|
@dot_ones.add(bignum, precision).should == BigDecimal("0.1E20")

View file

@ -1,44 +1,49 @@
require_relative '../../spec_helper'
require 'bigdecimal'
ruby_version_is ""..."3.0" do
describe "BigDecimal#precs" do
describe "BigDecimal#precs" do
before :each do
@infinity = BigDecimal("Infinity")
@infinity_neg = BigDecimal("-Infinity")
@nan = BigDecimal("NaN")
@zero = BigDecimal("0")
@zero_neg = BigDecimal("-0")
before :each do
@infinity = BigDecimal("Infinity")
@infinity_neg = BigDecimal("-Infinity")
@nan = BigDecimal("NaN")
@zero = BigDecimal("0")
@zero_neg = BigDecimal("-0")
@arr = [BigDecimal("2E40001"), BigDecimal("3E-20001"),\
@infinity, @infinity_neg, @nan, @zero, @zero_neg]
@precision = BigDecimal::BASE.to_s.length - 1
end
@arr = [BigDecimal("2E40001"), BigDecimal("3E-20001"),\
@infinity, @infinity_neg, @nan, @zero, @zero_neg]
@precision = BigDecimal::BASE.to_s.length - 1
end
it "returns array of two values" do
it "returns array of two values" do
suppress_warning do
@arr.each do |x|
x.precs.kind_of?(Array).should == true
x.precs.size.should == 2
end
end
end
it "returns Integers as array values" do
it "returns Integers as array values" do
suppress_warning do
@arr.each do |x|
x.precs[0].kind_of?(Integer).should == true
x.precs[1].kind_of?(Integer).should == true
end
end
end
it "returns the current value of significant digits as the first value" do
it "returns the current value of significant digits as the first value" do
suppress_warning do
BigDecimal("3.14159").precs[0].should >= 6
BigDecimal('1').precs[0].should == BigDecimal('1' + '0' * 100).precs[0]
[@infinity, @infinity_neg, @nan, @zero, @zero_neg].each do |value|
value.precs[0].should <= @precision
end
end
end
it "returns the maximum number of significant digits as the second value" do
it "returns the maximum number of significant digits as the second value" do
suppress_warning do
BigDecimal("3.14159").precs[1].should >= 6
BigDecimal('1').precs[1].should >= 1
BigDecimal('1' + '0' * 100).precs[1].should >= 101

View file

@ -6,7 +6,7 @@ describe :bigdecimal_to_int , shared: true do
-> { BigDecimal("NaN").send(@method) }.should raise_error(FloatDomainError)
end
it "returns Integer or Integer otherwise" do
it "returns Integer otherwise" do
BigDecimal("3E-20001").send(@method).should == 0
BigDecimal("2E4000").send(@method).should == 2 * 10 ** 4000
BigDecimal("2").send(@method).should == 2

View file

@ -16,11 +16,11 @@ describe "Matrix#/" do
# Guard against the Mathn library
guard -> { !defined?(Math.rsqrt) } do
it "returns the result of dividing self by an Integer" do
it "returns the result of dividing self by a Fixnum" do
(@a / 2).should == Matrix[ [0, 1], [1, 2] ]
end
it "returns the result of dividing self by an Integer" do
it "returns the result of dividing self by a Bignum" do
(@a / bignum_value).should == Matrix[ [0, 0], [0, 0] ]
end
end

View file

@ -16,11 +16,11 @@ describe "Matrix#*" do
(@a * Vector[1,2]).should == Vector[5, 11]
end
it "returns the result of multiplying the elements of self and an Integer" do
it "returns the result of multiplying the elements of self and a Fixnum" do
(@a * 2).should == Matrix[ [2, 4], [6, 8] ]
end
it "returns the result of multiplying the elements of self and an Integer" do
it "returns the result of multiplying the elements of self and a Bignum" do
(@a * bignum_value).should == Matrix[
[9223372036854775808, 18446744073709551616],
[27670116110564327424, 36893488147419103232]

View file

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/plus'
describe "Pathname#/" do
it_behaves_like :pathname_plus, :/
end

View file

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/plus'
describe "Pathname#+" do
it_behaves_like :pathname_plus, :+
end

View file

@ -0,0 +1,8 @@
require 'pathname'
describe :pathname_plus, shared: true do
it "appends a pathname to self" do
p = Pathname.new("/usr")
p.send(@method, "bin/ruby").should == Pathname.new("/usr/bin/ruby")
end
end

View file

@ -4,10 +4,26 @@ require_relative 'shared/each_byte'
ruby_version_is ''...'3.0' do
describe "StringIO#bytes" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_byte, :bytes
end
describe "StringIO#bytes when self is not readable" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_byte_not_readable, :bytes
end
end

View file

@ -4,10 +4,26 @@ require_relative 'shared/each_char'
ruby_version_is ''...'3.0' do
describe "StringIO#chars" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_char, :chars
end
describe "StringIO#chars when self is not readable" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_char_not_readable, :chars
end
end

View file

@ -4,9 +4,16 @@ require_relative 'fixtures/classes'
require_relative 'shared/codepoints'
ruby_version_is ''...'3.0' do
# See redmine #1667
describe "StringIO#codepoints" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_codepoints, :codepoints
end
end

View file

@ -4,18 +4,50 @@ require_relative 'shared/each'
ruby_version_is ''...'3.0' do
describe "StringIO#lines when passed a separator" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_separator, :lines
end
describe "StringIO#lines when passed no arguments" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_no_arguments, :lines
end
describe "StringIO#lines when self is not readable" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_not_readable, :lines
end
describe "StringIO#lines when passed chomp" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
end
after :each do
$VERBOSE = @verbose
end
it_behaves_like :stringio_each_chomp, :lines
end
end

View file

@ -22,7 +22,7 @@ describe :strscan_peek, shared: true do
-> { @s.send(@method, -2) }.should raise_error(ArgumentError)
end
it "raises a RangeError when the passed argument is an Integer" do
it "raises a RangeError when the passed argument is a Bignum" do
-> { @s.send(@method, bignum_value) }.should raise_error(RangeError)
end

View file

@ -187,14 +187,14 @@ describe "CApiBignumSpecs" do
it "returns a Fixnum for a Fixnum input value" do
val = @s.rb_dbl2big(2)
val.kind_of?(Fixnum).should == true
val.kind_of?(Integer).should == true
val.should == 2
end
it "returns a Fixnum for a Float input value" do
val = @s.rb_dbl2big(2.5)
val.kind_of?(Fixnum).should == true
val.kind_of?(Integer).should == true
val.should == 2
end
@ -202,7 +202,7 @@ describe "CApiBignumSpecs" do
input = 219238102380912830988.5 # chosen by fair dice roll
val = @s.rb_dbl2big(input)
val.kind_of?(Bignum).should == true
val.kind_of?(Integer).should == true
# This value is based on the output of a simple C extension that uses
# rb_dbl2big() to convert the above input value to a Bignum.

View file

@ -0,0 +1,19 @@
require_relative 'spec_helper'
load_extension("binding")
describe "CApiBindingSpecs" do
before :each do
@b = CApiBindingSpecs.new
end
describe "Kernel#binding" do
it "gives the top-most Ruby binding when called from C" do
foo = 14
b = @b.get_binding
b.local_variable_get(:foo).should == 14
b.local_variable_set :foo, 12
foo.should == 12
end
end
end

View file

@ -0,0 +1,19 @@
#include "ruby.h"
#include "rubyspec.h"
#ifdef __cplusplus
extern "C" {
#endif
static VALUE binding_spec_get_binding(VALUE self) {
return rb_funcall(self, rb_intern("binding"), 0);
}
void Init_binding_spec(void) {
VALUE cls = rb_define_class("CApiBindingSpecs", rb_cObject);
rb_define_method(cls, "get_binding", binding_spec_get_binding, 0);
}
#ifdef __cplusplus
}
#endif

Some files were not shown because too many files have changed in this diff Show more