This commit is contained in:
Benoit Daloze 2019-04-27 18:53:23 +02:00
parent 00c33d9c23
commit a1b4816759
193 changed files with 3026 additions and 3387 deletions

View file

@ -3,20 +3,18 @@ language: ruby
install: install:
- git clone https://github.com/ruby/mspec.git ../mspec - git clone https://github.com/ruby/mspec.git ../mspec
script: script:
- ../mspec/bin/mspec $MSPEC_OPTS - CHECK_LEAKS=true ../mspec/bin/mspec
matrix: matrix:
include: include:
- name: Running each spec twice
rvm: 2.5.5
script:
- CHECK_LEAKS=true ../mspec/bin/mspec -R2 -ff
- rvm: 2.4.6
- rvm: 2.5.5 - rvm: 2.5.5
env: MSPEC_OPTS="-R2 -ff" - rvm: 2.6.3
- rvm: 2.3.8 - name: RuboCop Lint Checks
- rvm: 2.4.5 rvm: 2.4.6
env: CHECK_LEAKS=true
- rvm: 2.5.5
env: CHECK_LEAKS=true
- rvm: 2.6.2
env: CHECK_LEAKS=true
- env: RUBOCOP=true
rvm: 2.4.5
script: script:
- gem install rubocop:0.61.0 - gem install rubocop:0.61.0
- rubocop - rubocop

View file

@ -144,11 +144,11 @@ end
# Combining guards # Combining guards
guard -> { platform_is :windows and ruby_version_is ""..."2.3" } do guard -> { platform_is :windows and ruby_version_is ""..."2.5" } do
# Windows and RUBY_VERSION < 2.3 # Windows and RUBY_VERSION < 2.5
end end
guard_not -> { platform_is :windows and ruby_version_is ""..."2.3" } do guard_not -> { platform_is :windows and ruby_version_is ""..."2.5" } do
# The opposite # The opposite
end end
@ -170,20 +170,20 @@ If an implementation does not support some feature, simply tag the related specs
### Shared Specs ### Shared Specs
Often throughout Ruby, identical functionality is used by different methods and modules. In order Often throughout Ruby, identical functionality is used by different methods and modules. In order
to avoid duplication of specs, we have shared specs that are re-used in other specs. The use is a to avoid duplication of specs, we have shared specs that are re-used in other specs. The use is a
bit tricky however, so let's go over it. bit tricky however, so let's go over it.
Commonly, if a shared spec is only reused within its own module, the shared spec will live within a Commonly, if a shared spec is only reused within its own module, the shared spec will live within a
shared directory inside that module's directory. For example, the `core/hash/shared/key.rb` spec is shared directory inside that module's directory. For example, the `core/hash/shared/key.rb` spec is
only used by `Hash` specs, and so it lives inside `core/hash/shared/`. only used by `Hash` specs, and so it lives inside `core/hash/shared/`.
When a shared spec is used across multiple modules or classes, it lives within the `shared/` directory. When a shared spec is used across multiple modules or classes, it lives within the `shared/` directory.
An example of this is the `shared/file/socket.rb` which is used by `core/file/socket_spec.rb`, An example of this is the `shared/file/socket.rb` which is used by `core/file/socket_spec.rb`,
`core/filetest/socket_spec.rb`, and `core/file/state/socket_spec.rb` and so it lives in the root `shared/`. `core/filetest/socket_spec.rb`, and `core/file/state/socket_spec.rb` and so it lives in the root `shared/`.
Defining a shared spec involves adding a `shared: true` option to the top-level `describe` block. This Defining a shared spec involves adding a `shared: true` option to the top-level `describe` block. This
will signal not to run the specs directly by the runner. Shared specs have access to two instance will signal not to run the specs directly by the runner. Shared specs have access to two instance
variables from the implementor spec: `@method` and `@object`, which the implementor spec will pass in. variables from the implementor spec: `@method` and `@object`, which the implementor spec will pass in.
Here's an example of a snippet of a shared spec and two specs which integrates it: Here's an example of a snippet of a shared spec and two specs which integrates it:

View file

@ -28,8 +28,8 @@ ruby/spec is known to be tested in these implementations for every commit:
* [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby) * [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby)
* [Opal](https://github.com/opal/opal/tree/master/spec) * [Opal](https://github.com/opal/opal/tree/master/spec)
ruby/spec describes the behavior of Ruby 2.3 and more recent Ruby versions. ruby/spec describes the behavior of Ruby 2.4 and more recent Ruby versions.
More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.3.x, 2.4.x, 2.5.x, 2.6.x, etc), and those are tested in TravisCI. More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.4.x, 2.5.x, 2.6.x, etc), and those are tested in TravisCI.
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.
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs. Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
@ -49,6 +49,7 @@ For older specs try these commits:
* Ruby 2.0.0-p647 - [Suite](https://github.com/ruby/spec/commit/245862558761d5abc676843ef74f86c9bcc8ea8d) using [MSpec](https://github.com/ruby/mspec/commit/f90efa068791064f955de7a843e96e2d7d3041c2) (may encounter 2 failures) * Ruby 2.0.0-p647 - [Suite](https://github.com/ruby/spec/commit/245862558761d5abc676843ef74f86c9bcc8ea8d) using [MSpec](https://github.com/ruby/mspec/commit/f90efa068791064f955de7a843e96e2d7d3041c2) (may encounter 2 failures)
* Ruby 2.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed) * Ruby 2.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed)
* Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3) * Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3)
* Ruby 2.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea)
### Running the specs ### Running the specs

View file

@ -37,15 +37,6 @@ describe "The --enable and --disable flags" do
ruby_exe("p 'foo'.frozen?", options: "--disable-frozen-string-literal").chomp.should == "false" ruby_exe("p 'foo'.frozen?", options: "--disable-frozen-string-literal").chomp.should == "false"
end end
ruby_version_is "2.6" do
it "can be used with jit" do
ruby_exe("p :OK", options: "--enable=jit 2>&1").chomp.should == ":OK"
ruby_exe("p :OK", options: "--disable=jit 2>&1").chomp.should == ":OK"
ruby_exe("p :OK", options: "--enable-jit 2>&1").chomp.should == ":OK"
ruby_exe("p :OK", options: "--disable-jit 2>&1").chomp.should == ":OK"
end
end
it "can be used with all" do it "can be used with all" do
e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]" e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
env = {'RUBYOPT' => '-w'} env = {'RUBYOPT' => '-w'}

View file

@ -110,23 +110,21 @@ describe "Array#concat" do
ary.concat([5, 6]).should == [4, 5, 6] ary.concat([5, 6]).should == [4, 5, 6]
end end
ruby_version_is "2.4" do it "takes multiple arguments" do
it "takes multiple arguments" do ary = [1, 2]
ary = [1, 2] ary.concat [3, 4]
ary.concat [3, 4] ary.should == [1, 2, 3, 4]
ary.should == [1, 2, 3, 4] end
end
it "concatenates the initial value when given arguments contain 2 self" do it "concatenates the initial value when given arguments contain 2 self" do
ary = [1, 2] ary = [1, 2]
ary.concat ary, ary ary.concat ary, ary
ary.should == [1, 2, 1, 2, 1, 2] ary.should == [1, 2, 1, 2, 1, 2]
end end
it "returns self when given no arguments" do it "returns self when given no arguments" do
ary = [1, 2] ary = [1, 2]
ary.concat.should equal(ary) ary.concat.should equal(ary)
ary.should == [1, 2] ary.should == [1, 2]
end
end end
end end

View file

@ -1,10 +1,8 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "Array#max" do describe "Array#max" do
ruby_version_is "2.4" do it "is defined on Array" do
it "is defined on Array" do [1].method(:max).owner.should equal Array
[1].method(:max).owner.should equal Array
end
end end
it "returns nil with no values" do it "returns nil with no values" do

View file

@ -1,10 +1,8 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
describe "Array#min" do describe "Array#min" do
ruby_version_is "2.4" do it "is defined on Array" do
it "is defined on Array" do [1].method(:max).owner.should equal Array
[1].method(:max).owner.should equal Array
end
end end
it "returns nil with no values" do it "returns nil with no values" do

View file

@ -2,51 +2,49 @@
require_relative '../../../spec_helper' require_relative '../../../spec_helper'
ruby_version_is '2.4' do describe "Array#pack with :buffer option" do
describe "Array#pack with :buffer option" do it "returns specified buffer" do
it "returns specified buffer" do n = [ 65, 66, 67 ]
buffer = " "*3
result = n.pack("ccc", buffer: buffer) #=> "ABC"
result.should equal(buffer)
end
it "adds result at the end of buffer content" do
n = [ 65, 66, 67 ] # result without buffer is "ABC"
buffer = ""
n.pack("ccc", buffer: buffer).should == "ABC"
buffer = "123"
n.pack("ccc", buffer: buffer).should == "123ABC"
buffer = "12345"
n.pack("ccc", buffer: buffer).should == "12345ABC"
end
it "raises TypeError exception if buffer is not String" do
lambda { [65].pack("ccc", buffer: []) }.should raise_error(
TypeError, "buffer must be String, not Array")
end
context "offset (@) is specified" do
it 'keeps buffer content if it is longer than offset' do
n = [ 65, 66, 67 ] n = [ 65, 66, 67 ]
buffer = " "*3 buffer = "123456"
result = n.pack("ccc", buffer: buffer) #=> "ABC" n.pack("@3ccc", buffer: buffer).should == "123ABC"
result.should equal(buffer)
end end
it "adds result at the end of buffer content" do it "fills the gap with \\0 if buffer content is shorter than offset" do
n = [ 65, 66, 67 ] # result without buffer is "ABC" n = [ 65, 66, 67 ]
buffer = ""
n.pack("ccc", buffer: buffer).should == "ABC"
buffer = "123" buffer = "123"
n.pack("ccc", buffer: buffer).should == "123ABC" n.pack("@6ccc", buffer: buffer).should == "123\0\0\0ABC"
buffer = "12345"
n.pack("ccc", buffer: buffer).should == "12345ABC"
end end
it "raises TypeError exception if buffer is not String" do it 'does not keep buffer content if it is longer than offset + result' do
lambda { [65].pack("ccc", buffer: []) }.should raise_error( n = [ 65, 66, 67 ]
TypeError, "buffer must be String, not Array") buffer = "1234567890"
end n.pack("@3ccc", buffer: buffer).should == "123ABC"
context "offset (@) is specified" do
it 'keeps buffer content if it is longer than offset' do
n = [ 65, 66, 67 ]
buffer = "123456"
n.pack("@3ccc", buffer: buffer).should == "123ABC"
end
it "fills the gap with \\0 if buffer content is shorter than offset" do
n = [ 65, 66, 67 ]
buffer = "123"
n.pack("@6ccc", buffer: buffer).should == "123\0\0\0ABC"
end
it 'does not keep buffer content if it is longer than offset + result' do
n = [ 65, 66, 67 ]
buffer = "1234567890"
n.pack("@3ccc", buffer: buffer).should == "123ABC"
end
end end
end end
end end

View file

@ -121,22 +121,20 @@ describe "Array#reject!" do
a.should == [1, 2, 3] a.should == [1, 2, 3]
end end
ruby_version_is "2.4" do it "only removes elements for which the block returns true, keeping the element which raised an error." do
it "only removes elements for which the block returns true, keeping the element which raised an error." do a = [1, 2, 3, 4]
a = [1, 2, 3, 4] begin
begin a.reject! do |x|
a.reject! do |x| case x
case x when 2 then true
when 2 then true when 3 then raise StandardError, 'Oops'
when 3 then raise StandardError, 'Oops' else false
else false
end
end end
rescue StandardError
end end
rescue StandardError
a.should == [1, 3, 4]
end end
a.should == [1, 3, 4]
end end
it_behaves_like :enumeratorize, :reject! it_behaves_like :enumeratorize, :reject!

View file

@ -1,44 +1,42 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe "Array#sum" do
describe "Array#sum" do it "returns the sum of elements" do
it "returns the sum of elements" do [1, 2, 3].sum.should == 6
[1, 2, 3].sum.should == 6 end
end
it "applies a block to each element before adding if it's given" do it "applies a block to each element before adding if it's given" do
[1, 2, 3].sum { |i| i * 10 }.should == 60 [1, 2, 3].sum { |i| i * 10 }.should == 60
end end
it "returns init value if array is empty" do it "returns init value if array is empty" do
[].sum(-1).should == -1 [].sum(-1).should == -1
end end
it "returns 0 if array is empty and init is omitted" do it "returns 0 if array is empty and init is omitted" do
[].sum.should == 0 [].sum.should == 0
end end
it "adds init value to the sum of elements" do it "adds init value to the sum of elements" do
[1, 2, 3].sum(10).should == 16 [1, 2, 3].sum(10).should == 16
end end
it "can be used for non-numeric objects by providing init value" do it "can be used for non-numeric objects by providing init value" do
["a", "b", "c"].sum("").should == "abc" ["a", "b", "c"].sum("").should == "abc"
end end
it 'raises TypeError if any element are not numeric' do it 'raises TypeError if any element are not numeric' do
lambda { ["a"].sum }.should raise_error(TypeError) lambda { ["a"].sum }.should raise_error(TypeError)
end end
it 'raises TypeError if any element cannot be added to init value' do it 'raises TypeError if any element cannot be added to init value' do
lambda { [1].sum([]) }.should raise_error(TypeError) lambda { [1].sum([]) }.should raise_error(TypeError)
end end
it "calls + to sum the elements" do it "calls + to sum the elements" do
a = mock("a") a = mock("a")
b = mock("b") b = mock("b")
a.should_receive(:+).with(b).and_return(42) a.should_receive(:+).with(b).and_return(42)
[b].sum(a).should == 42 [b].sum(a).should == 42
end
end end
end end

View file

@ -19,8 +19,12 @@ describe "BasicObject" do
BasicObjectSpecs::BOSubclass.kernel_defined?.should be_nil BasicObjectSpecs::BOSubclass.kernel_defined?.should be_nil
end end
it "is included in Object's list of constants" do
Object.constants(false).should include(:BasicObject)
end
it "includes itself in its list of constants" do it "includes itself in its list of constants" do
BasicObject.constants.should include(:BasicObject) BasicObject.constants(false).should include(:BasicObject)
end end
end end

View file

@ -1,50 +1,48 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is '2.4' do describe 'Comparable#clamp' do
describe 'Comparable#clamp' do it 'raises an Argument error unless given 2 parameters' do
it 'raises an Argument error unless given 2 parameters' do c = ComparableSpecs::Weird.new(0)
c = ComparableSpecs::Weird.new(0) lambda { c.clamp(c) }.should raise_error(ArgumentError)
lambda { c.clamp(c) }.should raise_error(ArgumentError) lambda { c.clamp(c, c, c) }.should raise_error(ArgumentError)
lambda { c.clamp(c, c, c) }.should raise_error(ArgumentError) end
end
it 'raises an Argument error unless the 2 parameters are correctly ordered' do it 'raises an Argument error unless the 2 parameters are correctly ordered' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1) one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2) two = ComparableSpecs::WithOnlyCompareDefined.new(2)
c = ComparableSpecs::Weird.new(3) c = ComparableSpecs::Weird.new(3)
lambda { c.clamp(two, one) }.should raise_error(ArgumentError) lambda { c.clamp(two, one) }.should raise_error(ArgumentError)
one.should_receive(:<=>).any_number_of_times.and_return(nil) one.should_receive(:<=>).any_number_of_times.and_return(nil)
lambda { c.clamp(one, two) }.should raise_error(ArgumentError) lambda { c.clamp(one, two) }.should raise_error(ArgumentError)
end end
it 'returns self if within the given parameters' do it 'returns self if within the given parameters' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1) one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2) two = ComparableSpecs::WithOnlyCompareDefined.new(2)
three = ComparableSpecs::WithOnlyCompareDefined.new(3) three = ComparableSpecs::WithOnlyCompareDefined.new(3)
c = ComparableSpecs::Weird.new(2) c = ComparableSpecs::Weird.new(2)
c.clamp(one, two).should equal(c) c.clamp(one, two).should equal(c)
c.clamp(two, two).should equal(c) c.clamp(two, two).should equal(c)
c.clamp(one, three).should equal(c) c.clamp(one, three).should equal(c)
c.clamp(two, three).should equal(c) c.clamp(two, three).should equal(c)
end end
it 'returns the min parameter if smaller than it' do it 'returns the min parameter if smaller than it' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1) one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2) two = ComparableSpecs::WithOnlyCompareDefined.new(2)
c = ComparableSpecs::Weird.new(0) c = ComparableSpecs::Weird.new(0)
c.clamp(one, two).should equal(one) c.clamp(one, two).should equal(one)
end end
it 'returns the max parameter if greater than it' do it 'returns the max parameter if greater than it' do
one = ComparableSpecs::WithOnlyCompareDefined.new(1) one = ComparableSpecs::WithOnlyCompareDefined.new(1)
two = ComparableSpecs::WithOnlyCompareDefined.new(2) two = ComparableSpecs::WithOnlyCompareDefined.new(2)
c = ComparableSpecs::Weird.new(3) c = ComparableSpecs::Weird.new(3)
c.clamp(one, two).should equal(two) c.clamp(one, two).should equal(two)
end
end end
end end

View file

@ -1,36 +1,32 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Complex#finite?" do
describe "Complex#finite?" do it "returns true if magnitude is finite" do
it "returns true if magnitude is finite" do (1+1i).finite?.should == true
(1+1i).finite?.should == true end
end
it "returns false for positive infinity" do it "returns false for positive infinity" do
value = Complex(Float::INFINITY, 42) value = Complex(Float::INFINITY, 42)
value.finite?.should == false value.finite?.should == false
end end
it "returns false for positive complex with infinite imaginary" do it "returns false for positive complex with infinite imaginary" do
value = Complex(1, Float::INFINITY) value = Complex(1, Float::INFINITY)
value.finite?.should == false value.finite?.should == false
end end
it "returns false for negative infinity" do it "returns false for negative infinity" do
value = -Complex(Float::INFINITY, 42) value = -Complex(Float::INFINITY, 42)
value.finite?.should == false value.finite?.should == false
end end
it "returns false for negative complex with infinite imaginary" do it "returns false for negative complex with infinite imaginary" do
value = -Complex(1, Float::INFINITY) value = -Complex(1, Float::INFINITY)
value.finite?.should == false value.finite?.should == false
end end
ruby_bug "#14014", "2.4"..."2.5" do it "returns false for NaN" do
it "returns false for NaN" do value = Complex(Float::NAN, Float::NAN)
value = Complex(Float::NAN, Float::NAN) value.finite?.should == false
value.finite?.should == false
end
end
end end
end end

View file

@ -1,34 +1,32 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Complex#infinite?" do
describe "Complex#infinite?" do it "returns nil if magnitude is finite" do
it "returns nil if magnitude is finite" do (1+1i).infinite?.should == nil
(1+1i).infinite?.should == nil end
end
it "returns 1 for positive infinity" do it "returns 1 for positive infinity" do
value = Complex(Float::INFINITY, 42).infinite? value = Complex(Float::INFINITY, 42).infinite?
value.should == 1 value.should == 1
end end
it "returns 1 for positive complex with infinite imaginary" do it "returns 1 for positive complex with infinite imaginary" do
value = Complex(1, Float::INFINITY).infinite? value = Complex(1, Float::INFINITY).infinite?
value.should == 1 value.should == 1
end end
it "returns -1 for negative infinity" do it "returns -1 for negative infinity" do
value = -Complex(Float::INFINITY, 42).infinite? value = -Complex(Float::INFINITY, 42).infinite?
value.should == -1 value.should == -1
end end
it "returns -1 for negative complex with infinite imaginary" do it "returns -1 for negative complex with infinite imaginary" do
value = -Complex(1, Float::INFINITY).infinite? value = -Complex(1, Float::INFINITY).infinite?
value.should == -1 value.should == -1
end end
it "returns nil for NaN" do it "returns nil for NaN" do
value = Complex(0, Float::NAN).infinite? value = Complex(0, Float::NAN).infinite?
value.should == nil value.should == nil
end
end end
end end

View file

@ -1,33 +1,31 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Dir.empty?" do
describe "Dir.empty?" do before :all do
before :all do @empty_dir = tmp("empty_dir")
@empty_dir = tmp("empty_dir") mkdir_p @empty_dir
mkdir_p @empty_dir end
end
after :all do after :all do
rm_r @empty_dir rm_r @empty_dir
end end
it "returns true for empty directories" do it "returns true for empty directories" do
result = Dir.empty? @empty_dir result = Dir.empty? @empty_dir
result.should be_true result.should be_true
end end
it "returns false for non-empty directories" do it "returns false for non-empty directories" do
result = Dir.empty? __dir__ result = Dir.empty? __dir__
result.should be_false result.should be_false
end end
it "returns false for a non-directory" do it "returns false for a non-directory" do
result = Dir.empty? __FILE__ result = Dir.empty? __FILE__
result.should be_false result.should be_false
end end
it "raises ENOENT for nonexistent directories" do it "raises ENOENT for nonexistent directories" do
lambda { Dir.empty? tmp("nonexistent") }.should raise_error(Errno::ENOENT) lambda { Dir.empty? tmp("nonexistent") }.should raise_error(Errno::ENOENT)
end
end end
end end

View file

@ -6,21 +6,11 @@ describe "Enumerable#chunk" do
ScratchPad.record [] ScratchPad.record []
end end
ruby_version_is ""..."2.4" do it "returns an Enumerator if called without a block" do
it "raises an ArgumentError if called without a block" do chunk = EnumerableSpecs::Numerous.new(1, 2, 3, 1, 2).chunk
lambda do chunk.should be_an_instance_of(Enumerator)
EnumerableSpecs::Numerous.new.chunk result = chunk.with_index {|elt, i| elt - i }.to_a
end.should raise_error(ArgumentError) result.should == [[1, [1, 2, 3]], [-2, [1, 2]]]
end
end
ruby_version_is "2.4" do
it "returns an Enumerator if called without a block" do
chunk = EnumerableSpecs::Numerous.new(1, 2, 3, 1, 2).chunk
chunk.should be_an_instance_of(Enumerator)
result = chunk.with_index {|elt, i| elt - i }.to_a
result.should == [[1, [1, 2, 3]], [-2, [1, 2]]]
end
end end
it "returns an Enumerator if given a block" do it "returns an Enumerator if given a block" do

View file

@ -1,30 +1,28 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is '2.4' do describe 'Enumerable#sum' do
describe 'Enumerable#sum' do before :each do
before :each do @enum = Object.new.to_enum
@enum = Object.new.to_enum class << @enum
class << @enum def each
def each yield 0
yield 0 yield(-1)
yield(-1) yield 2
yield 2 yield 2/3r
yield 2/3r
end
end end
end end
end
it 'returns amount of the elements with taking an argument as the initial value' do it 'returns amount of the elements with taking an argument as the initial value' do
@enum.sum(10).should == 35/3r @enum.sum(10).should == 35/3r
end end
it 'gives 0 as a default argument' do it 'gives 0 as a default argument' do
@enum.sum.should == 5/3r @enum.sum.should == 5/3r
end end
it 'takes a block to transform the elements' do it 'takes a block to transform the elements' do
@enum.sum { |element| element * 2 }.should == 10/3r @enum.sum { |element| element * 2 }.should == 10/3r
end
end end
end end

View file

@ -1,94 +1,90 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is '2.4' do describe 'Enumerable#uniq' do
describe 'Enumerable#uniq' do it 'returns an array that contains only unique elements' do
it 'returns an array that contains only unique elements' do [0, 1, 2, 3].to_enum.uniq { |n| n.even? }.should == [0, 1]
[0, 1, 2, 3].to_enum.uniq { |n| n.even? }.should == [0, 1] end
end
it "uses eql? semantics" do it "uses eql? semantics" do
[1.0, 1].to_enum.uniq.should == [1.0, 1] [1.0, 1].to_enum.uniq.should == [1.0, 1]
end end
it "compares elements first with hash" do it "compares elements first with hash" do
x = mock('0') x = mock('0')
x.should_receive(:hash).at_least(1).and_return(0) x.should_receive(:hash).at_least(1).and_return(0)
y = mock('0') y = mock('0')
y.should_receive(:hash).at_least(1).and_return(0) y.should_receive(:hash).at_least(1).and_return(0)
[x, y].to_enum.uniq.should == [x, y] [x, y].to_enum.uniq.should == [x, y]
end end
it "does not compare elements with different hash codes via eql?" do it "does not compare elements with different hash codes via eql?" do
x = mock('0') x = mock('0')
x.should_not_receive(:eql?) x.should_not_receive(:eql?)
y = mock('1') y = mock('1')
y.should_not_receive(:eql?) y.should_not_receive(:eql?)
x.should_receive(:hash).at_least(1).and_return(0) x.should_receive(:hash).at_least(1).and_return(0)
y.should_receive(:hash).at_least(1).and_return(1) y.should_receive(:hash).at_least(1).and_return(1)
[x, y].to_enum.uniq.should == [x, y] [x, y].to_enum.uniq.should == [x, y]
end end
it "compares elements with matching hash codes with #eql?" do it "compares elements with matching hash codes with #eql?" do
a = Array.new(2) do a = Array.new(2) do
obj = mock('0') obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0) obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o) def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or # It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both. # a[1].eql?(a[0]) so we taint both.
taint taint
o.taint o.taint
false false
end
obj
end end
a.uniq.should == a obj
a[0].tainted?.should == true
a[1].tainted?.should == true
a = Array.new(2) do
obj = mock('0')
obj.should_receive(:hash).at_least(1).and_return(0)
def obj.eql?(o)
# It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end
obj
end
a.to_enum.uniq.size.should == 1
a[0].tainted?.should == true
a[1].tainted?.should == true
end end
context 'when yielded with multiple arguments' do a.uniq.should == a
before :each do a[0].tainted?.should == true
@enum = Object.new.to_enum a[1].tainted?.should == true
class << @enum
def each a = Array.new(2) do
yield 0, 'foo' obj = mock('0')
yield 1, 'FOO' obj.should_receive(:hash).at_least(1).and_return(0)
yield 2, 'bar'
end def obj.eql?(o)
end # It's undefined whether the impl does a[0].eql?(a[1]) or
# a[1].eql?(a[0]) so we taint both.
taint
o.taint
true
end end
ruby_bug '#13669', ''...'2.5' do obj
it 'returns all yield arguments as an array' do end
@enum.uniq { |_, label| label.downcase }.should == [[0, 'foo'], [2, 'bar']]
a.to_enum.uniq.size.should == 1
a[0].tainted?.should == true
a[1].tainted?.should == true
end
context 'when yielded with multiple arguments' do
before :each do
@enum = Object.new.to_enum
class << @enum
def each
yield 0, 'foo'
yield 1, 'FOO'
yield 2, 'bar'
end end
end end
end end
it 'returns all yield arguments as an array' do
@enum.uniq { |_, label| label.downcase }.should == [[0, 'foo'], [2, 'bar']]
end
end end
end end

View file

@ -25,22 +25,12 @@ describe "Enumerator::Lazy#chunk" do
Enumerator::Lazy.new(Object.new, 100) {}.chunk { |v| v }.size.should == nil Enumerator::Lazy.new(Object.new, 100) {}.chunk { |v| v }.size.should == nil
end end
ruby_version_is ""..."2.4" do it "returns an Enumerator if called without a block" do
it "raises an ArgumentError if called without a block" do chunk = @yieldsmixed.chunk
lambda do chunk.should be_an_instance_of(Enumerator::Lazy)
@yieldsmixed.chunk
end.should raise_error(ArgumentError)
end
end
ruby_version_is "2.4" do res = chunk.each { |v| true }.force
it "returns an Enumerator if called without a block" do res.should == [[true, EnumeratorLazySpecs::YieldsMixed.gathered_yields]]
chunk = @yieldsmixed.chunk
chunk.should be_an_instance_of(Enumerator::Lazy)
res = chunk.each { |v| true }.force
res.should == [[true, EnumeratorLazySpecs::YieldsMixed.gathered_yields]]
end
end end
describe "when the returned lazy enumerator is evaluated by Enumerable#first" do describe "when the returned lazy enumerator is evaluated by Enumerable#first" do

View file

@ -14,9 +14,7 @@ describe "Enumerator::Lazy" do
:select, :slice_after, :slice_before, :slice_when, :take, :take_while, :select, :slice_after, :slice_before, :slice_when, :take, :take_while,
:to_enum, :zip :to_enum, :zip
] ]
ruby_version_is "2.4" do lazy_methods += [:chunk_while, :uniq]
lazy_methods += [:chunk_while, :uniq]
end
Enumerator::Lazy.instance_methods(false).should include(*lazy_methods) Enumerator::Lazy.instance_methods(false).should include(*lazy_methods)
end end

View file

@ -5,4 +5,43 @@ require_relative 'shared/select'
describe "Enumerator::Lazy#select" do describe "Enumerator::Lazy#select" do
it_behaves_like :enumerator_lazy_select, :select it_behaves_like :enumerator_lazy_select, :select
it "doesn't pre-evaluate the next element" do
eval_count = 0
enum = %w[Text1 Text2 Text3].lazy.select do
eval_count += 1
true
end
eval_count.should == 0
enum.next
eval_count.should == 1
end
it "doesn't over-evaluate when peeked" do
eval_count = 0
enum = %w[Text1 Text2 Text3].lazy.select do
eval_count += 1
true
end
eval_count.should == 0
enum.peek
enum.peek
eval_count.should == 1
end
it "doesn't re-evaluate after peek" do
eval_count = 0
enum = %w[Text1 Text2 Text3].lazy.select do
eval_count += 1
true
end
eval_count.should == 0
enum.peek
eval_count.should == 1
enum.next
eval_count.should == 1
end
end end

View file

@ -1,82 +1,74 @@
require_relative '../../../spec_helper' require_relative '../../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is '2.4' do describe 'Enumerator::Lazy#uniq' do
describe 'Enumerator::Lazy#uniq' do context 'without block' do
context 'without block' do before :each do
before :each do @lazy = [0, 1, 0, 1].to_enum.lazy.uniq
@lazy = [0, 1, 0, 1].to_enum.lazy.uniq
end
it 'returns a lazy enumerator' do
@lazy.should be_an_instance_of(Enumerator::Lazy)
@lazy.force.should == [0, 1]
end
ruby_bug "#14495", "2.4"..."2.5.2" do
it 'return same value after rewind' do
@lazy.force.should == [0, 1]
@lazy.force.should == [0, 1]
end
end
it 'sets the size to nil' do
@lazy.size.should == nil
end
end end
context 'when yielded with an argument' do it 'returns a lazy enumerator' do
before :each do @lazy.should be_an_instance_of(Enumerator::Lazy)
@lazy = [0, 1, 2, 3].to_enum.lazy.uniq(&:even?) @lazy.force.should == [0, 1]
end
it 'returns a lazy enumerator' do
@lazy.should be_an_instance_of(Enumerator::Lazy)
@lazy.force.should == [0, 1]
end
ruby_bug "#14495", "2.4"..."2.5.2" do
it 'return same value after rewind' do
@lazy.force.should == [0, 1]
@lazy.force.should == [0, 1]
end
end
it 'sets the size to nil' do
@lazy.size.should == nil
end
end end
context 'when yielded with multiple arguments' do it 'return same value after rewind' do
before :each do @lazy.force.should == [0, 1]
enum = Object.new.to_enum @lazy.force.should == [0, 1]
class << enum
def each
yield 0, 'foo'
yield 1, 'FOO'
yield 2, 'bar'
end
end
@lazy = enum.lazy
end
ruby_bug "#14495", "2.4"..."2.5.2" do
it 'return same value after rewind' do
enum = @lazy.uniq { |_, label| label.downcase }
enum.force.should == [[0, 'foo'], [2, 'bar']]
enum.force.should == [[0, 'foo'], [2, 'bar']]
end
end
it 'returns all yield arguments as an array' do
@lazy.uniq { |_, label| label.downcase }.force.should == [[0, 'foo'], [2, 'bar']]
end
end end
it "works with an infinite enumerable" do it 'sets the size to nil' do
s = 0..Float::INFINITY @lazy.size.should == nil
s.lazy.uniq.first(100).should ==
s.first(100).uniq
end end
end end
context 'when yielded with an argument' do
before :each do
@lazy = [0, 1, 2, 3].to_enum.lazy.uniq(&:even?)
end
it 'returns a lazy enumerator' do
@lazy.should be_an_instance_of(Enumerator::Lazy)
@lazy.force.should == [0, 1]
end
it 'return same value after rewind' do
@lazy.force.should == [0, 1]
@lazy.force.should == [0, 1]
end
it 'sets the size to nil' do
@lazy.size.should == nil
end
end
context 'when yielded with multiple arguments' do
before :each do
enum = Object.new.to_enum
class << enum
def each
yield 0, 'foo'
yield 1, 'FOO'
yield 2, 'bar'
end
end
@lazy = enum.lazy
end
it 'return same value after rewind' do
enum = @lazy.uniq { |_, label| label.downcase }
enum.force.should == [[0, 'foo'], [2, 'bar']]
enum.force.should == [[0, 'foo'], [2, 'bar']]
end
it 'returns all yield arguments as an array' do
@lazy.uniq { |_, label| label.downcase }.force.should == [[0, 'foo'], [2, 'bar']]
end
end
it "works with an infinite enumerable" do
s = 0..Float::INFINITY
s.lazy.uniq.first(100).should ==
s.first(100).uniq
end
end end

View file

@ -14,6 +14,12 @@ describe "ENV.fetch" do
context "when the key is not found" do context "when the key is not found" do
it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, ENV it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, ENV
it "formats the object with #inspect in the KeyError message" do
-> {
ENV.fetch('foo')
}.should raise_error(KeyError, 'key not found: "foo"')
end
end end
it "provides the given default parameter" do it "provides the given default parameter" do

View file

@ -1,9 +1,7 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe "FalseClass#dup" do
describe "FalseClass#dup" do it "returns self" do
it "returns self" do false.dup.should equal(false)
false.dup.should equal(false)
end
end end
end end

View file

@ -42,7 +42,7 @@ with_feature :fiber do
f.resume f.resume
# When we execute the second #resume call, the ensure block DOES exit, # When we execute the second #resume call, the ensure block DOES exit,
# the ensure clause runs. This is Ruby behavior as of 2.3.1. # the ensure clause runs.
f.resume f.resume
exit 0 exit 0

View file

@ -2,14 +2,12 @@ require_relative '../../spec_helper'
require_relative '../../shared/file/zero' require_relative '../../shared/file/zero'
describe "File.empty?" do describe "File.empty?" do
ruby_version_is "2.4" do it_behaves_like :file_zero, :empty?, File
it_behaves_like :file_zero, :empty?, File it_behaves_like :file_zero_missing, :empty?, File
it_behaves_like :file_zero_missing, :empty?, File
platform_is :solaris do platform_is :solaris do
it "returns false for /dev/null" do it "returns false for /dev/null" do
File.empty?('/dev/null').should == true File.empty?('/dev/null').should == true
end
end end
end end
end end

View file

@ -222,16 +222,14 @@ platform_is_not :windows do
ENV["HOME"] = @home ENV["HOME"] = @home
end end
ruby_version_is ''...'2.4' do it "uses the user database when passed '~' if HOME is nil" do
it "raises an ArgumentError when passed '~' if HOME is nil" do ENV.delete "HOME"
ENV.delete "HOME" File.directory?(File.expand_path("~")).should == true
lambda { File.expand_path("~") }.should raise_error(ArgumentError) end
end
it "raises an ArgumentError when passed '~/' if HOME is nil" do it "uses the user database when passed '~/' if HOME is nil" do
ENV.delete "HOME" ENV.delete "HOME"
lambda { File.expand_path("~/") }.should raise_error(ArgumentError) File.directory?(File.expand_path("~/")).should == true
end
end end
it "raises an ArgumentError when passed '~' if HOME == ''" do it "raises an ArgumentError when passed '~' if HOME == ''" do

View file

@ -12,7 +12,7 @@ describe "File.mtime" do
it "returns the modification Time of the file" do it "returns the modification Time of the file" do
File.mtime(@filename).should be_kind_of(Time) File.mtime(@filename).should be_kind_of(Time)
File.mtime(@filename).should be_close(@mtime, 60.0) File.mtime(@filename).should be_close(@mtime, TIME_TOLERANCE)
end end
guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do

View file

@ -9,11 +9,9 @@ describe "File::Stat#dev_major" do
rm_r @name rm_r @name
end end
ruby_version_is "2.4" do platform_is_not :windows do
platform_is_not :windows do it "returns the major part of File::Stat#dev" do
it "returns the major part of File::Stat#dev" do File.stat(@name).dev_major.should be_kind_of(Integer)
File.stat(@name).dev_major.should be_kind_of(Integer)
end
end end
end end

View file

@ -9,11 +9,9 @@ describe "File::Stat#dev_minor" do
rm_r @name rm_r @name
end end
ruby_version_is "2.4" do platform_is_not :windows do
platform_is_not :windows do it "returns the minor part of File::Stat#dev" do
it "returns the minor part of File::Stat#dev" do File.stat(@name).dev_minor.should be_kind_of(Integer)
File.stat(@name).dev_minor.should be_kind_of(Integer)
end
end end
end end

View file

@ -17,11 +17,9 @@ describe "File::Stat#rdev_major" do
end end
end end
ruby_version_is "2.4" do platform_is_not :windows do
platform_is_not :windows do it "returns the major part of File::Stat#rdev" do
it "returns the major part of File::Stat#rdev" do File.stat(@name).rdev_major.should be_kind_of(Integer)
File.stat(@name).rdev_major.should be_kind_of(Integer)
end
end end
end end

View file

@ -17,11 +17,9 @@ describe "File::Stat#rdev_minor" do
end end
end end
ruby_version_is "2.4" do platform_is_not :windows do
platform_is_not :windows do it "returns the minor part of File::Stat#rdev" do
it "returns the minor part of File::Stat#rdev" do File.stat(@name).rdev_minor.should be_kind_of(Integer)
File.stat(@name).rdev_minor.should be_kind_of(Integer)
end
end end
end end

View file

@ -27,10 +27,10 @@ describe "File.utime" do
File.atime(@file2).should be_close(@atime, 0.0001) File.atime(@file2).should be_close(@atime, 0.0001)
File.mtime(@file2).should be_close(@mtime, 0.0001) File.mtime(@file2).should be_close(@mtime, 0.0001)
else else
File.atime(@file1).to_i.should be_close(@atime.to_i, 2) File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
File.atime(@file2).to_i.should be_close(@atime.to_i, 2) File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
end end
end end
@ -43,10 +43,10 @@ describe "File.utime" do
File.atime(@file2).should be_close(tn, 0.050) File.atime(@file2).should be_close(tn, 0.050)
File.mtime(@file2).should be_close(tn, 0.050) File.mtime(@file2).should be_close(tn, 0.050)
else else
File.atime(@file1).to_i.should be_close(Time.now.to_i, 2) File.atime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
File.mtime(@file1).to_i.should be_close(Time.now.to_i, 2) File.mtime(@file1).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
File.atime(@file2).to_i.should be_close(Time.now.to_i, 2) File.atime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
File.mtime(@file2).to_i.should be_close(Time.now.to_i, 2) File.mtime(@file2).to_i.should be_close(Time.now.to_i, TIME_TOLERANCE)
end end
end end
@ -63,10 +63,10 @@ describe "File.utime" do
File.mtime(@file2).should be_close(@mtime, 0.0001) File.mtime(@file2).should be_close(@mtime, 0.0001)
else else
File.utime(@atime.to_i, @mtime.to_i, @file1, @file2) File.utime(@atime.to_i, @mtime.to_i, @file1, @file2)
File.atime(@file1).to_i.should be_close(@atime.to_i, 2) File.atime(@file1).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
File.mtime(@file1).to_i.should be_close(@mtime.to_i, 2) File.mtime(@file1).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
File.atime(@file2).to_i.should be_close(@atime.to_i, 2) File.atime(@file2).to_i.should be_close(@atime.to_i, TIME_TOLERANCE)
File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2) File.mtime(@file2).to_i.should be_close(@mtime.to_i, TIME_TOLERANCE)
end end
end end

View file

@ -11,13 +11,11 @@ describe "Float#ceil" do
+9223372036854775808.1.ceil.should eql(+9223372036854775808) +9223372036854775808.1.ceil.should eql(+9223372036854775808)
end end
ruby_version_is "2.4" do it "returns the smallest number greater than or equal to self with an optionally given precision" do
it "returns the smallest number greater than or equal to self with an optionally given precision" do 2.1679.ceil(0).should eql(3)
2.1679.ceil(0).should eql(3) 214.94.ceil(-1).should eql(220)
214.94.ceil(-1).should eql(220) 7.0.ceil(1).should eql(7.0)
7.0.ceil(1).should eql(7.0) -1.234.ceil(2).should eql(-1.23)
-1.234.ceil(2).should eql(-1.23) 5.123812.ceil(4).should eql(5.1239)
5.123812.ceil(4).should eql(5.1239)
end
end end
end end

View file

@ -1,10 +1,8 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe "Float#dup" do
describe "Float#dup" do it "returns self" do
it "returns self" do float = 2.4
float = 2.4 float.dup.should equal(float)
float.dup.should equal(float)
end
end end
end end

View file

@ -11,13 +11,11 @@ describe "Float#floor" do
+9223372036854775808.1.floor.should eql(+9223372036854775808) +9223372036854775808.1.floor.should eql(+9223372036854775808)
end end
ruby_version_is "2.4" do it "returns the largest number less than or equal to self with an optionally given precision" do
it "returns the largest number less than or equal to self with an optionally given precision" do 2.1679.floor(0).should eql(2)
2.1679.floor(0).should eql(2) 214.94.floor(-1).should eql(210)
214.94.floor(-1).should eql(210) 7.0.floor(1).should eql(7.0)
7.0.floor(1).should eql(7.0) -1.234.floor(2).should eql(-1.24)
-1.234.floor(2).should eql(-1.24) 5.123812.floor(4).should eql(5.1238)
5.123812.floor(4).should eql(5.1238)
end
end end
end end

View file

@ -83,17 +83,35 @@ describe "Float#round" do
-2.4e200.round(-200).should eql( -2 * 10 ** 200 ) -2.4e200.round(-200).should eql( -2 * 10 ** 200 )
end end
ruby_version_is "2.4" do it "returns different rounded values depending on the half option" do
it "returns different rounded values depending on the half option" do 2.5.round(half: nil).should eql(3)
2.5.round(half: :up).should eql(3) 2.5.round(half: :up).should eql(3)
2.5.round(half: :down).should eql(2) 2.5.round(half: :down).should eql(2)
2.5.round(half: :even).should eql(2) 2.5.round(half: :even).should eql(2)
3.5.round(half: :up).should eql(4) 3.5.round(half: nil).should eql(4)
3.5.round(half: :down).should eql(3) 3.5.round(half: :up).should eql(4)
3.5.round(half: :even).should eql(4) 3.5.round(half: :down).should eql(3)
(-2.5).round(half: :up).should eql(-3) 3.5.round(half: :even).should eql(4)
(-2.5).round(half: :down).should eql(-2) (-2.5).round(half: nil).should eql(-3)
(-2.5).round(half: :even).should eql(-2) (-2.5).round(half: :up).should eql(-3)
end (-2.5).round(half: :down).should eql(-2)
(-2.5).round(half: :even).should eql(-2)
end
it "rounds self to an optionally given precision with a half option" do
5.55.round(1, half: nil).should eql(5.6)
5.55.round(1, half: :up).should eql(5.6)
5.55.round(1, half: :down).should eql(5.5)
5.55.round(1, half: :even).should eql(5.6)
end
it "raises FloatDomainError for exceptional values with a half option" do
lambda { (+infinity_value).round(half: :up) }.should raise_error(FloatDomainError)
lambda { (-infinity_value).round(half: :down) }.should raise_error(FloatDomainError)
lambda { nan_value.round(half: :even) }.should raise_error(FloatDomainError)
end
it "raise for a non-existent round mode" do
lambda { 14.2.round(half: :nonsense) }.should raise_error(ArgumentError, "invalid rounding mode: nonsense")
end end
end end

View file

@ -4,13 +4,11 @@ require_relative 'shared/to_i'
describe "Float#truncate" do describe "Float#truncate" do
it_behaves_like :float_to_i, :truncate it_behaves_like :float_to_i, :truncate
ruby_version_is "2.4" do it "returns self truncated to an optionally given precision" do
it "returns self truncated to an optionally given precision" do 2.1679.truncate(0).should eql(2)
2.1679.truncate(0).should eql(2) 7.1.truncate(1).should eql(7.1)
7.1.truncate(1).should eql(7.1) 214.94.truncate(-1).should eql(210)
214.94.truncate(-1).should eql(210) -1.234.truncate(2).should eql(-1.23)
-1.234.truncate(2).should eql(-1.23) 5.123812.truncate(4).should eql(5.1238)
5.123812.truncate(4).should eql(5.1238)
end
end end
end end

View file

@ -1,61 +1,59 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is "2.4" do describe "Hash#compact" do
describe "Hash#compact" do before :each do
@hash = { truthy: true, false: false, nil: nil, nil => true }
@initial_pairs = @hash.dup
@compact = { truthy: true, false: false, nil => true }
end
it "returns new object that rejects pair has nil value" do
ret = @hash.compact
ret.should_not equal(@hash)
ret.should == @compact
end
it "keeps own pairs" do
@hash.compact
@hash.should == @initial_pairs
end
end
describe "Hash#compact!" do
before :each do
@hash = { truthy: true, false: false, nil: nil, nil => true }
@initial_pairs = @hash.dup
@compact = { truthy: true, false: false, nil => true }
end
it "returns self" do
@hash.compact!.should equal(@hash)
end
it "rejects own pair has nil value" do
@hash.compact!
@hash.should == @compact
end
context "when each pair does not have nil value" do
before :each do before :each do
@hash = { truthy: true, false: false, nil: nil, nil => true } @hash.compact!
@initial_pairs = @hash.dup
@compact = { truthy: true, false: false, nil => true }
end end
it "returns new object that rejects pair has nil value" do it "returns nil" do
ret = @hash.compact @hash.compact!.should be_nil
ret.should_not equal(@hash) end
ret.should == @compact end
describe "on frozen instance" do
before :each do
@hash.freeze
end end
it "keeps own pairs" do it "keeps pairs and raises a #{frozen_error_class}" do
@hash.compact ->{ @hash.compact! }.should raise_error(frozen_error_class)
@hash.should == @initial_pairs @hash.should == @initial_pairs
end end
end end
describe "Hash#compact!" do
before :each do
@hash = { truthy: true, false: false, nil: nil, nil => true }
@initial_pairs = @hash.dup
@compact = { truthy: true, false: false, nil => true }
end
it "returns self" do
@hash.compact!.should equal(@hash)
end
it "rejects own pair has nil value" do
@hash.compact!
@hash.should == @compact
end
context "when each pair does not have nil value" do
before :each do
@hash.compact!
end
it "returns nil" do
@hash.compact!.should be_nil
end
end
describe "on frozen instance" do
before :each do
@hash.freeze
end
it "keeps pairs and raises a #{frozen_error_class}" do
->{ @hash.compact! }.should raise_error(frozen_error_class)
@hash.should == @initial_pairs
end
end
end
end end

View file

@ -108,13 +108,11 @@ describe "Hash#compare_by_identity" do
@idh.keys.first.should equal foo @idh.keys.first.should equal foo
end end
ruby_bug "#12855", ""..."2.4.1" do it "gives different identity for string literals" do
it "gives different identity for string literals" do @idh['foo'] = 1
@idh['foo'] = 1 @idh['foo'] = 2
@idh['foo'] = 2 @idh.values.should == [1, 2]
@idh.values.should == [1, 2] @idh.size.should == 2
@idh.size.should == 2
end
end end
end end

View file

@ -8,6 +8,12 @@ describe "Hash#fetch" do
it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, {} it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, {}
it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, Hash.new { 5 } it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, Hash.new { 5 }
it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, Hash.new(5) it_behaves_like :key_error, ->(obj, key) { obj.fetch(key) }, Hash.new(5)
it "formats the object with #inspect in the KeyError message" do
-> {
{}.fetch('foo')
}.should raise_error(KeyError, 'key not found: "foo"')
end
end end
it "returns the value for key" do it "returns the value for key" do

View file

@ -69,9 +69,12 @@ describe "Hash#merge" do
result.should == { a: 1, b: 2, c: 3, d: 4 } result.should == { a: 1, b: 2, c: 3, d: 4 }
end end
it "accepts zero arguments and returns self" do it "accepts zero arguments and returns a copy of self" do
hash = { a: 1 } hash = { a: 1 }
hash.merge.should eql(hash) merged = hash.merge
merged.should eql(hash)
merged.should_not equal(hash)
end end
end end
end end

View file

@ -21,7 +21,7 @@ describe :hash_each, shared: true do
ary.sort.should == ["a", "b", "c"] ary.sort.should == ["a", "b", "c"]
end end
it "yields 2 values and not an Array of 2 elements" do it "yields 2 values and not an Array of 2 elements when given a callable of arity 2" do
obj = Object.new obj = Object.new
def obj.foo(key, value) def obj.foo(key, value)
ScratchPad << key << value ScratchPad << key << value

View file

@ -1,98 +1,96 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Hash#transform_values" do
describe "Hash#transform_values" do before :each do
before :each do @hash = { a: 1, b: 2, c: 3 }
@hash = { a: 1, b: 2, c: 3 } end
end
it "returns new hash" do it "returns new hash" do
ret = @hash.transform_values(&:succ) ret = @hash.transform_values(&:succ)
ret.should_not equal(@hash) ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash) ret.should be_an_instance_of(Hash)
end end
it "sets the result as transformed values with the given block" do it "sets the result as transformed values with the given block" do
@hash.transform_values(&:succ).should == { a: 2, b: 3, c: 4 } @hash.transform_values(&:succ).should == { a: 2, b: 3, c: 4 }
end end
it "makes both hashes to share keys" do it "makes both hashes to share keys" do
key = [1, 2, 3] key = [1, 2, 3]
new_hash = { key => 1 }.transform_values(&:succ) new_hash = { key => 1 }.transform_values(&:succ)
new_hash[key].should == 2 new_hash[key].should == 2
new_hash.keys[0].should equal(key) new_hash.keys[0].should equal(key)
end end
context "when no block is given" do context "when no block is given" do
it "returns a sized Enumerator" do it "returns a sized Enumerator" do
enumerator = @hash.transform_values enumerator = @hash.transform_values
enumerator.should be_an_instance_of(Enumerator) enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size enumerator.size.should == @hash.size
enumerator.each(&:succ).should == { a: 2, b: 3, c: 4 } enumerator.each(&:succ).should == { a: 2, b: 3, c: 4 }
end
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:foo] = 42
r = h.transform_values{|v| 2 * v}
r[:foo].should == 84
r.class.should == Hash
end end
end end
describe "Hash#transform_values!" do it "returns a Hash instance, even on subclasses" do
before :each do klass = Class.new(Hash)
@hash = { a: 1, b: 2, c: 3 } h = klass.new
@initial_pairs = @hash.dup h[:foo] = 42
end r = h.transform_values{|v| 2 * v}
r[:foo].should == 84
r.class.should == Hash
end
end
it "returns self" do describe "Hash#transform_values!" do
@hash.transform_values!(&:succ).should equal(@hash) before :each do
end @hash = { a: 1, b: 2, c: 3 }
@initial_pairs = @hash.dup
end
it "updates self as transformed values with the given block" do it "returns self" do
@hash.transform_values!(&:succ) @hash.transform_values!(&:succ).should equal(@hash)
end
it "updates self as transformed values with the given block" do
@hash.transform_values!(&:succ)
@hash.should == { a: 2, b: 3, c: 4 }
end
it "partially modifies the contents if we broke from the block" do
@hash.transform_values! do |v|
break if v == 3
100 + v
end
@hash.should == { a: 101, b: 102, c: 3}
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_values!
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:succ)
@hash.should == { a: 2, b: 3, c: 4 } @hash.should == { a: 2, b: 3, c: 4 }
end end
end
it "partially modifies the contents if we broke from the block" do describe "on frozen instance" do
@hash.transform_values! do |v| before :each do
break if v == 3 @hash.freeze
100 + v end
end
@hash.should == { a: 101, b: 102, c: 3} it "raises a #{frozen_error_class} on an empty hash" do
->{ {}.freeze.transform_values!(&:succ) }.should raise_error(frozen_error_class)
end
it "keeps pairs and raises a #{frozen_error_class}" do
->{ @hash.transform_values!(&:succ) }.should raise_error(frozen_error_class)
@hash.should == @initial_pairs
end end
context "when no block is given" do context "when no block is given" do
it "returns a sized Enumerator" do it "does not raise an exception" do
enumerator = @hash.transform_values! @hash.transform_values!.should be_an_instance_of(Enumerator)
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:succ)
@hash.should == { a: 2, b: 3, c: 4 }
end
end
describe "on frozen instance" do
before :each do
@hash.freeze
end
it "raises a #{frozen_error_class} on an empty hash" do
->{ {}.freeze.transform_values!(&:succ) }.should raise_error(frozen_error_class)
end
it "keeps pairs and raises a #{frozen_error_class}" do
->{ @hash.transform_values!(&:succ) }.should raise_error(frozen_error_class)
@hash.should == @initial_pairs
end
context "when no block is given" do
it "does not raise an exception" do
@hash.transform_values!.should be_an_instance_of(Enumerator)
end
end end
end end
end end

View file

@ -6,16 +6,14 @@ describe "Integer#ceil" do
it_behaves_like :integer_to_i, :ceil it_behaves_like :integer_to_i, :ceil
it_behaves_like :integer_rounding_positive_precision, :ceil it_behaves_like :integer_rounding_positive_precision, :ceil
ruby_version_is "2.4" do context "precision argument specified as part of the ceil method is negative" do
context "precision argument specified as part of the ceil method is negative" do it "returns the smallest integer greater than self with at least precision.abs trailing zeros" do
it "returns the smallest integer greater than self with at least precision.abs trailing zeros" do 18.ceil(-1).should eql(20)
18.ceil(-1).should eql(20) 18.ceil(-2).should eql(100)
18.ceil(-2).should eql(100) 18.ceil(-3).should eql(1000)
18.ceil(-3).should eql(1000) -1832.ceil(-1).should eql(-1830)
-1832.ceil(-1).should eql(-1830) -1832.ceil(-2).should eql(-1800)
-1832.ceil(-2).should eql(-1800) -1832.ceil(-3).should eql(-1000)
-1832.ceil(-3).should eql(-1000)
end
end end
end end
end end

View file

@ -68,38 +68,24 @@ describe "Integer#coerce" do
lambda { a.coerce(:test) }.should raise_error(TypeError) lambda { a.coerce(:test) }.should raise_error(TypeError)
end end
ruby_version_is ""..."2.4" do it "coerces both values to Floats and returns [other, self] when passed a Float" do
it "raises a TypeError when passed a String" do a = bignum_value
a = bignum_value a.coerce(1.2).should == [1.2, a.to_f]
lambda { a.coerce("123") }.should raise_error(TypeError)
end
it "raises a TypeError when passed a Float" do
a = bignum_value
lambda { a.coerce(12.3) }.should raise_error(TypeError)
end
end end
ruby_version_is "2.4" do it "coerces both values to Floats and returns [other, self] when passed a String" do
it "coerces both values to Floats and returns [other, self] when passed a Float" do a = bignum_value
a = bignum_value a.coerce("123").should == [123.0, a.to_f]
a.coerce(1.2).should == [1.2, a.to_f] end
end
it "coerces both values to Floats and returns [other, self] when passed a String" do it "calls #to_f to coerce other to a Float" do
a = bignum_value b = mock("bignum value")
a.coerce("123").should == [123.0, a.to_f] b.should_receive(:to_f).and_return(1.2)
end
it "calls #to_f to coerce other to a Float" do a = bignum_value
b = mock("bignum value") ary = a.coerce(b)
b.should_receive(:to_f).and_return(1.2)
a = bignum_value ary.should == [1.2, a.to_f]
ary = a.coerce(b)
ary.should == [1.2, a.to_f]
end
end end
end end
end end

View file

@ -1,34 +1,32 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Integer#digits" do
describe "Integer#digits" do it "returns an array of place values in base-10 by default" do
it "returns an array of place values in base-10 by default" do 12345.digits.should == [5,4,3,2,1]
12345.digits.should == [5,4,3,2,1] end
end
it "returns digits by place value of a given radix" do it "returns digits by place value of a given radix" do
12345.digits(7).should == [4,6,6,0,5] 12345.digits(7).should == [4,6,6,0,5]
end end
it "converts the radix with #to_int" do it "converts the radix with #to_int" do
12345.digits(mock_int(2)).should == [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1] 12345.digits(mock_int(2)).should == [1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1]
end end
it "returns [0] when called on 0, regardless of base" do it "returns [0] when called on 0, regardless of base" do
0.digits.should == [0] 0.digits.should == [0]
0.digits(7).should == [0] 0.digits(7).should == [0]
end end
it "raises ArgumentError when calling with a radix less than 2" do it "raises ArgumentError when calling with a radix less than 2" do
lambda { 12345.digits(1) }.should raise_error(ArgumentError) lambda { 12345.digits(1) }.should raise_error(ArgumentError)
end end
it "raises ArgumentError when calling with a negative radix" do it "raises ArgumentError when calling with a negative radix" do
lambda { 12345.digits(-2) }.should raise_error(ArgumentError) lambda { 12345.digits(-2) }.should raise_error(ArgumentError)
end end
it "raises Math::DomainError when calling digits on a negative number" do it "raises Math::DomainError when calling digits on a negative number" do
lambda { -12345.digits(7) }.should raise_error(Math::DomainError) lambda { -12345.digits(7) }.should raise_error(Math::DomainError)
end
end end
end end

View file

@ -1,15 +1,13 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe "Integer#dup" do
describe "Integer#dup" do it "returns self for small integers" do
it "returns self for small integers" do integer = 1_000
integer = 1_000 integer.dup.should equal(integer)
integer.dup.should equal(integer) end
end
it "returns self for large integers" do it "returns self for large integers" do
integer = 4_611_686_018_427_387_905 integer = 4_611_686_018_427_387_905
integer.dup.should equal(integer) integer.dup.should equal(integer)
end
end end
end end

View file

@ -6,16 +6,14 @@ describe "Integer#floor" do
it_behaves_like :integer_to_i, :floor it_behaves_like :integer_to_i, :floor
it_behaves_like :integer_rounding_positive_precision, :floor it_behaves_like :integer_rounding_positive_precision, :floor
ruby_version_is "2.4" do context "precision argument specified as part of the floor method is negative" do
context "precision argument specified as part of the floor method is negative" do it "returns the largest integer less than self with at least precision.abs trailing zeros" do
it "returns the largest integer less than self with at least precision.abs trailing zeros" do 1832.floor(-1).should eql(1830)
1832.floor(-1).should eql(1830) 1832.floor(-2).should eql(1800)
1832.floor(-2).should eql(1800) 1832.floor(-3).should eql(1000)
1832.floor(-3).should eql(1000) -1832.floor(-1).should eql(-1840)
-1832.floor(-1).should eql(-1840) -1832.floor(-2).should eql(-1900)
-1832.floor(-2).should eql(-1900) -1832.floor(-3).should eql(-2000)
-1832.floor(-3).should eql(-2000)
end
end end
end end
end end

View file

@ -5,11 +5,9 @@ describe "Integer" do
Integer.include?(Comparable).should == true Integer.include?(Comparable).should == true
end end
ruby_version_is "2.4" do it "is the class of both small and large integers" do
it "is the class of both small and large integers" do 42.class.should equal(Integer)
42.class.should equal(Integer) bignum_value.class.should equal(Integer)
bignum_value.class.should equal(Integer)
end
end end
end end

View file

@ -16,13 +16,11 @@ ruby_version_is "2.5" do
2.pow(8, 15).should == 1 2.pow(8, 15).should == 1
end end
ruby_bug '#13669', '2.5'...'2.5.1' do it "works well with bignums" do
it "works well with bignums" do 2.pow(61, 5843009213693951).should eql 3697379018277258
2.pow(61, 5843009213693951).should eql 3697379018277258 2.pow(62, 5843009213693952).should eql 1551748822859776
2.pow(62, 5843009213693952).should eql 1551748822859776 2.pow(63, 5843009213693953).should eql 3103497645717974
2.pow(63, 5843009213693953).should eql 3103497645717974 2.pow(64, 5843009213693954).should eql 363986077738838
2.pow(64, 5843009213693954).should eql 363986077738838
end
end end
it "handles sign like #divmod does" do it "handles sign like #divmod does" do

View file

@ -63,18 +63,16 @@ describe "Integer#round" do
lambda { 42.round(obj) }.should raise_error(TypeError) lambda { 42.round(obj) }.should raise_error(TypeError)
end end
ruby_version_is "2.4" do it "returns different rounded values depending on the half option" do
it "returns different rounded values depending on the half option" do 25.round(-1, half: :up).should eql(30)
25.round(-1, half: :up).should eql(30) 25.round(-1, half: :down).should eql(20)
25.round(-1, half: :down).should eql(20) 25.round(-1, half: :even).should eql(20)
25.round(-1, half: :even).should eql(20) 35.round(-1, half: :up).should eql(40)
35.round(-1, half: :up).should eql(40) 35.round(-1, half: :down).should eql(30)
35.round(-1, half: :down).should eql(30) 35.round(-1, half: :even).should eql(40)
35.round(-1, half: :even).should eql(40) (-25).round(-1, half: :up).should eql(-30)
(-25).round(-1, half: :up).should eql(-30) (-25).round(-1, half: :down).should eql(-20)
(-25).round(-1, half: :down).should eql(-20) (-25).round(-1, half: :even).should eql(-20)
(-25).round(-1, half: :even).should eql(-20)
end
end end
ruby_version_is "2.4"..."2.5" do ruby_version_is "2.4"..."2.5" do

View file

@ -5,11 +5,9 @@ describe :integer_rounding_positive_precision, shared: true do
end end
end end
ruby_version_is "2.4" do it "returns self if passed a precision of zero" do
it "returns self if passed a precision of zero" do [2, -4, 10**70, -10**100].each do |v|
[2, -4, 10**70, -10**100].each do |v| v.send(@method, 0).should eql(v)
v.send(@method, 0).should eql(v)
end
end end
end end

View file

@ -6,16 +6,14 @@ describe "Integer#truncate" do
it_behaves_like :integer_to_i, :truncate it_behaves_like :integer_to_i, :truncate
it_behaves_like :integer_rounding_positive_precision, :truncate it_behaves_like :integer_rounding_positive_precision, :truncate
ruby_version_is "2.4" do context "precision argument specified as part of the truncate method is negative" do
context "precision argument specified as part of the truncate method is negative" do it "returns an integer with at least precision.abs trailing zeros" do
it "returns an integer with at least precision.abs trailing zeros" do 1832.truncate(-1).should eql(1830)
1832.truncate(-1).should eql(1830) 1832.truncate(-2).should eql(1800)
1832.truncate(-2).should eql(1800) 1832.truncate(-3).should eql(1000)
1832.truncate(-3).should eql(1000) -1832.truncate(-1).should eql(-1830)
-1832.truncate(-1).should eql(-1830) -1832.truncate(-2).should eql(-1800)
-1832.truncate(-2).should eql(-1800) -1832.truncate(-3).should eql(-1000)
-1832.truncate(-3).should eql(-1000)
end
end end
end end
end end

View file

@ -139,11 +139,9 @@ describe "IO#gets" do
end end
end end
ruby_version_is "2.4" do describe "when passed chomp" do
describe "when passed chomp" do it "returns the first line without a trailing newline character" do
it "returns the first line without a trailing newline character" do @io.gets(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
@io.gets(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
end
end end
end end
end end

View file

@ -43,11 +43,9 @@ describe "IO#readline" do
end end
end end
ruby_version_is "2.4" do describe "when passed chomp" do
describe "when passed chomp" do it "returns the first line without a trailing newline character" do
it "returns the first line without a trailing newline character" do @io.readline(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
@io.readline(chomp: true).should == IOSpecs.lines_without_newline_characters[0]
end
end end
end end
end end

View file

@ -156,12 +156,10 @@ describe :io_each, shared: true do
end end
end end
ruby_version_is "2.4" do describe "when passed chomp" do
describe "when passed chomp" do it "yields each line without trailing newline characters to the passed block" do
it "yields each line without trailing newline characters to the passed block" do @io.send(@method, chomp: true) { |s| ScratchPad << s }
@io.send(@method, chomp: true) { |s| ScratchPad << s } ScratchPad.recorded.should == IOSpecs.lines_without_newline_characters
ScratchPad.recorded.should == IOSpecs.lines_without_newline_characters
end
end end
end end
end end

View file

@ -18,11 +18,9 @@ describe :io_readlines, shared: true do
(result ? result : ScratchPad.recorded).should == IOSpecs.lines_empty_separator (result ? result : ScratchPad.recorded).should == IOSpecs.lines_empty_separator
end end
ruby_version_is "2.4" do it "yields a sequence of lines without trailing newline characters when chomp is passed" do
it "yields a sequence of lines without trailing newline characters when chomp is passed" do result = IO.send(@method, @name, chomp: true, &@object)
result = IO.send(@method, @name, chomp: true, &@object) (result ? result : ScratchPad.recorded).should == IOSpecs.lines_without_newline_characters
(result ? result : ScratchPad.recorded).should == IOSpecs.lines_without_newline_characters
end
end end
end end

View file

@ -175,13 +175,11 @@ describe "Kernel.Complex()" do
end end
end end
ruby_bug "#15525", "2.6"..."2.6.1" do describe "and nil arguments" do
describe "and nil arguments" do it "swallows an error" do
it "swallows an error" do Complex(nil, exception: false).should == nil
Complex(nil, exception: false).should == nil Complex(0, nil, exception: false).should == nil
Complex(0, nil, exception: false).should == nil Complex(nil, 0, exception: false).should == nil
Complex(nil, 0, exception: false).should == nil
end
end end
end end
end end

View file

@ -125,17 +125,15 @@ describe :kernel_integer, shared: true do
end end
end end
ruby_bug "#15525", "2.6"..."2.6.1" do describe "and passed NaN" do
describe "and passed NaN" do it "swallows an error" do
it "swallows an error" do Integer(nan_value, exception: false).should == nil
Integer(nan_value, exception: false).should == nil
end
end end
end
describe "and passed Infinity" do describe "and passed Infinity" do
it "swallows an error" do it "swallows an error" do
Integer(infinity_value, exception: false).should == nil Integer(infinity_value, exception: false).should == nil
end
end end
end end

View file

@ -37,14 +37,12 @@ describe "Kernel#clone" do
o3.frozen?.should == true o3.frozen?.should == true
end end
ruby_version_is '2.4' do it 'takes an option to copy freeze state or not' do
it 'takes an option to copy freeze state or not' do @obj.clone(freeze: true).frozen?.should == false
@obj.clone(freeze: true).frozen?.should == false @obj.clone(freeze: false).frozen?.should == false
@obj.clone(freeze: false).frozen?.should == false @obj.freeze
@obj.freeze @obj.clone(freeze: true).frozen?.should == true
@obj.clone(freeze: true).frozen?.should == true @obj.clone(freeze: false).frozen?.should == false
@obj.clone(freeze: false).frozen?.should == false
end
end end
it "copies instance variables" do it "copies instance variables" do

View file

@ -79,48 +79,24 @@ describe :kernel_dup_clone, shared: true do
o3.untrusted?.should == true o3.untrusted?.should == true
end end
ruby_version_is ''...'2.4' do it "returns nil for NilClass" do
it "raises a TypeError for NilClass" do nil.send(@method).should == nil
lambda { nil.send(@method) }.should raise_error(TypeError)
end
it "raises a TypeError for TrueClass" do
lambda { true.send(@method) }.should raise_error(TypeError)
end
it "raises a TypeError for FalseClass" do
lambda { false.send(@method) }.should raise_error(TypeError)
end
it "raises a TypeError for Fixnum" do
lambda { 1.send(@method) }.should raise_error(TypeError)
end
it "raises a TypeError for Symbol" do
lambda { :my_symbol.send(@method) }.should raise_error(TypeError)
end
end end
ruby_version_is '2.4' do it "returns true for TrueClass" do
it "returns nil for NilClass" do true.send(@method).should == true
nil.send(@method).should == nil end
end
it "returns true for TrueClass" do it "returns false for FalseClass" do
true.send(@method).should == true false.send(@method).should == false
end end
it "returns false for FalseClass" do it "returns the same Integer for Integer" do
false.send(@method).should == false 1.send(@method).should == 1
end end
it "returns the same Integer for Integer" do it "returns the same Symbol for Symbol" do
1.send(@method).should == 1 :my_symbol.send(@method).should == :my_symbol
end
it "returns the same Symbol for Symbol" do
:my_symbol.send(@method).should == :my_symbol
end
end end
ruby_version_is ''...'2.5' do ruby_version_is ''...'2.5' do

View file

@ -553,6 +553,15 @@ describe :kernel_require, shared: true do
required = ruby_exe(code, options: '--disable-gems') required = ruby_exe(code, options: '--disable-gems')
required.should == "false\n" * provided.size required.should == "false\n" * provided.size
end end
it "unicode_normalize is part of core and not $LOADED_FEATURES" do
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
features.lines.each { |feature|
feature.should_not include("unicode_normalize")
}
-> { @object.require("unicode_normalize") }.should raise_error(LoadError)
end
end end
end end

View file

@ -101,11 +101,9 @@ describe "Kernel#warn" do
-> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|) -> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
end end
ruby_bug "#14846", "2.5"..."2.6" do it "does not prepend caller information if line number is too big" do
it "does not prepend caller information if line number is too big" do w = KernelSpecs::WarnInNestedCall.new
w = KernelSpecs::WarnInNestedCall.new -> { w.f4("foo", 100) }.should output(nil, "warning: foo\n")
-> { w.f4("foo", 100) }.should output(nil, "warning: foo\n")
end
end end
it "prepends even if a message is empty or nil" do it "prepends even if a message is empty or nil" do
@ -127,10 +125,8 @@ describe "Kernel#warn" do
-> { warn "", uplevel: -100 }.should raise_error(ArgumentError) -> { warn "", uplevel: -100 }.should raise_error(ArgumentError)
end end
ruby_bug "#14846", "2.5"..."2.6" do it "raises ArgumentError if passed -1" do
it "raises ArgumentError if passed -1" do -> { warn "", uplevel: -1 }.should raise_error(ArgumentError)
-> { warn "", uplevel: -1 }.should raise_error(ArgumentError)
end
end end
it "raises TypeError if passed not Integer" do it "raises TypeError if passed not Integer" do

View file

@ -1,17 +1,15 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe 'MatchData#named_captures' do
describe 'MatchData#named_captures' do it 'returns a Hash that has captured name and the matched string pairs' do
it 'returns a Hash that has captured name and the matched string pairs' do /(?<a>.)(?<b>.)?/.match('0').named_captures.should == { 'a' => '0', 'b' => nil }
/(?<a>.)(?<b>.)?/.match('0').named_captures.should == { 'a' => '0', 'b' => nil } end
end
it 'prefers later captures' do it 'prefers later captures' do
/\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)\z/.match('0123').named_captures.should == { 'a' => '3', 'b' => '2' } /\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)\z/.match('0123').named_captures.should == { 'a' => '3', 'b' => '2' }
end end
it 'returns the latest matched capture, even if a later one that does not match exists' do it 'returns the latest matched capture, even if a later one that does not match exists' do
/\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)?\z/.match('012').named_captures.should == { 'a' => '0', 'b' => '2' } /\A(?<a>.)(?<b>.)(?<b>.)(?<a>.)?\z/.match('012').named_captures.should == { 'a' => '0', 'b' => '2' }
end
end end
end end

View file

@ -11,13 +11,11 @@ describe "MatchData#values_at" do
end end
end end
ruby_version_is '2.4' do it 'slices captures with the given names' do
it 'slices captures with the given names' do /(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at(:c, :a).should == ['2', '0']
/(?<a>.)(?<b>.)(?<c>.)/.match('012').values_at(:c, :a).should == ['2', '0'] end
end
it 'takes names and indices' do it 'takes names and indices' do
/\A(?<a>.)(?<b>.)\z/.match('01').values_at(0, 1, 2, :a, :b).should == ['01', '0', '1', '0', '1'] /\A(?<a>.)(?<b>.)\z/.match('01').values_at(0, 1, 2, :a, :b).should == ['01', '0', '1', '0', '1']
end
end end
end end

View file

@ -11,10 +11,8 @@ describe "Math.lgamma" do
end end
end end
ruby_version_is "2.4" do it "returns [Infinity, -1] when passed -0.0" do
it "returns [Infinity, -1] when passed -0.0" do Math.lgamma(-0.0).should == [infinity_value, -1]
Math.lgamma(-0.0).should == [infinity_value, -1]
end
end end
it "returns [log(sqrt(PI)), 1] when passed 0.5" do it "returns [log(sqrt(PI)), 1] when passed 0.5" do

View file

@ -243,17 +243,19 @@ describe "Method#parameters" do
end end
it "returns [[:rest]] for core methods with variable-length argument lists" do it "returns [[:rest]] for core methods with variable-length argument lists" do
m = "foo" # delete! takes rest args
"foo".method(:delete!).parameters.should == [[:rest]]
end
# match takes rest args it "returns [[:rest]] or [[:opt]] for core methods with optional arguments" do
m.method(:match).parameters.should == [[:rest]] # pop takes 1 optional argument
[
# [] takes 1 to 3 args [[:rest]],
m.method(:[]).parameters.should == [[:rest]] [[:opt]]
].should include([].method(:pop).parameters)
end end
it "returns [[:req]] for each parameter for core methods with fixed-length argument lists" do it "returns [[:req]] for each parameter for core methods with fixed-length argument lists" do
m = "foo" "foo".method(:+).parameters.should == [[:req]]
m.method(:+).parameters.should == [[:req]]
end end
end end

View file

@ -165,24 +165,12 @@ describe "Module#include" do
}.should raise_error(ArgumentError) }.should raise_error(ArgumentError)
end end
ruby_version_is ''...'2.4' do it "doesn't accept no-arguments" do
it "accepts no-arguments" do lambda {
lambda { Module.new do
Module.new do include
include end
end }.should raise_error(ArgumentError)
}.should_not raise_error
end
end
ruby_version_is '2.4' do
it "doesn't accept no-arguments" do
lambda {
Module.new do
include
end
}.should raise_error(ArgumentError)
end
end end
it "returns the class it's included into" do it "returns the class it's included into" do

View file

@ -231,24 +231,12 @@ describe "Module#prepend" do
}.should raise_error(ArgumentError) }.should raise_error(ArgumentError)
end end
ruby_version_is ''...'2.4' do it "doesn't accept no-arguments" do
it "accepts no-arguments" do lambda {
lambda { Module.new do
Module.new do prepend
prepend end
end }.should raise_error(ArgumentError)
}.should_not raise_error
end
end
ruby_version_is '2.4' do
it "doesn't accept no-arguments" do
lambda {
Module.new do
prepend
end
}.should raise_error(ArgumentError)
end
end end
it "returns the class it's included into" do it "returns the class it's included into" do

View file

@ -52,44 +52,42 @@ describe "Module#private" do
end.should raise_error(NameError) end.should raise_error(NameError)
end end
ruby_bug "#14604", ""..."2.5.1" do it "only makes the method private in the class it is called on" do
it "only makes the method private in the class it is called on" do base = Class.new do
base = Class.new do def wrapped
def wrapped 1
1
end
end end
klass = Class.new(base) do
def wrapped
super + 1
end
private :wrapped
end
base.new.wrapped.should == 1
lambda do
klass.new.wrapped
end.should raise_error(NameError)
end end
it "continues to allow a prepended module method to call super" do klass = Class.new(base) do
wrapper = Module.new do def wrapped
def wrapped super + 1
super + 1
end
end end
private :wrapped
klass = Class.new do
prepend wrapper
def wrapped
1
end
private :wrapped
end
klass.new.wrapped.should == 2
end end
base.new.wrapped.should == 1
lambda do
klass.new.wrapped
end.should raise_error(NameError)
end
it "continues to allow a prepended module method to call super" do
wrapper = Module.new do
def wrapped
super + 1
end
end
klass = Class.new do
prepend wrapper
def wrapped
1
end
private :wrapped
end
klass.new.wrapped.should == 2
end end
end end

View file

@ -74,29 +74,17 @@ describe "Module#refine" do
end.should raise_error(TypeError) end.should raise_error(TypeError)
end end
ruby_version_is "" ... "2.4" do it "accepts a module as argument" do
it "raises TypeError if passed a module" do inner_self = nil
lambda do Module.new do
Module.new do refine(Enumerable) do
refine(Enumerable) {} def blah
end
end.should raise_error(TypeError)
end
end
ruby_version_is "2.4" do
it "accepts a module as argument" do
inner_self = nil
Module.new do
refine(Enumerable) do
def blah
end
inner_self = self
end end
inner_self = self
end end
inner_self.public_instance_methods.should include(:blah)
end end
inner_self.public_instance_methods.should include(:blah)
end end
it "raises ArgumentError if not given a block" do it "raises ArgumentError if not given a block" do
@ -319,108 +307,54 @@ describe "Module#refine" do
end end
context "for methods accessed indirectly" do context "for methods accessed indirectly" do
ruby_version_is "" ... "2.4" do it "is honored by Kernel#send" do
it "is not honored by Kernel#send" do refinement = Module.new do
refinement = Module.new do refine ModuleSpecs::ClassWithFoo do
refine ModuleSpecs::ClassWithFoo do def foo; "foo from refinement"; end
def foo; "foo from refinement"; end
end
end end
result = nil
Module.new do
using refinement
result = ModuleSpecs::ClassWithFoo.new.send :foo
end
result.should == "foo"
end end
it "is not honored by BasicObject#__send__" do result = nil
refinement = Module.new do Module.new do
refine ModuleSpecs::ClassWithFoo do using refinement
def foo; "foo from refinement"; end result = ModuleSpecs::ClassWithFoo.new.send :foo
end
end
result = nil
Module.new do
using refinement
result = ModuleSpecs::ClassWithFoo.new.__send__ :foo
end
result.should == "foo"
end end
it "is not honored by Symbol#to_proc" do result.should == "foo from refinement"
refinement = Module.new do
refine Integer do
def to_s
"(#{super})"
end
end
end
result = nil
Module.new do
using refinement
result = [1, 2, 3].map(&:to_s)
end
result.should == ["1", "2", "3"]
end
end end
ruby_version_is "2.4" do it "is honored by BasicObject#__send__" do
it "is honored by Kernel#send" do refinement = Module.new do
refinement = Module.new do refine ModuleSpecs::ClassWithFoo do
refine ModuleSpecs::ClassWithFoo do def foo; "foo from refinement"; end
def foo; "foo from refinement"; end
end
end end
result = nil
Module.new do
using refinement
result = ModuleSpecs::ClassWithFoo.new.send :foo
end
result.should == "foo from refinement"
end end
it "is honored by BasicObject#__send__" do result = nil
refinement = Module.new do Module.new do
refine ModuleSpecs::ClassWithFoo do using refinement
def foo; "foo from refinement"; end result = ModuleSpecs::ClassWithFoo.new.__send__ :foo
end
end
result = nil
Module.new do
using refinement
result = ModuleSpecs::ClassWithFoo.new.__send__ :foo
end
result.should == "foo from refinement"
end end
it "is honored by Symbol#to_proc" do result.should == "foo from refinement"
refinement = Module.new do end
refine Integer do
def to_s it "is honored by Symbol#to_proc" do
"(#{super})" refinement = Module.new do
end refine Integer do
def to_s
"(#{super})"
end end
end end
result = nil
Module.new do
using refinement
result = [1, 2, 3].map(&:to_s)
end
result.should == ["(1)", "(2)", "(3)"]
end end
result = nil
Module.new do
using refinement
result = [1, 2, 3].map(&:to_s)
end
result.should == ["(1)", "(2)", "(3)"]
end end
ruby_version_is "" ... "2.6" do ruby_version_is "" ... "2.6" do

View file

@ -1,9 +1,7 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is '2.4' do describe "NilClass#dup" do
describe "NilClass#dup" do it "returns self" do
it "returns self" do nil.dup.should equal(nil)
nil.dup.should equal(nil)
end
end end
end end

View file

@ -1,10 +1,8 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Numeric#finite?" do
describe "Numeric#finite?" do it "returns true by default" do
it "returns true by default" do o = mock_numeric("finite")
o = mock_numeric("finite") o.finite?.should be_true
o.finite?.should be_true
end
end end
end end

View file

@ -1,10 +1,8 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "Numeric#infinite?" do
describe "Numeric#infinite?" do it "returns nil by default" do
it "returns nil by default" do o = mock_numeric("infinite")
o = mock_numeric("infinite") o.infinite?.should == nil
o.infinite?.should == nil
end
end end
end end

View file

@ -224,9 +224,6 @@ describe :numeric_step, :shared => true do
describe "when step is a String" do describe "when step is a String" do
error = nil error = nil
ruby_version_is ""..."2.4" do
error = ArgumentError
end
ruby_version_is "2.4"..."2.5" do ruby_version_is "2.4"..."2.5" do
error = TypeError error = TypeError
end end
@ -305,9 +302,6 @@ describe :numeric_step, :shared => true do
describe "size" do describe "size" do
describe "when step is a String" do describe "when step is a String" do
error = nil error = nil
ruby_version_is ""..."2.4" do
error = ArgumentError
end
ruby_version_is "2.4"..."2.5" do ruby_version_is "2.4"..."2.5" do
error = TypeError error = TypeError
end end

View file

@ -201,7 +201,6 @@ describe "ObjectSpace.each_object" do
expected = [ a, b, c, d ] expected = [ a, b, c, d ]
# singleton classes should be walked only on >= 2.3
expected << c_sclass expected << c_sclass
c_sclass.should be_kind_of(a.singleton_class) c_sclass.should be_kind_of(a.singleton_class)

View file

@ -17,13 +17,11 @@ describe "Proc#call on a Proc created with Kernel#lambda or Kernel#proc" do
it_behaves_like :proc_call_on_proc_or_lambda, :call it_behaves_like :proc_call_on_proc_or_lambda, :call
end end
ruby_bug "#15118", ""..."2.6" do describe "Proc#[] with frozen_string_literals" do
describe "Proc#[] with frozen_string_literals" do it "doesn't duplicate frozen strings" do
it "doesn't duplicate frozen strings" do ProcArefSpecs.aref.frozen?.should be_false
ProcArefSpecs.aref.frozen?.should be_false ProcArefSpecs.aref_freeze.frozen?.should be_true
ProcArefSpecs.aref_freeze.frozen?.should be_true ProcArefFrozenSpecs.aref.frozen?.should be_true
ProcArefFrozenSpecs.aref.frozen?.should be_true ProcArefFrozenSpecs.aref_freeze.frozen?.should be_true
ProcArefFrozenSpecs.aref_freeze.frozen?.should be_true
end
end end
end end

View file

@ -0,0 +1,55 @@
require_relative '../../spec_helper'
require_relative 'fixtures/clocks'
describe "Process.clock_getres" do
ProcessSpecs.clock_constants.each do |name, value|
it "matches the clock in practice for Process::#{name}" do
times = []
10_000.times do
times << Process.clock_gettime(value, :nanosecond)
end
reported = Process.clock_getres(value, :nanosecond)
# The clock should not be more accurate than reported (times should be
# a multiple of reported precision.)
times.select { |t| t % reported > 0 }.should be_empty
# We're assuming precision is a multiple of ten - it may or may not
# be an incompatibility if it isn't but we'd like to notice this,
# and the spec following these wouldn't work if it isn't.
reported.should > 0
(reported == 1 || reported % 10 == 0).should be_true
# The clock should not be less accurate than reported (times should
# not all be a multiple of the next precision up, assuming precisions
# are multiples of ten.)
times.select { |t| t % (reported * 10) == 0 }.size.should_not == times.size
end
end
# These are documented
it "with :GETTIMEOFDAY_BASED_CLOCK_REALTIME reports 1 microsecond" do
Process.clock_getres(:GETTIMEOFDAY_BASED_CLOCK_REALTIME, :nanosecond).should == 1_000
end
it "with :TIME_BASED_CLOCK_REALTIME reports 1 second" do
Process.clock_getres(:TIME_BASED_CLOCK_REALTIME, :nanosecond).should == 1_000_000_000
end
platform_is_not :windows do
it "with :GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID reports 1 microsecond" do
Process.clock_getres(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID, :nanosecond).should == 1_000
end
end
# These are observed
it "with Process::CLOCK_REALTIME reports at least 1 microsecond" do
Process.clock_getres(Process::CLOCK_REALTIME, :nanosecond).should <= 1_000
end
it "with Process::CLOCK_MONOTONIC reports at least 1 microsecond" do
Process.clock_getres(Process::CLOCK_MONOTONIC, :nanosecond).should <= 1_000
end
end

View file

@ -1,18 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/clocks'
describe "Process.clock_gettime" do describe "Process.clock_gettime" do
platform_is_not :windows, :solaris do ProcessSpecs.clock_constants.each do |name, value|
Process.constants.select { |c| it "can be called with Process::#{name}" do
c.to_s.start_with?('CLOCK_') && Process.clock_gettime(value).should be_an_instance_of(Float)
# These require CAP_WAKE_ALARM and are not documented in clock_gettime(),
# they return EINVAL if the permission is not granted.
c != :CLOCK_BOOTTIME_ALARM &&
c != :CLOCK_REALTIME_ALARM
}.each do |c|
it "can be called with Process::#{c}" do
value = Process.const_get(c)
Process.clock_gettime(value).should be_an_instance_of(Float)
end
end end
end end
@ -36,7 +28,8 @@ describe "Process.clock_gettime" do
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
t1.should be_an_instance_of(Float) t1.should be_an_instance_of(Float)
t2.should be_close(t1, 2.0) # 2.0 is chosen arbitrarily to allow for time skew without admitting failure cases, which would be off by an order of magnitude. t2.should be_an_instance_of(Float)
t2.should be_close(t1, TIME_TOLERANCE)
end end
it 'uses the default time unit (:float_second) when passed nil' do it 'uses the default time unit (:float_second) when passed nil' do
@ -44,7 +37,8 @@ describe "Process.clock_gettime" do
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
t1.should be_an_instance_of(Float) t1.should be_an_instance_of(Float)
t2.should be_close(t1, 2.0) # 2.0 is chosen arbitrarily to allow for time skew without admitting failure cases, which would be off by an order of magnitude. t2.should be_an_instance_of(Float)
t2.should be_close(t1, TIME_TOLERANCE)
end end
end end
end end

View file

@ -0,0 +1,24 @@
module ProcessSpecs
def self.clock_constants
clocks = []
platform_is_not :windows, :solaris do
clocks += Process.constants.select { |c| c.to_s.start_with?('CLOCK_') }
# These require CAP_WAKE_ALARM and are not documented in
# Process#clock_gettime they return EINVAL if the permission
# is not granted.
clocks -= [:CLOCK_BOOTTIME_ALARM, :CLOCK_REALTIME_ALARM]
# These clocks in practice on Linux do not seem to match
# their reported resolution.
clocks -= [:CLOCK_REALTIME_COARSE, :CLOCK_MONOTONIC_COARSE]
clocks.map! { |c|
[c, Process.const_get(c)]
}
end
clocks
end
end

View file

@ -13,10 +13,8 @@ describe "Process.wait2" do
end end
leaked = Process.waitall leaked = Process.waitall
$stderr.puts "leaked before wait2 specs: #{leaked}" unless leaked.empty? $stderr.puts "leaked before wait2 specs: #{leaked}" unless leaked.empty?
with_feature :mjit do # Ruby-space should not see PIDs used by mjit
# Ruby-space should not see PIDs used by mjit leaked.should be_empty
leaked.should be_empty
end
rescue Errno::ECHILD # No child processes rescue Errno::ECHILD # No child processes
rescue NotImplementedError rescue NotImplementedError
end end

View file

@ -8,10 +8,8 @@ describe "Process.wait" do
begin begin
leaked = Process.waitall leaked = Process.waitall
puts "leaked before wait specs: #{leaked}" unless leaked.empty? puts "leaked before wait specs: #{leaked}" unless leaked.empty?
with_feature :mjit do # Ruby-space should not see PIDs used by mjit
# Ruby-space should not see PIDs used by mjit leaked.should be_empty
leaked.should be_empty
end
rescue NotImplementedError rescue NotImplementedError
end end
end end

View file

@ -1,3 +1,4 @@
require_relative '../../spec_helper'
require_relative '../../shared/rational/round' require_relative '../../shared/rational/round'
describe "Rational#round" do describe "Rational#round" do

View file

@ -111,32 +111,30 @@ describe "Regexp#match" do
end end
end end
ruby_version_is "2.4" do describe "Regexp#match?" do
describe "Regexp#match?" do before :each do
before :each do # Resetting Regexp.last_match
# Resetting Regexp.last_match /DONTMATCH/.match ''
/DONTMATCH/.match '' end
end
context "when matches the given value" do context "when matches the given value" do
it "returns true but does not set Regexp.last_match" do it "returns true but does not set Regexp.last_match" do
/string/i.match?('string').should be_true /string/i.match?('string').should be_true
Regexp.last_match.should be_nil Regexp.last_match.should be_nil
end
end end
end
it "returns false when does not match the given value" do it "returns false when does not match the given value" do
/STRING/.match?('string').should be_false /STRING/.match?('string').should be_false
end end
it "takes matching position as the 2nd argument" do it "takes matching position as the 2nd argument" do
/str/i.match?('string', 0).should be_true /str/i.match?('string', 0).should be_true
/str/i.match?('string', 1).should be_false /str/i.match?('string', 1).should be_false
end end
it "returns false when given nil" do it "returns false when given nil" do
/./.match?(nil).should be_false /./.match?(nil).should be_false
end
end end
end end

View file

@ -17,75 +17,65 @@ describe "String#capitalize" do
"hello".taint.capitalize.tainted?.should == true "hello".taint.capitalize.tainted?.should == true
end end
ruby_version_is ''...'2.4' do describe "full Unicode case mapping" do
it "is locale insensitive (only upcases a-z and only downcases A-Z)" do it "works for all of Unicode with no option" do
"ÄÖÜ".capitalize.should == "ÄÖÜ" "äöÜ".capitalize.should == "Äöü"
"ärger".capitalize.should == "ärger" end
"BÄR".capitalize.should == "BÄr"
it "only capitalizes the first resulting character when upcasing a character produces a multi-character sequence" do
"ß".capitalize.should == "Ss"
end
it "updates string metadata" do
capitalized = "ßeT".capitalize
capitalized.should == "Sset"
capitalized.size.should == 4
capitalized.bytesize.should == 4
capitalized.ascii_only?.should be_true
end end
end end
ruby_version_is '2.4' do describe "ASCII-only case mapping" do
describe "full Unicode case mapping" do it "does not capitalize non-ASCII characters" do
it "works for all of Unicode with no option" do "ßet".capitalize(:ascii).should == "ßet"
"äöÜ".capitalize.should == "Äöü" end
end end
it "only capitalizes the first resulting character when upcasing a character produces a multi-character sequence" do describe "full Unicode case mapping adapted for Turkic languages" do
"ß".capitalize.should == "Ss" it "capitalizes ASCII characters according to Turkic semantics" do
end "iSa".capitalize(:turkic).should == "İsa"
it "updates string metadata" do
capitalized = "ßeT".capitalize
capitalized.should == "Sset"
capitalized.size.should == 4
capitalized.bytesize.should == 4
capitalized.ascii_only?.should be_true
end
end end
describe "ASCII-only case mapping" do it "allows Lithuanian as an extra option" do
it "does not capitalize non-ASCII characters" do "iSa".capitalize(:turkic, :lithuanian).should == "İsa"
"ßet".capitalize(:ascii).should == "ßet"
end
end end
describe "full Unicode case mapping adapted for Turkic languages" do it "does not allow any other additional option" do
it "capitalizes ASCII characters according to Turkic semantics" do lambda { "iSa".capitalize(:turkic, :ascii) }.should raise_error(ArgumentError)
"iSa".capitalize(:turkic).should == "İsa" end
end end
it "allows Lithuanian as an extra option" do describe "full Unicode case mapping adapted for Lithuanian" do
"iSa".capitalize(:turkic, :lithuanian).should == "İsa" it "currently works the same as full Unicode case mapping" do
end "".capitalize(:lithuanian).should == ""
it "does not allow any other additional option" do
lambda { "iSa".capitalize(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
it "currently works the same as full Unicode case mapping" do "".capitalize(:lithuanian, :turkic).should == "İß"
"".capitalize(:lithuanian).should == ""
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do
"".capitalize(:lithuanian, :turkic).should == "İß"
end
it "does not allow any other additional option" do
lambda { "".capitalize(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "does not allow any other additional option" do
lambda { "abc".capitalize(:fold) }.should raise_error(ArgumentError) lambda { "".capitalize(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end
it "does not allow invalid options" do it "does not allow the :fold option for upcasing" do
lambda { "abc".capitalize(:invalid_option) }.should raise_error(ArgumentError) lambda { "abc".capitalize(:fold) }.should raise_error(ArgumentError)
end end
it "does not allow invalid options" do
lambda { "abc".capitalize(:invalid_option) }.should raise_error(ArgumentError)
end end
it "returns subclass instances when called on a subclass" do it "returns subclass instances when called on a subclass" do
@ -101,82 +91,80 @@ describe "String#capitalize!" do
a.should == "Hello" a.should == "Hello"
end end
ruby_version_is '2.4' do describe "full Unicode case mapping" do
describe "full Unicode case mapping" do it "modifies self in place for all of Unicode with no option" do
it "modifies self in place for all of Unicode with no option" do a = "äöÜ"
a = "äöÜ" a.capitalize!
a.capitalize! a.should == "Äöü"
a.should == "Äöü"
end
it "only capitalizes the first resulting character when upcasing a character produces a multi-character sequence" do
a = "ß"
a.capitalize!
a.should == "Ss"
end
it "updates string metadata" do
capitalized = "ßeT"
capitalized.capitalize!
capitalized.should == "Sset"
capitalized.size.should == 4
capitalized.bytesize.should == 4
capitalized.ascii_only?.should be_true
end
end end
describe "modifies self in place for ASCII-only case mapping" do it "only capitalizes the first resulting character when upcasing a character produces a multi-character sequence" do
it "does not capitalize non-ASCII characters" do a = "ß"
a = "ßet" a.capitalize!
a.capitalize!(:ascii) a.should == "Ss"
a.should == "ßet"
end
end end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do it "updates string metadata" do
it "capitalizes ASCII characters according to Turkic semantics" do capitalized = "ßeT"
a = "iSa" capitalized.capitalize!
a.capitalize!(:turkic)
a.should == "İsa"
end
it "allows Lithuanian as an extra option" do capitalized.should == "Sset"
a = "iSa" capitalized.size.should == 4
a.capitalize!(:turkic, :lithuanian) capitalized.bytesize.should == 4
a.should == "İsa" capitalized.ascii_only?.should be_true
end end
end
it "does not allow any other additional option" do describe "modifies self in place for ASCII-only case mapping" do
lambda { a = "iSa"; a.capitalize!(:turkic, :ascii) }.should raise_error(ArgumentError) it "does not capitalize non-ASCII characters" do
end a = "ßet"
a.capitalize!(:ascii)
a.should == "ßet"
end
end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do
it "capitalizes ASCII characters according to Turkic semantics" do
a = "iSa"
a.capitalize!(:turkic)
a.should == "İsa"
end end
describe "modifies self in place for full Unicode case mapping adapted for Lithuanian" do it "allows Lithuanian as an extra option" do
it "currently works the same as full Unicode case mapping" do a = "iSa"
a = "" a.capitalize!(:turkic, :lithuanian)
a.capitalize!(:lithuanian) a.should == "İsa"
a.should == ""
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do
a = ""
a.capitalize!(:lithuanian, :turkic)
a.should == "İß"
end
it "does not allow any other additional option" do
lambda { a = ""; a.capitalize!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "does not allow any other additional option" do
lambda { a = "abc"; a.capitalize!(:fold) }.should raise_error(ArgumentError) lambda { a = "iSa"; a.capitalize!(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end
describe "modifies self in place for full Unicode case mapping adapted for Lithuanian" do
it "currently works the same as full Unicode case mapping" do
a = ""
a.capitalize!(:lithuanian)
a.should == ""
end end
it "does not allow invalid options" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
lambda { a = "abc"; a.capitalize!(:invalid_option) }.should raise_error(ArgumentError) a = ""
a.capitalize!(:lithuanian, :turkic)
a.should == "İß"
end end
it "does not allow any other additional option" do
lambda { a = ""; a.capitalize!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end
it "does not allow the :fold option for upcasing" do
lambda { a = "abc"; a.capitalize!(:fold) }.should raise_error(ArgumentError)
end
it "does not allow invalid options" do
lambda { a = "abc"; a.capitalize!(:invalid_option) }.should raise_error(ArgumentError)
end end
it "returns nil when no changes are made" do it "returns nil when no changes are made" do

View file

@ -101,10 +101,8 @@ describe "String#casecmp independent of case" do
@lower_a_tilde.casecmp(@upper_a_tilde).should == 1 @lower_a_tilde.casecmp(@upper_a_tilde).should == 1
end end
ruby_version_is "2.4" do it "does not case fold" do
it "does not case fold" do "ß".casecmp("ss").should == 1
"ß".casecmp("ss").should == 1
end
end end
end end
@ -129,88 +127,84 @@ describe "String#casecmp independent of case" do
end end
end end
ruby_version_is "2.4" do describe 'String#casecmp? independent of case' do
describe 'String#casecmp? independent of case' do it 'returns true when equal to other' do
'abc'.casecmp?('abc').should == true
'abc'.casecmp?('ABC').should == true
end
it 'returns false when not equal to other' do
'abc'.casecmp?('DEF').should == false
'abc'.casecmp?('def').should == false
end
it "tries to convert other to string using to_str" do
other = mock('x')
other.should_receive(:to_str).and_return("abc")
"abc".casecmp?(other).should == true
end
it "returns nil if incompatible encodings" do
"あれ".casecmp?("".encode(Encoding::EUC_JP)).should be_nil
end
describe 'for UNICODE characters' do
it 'returns true when downcase(:fold) on unicode' do
'äöü'.casecmp?('ÄÖÜ').should == true
end
end
describe "when comparing a subclass instance" do
it 'returns true when equal to other' do it 'returns true when equal to other' do
'abc'.casecmp?('abc').should == true a = StringSpecs::MyString.new "a"
'abc'.casecmp?('ABC').should == true 'a'.casecmp?(a).should == true
'A'.casecmp?(a).should == true
end end
it 'returns false when not equal to other' do it 'returns false when not equal to other' do
'abc'.casecmp?('DEF').should == false b = StringSpecs::MyString.new "a"
'abc'.casecmp?('def').should == false 'b'.casecmp?(b).should == false
'B'.casecmp?(b).should == false
end end
end
it "tries to convert other to string using to_str" do describe "in UTF-8 mode" do
other = mock('x') describe "for non-ASCII characters" do
other.should_receive(:to_str).and_return("abc") before :each do
@upper_a_tilde = "Ã"
"abc".casecmp?(other).should == true @lower_a_tilde = "ã"
end @upper_a_umlaut = "Ä"
@lower_a_umlaut = "ä"
it "returns nil if incompatible encodings" do
"あれ".casecmp?("".encode(Encoding::EUC_JP)).should be_nil
end
describe 'for UNICODE characters' do
it 'returns true when downcase(:fold) on unicode' do
'äöü'.casecmp?('ÄÖÜ').should == true
end
end
describe "when comparing a subclass instance" do
it 'returns true when equal to other' do
a = StringSpecs::MyString.new "a"
'a'.casecmp?(a).should == true
'A'.casecmp?(a).should == true
end end
it 'returns false when not equal to other' do it "returns true when they are the same with normalized case" do
b = StringSpecs::MyString.new "a" @upper_a_tilde.casecmp?(@lower_a_tilde).should == true
'b'.casecmp?(b).should == false
'B'.casecmp?(b).should == false
end end
end
describe "in UTF-8 mode" do it "returns false when they are unrelated" do
describe "for non-ASCII characters" do @upper_a_tilde.casecmp?(@upper_a_umlaut).should == false
before :each do
@upper_a_tilde = "Ã"
@lower_a_tilde = "ã"
@upper_a_umlaut = "Ä"
@lower_a_umlaut = "ä"
end
it "returns true when they are the same with normalized case" do
@upper_a_tilde.casecmp?(@lower_a_tilde).should == true
end
it "returns false when they are unrelated" do
@upper_a_tilde.casecmp?(@upper_a_umlaut).should == false
end
it "returns true when they have the same bytes" do
@upper_a_tilde.casecmp?(@upper_a_tilde).should == true
end
end end
end
ruby_version_is "2.4" do it "returns true when they have the same bytes" do
it "case folds" do @upper_a_tilde.casecmp?(@upper_a_tilde).should == true
"ß".casecmp?("ss").should be_true
end
end
ruby_version_is "2.4" ... "2.5" do
it "raises a TypeError if other can't be converted to a string" do
lambda { "abc".casecmp?(mock('abc')) }.should raise_error(TypeError)
end
end
ruby_version_is "2.5" do
it "returns nil if other can't be converted to a string" do
"abc".casecmp?(mock('abc')).should be_nil
end end
end end
end end
it "case folds" do
"ß".casecmp?("ss").should be_true
end
ruby_version_is "2.4"..."2.5" do
it "raises a TypeError if other can't be converted to a string" do
lambda { "abc".casecmp?(mock('abc')) }.should raise_error(TypeError)
end
end
ruby_version_is "2.5" do
it "returns nil if other can't be converted to a string" do
"abc".casecmp?(mock('abc')).should be_nil
end
end
end end

View file

@ -6,23 +6,21 @@ describe "String#concat" do
it_behaves_like :string_concat, :concat it_behaves_like :string_concat, :concat
it_behaves_like :string_concat_encoding, :concat it_behaves_like :string_concat_encoding, :concat
ruby_version_is "2.4" do it "takes multiple arguments" do
it "takes multiple arguments" do str = "hello "
str = "hello " str.concat "wo", "", "rld"
str.concat "wo", "", "rld" str.should == "hello world"
str.should == "hello world" end
end
it "concatenates the initial value when given arguments contain 2 self" do it "concatenates the initial value when given arguments contain 2 self" do
str = "hello" str = "hello"
str.concat str, str str.concat str, str
str.should == "hellohellohello" str.should == "hellohellohello"
end end
it "returns self when given no arguments" do it "returns self when given no arguments" do
str = "hello" str = "hello"
str.concat.should equal(str) str.concat.should equal(str)
str.should == "hello" str.should == "hello"
end
end end
end end

View file

@ -8,82 +8,66 @@ describe "String#downcase" do
"hello".downcase.should == "hello" "hello".downcase.should == "hello"
end end
ruby_version_is ''...'2.4' do describe "full Unicode case mapping" do
it "is locale insensitive (only replaces A-Z)" do it "works for all of Unicode with no option" do
"ÄÖÜ".downcase.should == "ÄÖÜ" "ÄÖÜ".downcase.should == "äöü"
end
str = Array.new(256) { |c| c.chr }.join it "updates string metadata" do
expected = Array.new(256) do |i| downcased = "\u{212A}ING".downcase
c = i.chr
c.between?("A", "Z") ? c.downcase : c
end.join
str.downcase.should == expected downcased.should == "king"
downcased.size.should == 4
downcased.bytesize.should == 4
downcased.ascii_only?.should be_true
end end
end end
ruby_version_is '2.4' do describe "ASCII-only case mapping" do
describe "full Unicode case mapping" do it "does not downcase non-ASCII characters" do
it "works for all of Unicode with no option" do "CÅR".downcase(:ascii).should == "cÅr"
"ÄÖÜ".downcase.should == "äöü" end
end end
it "updates string metadata" do describe "full Unicode case mapping adapted for Turkic languages" do
downcased = "\u{212A}ING".downcase it "downcases characters according to Turkic semantics" do
"İ".downcase(:turkic).should == "i"
downcased.should == "king"
downcased.size.should == 4
downcased.bytesize.should == 4
downcased.ascii_only?.should be_true
end
end end
describe "ASCII-only case mapping" do it "allows Lithuanian as an extra option" do
it "does not downcase non-ASCII characters" do "İ".downcase(:turkic, :lithuanian).should == "i"
"CÅR".downcase(:ascii).should == "cÅr"
end
end end
describe "full Unicode case mapping adapted for Turkic languages" do it "does not allow any other additional option" do
it "downcases characters according to Turkic semantics" do lambda { "İ".downcase(:turkic, :ascii) }.should raise_error(ArgumentError)
"İ".downcase(:turkic).should == "i" end
end end
it "allows Lithuanian as an extra option" do describe "full Unicode case mapping adapted for Lithuanian" do
"İ".downcase(:turkic, :lithuanian).should == "i" it "currently works the same as full Unicode case mapping" do
end "İS".downcase(:lithuanian).should == "i\u{307}s"
it "does not allow any other additional option" do
lambda { "İ".downcase(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
it "currently works the same as full Unicode case mapping" do "İS".downcase(:lithuanian, :turkic).should == "is"
"İS".downcase(:lithuanian).should == "i\u{307}s"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do
"İS".downcase(:lithuanian, :turkic).should == "is"
end
it "does not allow any other additional option" do
lambda { "İS".downcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "case folding" do it "does not allow any other additional option" do
it "case folds special characters" do lambda { "İS".downcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
"ß".downcase.should == "ß"
"ß".downcase(:fold).should == "ss"
end
end end
end
it "does not allow invalid options" do describe "case folding" do
lambda { "ABC".downcase(:invalid_option) }.should raise_error(ArgumentError) it "case folds special characters" do
"ß".downcase.should == "ß"
"ß".downcase(:fold).should == "ss"
end end
end end
it "does not allow invalid options" do
lambda { "ABC".downcase(:invalid_option) }.should raise_error(ArgumentError)
end
it "taints result when self is tainted" do it "taints result when self is tainted" do
"".taint.downcase.tainted?.should == true "".taint.downcase.tainted?.should == true
"x".taint.downcase.tainted?.should == true "x".taint.downcase.tainted?.should == true
@ -102,85 +86,83 @@ describe "String#downcase!" do
a.should == "hello" a.should == "hello"
end end
ruby_version_is '2.4' do describe "full Unicode case mapping" do
describe "full Unicode case mapping" do it "modifies self in place for all of Unicode with no option" do
it "modifies self in place for all of Unicode with no option" do a = "ÄÖÜ"
a = "ÄÖÜ" a.downcase!
a.downcase! a.should == "äöü"
a.should == "äöü"
end
it "updates string metadata" do
downcased = "\u{212A}ING"
downcased.downcase!
downcased.should == "king"
downcased.size.should == 4
downcased.bytesize.should == 4
downcased.ascii_only?.should be_true
end
end end
describe "ASCII-only case mapping" do it "updates string metadata" do
it "does not downcase non-ASCII characters" do downcased = "\u{212A}ING"
a = "CÅR" downcased.downcase!
a.downcase!(:ascii)
a.should == "cÅr" downcased.should == "king"
end downcased.size.should == 4
downcased.bytesize.should == 4
downcased.ascii_only?.should be_true
end
end
describe "ASCII-only case mapping" do
it "does not downcase non-ASCII characters" do
a = "CÅR"
a.downcase!(:ascii)
a.should == "cÅr"
end
end
describe "full Unicode case mapping adapted for Turkic languages" do
it "downcases characters according to Turkic semantics" do
a = "İ"
a.downcase!(:turkic)
a.should == "i"
end end
describe "full Unicode case mapping adapted for Turkic languages" do it "allows Lithuanian as an extra option" do
it "downcases characters according to Turkic semantics" do a = "İ"
a = "İ" a.downcase!(:turkic, :lithuanian)
a.downcase!(:turkic) a.should == "i"
a.should == "i"
end
it "allows Lithuanian as an extra option" do
a = "İ"
a.downcase!(:turkic, :lithuanian)
a.should == "i"
end
it "does not allow any other additional option" do
lambda { a = "İ"; a.downcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "does not allow any other additional option" do
it "currently works the same as full Unicode case mapping" do lambda { a = "İ"; a.downcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
a = "İS" end
a.downcase!(:lithuanian) end
a.should == "i\u{307}s"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do describe "full Unicode case mapping adapted for Lithuanian" do
a = "İS" it "currently works the same as full Unicode case mapping" do
a.downcase!(:lithuanian, :turkic) a = "İS"
a.should == "is" a.downcase!(:lithuanian)
end a.should == "i\u{307}s"
it "does not allow any other additional option" do
lambda { a = "İS"; a.downcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "case folding" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
it "case folds special characters" do a = "İS"
a = "ß" a.downcase!(:lithuanian, :turkic)
a.downcase! a.should == "is"
a.should == "ß"
a.downcase!(:fold)
a.should == "ss"
end
end end
it "does not allow invalid options" do it "does not allow any other additional option" do
lambda { a = "ABC"; a.downcase!(:invalid_option) }.should raise_error(ArgumentError) lambda { a = "İS"; a.downcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end end
describe "case folding" do
it "case folds special characters" do
a = "ß"
a.downcase!
a.should == "ß"
a.downcase!(:fold)
a.should == "ss"
end
end
it "does not allow invalid options" do
lambda { a = "ABC"; a.downcase!(:invalid_option) }.should raise_error(ArgumentError)
end
it "returns nil if no modifications were made" do it "returns nil if no modifications were made" do
a = "hello" a = "hello"
a.downcase!.should == nil a.downcase!.should == nil

View file

@ -352,78 +352,39 @@ describe "String#dump" do
].should be_computed_by(:dump) ].should be_computed_by(:dump)
end end
ruby_version_is ''...'2.4' do it "returns a string with multi-byte UTF-8 characters replaced by \\u{} notation with upper-case hex digits" do
it "returns a string with multi-byte UTF-8 characters replaced by \\u{} notation with lower-case hex digits" do [ [0200.chr('utf-8'), '"\u0080"'],
[ [0200.chr('utf-8'), '"\u{80}"'], [0201.chr('utf-8'), '"\u0081"'],
[0201.chr('utf-8'), '"\u{81}"'], [0202.chr('utf-8'), '"\u0082"'],
[0202.chr('utf-8'), '"\u{82}"'], [0203.chr('utf-8'), '"\u0083"'],
[0203.chr('utf-8'), '"\u{83}"'], [0204.chr('utf-8'), '"\u0084"'],
[0204.chr('utf-8'), '"\u{84}"'], [0206.chr('utf-8'), '"\u0086"'],
[0206.chr('utf-8'), '"\u{86}"'], [0207.chr('utf-8'), '"\u0087"'],
[0207.chr('utf-8'), '"\u{87}"'], [0210.chr('utf-8'), '"\u0088"'],
[0210.chr('utf-8'), '"\u{88}"'], [0211.chr('utf-8'), '"\u0089"'],
[0211.chr('utf-8'), '"\u{89}"'], [0212.chr('utf-8'), '"\u008A"'],
[0212.chr('utf-8'), '"\u{8a}"'], [0213.chr('utf-8'), '"\u008B"'],
[0213.chr('utf-8'), '"\u{8b}"'], [0214.chr('utf-8'), '"\u008C"'],
[0214.chr('utf-8'), '"\u{8c}"'], [0215.chr('utf-8'), '"\u008D"'],
[0215.chr('utf-8'), '"\u{8d}"'], [0216.chr('utf-8'), '"\u008E"'],
[0216.chr('utf-8'), '"\u{8e}"'], [0217.chr('utf-8'), '"\u008F"'],
[0217.chr('utf-8'), '"\u{8f}"'], [0220.chr('utf-8'), '"\u0090"'],
[0220.chr('utf-8'), '"\u{90}"'], [0221.chr('utf-8'), '"\u0091"'],
[0221.chr('utf-8'), '"\u{91}"'], [0222.chr('utf-8'), '"\u0092"'],
[0222.chr('utf-8'), '"\u{92}"'], [0223.chr('utf-8'), '"\u0093"'],
[0223.chr('utf-8'), '"\u{93}"'], [0224.chr('utf-8'), '"\u0094"'],
[0224.chr('utf-8'), '"\u{94}"'], [0225.chr('utf-8'), '"\u0095"'],
[0225.chr('utf-8'), '"\u{95}"'], [0226.chr('utf-8'), '"\u0096"'],
[0226.chr('utf-8'), '"\u{96}"'], [0227.chr('utf-8'), '"\u0097"'],
[0227.chr('utf-8'), '"\u{97}"'], [0230.chr('utf-8'), '"\u0098"'],
[0230.chr('utf-8'), '"\u{98}"'], [0231.chr('utf-8'), '"\u0099"'],
[0231.chr('utf-8'), '"\u{99}"'], [0232.chr('utf-8'), '"\u009A"'],
[0232.chr('utf-8'), '"\u{9a}"'], [0233.chr('utf-8'), '"\u009B"'],
[0233.chr('utf-8'), '"\u{9b}"'], [0234.chr('utf-8'), '"\u009C"'],
[0234.chr('utf-8'), '"\u{9c}"'], [0235.chr('utf-8'), '"\u009D"'],
[0235.chr('utf-8'), '"\u{9d}"'], [0236.chr('utf-8'), '"\u009E"'],
[0236.chr('utf-8'), '"\u{9e}"'], [0237.chr('utf-8'), '"\u009F"'],
[0237.chr('utf-8'), '"\u{9f}"'], ].should be_computed_by(:dump)
].should be_computed_by(:dump)
end
end
ruby_version_is '2.4' do
it "returns a string with multi-byte UTF-8 characters replaced by \\u{} notation with upper-case hex digits" do
[ [0200.chr('utf-8'), '"\u0080"'],
[0201.chr('utf-8'), '"\u0081"'],
[0202.chr('utf-8'), '"\u0082"'],
[0203.chr('utf-8'), '"\u0083"'],
[0204.chr('utf-8'), '"\u0084"'],
[0206.chr('utf-8'), '"\u0086"'],
[0207.chr('utf-8'), '"\u0087"'],
[0210.chr('utf-8'), '"\u0088"'],
[0211.chr('utf-8'), '"\u0089"'],
[0212.chr('utf-8'), '"\u008A"'],
[0213.chr('utf-8'), '"\u008B"'],
[0214.chr('utf-8'), '"\u008C"'],
[0215.chr('utf-8'), '"\u008D"'],
[0216.chr('utf-8'), '"\u008E"'],
[0217.chr('utf-8'), '"\u008F"'],
[0220.chr('utf-8'), '"\u0090"'],
[0221.chr('utf-8'), '"\u0091"'],
[0222.chr('utf-8'), '"\u0092"'],
[0223.chr('utf-8'), '"\u0093"'],
[0224.chr('utf-8'), '"\u0094"'],
[0225.chr('utf-8'), '"\u0095"'],
[0226.chr('utf-8'), '"\u0096"'],
[0227.chr('utf-8'), '"\u0097"'],
[0230.chr('utf-8'), '"\u0098"'],
[0231.chr('utf-8'), '"\u0099"'],
[0232.chr('utf-8'), '"\u009A"'],
[0233.chr('utf-8'), '"\u009B"'],
[0234.chr('utf-8'), '"\u009C"'],
[0235.chr('utf-8'), '"\u009D"'],
[0236.chr('utf-8'), '"\u009E"'],
[0237.chr('utf-8'), '"\u009F"'],
].should be_computed_by(:dump)
end
end end
it "includes .force_encoding(name) if the encoding isn't ASCII compatible" do it "includes .force_encoding(name) if the encoding isn't ASCII compatible" do

View file

@ -11,12 +11,10 @@ describe "String#lines" do
ary.should == ["hello ", "world"] ary.should == ["hello ", "world"]
end end
ruby_version_is '2.4' do context "when `chomp` keyword argument is passed" do
context "when `chomp` keyword argument is passed" do it "removes new line characters" do
it "removes new line characters" do "hello \nworld\n".lines(chomp: true).should == ["hello ", "world"]
"hello \nworld\n".lines(chomp: true).should == ["hello ", "world"] "hello \r\nworld\r\n".lines(chomp: true).should == ["hello ", "world"]
"hello \r\nworld\r\n".lines(chomp: true).should == ["hello ", "world"]
end
end end
end end
end end

View file

@ -149,27 +149,25 @@ describe "String#match" do
end end
end end
ruby_version_is "2.4" do describe "String#match?" do
describe "String#match?" do before :each do
before :each do # Resetting Regexp.last_match
# Resetting Regexp.last_match /DONTMATCH/.match ''
/DONTMATCH/.match '' end
end
context "when matches the given regex" do context "when matches the given regex" do
it "returns true but does not set Regexp.last_match" do it "returns true but does not set Regexp.last_match" do
'string'.match?(/string/i).should be_true 'string'.match?(/string/i).should be_true
Regexp.last_match.should be_nil Regexp.last_match.should be_nil
end
end
it "returns false when does not match the given regex" do
'string'.match?(/STRING/).should be_false
end
it "takes matching position as the 2nd argument" do
'string'.match?(/str/i, 0).should be_true
'string'.match?(/str/i, 1).should be_false
end end
end end
it "returns false when does not match the given regex" do
'string'.match?(/STRING/).should be_false
end
it "takes matching position as the 2nd argument" do
'string'.match?(/str/i, 0).should be_true
'string'.match?(/str/i, 1).should be_false
end
end end

View file

@ -13,11 +13,9 @@ describe "String.new" do
str.encoding.should == Encoding::EUC_JP str.encoding.should == Encoding::EUC_JP
end end
ruby_version_is "2.4" do it "accepts a capacity argument" do
it "accepts a capacity argument" do String.new("", capacity: 100_000).should == ""
String.new("", capacity: 100_000).should == "" String.new("abc", capacity: 100_000).should == "abc"
String.new("abc", capacity: 100_000).should == "abc"
end
end end
it "returns a fully-formed String" do it "returns a fully-formed String" do

View file

@ -42,23 +42,21 @@ describe "String#prepend" do
x.prepend("y".taint).tainted?.should be_true x.prepend("y".taint).tainted?.should be_true
end end
ruby_version_is "2.4" do it "takes multiple arguments" do
it "takes multiple arguments" do str = " world"
str = " world" str.prepend "he", "", "llo"
str.prepend "he", "", "llo" str.should == "hello world"
str.should == "hello world" end
end
it "prepends the initial value when given arguments contain 2 self" do it "prepends the initial value when given arguments contain 2 self" do
str = "hello" str = "hello"
str.prepend str, str str.prepend str, str
str.should == "hellohellohello" str.should == "hellohellohello"
end end
it "returns self when given no arguments" do it "returns self when given no arguments" do
str = "hello" str = "hello"
str.prepend.should equal(str) str.prepend.should equal(str)
str.should == "hello" str.should == "hello"
end
end end
end end

View file

@ -145,34 +145,32 @@ describe :string_each_line, shared: true do
lambda { "hello world".send(@method, :o).to_a }.should raise_error(TypeError) lambda { "hello world".send(@method, :o).to_a }.should raise_error(TypeError)
end end
ruby_version_is '2.4' do context "when `chomp` keyword argument is passed" do
context "when `chomp` keyword argument is passed" do it "removes new line characters when separator is not specified" do
it "removes new line characters when separator is not specified" do a = []
a = [] "hello \nworld\n".send(@method, chomp: true) { |s| a << s }
"hello \nworld\n".send(@method, chomp: true) { |s| a << s } a.should == ["hello ", "world"]
a.should == ["hello ", "world"]
a = [] a = []
"hello \r\nworld\r\n".send(@method, chomp: true) { |s| a << s } "hello \r\nworld\r\n".send(@method, chomp: true) { |s| a << s }
a.should == ["hello ", "world"] a.should == ["hello ", "world"]
end end
it "removes only specified separator" do it "removes only specified separator" do
a = [] a = []
"hello world".send(@method, ' ', chomp: true) { |s| a << s } "hello world".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello", "world"] a.should == ["hello", "world"]
end end
# https://bugs.ruby-lang.org/issues/14257 # https://bugs.ruby-lang.org/issues/14257
it "ignores new line characters when separator is specified" do it "ignores new line characters when separator is specified" do
a = [] a = []
"hello\n world\n".send(@method, ' ', chomp: true) { |s| a << s } "hello\n world\n".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello\n", "world\n"] a.should == ["hello\n", "world\n"]
a = [] a = []
"hello\r\n world\r\n".send(@method, ' ', chomp: true) { |s| a << s } "hello\r\n world\r\n".send(@method, ' ', chomp: true) { |s| a << s }
a.should == ["hello\r\n", "world\r\n"] a.should == ["hello\r\n", "world\r\n"]
end
end end
end end
end end

View file

@ -65,28 +65,26 @@ describe "String#split with String" do
end end
it "defaults to $; when string isn't given or nil" do it "defaults to $; when string isn't given or nil" do
begin suppress_warning do
verbose = $VERBOSE
$VERBOSE = nil
old_fs = $; old_fs = $;
begin
[",", ":", "", "XY", nil].each do |fs|
$; = fs
[",", ":", "", "XY", nil].each do |fs| ["x,y,z,,,", "1:2:", "aXYbXYcXY", ""].each do |str|
$; = fs expected = str.split(fs || " ")
["x,y,z,,,", "1:2:", "aXYbXYcXY", ""].each do |str| str.split(nil).should == expected
expected = str.split(fs || " ") str.split.should == expected
str.split(nil).should == expected str.split(nil, -1).should == str.split(fs || " ", -1)
str.split.should == expected str.split(nil, 0).should == str.split(fs || " ", 0)
str.split(nil, 2).should == str.split(fs || " ", 2)
str.split(nil, -1).should == str.split(fs || " ", -1) end
str.split(nil, 0).should == str.split(fs || " ", 0)
str.split(nil, 2).should == str.split(fs || " ", 2)
end end
ensure
$; = old_fs
end end
ensure
$; = old_fs
$VERBOSE = verbose
end end
end end
@ -241,28 +239,26 @@ describe "String#split with Regexp" do
end end
it "defaults to $; when regexp isn't given or nil" do it "defaults to $; when regexp isn't given or nil" do
begin suppress_warning do
verbose = $VERBOSE
$VERBOSE = nil
old_fs = $; old_fs = $;
begin
[/,/, /:/, //, /XY/, /./].each do |fs|
$; = fs
[/,/, /:/, //, /XY/, /./].each do |fs| ["x,y,z,,,", "1:2:", "aXYbXYcXY", ""].each do |str|
$; = fs expected = str.split(fs)
["x,y,z,,,", "1:2:", "aXYbXYcXY", ""].each do |str| str.split(nil).should == expected
expected = str.split(fs) str.split.should == expected
str.split(nil).should == expected str.split(nil, -1).should == str.split(fs, -1)
str.split.should == expected str.split(nil, 0).should == str.split(fs, 0)
str.split(nil, 2).should == str.split(fs, 2)
str.split(nil, -1).should == str.split(fs, -1) end
str.split(nil, 0).should == str.split(fs, 0)
str.split(nil, 2).should == str.split(fs, 2)
end end
ensure
$; = old_fs
end end
ensure
$; = old_fs
$VERBOSE = verbose
end end
end end

View file

@ -14,71 +14,61 @@ describe "String#swapcase" do
"hello".taint.swapcase.tainted?.should == true "hello".taint.swapcase.tainted?.should == true
end end
ruby_version_is ''...'2.4' do describe "full Unicode case mapping" do
it "is locale insensitive (only upcases a-z and only downcases A-Z)" do it "works for all of Unicode with no option" do
"ÄÖÜ".swapcase.should == "ÄÖÜ" "äÖü".swapcase.should == "ÄöÜ"
"ärger".swapcase.should == "äRGER" end
"BÄR".swapcase.should == "bÄr"
it "updates string metadata" do
swapcased = "Aßet".swapcase
swapcased.should == "aSSET"
swapcased.size.should == 5
swapcased.bytesize.should == 5
swapcased.ascii_only?.should be_true
end end
end end
ruby_version_is '2.4' do describe "ASCII-only case mapping" do
describe "full Unicode case mapping" do it "does not swapcase non-ASCII characters" do
it "works for all of Unicode with no option" do "aßet".swapcase(:ascii).should == "AßET"
"äÖü".swapcase.should == "ÄöÜ" end
end end
it "updates string metadata" do describe "full Unicode case mapping adapted for Turkic languages" do
swapcased = "Aßet".swapcase it "swaps case of ASCII characters according to Turkic semantics" do
"aiS".swapcase(:turkic).should == "Aİs"
swapcased.should == "aSSET"
swapcased.size.should == 5
swapcased.bytesize.should == 5
swapcased.ascii_only?.should be_true
end
end end
describe "ASCII-only case mapping" do it "allows Lithuanian as an extra option" do
it "does not swapcase non-ASCII characters" do "aiS".swapcase(:turkic, :lithuanian).should == "Aİs"
"aßet".swapcase(:ascii).should == "AßET"
end
end end
describe "full Unicode case mapping adapted for Turkic languages" do it "does not allow any other additional option" do
it "swaps case of ASCII characters according to Turkic semantics" do lambda { "aiS".swapcase(:turkic, :ascii) }.should raise_error(ArgumentError)
"aiS".swapcase(:turkic).should == "Aİs" end
end end
it "allows Lithuanian as an extra option" do describe "full Unicode case mapping adapted for Lithuanian" do
"aiS".swapcase(:turkic, :lithuanian).should == "Aİs" it "currently works the same as full Unicode case mapping" do
end "".swapcase(:lithuanian).should == "iSS"
it "does not allow any other additional option" do
lambda { "aiS".swapcase(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
it "currently works the same as full Unicode case mapping" do "iS".swapcase(:lithuanian, :turkic).should == "İs"
"".swapcase(:lithuanian).should == "iSS"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do
"iS".swapcase(:lithuanian, :turkic).should == "İs"
end
it "does not allow any other additional option" do
lambda { "aiS".swapcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "does not allow any other additional option" do
lambda { "abc".swapcase(:fold) }.should raise_error(ArgumentError) lambda { "aiS".swapcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end
it "does not allow invalid options" do it "does not allow the :fold option for upcasing" do
lambda { "abc".swapcase(:invalid_option) }.should raise_error(ArgumentError) lambda { "abc".swapcase(:fold) }.should raise_error(ArgumentError)
end end
it "does not allow invalid options" do
lambda { "abc".swapcase(:invalid_option) }.should raise_error(ArgumentError)
end end
it "returns subclass instances when called on a subclass" do it "returns subclass instances when called on a subclass" do
@ -94,78 +84,76 @@ describe "String#swapcase!" do
a.should == "CyBeR_pUnK11" a.should == "CyBeR_pUnK11"
end end
ruby_version_is '2.4' do describe "full Unicode case mapping" do
describe "full Unicode case mapping" do it "modifies self in place for all of Unicode with no option" do
it "modifies self in place for all of Unicode with no option" do a = "äÖü"
a = "äÖü" a.swapcase!
a.swapcase! a.should == "ÄöÜ"
a.should == "ÄöÜ"
end
it "updates string metadata" do
swapcased = "Aßet"
swapcased.swapcase!
swapcased.should == "aSSET"
swapcased.size.should == 5
swapcased.bytesize.should == 5
swapcased.ascii_only?.should be_true
end
end end
describe "modifies self in place for ASCII-only case mapping" do it "updates string metadata" do
it "does not swapcase non-ASCII characters" do swapcased = "Aßet"
a = "aßet" swapcased.swapcase!
a.swapcase!(:ascii)
a.should == "AßET" swapcased.should == "aSSET"
end swapcased.size.should == 5
swapcased.bytesize.should == 5
swapcased.ascii_only?.should be_true
end
end
describe "modifies self in place for ASCII-only case mapping" do
it "does not swapcase non-ASCII characters" do
a = "aßet"
a.swapcase!(:ascii)
a.should == "AßET"
end
end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do
it "swaps case of ASCII characters according to Turkic semantics" do
a = "aiS"
a.swapcase!(:turkic)
a.should == "Aİs"
end end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do it "allows Lithuanian as an extra option" do
it "swaps case of ASCII characters according to Turkic semantics" do a = "aiS"
a = "aiS" a.swapcase!(:turkic, :lithuanian)
a.swapcase!(:turkic) a.should == "Aİs"
a.should == "Aİs"
end
it "allows Lithuanian as an extra option" do
a = "aiS"
a.swapcase!(:turkic, :lithuanian)
a.should == "Aİs"
end
it "does not allow any other additional option" do
lambda { a = "aiS"; a.swapcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "does not allow any other additional option" do
it "currently works the same as full Unicode case mapping" do lambda { a = "aiS"; a.swapcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
a = "" end
a.swapcase!(:lithuanian) end
a.should == "iSS"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do describe "full Unicode case mapping adapted for Lithuanian" do
a = "iS" it "currently works the same as full Unicode case mapping" do
a.swapcase!(:lithuanian, :turkic) a = ""
a.should == "İs" a.swapcase!(:lithuanian)
end a.should == "iSS"
it "does not allow any other additional option" do
lambda { a = "aiS"; a.swapcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
lambda { a = "abc"; a.swapcase!(:fold) }.should raise_error(ArgumentError) a = "iS"
a.swapcase!(:lithuanian, :turkic)
a.should == "İs"
end end
it "does not allow invalid options" do it "does not allow any other additional option" do
lambda { a = "abc"; a.swapcase!(:invalid_option) }.should raise_error(ArgumentError) lambda { a = "aiS"; a.swapcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end end
it "does not allow the :fold option for upcasing" do
lambda { a = "abc"; a.swapcase!(:fold) }.should raise_error(ArgumentError)
end
it "does not allow invalid options" do
lambda { a = "abc"; a.swapcase!(:invalid_option) }.should raise_error(ArgumentError)
end
it "returns nil if no modifications were made" do it "returns nil if no modifications were made" do
a = "+++---111222???" a = "+++---111222???"
a.swapcase!.should == nil a.swapcase!.should == nil

View file

@ -12,6 +12,7 @@ describe "String#to_f" do
".5".to_f.should == 0.5 ".5".to_f.should == 0.5
".5e1".to_f.should == 5.0 ".5e1".to_f.should == 5.0
"5.".to_f.should == 5.0
"5e".to_f.should == 5.0 "5e".to_f.should == 5.0
"5E".to_f.should == 5.0 "5E".to_f.should == 5.0
end end

View file

@ -1,12 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.4" do describe "String#unpack1" do
describe "String#unpack1" do it "returns the first value of #unpack" do
it "returns the first value of #unpack" do "ABCD".unpack1('x3C').should == "ABCD".unpack('x3C')[0]
"ABCD".unpack1('x3C').should == "ABCD".unpack('x3C')[0] "\u{3042 3044 3046}".unpack1("U*").should == 0x3042
"\u{3042 3044 3046}".unpack1("U*").should == 0x3042 "aG9nZWZ1Z2E=".unpack1("m").should == "hogefuga"
"aG9nZWZ1Z2E=".unpack1("m").should == "hogefuga" "A".unpack1("B*").should == "01000001"
"A".unpack1("B*").should == "01000001"
end
end end
end end

View file

@ -8,77 +8,61 @@ describe "String#upcase" do
"hello".upcase.should == "HELLO" "hello".upcase.should == "HELLO"
end end
ruby_version_is ''...'2.4' do describe "full Unicode case mapping" do
it "is locale insensitive (only replaces a-z)" do it "works for all of Unicode with no option" do
"äöü".upcase.should == "äöü" "äöü".upcase.should == "ÄÖÜ"
end
str = Array.new(256) { |c| c.chr }.join it "updates string metadata" do
expected = Array.new(256) do |i| upcased = "aßet".upcase
c = i.chr
c.between?("a", "z") ? c.upcase : c
end.join
str.upcase.should == expected upcased.should == "ASSET"
upcased.size.should == 5
upcased.bytesize.should == 5
upcased.ascii_only?.should be_true
end end
end end
ruby_version_is '2.4' do describe "ASCII-only case mapping" do
describe "full Unicode case mapping" do it "does not upcase non-ASCII characters" do
it "works for all of Unicode with no option" do "aßet".upcase(:ascii).should == "AßET"
"äöü".upcase.should == "ÄÖÜ" end
end end
it "updates string metadata" do describe "full Unicode case mapping adapted for Turkic languages" do
upcased = "aßet".upcase it "upcases ASCII characters according to Turkic semantics" do
"i".upcase(:turkic).should == "İ"
upcased.should == "ASSET"
upcased.size.should == 5
upcased.bytesize.should == 5
upcased.ascii_only?.should be_true
end
end end
describe "ASCII-only case mapping" do it "allows Lithuanian as an extra option" do
it "does not upcase non-ASCII characters" do "i".upcase(:turkic, :lithuanian).should == "İ"
"aßet".upcase(:ascii).should == "AßET"
end
end end
describe "full Unicode case mapping adapted for Turkic languages" do it "does not allow any other additional option" do
it "upcases ASCII characters according to Turkic semantics" do lambda { "i".upcase(:turkic, :ascii) }.should raise_error(ArgumentError)
"i".upcase(:turkic).should == "İ" end
end end
it "allows Lithuanian as an extra option" do describe "full Unicode case mapping adapted for Lithuanian" do
"i".upcase(:turkic, :lithuanian).should == "İ" it "currently works the same as full Unicode case mapping" do
end "".upcase(:lithuanian).should == "ISS"
it "does not allow any other additional option" do
lambda { "i".upcase(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "full Unicode case mapping adapted for Lithuanian" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
it "currently works the same as full Unicode case mapping" do "".upcase(:lithuanian, :turkic).should == "İSS"
"".upcase(:lithuanian).should == "ISS"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do
"".upcase(:lithuanian, :turkic).should == "İSS"
end
it "does not allow any other additional option" do
lambda { "".upcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "does not allow any other additional option" do
lambda { "abc".upcase(:fold) }.should raise_error(ArgumentError) lambda { "".upcase(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end
it "does not allow invalid options" do it "does not allow the :fold option for upcasing" do
lambda { "abc".upcase(:invalid_option) }.should raise_error(ArgumentError) lambda { "abc".upcase(:fold) }.should raise_error(ArgumentError)
end end
it "does not allow invalid options" do
lambda { "abc".upcase(:invalid_option) }.should raise_error(ArgumentError)
end end
it "taints result when self is tainted" do it "taints result when self is tainted" do
@ -99,78 +83,76 @@ describe "String#upcase!" do
a.should == "HELLO" a.should == "HELLO"
end end
ruby_version_is '2.4' do describe "full Unicode case mapping" do
describe "full Unicode case mapping" do it "modifies self in place for all of Unicode with no option" do
it "modifies self in place for all of Unicode with no option" do a = "äöü"
a = "äöü" a.upcase!
a.upcase! a.should == "ÄÖÜ"
a.should == "ÄÖÜ"
end
it "updates string metadata for self" do
upcased = "aßet"
upcased.upcase!
upcased.should == "ASSET"
upcased.size.should == 5
upcased.bytesize.should == 5
upcased.ascii_only?.should be_true
end
end end
describe "modifies self in place for ASCII-only case mapping" do it "updates string metadata for self" do
it "does not upcase non-ASCII characters" do upcased = "aßet"
a = "aßet" upcased.upcase!
a.upcase!(:ascii)
a.should == "AßET" upcased.should == "ASSET"
end upcased.size.should == 5
upcased.bytesize.should == 5
upcased.ascii_only?.should be_true
end
end
describe "modifies self in place for ASCII-only case mapping" do
it "does not upcase non-ASCII characters" do
a = "aßet"
a.upcase!(:ascii)
a.should == "AßET"
end
end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do
it "upcases ASCII characters according to Turkic semantics" do
a = "i"
a.upcase!(:turkic)
a.should == "İ"
end end
describe "modifies self in place for full Unicode case mapping adapted for Turkic languages" do it "allows Lithuanian as an extra option" do
it "upcases ASCII characters according to Turkic semantics" do a = "i"
a = "i" a.upcase!(:turkic, :lithuanian)
a.upcase!(:turkic) a.should == "İ"
a.should == "İ"
end
it "allows Lithuanian as an extra option" do
a = "i"
a.upcase!(:turkic, :lithuanian)
a.should == "İ"
end
it "does not allow any other additional option" do
lambda { a = "i"; a.upcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
end
end end
describe "modifies self in place for full Unicode case mapping adapted for Lithuanian" do it "does not allow any other additional option" do
it "currently works the same as full Unicode case mapping" do lambda { a = "i"; a.upcase!(:turkic, :ascii) }.should raise_error(ArgumentError)
a = "" end
a.upcase!(:lithuanian) end
a.should == "ISS"
end
it "allows Turkic as an extra option (and applies Turkic semantics)" do describe "modifies self in place for full Unicode case mapping adapted for Lithuanian" do
a = "" it "currently works the same as full Unicode case mapping" do
a.upcase!(:lithuanian, :turkic) a = ""
a.should == "İSS" a.upcase!(:lithuanian)
end a.should == "ISS"
it "does not allow any other additional option" do
lambda { a = ""; a.upcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end
end end
it "does not allow the :fold option for upcasing" do it "allows Turkic as an extra option (and applies Turkic semantics)" do
lambda { a = "abc"; a.upcase!(:fold) }.should raise_error(ArgumentError) a = ""
a.upcase!(:lithuanian, :turkic)
a.should == "İSS"
end end
it "does not allow invalid options" do it "does not allow any other additional option" do
lambda { a = "abc"; a.upcase!(:invalid_option) }.should raise_error(ArgumentError) lambda { a = ""; a.upcase!(:lithuanian, :ascii) }.should raise_error(ArgumentError)
end end
end end
it "does not allow the :fold option for upcasing" do
lambda { a = "abc"; a.upcase!(:fold) }.should raise_error(ArgumentError)
end
it "does not allow invalid options" do
lambda { a = "abc"; a.upcase!(:invalid_option) }.should raise_error(ArgumentError)
end
it "returns nil if no modifications were made" do it "returns nil if no modifications were made" do
a = "HELLO" a = "HELLO"
a.upcase!.should == nil a.upcase!.should == nil

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