1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Drop support for ruby 2.4 from ruby/spec

This commit is contained in:
Nobuyoshi Nakada 2020-02-08 19:43:27 +09:00
parent 3a2073e61b
commit 826f44834f
Notes: git 2020-04-01 15:36:48 +09:00
145 changed files with 2343 additions and 3347 deletions

View file

@ -360,17 +360,17 @@ env:
-Wunused-variable'
- LDFLAGS=-Wno-unused-command-line-argument
- &rubyspec24
name: Check ruby/spec version guards on Ruby 2.4
- &rubyspec25
name: Check ruby/spec version guards on Ruby 2.5
language: ruby
rvm: 2.4.9
rvm: 2.5.7
before_install:
install:
before_script: chmod -R u+w spec/ruby
# -j randomly hangs.
script: ruby -C spec/ruby ../mspec/bin/mspec .
after_failure:
- echo "ruby/spec failed on Ruby 2.4. This is likely because of a missing ruby_version_is guard, please add it. See spec/README.md."
- echo "ruby/spec failed on Ruby 2.5. This is likely because of a missing ruby_version_is guard, please add it. See spec/README.md."
- &rubyspec27
name: Check ruby/spec version guards on Ruby 2.7
@ -435,7 +435,7 @@ matrix:
- <<: *pedanticism
- <<: *assertions
- <<: *baseruby
- <<: *rubyspec24
- <<: *rubyspec25
- <<: *rubyspec27
- <<: *dependency
# Build every commit (Allowed Failures):

View file

@ -38,7 +38,7 @@ specs in a manner compatible with multiple Ruby implementations.
## Requirements
MSpec requires Ruby 2.4 or more recent.
MSpec requires Ruby 2.5 or more recent.
## Bundler

View file

@ -39,8 +39,8 @@ class MSpecScript
end
def initialize
ruby_version_is ""..."2.4" do
abort "MSpec needs Ruby 2.4 or more recent"
ruby_version_is ""..."2.5" do
abort "MSpec needs Ruby 2.5 or more recent"
end
config[:formatter] = nil

View file

@ -1,20 +1,6 @@
require 'mspec/guards/version'
if RUBY_ENGINE == "ruby"
ruby_version_is "2.4"..."2.5" do
# Kernel#warn does not delegate to Warning.warn in 2.4
module Kernel
remove_method :warn
def warn(*messages)
return if $VERBOSE == nil or messages.empty?
msg = messages.join("\n")
msg += "\n" unless msg.end_with?("\n")
Warning.warn(msg)
end
private :warn
end
end
def Warning.warn(message)
# Suppress any warning inside the method to prevent recursion
verbose = $VERBOSE

View file

@ -1,7 +1,7 @@
inherit_from: .rubocop_todo.yml
AllCops:
TargetRubyVersion: 2.4
TargetRubyVersion: 2.5
DisplayCopNames: true
Exclude:
- command_line/fixtures/bad_syntax.rb

View file

@ -133,12 +133,12 @@ Here is a list of the most commonly-used guards:
#### Version guards
```ruby
ruby_version_is ""..."2.4" do
# Specs for RUBY_VERSION < 2.4
ruby_version_is ""..."2.6 do
# Specs for RUBY_VERSION < 2.6
end
ruby_version_is "2.4" do
# Specs for RUBY_VERSION >= 2.4
ruby_version_is "2.6 do
# Specs for RUBY_VERSION >= 2.6
end
```
@ -185,11 +185,11 @@ end
#### Combining guards
```ruby
guard -> { platform_is :windows and ruby_version_is ""..."2.5" } do
# Windows and RUBY_VERSION < 2.5
guard -> { platform_is :windows and ruby_version_is ""..."2.6" } do
# Windows and RUBY_VERSION < 2.6
end
guard_not -> { platform_is :windows and ruby_version_is ""..."2.5" } do
guard_not -> { platform_is :windows and ruby_version_is ""..."2.6" } do
# The opposite
end
```

View file

@ -27,8 +27,8 @@ ruby/spec is known to be tested in these implementations for every commit:
* [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby)
* [Opal](https://github.com/opal/opal/tree/master/spec)
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.4.x, 2.5.x, 2.6.x, 2.7.x, etc), and those are tested in TravisCI.
ruby/spec describes the behavior of Ruby 2.5 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.5.x, 2.6.x, 2.7.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.
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
@ -49,6 +49,8 @@ For older specs try these commits:
* 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.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea)
* Ruby 2.4.10 - [Suite](https://github.com/ruby/spec/commit/f03892a0a9cac6972e0aa6f83cb08bb8e9b5739c) using [MSpec](https://github.com/ruby/mspec/commit/18fd75a7b4853d79d8148f6a503f99733be91712)
* Ruby 2.5.8 - [Suite](https://github.com/ruby/spec/commit/f03892a0a9cac6972e0aa6f83cb08bb8e9b5739c) using [MSpec](https://github.com/ruby/mspec/commit/18fd75a7b4853d79d8148f6a503f99733be91712)
### Running the specs

View file

@ -11,12 +11,10 @@ describe "The -l command line option" do
"false\nfalse\nfalse\n"
end
ruby_version_is "2.5" do
it "chomps last line based on $/" do
ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"alice j\nbob field\njames grey\n"
end
it "chomps last line based on $/" do
ruby_exe('BEGIN { $/ = "ones\n" }; puts $_', options: "-W0 -n -l", escape: true,
args: " < #{@names}").should ==
"alice j\nbob field\njames grey\n"
end
it "sets $\\ to the value of $/" do

View file

@ -35,8 +35,6 @@ describe "Array#<<" do
end
end
ruby_version_is "2.5" do
describe "Array#append" do
it_behaves_like :array_push, :append
end
describe "Array#append" do
it_behaves_like :array_push, :append
end

View file

@ -109,20 +109,10 @@ describe "Array#flatten" do
-> { [@obj].flatten }.should raise_error(TypeError)
end
ruby_version_is ""..."2.5" do
it "calls respond_to_missing?(:to_ary, false) to try coercing" do
def @obj.respond_to_missing?(*args) ScratchPad << args; false end
[@obj].flatten.should == [@obj]
ScratchPad.recorded.should == [[:to_ary, false]]
end
end
ruby_version_is "2.5" do
it "calls respond_to_missing?(:to_ary, true) to try coercing" do
def @obj.respond_to_missing?(*args) ScratchPad << args; false end
[@obj].flatten.should == [@obj]
ScratchPad.recorded.should == [[:to_ary, true]]
end
it "calls respond_to_missing?(:to_ary, true) to try coercing" do
def @obj.respond_to_missing?(*args) ScratchPad << args; false end
[@obj].flatten.should == [@obj]
ScratchPad.recorded.should == [[:to_ary, true]]
end
it "does not call #to_ary if not defined when #respond_to_missing? returns false" do

View file

@ -2,8 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/unshift'
ruby_version_is "2.5" do
describe "Array#prepend" do
it_behaves_like :array_unshift, :prepend
end
describe "Array#prepend" do
it_behaves_like :array_unshift, :prepend
end

View file

@ -1,18 +1,16 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Binding#irb" do
it "creates an IRB session with the binding in scope" do
irb_fixture = fixture __FILE__, "irb.rb"
irbrc_fixture = fixture __FILE__, "irbrc"
describe "Binding#irb" do
it "creates an IRB session with the binding in scope" do
irb_fixture = fixture __FILE__, "irb.rb"
irbrc_fixture = fixture __FILE__, "irbrc"
out = IO.popen([{"IRBRC"=>irbrc_fixture}, *ruby_exe, irb_fixture], "r+") do |pipe|
pipe.puts "a ** 2"
pipe.puts "exit"
pipe.readlines.map(&:chomp)
end
out[-3..-1].should == ["a ** 2", "100", "exit"]
out = IO.popen([{"IRBRC"=>irbrc_fixture}, *ruby_exe, irb_fixture], "r+") do |pipe|
pipe.puts "a ** 2"
pipe.puts "exit"
pipe.readlines.map(&:chomp)
end
out[-3..-1].should == ["a ** 2", "100", "exit"]
end
end

View file

@ -7,9 +7,7 @@ describe "Data" do
end
end
ruby_version_is "2.5" do
it "is deprecated" do
-> { Data }.should complain(/constant ::Data is deprecated/)
end
it "is deprecated" do
-> { Data }.should complain(/constant ::Data is deprecated/)
end
end

View file

@ -3,71 +3,69 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'
ruby_version_is "2.5" do
describe "Dir.children" do
before :all do
DirSpecs.create_mock_dirs
describe "Dir.children" do
before :all do
DirSpecs.create_mock_dirs
end
before :each do
@internal = Encoding.default_internal
end
after :all do
DirSpecs.delete_mock_dirs
end
after :each do
Encoding.default_internal = @internal
end
it "returns an Array of filenames in an existing directory including dotfiles" do
a = Dir.children(DirSpecs.mock_dir).sort
a.should == DirSpecs.expected_paths - %w[. ..]
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested").sort
a.should == %w|.dotfile.ext directory|
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.children(p)
end
it "accepts an options Hash" do
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort
a.should == %w|.dotfile.ext directory|
end
it "returns children encoded with the filesystem encoding by default" do
# This spec depends on the locale not being US-ASCII because if it is, the
# children that are not ascii_only? will be BINARY encoded.
children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
encoding = Encoding.find("filesystem")
encoding = Encoding::BINARY if encoding == Encoding::US_ASCII
platform_is_not :windows do
children.should include("こんにちは.txt".force_encoding(encoding))
end
children.first.encoding.should equal(Encoding.find("filesystem"))
end
before :each do
@internal = Encoding.default_internal
end
it "returns children encoded with the specified encoding" do
dir = File.join(DirSpecs.mock_dir, 'special')
children = Dir.children(dir, encoding: "euc-jp").sort
children.first.encoding.should equal(Encoding::EUC_JP)
end
after :all do
DirSpecs.delete_mock_dirs
end
it "returns children transcoded to the default internal encoding" do
Encoding.default_internal = Encoding::EUC_KR
children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
children.first.encoding.should equal(Encoding::EUC_KR)
end
after :each do
Encoding.default_internal = @internal
end
it "returns an Array of filenames in an existing directory including dotfiles" do
a = Dir.children(DirSpecs.mock_dir).sort
a.should == DirSpecs.expected_paths - %w[. ..]
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested").sort
a.should == %w|.dotfile.ext directory|
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.children(p)
end
it "accepts an options Hash" do
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort
a.should == %w|.dotfile.ext directory|
end
it "returns children encoded with the filesystem encoding by default" do
# This spec depends on the locale not being US-ASCII because if it is, the
# children that are not ascii_only? will be BINARY encoded.
children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
encoding = Encoding.find("filesystem")
encoding = Encoding::BINARY if encoding == Encoding::US_ASCII
platform_is_not :windows do
children.should include("こんにちは.txt".force_encoding(encoding))
end
children.first.encoding.should equal(Encoding.find("filesystem"))
end
it "returns children encoded with the specified encoding" do
dir = File.join(DirSpecs.mock_dir, 'special')
children = Dir.children(dir, encoding: "euc-jp").sort
children.first.encoding.should equal(Encoding::EUC_JP)
end
it "returns children transcoded to the default internal encoding" do
Encoding.default_internal = Encoding::EUC_KR
children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
children.first.encoding.should equal(Encoding::EUC_KR)
end
it "raises a SystemCallError if called with a nonexistent directory" do
-> { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError)
end
it "raises a SystemCallError if called with a nonexistent directory" do
-> { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError)
end
end

View file

@ -1,51 +1,49 @@
require_relative '../../spec_helper'
require_relative 'fixtures/common'
ruby_version_is "2.5" do
describe "Dir.each_child" do
before :all do
DirSpecs.create_mock_dirs
describe "Dir.each_child" do
before :all do
DirSpecs.create_mock_dirs
end
after :all do
DirSpecs.delete_mock_dirs
end
it "yields all names in an existing directory to the provided block" do
a, b = [], []
Dir.each_child(DirSpecs.mock_dir) {|f| a << f}
Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested") {|f| b << f}
a.sort.should == DirSpecs.expected_paths - %w[. ..]
b.sort.should == %w|.dotfile.ext directory|
end
it "returns nil when successful" do
Dir.each_child(DirSpecs.mock_dir) {|f| f}.should == nil
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.each_child(p).to_a
end
it "raises a SystemCallError if passed a nonexistent directory" do
-> { Dir.each_child(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError)
end
describe "when no block is given" do
it "returns an Enumerator" do
Dir.each_child(DirSpecs.mock_dir).should be_an_instance_of(Enumerator)
Dir.each_child(DirSpecs.mock_dir).to_a.sort.should == DirSpecs.expected_paths - %w[. ..]
end
after :all do
DirSpecs.delete_mock_dirs
end
it "yields all names in an existing directory to the provided block" do
a, b = [], []
Dir.each_child(DirSpecs.mock_dir) {|f| a << f}
Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested") {|f| b << f}
a.sort.should == DirSpecs.expected_paths - %w[. ..]
b.sort.should == %w|.dotfile.ext directory|
end
it "returns nil when successful" do
Dir.each_child(DirSpecs.mock_dir) {|f| f}.should == nil
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.each_child(p).to_a
end
it "raises a SystemCallError if passed a nonexistent directory" do
-> { Dir.each_child(DirSpecs.nonexistent) {} }.should raise_error(SystemCallError)
end
describe "when no block is given" do
it "returns an Enumerator" do
Dir.each_child(DirSpecs.mock_dir).should be_an_instance_of(Enumerator)
Dir.each_child(DirSpecs.mock_dir).to_a.sort.should == DirSpecs.expected_paths - %w[. ..]
end
describe "returned Enumerator" do
describe "size" do
it "should return nil" do
Dir.each_child(DirSpecs.mock_dir).size.should == nil
end
describe "returned Enumerator" do
describe "size" do
it "should return nil" do
Dir.each_child(DirSpecs.mock_dir).size.should == nil
end
end
end

View file

@ -291,74 +291,72 @@ describe :dir_glob, shared: true do
end
end
ruby_version_is "2.5" do
context ":base option passed" do
before :each do
@mock_dir = File.expand_path tmp('dir_glob_mock')
context ":base option passed" do
before :each do
@mock_dir = File.expand_path tmp('dir_glob_mock')
%w[
%w[
a/b/x
a/b/c/y
a/b/c/d/z
].each do |path|
file = File.join @mock_dir, path
mkdir_p File.dirname(file)
touch file
end
file = File.join @mock_dir, path
mkdir_p File.dirname(file)
touch file
end
end
after :each do
rm_r @mock_dir
after :each do
rm_r @mock_dir
end
it "matches entries only from within the specified directory" do
path = File.join(@mock_dir, "a/b/c")
Dir.send(@method, "*", base: path).sort.should == %w( d y )
end
it "accepts both relative and absolute paths" do
require 'pathname'
path_abs = File.join(@mock_dir, "a/b/c")
path_rel = Pathname.new(path_abs).relative_path_from(Pathname.new(Dir.pwd))
result_abs = Dir.send(@method, "*", base: path_abs).sort
result_rel = Dir.send(@method, "*", base: path_rel).sort
result_abs.should == %w( d y )
result_rel.should == %w( d y )
end
it "returns [] if specified path does not exist" do
path = File.join(@mock_dir, "fake-name")
File.should_not.exist?(path)
Dir.send(@method, "*", base: path).should == []
end
it "returns [] if specified path is a file" do
path = File.join(@mock_dir, "a/b/x")
File.should.exist?(path)
Dir.send(@method, "*", base: path).should == []
end
it "raises TypeError when cannot convert value to string" do
-> {
Dir.send(@method, "*", base: [])
}.should raise_error(TypeError)
end
it "handles '' as current directory path" do
Dir.chdir @mock_dir do
Dir.send(@method, "*", base: "").should == %w( a )
end
end
it "matches entries only from within the specified directory" do
path = File.join(@mock_dir, "a/b/c")
Dir.send(@method, "*", base: path).sort.should == %w( d y )
end
it "accepts both relative and absolute paths" do
require 'pathname'
path_abs = File.join(@mock_dir, "a/b/c")
path_rel = Pathname.new(path_abs).relative_path_from(Pathname.new(Dir.pwd))
result_abs = Dir.send(@method, "*", base: path_abs).sort
result_rel = Dir.send(@method, "*", base: path_rel).sort
result_abs.should == %w( d y )
result_rel.should == %w( d y )
end
it "returns [] if specified path does not exist" do
path = File.join(@mock_dir, "fake-name")
File.should_not.exist?(path)
Dir.send(@method, "*", base: path).should == []
end
it "returns [] if specified path is a file" do
path = File.join(@mock_dir, "a/b/x")
File.should.exist?(path)
Dir.send(@method, "*", base: path).should == []
end
it "raises TypeError when cannot convert value to string" do
-> {
Dir.send(@method, "*", base: [])
}.should raise_error(TypeError)
end
it "handles '' as current directory path" do
Dir.chdir @mock_dir do
Dir.send(@method, "*", base: "").should == %w( a )
end
end
it "handles nil as current directory path" do
Dir.chdir @mock_dir do
Dir.send(@method, "*", base: nil).should == %w( a )
end
it "handles nil as current directory path" do
Dir.chdir @mock_dir do
Dir.send(@method, "*", base: nil).should == %w( a )
end
end
end

View file

@ -26,15 +26,6 @@ describe "Enumerable#all?" do
-> { {}.all?(1, 2, 3) }.should raise_error(ArgumentError)
end
ruby_version_is ""..."2.5" do
it "raises an ArgumentError when any arguments provided" do
-> { @enum.all?(Proc.new {}) }.should raise_error(ArgumentError)
-> { @enum.all?(nil) }.should raise_error(ArgumentError)
-> { @empty.all?(1) }.should raise_error(ArgumentError)
-> { @enum1.all?(1) {} }.should raise_error(ArgumentError)
end
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.all?
@ -133,69 +124,67 @@ describe "Enumerable#all?" do
end
end
ruby_version_is "2.5" do
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
@enum1.all?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
@enum1.all?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.all?(NilClass) { raise }.should == false
[1, 2, nil].all?(NilClass) { raise }.should == false
{a: 1}.all?(Array) { raise }.should == true
end
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.all?(NilClass) { raise }.should == false
[1, 2, nil].all?(NilClass) { raise }.should == false
{a: 1}.all?(Array) { raise }.should == true
end
end
it "always returns true on empty enumeration" do
@empty.all?(Integer).should == true
[].all?(Integer).should == true
{}.all?(NilClass).should == true
end
it "always returns true on empty enumeration" do
@empty.all?(Integer).should == true
[].all?(Integer).should == true
{}.all?(NilClass).should == true
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.all?(Integer)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.all?(Integer)
}.should raise_error(RuntimeError)
end
it "returns true if the pattern never returns false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| 42 }
@enum.all?(pattern).should == true
it "returns true if the pattern never returns false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| 42 }
@enum.all?(pattern).should == true
[1, 42, 3].all?(pattern).should == true
[1, 42, 3].all?(pattern).should == true
pattern = EnumerableSpecs::Pattern.new { |x| Array === x }
{a: 1, b: 2}.all?(pattern).should == true
end
pattern = EnumerableSpecs::Pattern.new { |x| Array === x }
{a: 1, b: 2}.all?(pattern).should == true
end
it "returns false if the pattern ever returns false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
@enum1.all?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
it "returns false if the pattern ever returns false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| x >= 0 }
@enum1.all?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
[1, 2, 3, -1].all?(pattern).should == false
[1, 2, 3, -1].all?(pattern).should == false
pattern = EnumerableSpecs::Pattern.new { |x| x[1] >= 0 }
{a: 1, b: -1}.all?(pattern).should == false
end
pattern = EnumerableSpecs::Pattern.new { |x| x[1] >= 0 }
{a: 1, b: -1}.all?(pattern).should == false
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.all?(pattern)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.all?(pattern)
}.should raise_error(RuntimeError)
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { true }
multi.all?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { true }
multi.all?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end

View file

@ -26,15 +26,6 @@ describe "Enumerable#any?" do
-> { {}.any?(1, 2, 3) }.should raise_error(ArgumentError)
end
ruby_version_is ""..."2.5" do
it "raises an ArgumentError when any arguments provided" do
-> { @enum.any?(Proc.new {}) }.should raise_error(ArgumentError)
-> { @enum.any?(nil) }.should raise_error(ArgumentError)
-> { @empty.any?(1) }.should raise_error(ArgumentError)
-> { @enum1.any?(1) {} }.should raise_error(ArgumentError)
end
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.any?
@ -147,68 +138,66 @@ describe "Enumerable#any?" do
end
end
ruby_version_is "2.5" do
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
@enum1.any?(pattern).should == true
pattern.yielded.should == [[0], [1], [2]]
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
@enum1.any?(pattern).should == true
pattern.yielded.should == [[0], [1], [2]]
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.any?(NilClass) { raise }.should == true
[1, 2, nil].any?(NilClass) { raise }.should == true
{a: 1}.any?(Array) { raise }.should == true
end
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.any?(NilClass) { raise }.should == true
[1, 2, nil].any?(NilClass) { raise }.should == true
{a: 1}.any?(Array) { raise }.should == true
end
end
it "always returns false on empty enumeration" do
@empty.any?(Integer).should == false
[].any?(Integer).should == false
{}.any?(NilClass).should == false
end
it "always returns false on empty enumeration" do
@empty.any?(Integer).should == false
[].any?(Integer).should == false
{}.any?(NilClass).should == false
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.any?(Integer)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.any?(Integer)
}.should raise_error(RuntimeError)
end
it "returns true if the pattern ever returns a truthy value" do
@enum2.any?(NilClass).should == true
pattern = EnumerableSpecs::Pattern.new { |x| 42 }
@enum.any?(pattern).should == true
it "returns true if the pattern ever returns a truthy value" do
@enum2.any?(NilClass).should == true
pattern = EnumerableSpecs::Pattern.new { |x| 42 }
@enum.any?(pattern).should == true
[1, 42, 3].any?(pattern).should == true
[1, 42, 3].any?(pattern).should == true
pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
{a: 1, b: 2}.any?(pattern).should == true
end
pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
{a: 1, b: 2}.any?(pattern).should == true
end
it "returns false if the block never returns other than false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum1.any?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
it "returns false if the block never returns other than false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum1.any?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
[1, 2, 3].any?(pattern).should == false
{a: 1}.any?(pattern).should == false
end
[1, 2, 3].any?(pattern).should == false
{a: 1}.any?(pattern).should == false
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.any?(pattern)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.any?(pattern)
}.should raise_error(RuntimeError)
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.any?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.any?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end

View file

@ -20,15 +20,6 @@ describe "Enumerable#none?" do
-> { {}.none?(1, 2, 3) }.should raise_error(ArgumentError)
end
ruby_version_is ""..."2.5" do
it "raises an ArgumentError when any arguments provided" do
-> { @enum.none?(Proc.new {}) }.should raise_error(ArgumentError)
-> { @enum.none?(nil) }.should raise_error(ArgumentError)
-> { @empty.none?(1) }.should raise_error(ArgumentError)
-> { @enum.none?(1) {} }.should raise_error(ArgumentError)
end
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.none?
@ -102,66 +93,64 @@ describe "Enumerable#none?" do
end
end
ruby_version_is "2.5" do
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 3 }
@enum1.none?(pattern).should == true
pattern.yielded.should == [[0], [1], [2], [-1]]
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 3 }
@enum1.none?(pattern).should == true
pattern.yielded.should == [[0], [1], [2], [-1]]
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.none?(Integer) { raise }.should == true
[1, 2, nil].none?(TrueClass) { raise }.should == true
{a: 1}.none?(Hash) { raise }.should == true
end
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.none?(Integer) { raise }.should == true
[1, 2, nil].none?(TrueClass) { raise }.should == true
{a: 1}.none?(Hash) { raise }.should == true
end
end
it "always returns true on empty enumeration" do
@empty.none?(Integer).should == true
[].none?(Integer).should == true
{}.none?(NilClass).should == true
end
it "always returns true on empty enumeration" do
@empty.none?(Integer).should == true
[].none?(Integer).should == true
{}.none?(NilClass).should == true
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.none?(Integer)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.none?(Integer)
}.should raise_error(RuntimeError)
end
it "returns true if the pattern never returns a truthy value" do
@enum2.none?(Integer).should == true
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum.none?(pattern).should == true
it "returns true if the pattern never returns a truthy value" do
@enum2.none?(Integer).should == true
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum.none?(pattern).should == true
[1, 42, 3].none?(pattern).should == true
{a: 1, b: 2}.none?(pattern).should == true
end
[1, 42, 3].none?(pattern).should == true
{a: 1, b: 2}.none?(pattern).should == true
end
it "returns false if the pattern ever returns other than false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| x < 0 }
@enum1.none?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
it "returns false if the pattern ever returns other than false or nil" do
pattern = EnumerableSpecs::Pattern.new { |x| x < 0 }
@enum1.none?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
[1, 2, 3, -1].none?(pattern).should == false
{a: 1}.none?(Array).should == false
end
[1, 2, 3, -1].none?(pattern).should == false
{a: 1}.none?(Array).should == false
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.none?(pattern)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.none?(pattern)
}.should raise_error(RuntimeError)
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.none?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.none?(pattern).should == true
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end

View file

@ -20,15 +20,6 @@ describe "Enumerable#one?" do
-> { {}.one?(1, 2, 3) }.should raise_error(ArgumentError)
end
ruby_version_is ""..."2.5" do
it "raises an ArgumentError when any arguments provided" do
-> { @enum.one?(Proc.new {}) }.should raise_error(ArgumentError)
-> { @enum.one?(nil) }.should raise_error(ArgumentError)
-> { @empty.one?(1) }.should raise_error(ArgumentError)
-> { @enum.one?(1) {} }.should raise_error(ArgumentError)
end
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.one?
@ -93,77 +84,75 @@ describe "Enumerable#one?" do
end
ruby_version_is "2.5" do
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 1 }
@enum1.one?(pattern).should == true
pattern.yielded.should == [[0], [1], [2], [-1]]
describe 'when given a pattern argument' do
it "calls `===` on the pattern the return value " do
pattern = EnumerableSpecs::Pattern.new { |x| x == 1 }
@enum1.one?(pattern).should == true
pattern.yielded.should == [[0], [1], [2], [-1]]
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.one?(NilClass) { raise }.should == true
[1, 2, nil].one?(NilClass) { raise }.should == true
{a: 1}.one?(Array) { raise }.should == true
end
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.one?(NilClass) { raise }.should == true
[1, 2, nil].one?(NilClass) { raise }.should == true
{a: 1}.one?(Array) { raise }.should == true
end
end
it "always returns false on empty enumeration" do
@empty.one?(Integer).should == false
[].one?(Integer).should == false
{}.one?(NilClass).should == false
end
it "always returns false on empty enumeration" do
@empty.one?(Integer).should == false
[].one?(Integer).should == false
{}.one?(NilClass).should == false
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.one?(Integer)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of #each" do
-> {
EnumerableSpecs::ThrowingEach.new.one?(Integer)
}.should raise_error(RuntimeError)
end
it "returns true if the pattern returns a truthy value only once" do
@enum2.one?(NilClass).should == true
pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
@enum1.one?(pattern).should == true
it "returns true if the pattern returns a truthy value only once" do
@enum2.one?(NilClass).should == true
pattern = EnumerableSpecs::Pattern.new { |x| x == 2 }
@enum1.one?(pattern).should == true
[1, 2, 42, 3].one?(pattern).should == true
[1, 2, 42, 3].one?(pattern).should == true
pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
{a: 1, b: 2}.one?(pattern).should == true
end
pattern = EnumerableSpecs::Pattern.new { |x| x == [:b, 2] }
{a: 1, b: 2}.one?(pattern).should == true
end
it "returns false if the pattern returns a truthy value more than once" do
pattern = EnumerableSpecs::Pattern.new { |x| !x }
@enum2.one?(pattern).should == false
pattern.yielded.should == [[nil], [false]]
it "returns false if the pattern returns a truthy value more than once" do
pattern = EnumerableSpecs::Pattern.new { |x| !x }
@enum2.one?(pattern).should == false
pattern.yielded.should == [[nil], [false]]
[1, 2, 3].one?(Integer).should == false
{a: 1, b: 2}.one?(Array).should == false
end
[1, 2, 3].one?(Integer).should == false
{a: 1, b: 2}.one?(Array).should == false
end
it "returns false if the pattern never returns a truthy value" do
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum1.one?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
it "returns false if the pattern never returns a truthy value" do
pattern = EnumerableSpecs::Pattern.new { |x| nil }
@enum1.one?(pattern).should == false
pattern.yielded.should == [[0], [1], [2], [-1]]
[1, 2, 3].one?(pattern).should == false
{a: 1}.one?(pattern).should == false
end
[1, 2, 3].one?(pattern).should == false
{a: 1}.one?(pattern).should == false
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.one?(pattern)
}.should raise_error(RuntimeError)
end
it "does not hide exceptions out of pattern#===" do
pattern = EnumerableSpecs::Pattern.new { raise "from pattern" }
-> {
@enum.one?(pattern)
}.should raise_error(RuntimeError)
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.one?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
it "calls the pattern with gathered array when yielded with multiple arguments" do
multi = EnumerableSpecs::YieldsMulti.new
pattern = EnumerableSpecs::Pattern.new { false }
multi.one?(pattern).should == false
pattern.yielded.should == [[[1, 2]], [[3, 4, 5]], [[6, 7, 8, 9]]]
end
end
end

View file

@ -1,94 +1,92 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Exception#full_message" do
it "returns formatted string of exception using the same format that is used to print an uncaught exceptions to stderr" do
describe "Exception#full_message" do
it "returns formatted string of exception using the same format that is used to print an uncaught exceptions to stderr" do
e = RuntimeError.new("Some runtime error")
e.set_backtrace(["a.rb:1", "b.rb:2"])
full_message = e.full_message
full_message.should include "RuntimeError"
full_message.should include "Some runtime error"
full_message.should include "a.rb:1"
full_message.should include "b.rb:2"
end
ruby_version_is "2.5.1" do
it "supports :highlight option and adds escape sequences to highlight some strings" do
e = RuntimeError.new("Some runtime error")
full_message = e.full_message(highlight: true, order: :bottom)
full_message.should include "\e[1mTraceback\e[m (most recent call last)"
full_message.should include "\e[1mSome runtime error (\e[1;4mRuntimeError\e[m\e[1m)"
full_message = e.full_message(highlight: false, order: :bottom)
full_message.should include "Traceback (most recent call last)"
full_message.should include "Some runtime error (RuntimeError)"
end
it "supports :order option and places the error message and the backtrace at the top or the bottom" do
e = RuntimeError.new("Some runtime error")
e.set_backtrace(["a.rb:1", "b.rb:2"])
full_message = e.full_message
full_message.should include "RuntimeError"
full_message.should include "Some runtime error"
full_message.should include "a.rb:1"
full_message.should include "b.rb:2"
e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m
e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m
end
ruby_version_is "2.5.1" do
it "supports :highlight option and adds escape sequences to highlight some strings" do
e = RuntimeError.new("Some runtime error")
full_message = e.full_message(highlight: true, order: :bottom)
full_message.should include "\e[1mTraceback\e[m (most recent call last)"
full_message.should include "\e[1mSome runtime error (\e[1;4mRuntimeError\e[m\e[1m)"
full_message = e.full_message(highlight: false, order: :bottom)
full_message.should include "Traceback (most recent call last)"
full_message.should include "Some runtime error (RuntimeError)"
end
it "supports :order option and places the error message and the backtrace at the top or the bottom" do
e = RuntimeError.new("Some runtime error")
e.set_backtrace(["a.rb:1", "b.rb:2"])
e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m
e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m
end
it "shows the caller if the exception has no backtrace" do
e = RuntimeError.new("Some runtime error")
e.backtrace.should == nil
full_message = e.full_message(highlight: false, order: :top)
full_message.should include("#{__FILE__}:#{__LINE__-1}:in `")
full_message.should include("': Some runtime error (RuntimeError)\n")
end
it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
begin
line = __LINE__; raise "first line\nsecond line"
rescue => e
full_message = e.full_message(highlight: false, order: :top).lines
full_message[0].should include("#{__FILE__}:#{line}:in `")
full_message[0].should include(": first line (RuntimeError)\n")
full_message[1].should == "second line\n"
end
end
it "shows the caller if the exception has no backtrace" do
e = RuntimeError.new("Some runtime error")
e.backtrace.should == nil
full_message = e.full_message(highlight: false, order: :top)
full_message.should include("#{__FILE__}:#{__LINE__-1}:in `")
full_message.should include("': Some runtime error (RuntimeError)\n")
end
ruby_version_is "2.6" do
it "contains cause of exception" do
begin
begin
raise 'the cause'
rescue
raise 'main exception'
end
rescue => e
exception = e
end
exception.full_message.should include "main exception"
exception.full_message.should include "the cause"
end
it 'contains all the chain of exceptions' do
begin
begin
begin
raise 'origin exception'
rescue
raise 'intermediate exception'
end
rescue
raise 'last exception'
end
rescue => e
exception = e
end
exception.full_message.should include "last exception"
exception.full_message.should include "intermediate exception"
exception.full_message.should include "origin exception"
it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
begin
line = __LINE__; raise "first line\nsecond line"
rescue => e
full_message = e.full_message(highlight: false, order: :top).lines
full_message[0].should include("#{__FILE__}:#{line}:in `")
full_message[0].should include(": first line (RuntimeError)\n")
full_message[1].should == "second line\n"
end
end
end
ruby_version_is "2.6" do
it "contains cause of exception" do
begin
begin
raise 'the cause'
rescue
raise 'main exception'
end
rescue => e
exception = e
end
exception.full_message.should include "main exception"
exception.full_message.should include "the cause"
end
it 'contains all the chain of exceptions' do
begin
begin
begin
raise 'origin exception'
rescue
raise 'intermediate exception'
end
rescue
raise 'last exception'
end
rescue => e
exception = e
end
exception.full_message.should include "last exception"
exception.full_message.should include "intermediate exception"
exception.full_message.should include "origin exception"
end
end
end

View file

@ -37,7 +37,9 @@ describe "Exception" do
FloatDomainError => nil,
},
RegexpError => nil,
RuntimeError => nil,
RuntimeError => {
FrozenError => nil,
},
SystemCallError => nil,
ThreadError => nil,
TypeError => nil,
@ -47,9 +49,7 @@ describe "Exception" do
SystemStackError => nil,
},
}
ruby_version_is "2.5" do
hierarchy[Exception][StandardError][RuntimeError] = {FrozenError => nil}
end
traverse = -> parent_class, parent_subclass_hash {
parent_subclass_hash.each do |child_class, child_subclass_hash|
child_class.class.should == Class

View file

@ -15,7 +15,7 @@ describe "File.atime" do
File.atime(@file).should be_kind_of(Time)
end
guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do
guard -> { platform_is :linux or platform_is :windows } do
## NOTE also that some Linux systems disable atime (e.g. via mount params) for better filesystem speed.
it "returns the last access time for the named file with microseconds" do
supports_subseconds = Integer(`stat -c%x '#{__FILE__}'`[/\.(\d+)/, 1], 10)

View file

@ -14,7 +14,7 @@ describe "File.ctime" do
File.ctime(@file).should be_kind_of(Time)
end
guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do
guard -> { platform_is :linux or platform_is :windows } do
it "returns the change time for the named file (the time at which directory information about the file was changed, not the file itself) with microseconds." do
supports_subseconds = Integer(`stat -c%z '#{__FILE__}'`[/\.(\d+)/, 1], 10)
if supports_subseconds != 0

View file

@ -1,40 +1,38 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "File.lutime" do
platform_is_not :windows do
before :each do
@atime = Time.utc(2000)
@mtime = Time.utc(2001)
@file = tmp("specs_lutime_file")
@symlink = tmp("specs_lutime_symlink")
touch @file
File.symlink(@file, @symlink)
end
describe "File.lutime" do
platform_is_not :windows do
before :each do
@atime = Time.utc(2000)
@mtime = Time.utc(2001)
@file = tmp("specs_lutime_file")
@symlink = tmp("specs_lutime_symlink")
touch @file
File.symlink(@file, @symlink)
end
after :each do
rm_r @file, @symlink
end
after :each do
rm_r @file, @symlink
end
it "sets the access and modification time for a regular file" do
File.lutime(@atime, @mtime, @file)
stat = File.stat(@file)
stat.atime.should == @atime
stat.mtime.should === @mtime
end
it "sets the access and modification time for a regular file" do
File.lutime(@atime, @mtime, @file)
stat = File.stat(@file)
stat.atime.should == @atime
stat.mtime.should === @mtime
end
it "sets the access and modification time for a symlink" do
original = File.stat(@file)
it "sets the access and modification time for a symlink" do
original = File.stat(@file)
File.lutime(@atime, @mtime, @symlink)
stat = File.lstat(@symlink)
stat.atime.should == @atime
stat.mtime.should === @mtime
File.lutime(@atime, @mtime, @symlink)
stat = File.lstat(@symlink)
stat.atime.should == @atime
stat.mtime.should === @mtime
file = File.stat(@file)
file.atime.should == original.atime
file.mtime.should == original.mtime
end
file = File.stat(@file)
file.atime.should == original.atime
file.mtime.should == original.mtime
end
end
end

View file

@ -15,7 +15,7 @@ describe "File.mtime" do
File.mtime(@filename).should be_close(@mtime, TIME_TOLERANCE)
end
guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do
guard -> { platform_is :linux or platform_is :windows } do
it "returns the modification Time of the file with microseconds" do
supports_subseconds = Integer(`stat -c%y '#{__FILE__}'`[/\.(\d+)/, 1], 10)
if supports_subseconds != 0

View file

@ -623,12 +623,10 @@ describe "File.open" do
end
end
ruby_version_is "2.5" do
it "raises ArgumentError if mixing :newline and binary mode" do
-> {
File.open(@file, "rb", newline: :universal) {}
}.should raise_error(ArgumentError, "newline decorator with binary mode")
end
it "raises ArgumentError if mixing :newline and binary mode" do
-> {
File.open(@file, "rb", newline: :universal) {}
}.should raise_error(ArgumentError, "newline decorator with binary mode")
end
ruby_version_is "2.6" do

View file

@ -50,26 +50,24 @@ describe :file_path, shared: true do
@file.send(@method).encoding.should == Encoding.find("euc-jp")
end
ruby_version_is "2.5" do
platform_is :linux do
guard -> { defined?(File::TMPFILE) } do
before :each do
@dir = tmp("tmpfilespec")
mkdir_p @dir
end
platform_is :linux do
guard -> { defined?(File::TMPFILE) } do
before :each do
@dir = tmp("tmpfilespec")
mkdir_p @dir
end
after :each do
rm_r @dir
end
after :each do
rm_r @dir
end
it "raises IOError if file was opened with File::TMPFILE" do
begin
File.open(@dir, File::RDWR | File::TMPFILE) do |f|
-> { f.send(@method) }.should raise_error(IOError)
end
rescue Errno::EOPNOTSUPP, Errno::EINVAL, Errno::EISDIR
skip "no support from the filesystem"
it "raises IOError if file was opened with File::TMPFILE" do
begin
File.open(@dir, File::RDWR | File::TMPFILE) do |f|
-> { f.send(@method) }.should raise_error(IOError)
end
rescue Errno::EOPNOTSUPP, Errno::EINVAL, Errno::EISDIR
skip "no support from the filesystem"
end
end
end

View file

@ -33,19 +33,17 @@ describe "Float#<=>" do
coercible.call_count.should == 3
end
ruby_version_is "2.5" do
it "raises TypeError when #coerce misbehaves" do
klass = Class.new do
def coerce(other)
:incorrect
end
it "raises TypeError when #coerce misbehaves" do
klass = Class.new do
def coerce(other)
:incorrect
end
bad_coercible = klass.new
-> {
4.2 <=> bad_coercible
}.should raise_error(TypeError, "coerce must return [x, y]")
end
bad_coercible = klass.new
-> {
4.2 <=> bad_coercible
}.should raise_error(TypeError, "coerce must return [x, y]")
end
# The 4 tests below are taken from matz's revision 23730 for Ruby trunk

View file

@ -1,33 +1,11 @@
require_relative '../fixtures/classes'
describe :float_arithmetic_exception_in_coerce, shared: true do
ruby_version_is ""..."2.5" do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises TypeError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(TypeError, /MockObject can't be coerced into Float/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(exception)
end
end
end
ruby_version_is "2.5" do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(FloatSpecs::CoerceError)
end
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(FloatSpecs::CoerceError)
end
end

View file

@ -1,35 +1,11 @@
require_relative '../fixtures/classes'
describe :float_comparison_exception_in_coerce, shared: true do
ruby_version_is ""..."2.5" do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises ArgumentError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
# e.g. 1.0 > b
-> {
-> { 1.0.send(@method, b) }.should raise_error(ArgumentError, /comparison of Float with MockObject failed/)
}.should complain(/Numerical comparison operators will no more rescue exceptions of #coerce/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(exception)
end
end
end
ruby_version_is "2.5" do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(FloatSpecs::CoerceError)
end
# e.g. 1.0 > b
-> { 1.0.send(@method, b) }.should raise_error(FloatSpecs::CoerceError)
end
end

View file

@ -1,55 +1,53 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Hash#slice" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
describe "Hash#slice" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
it "returns a new empty hash without arguments" do
ret = @hash.slice
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
ret.should == {}
end
it "returns a new empty hash without arguments" do
ret = @hash.slice
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
ret.should == {}
end
it "returns the requested subset" do
@hash.slice(:c, :a).should == { c: 3, a: 1 }
end
it "returns the requested subset" do
@hash.slice(:c, :a).should == { c: 3, a: 1 }
end
it "returns a hash ordered in the order of the requested keys" do
@hash.slice(:c, :a).keys.should == [:c, :a]
end
it "returns a hash ordered in the order of the requested keys" do
@hash.slice(:c, :a).keys.should == [:c, :a]
end
it "returns only the keys of the original hash" do
@hash.slice(:a, :chunky_bacon).should == { a: 1 }
end
it "returns only the keys of the original hash" do
@hash.slice(:a, :chunky_bacon).should == { a: 1 }
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:bar] = 12
h[:foo] = 42
r = h.slice(:foo)
r.should == {foo: 42}
r.class.should == Hash
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:bar] = 12
h[:foo] = 42
r = h.slice(:foo)
r.should == {foo: 42}
r.class.should == Hash
end
it "uses the regular Hash#[] method, even on subclasses that override it" do
ScratchPad.record []
klass = Class.new(Hash) do
def [](value)
ScratchPad << :used_subclassed_operator
super
end
it "uses the regular Hash#[] method, even on subclasses that override it" do
ScratchPad.record []
klass = Class.new(Hash) do
def [](value)
ScratchPad << :used_subclassed_operator
super
end
h = klass.new
h[:bar] = 12
h[:foo] = 42
h.slice(:foo)
ScratchPad.recorded.should == []
end
h = klass.new
h[:bar] = 12
h[:foo] = 42
h.slice(:foo)
ScratchPad.recorded.should == []
end
end

View file

@ -1,131 +1,129 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Hash#transform_keys" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
describe "Hash#transform_keys" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
it "returns new hash" do
ret = @hash.transform_keys(&:succ)
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
end
it "returns new hash" do
ret = @hash.transform_keys(&:succ)
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
end
it "sets the result as transformed keys with the given block" do
@hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 }
end
it "sets the result as transformed keys with the given block" do
@hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 }
end
it "keeps last pair if new keys conflict" do
@hash.transform_keys { |_| :a }.should == { a: 3 }
end
it "keeps last pair if new keys conflict" do
@hash.transform_keys { |_| :a }.should == { a: 3 }
end
it "makes both hashes to share values" do
value = [1, 2, 3]
new_hash = { a: value }.transform_keys(&:upcase)
new_hash[:A].should equal(value)
end
it "makes both hashes to share values" do
value = [1, 2, 3]
new_hash = { a: value }.transform_keys(&:upcase)
new_hash[:A].should equal(value)
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:succ).should == { b: 1, c: 2, d: 3 }
end
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:foo] = 42
r = h.transform_keys{|v| :"x#{v}"}
r.keys.should == [:xfoo]
r.class.should == Hash
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:succ).should == { b: 1, c: 2, d: 3 }
end
end
describe "Hash#transform_keys!" do
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:foo] = 42
r = h.transform_keys{|v| :"x#{v}"}
r.keys.should == [:xfoo]
r.class.should == Hash
end
end
describe "Hash#transform_keys!" do
before :each do
@hash = { a: 1, b: 2, c: 3, d: 4 }
@initial_pairs = @hash.dup
end
it "returns self" do
@hash.transform_keys!(&:succ).should equal(@hash)
end
it "updates self as transformed values with the given block" do
@hash.transform_keys!(&:to_s)
@hash.should == { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 }
end
# https://bugs.ruby-lang.org/issues/14380
ruby_version_is ""..."2.5.1" do
it "does not prevent conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { e: 1 }
end
end
ruby_version_is "2.5.1" do
it "prevents conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { b: 1, c: 2, d: 3, e: 4 }
end
end
ruby_version_is ""..."2.5.1" do
it "partially modifies the contents if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
end
@hash.should == { c: 1, d: 4 }
end
end
ruby_version_is "2.5.1" do
it "returns the processed keys if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
end
@hash.should == { b: 1, c: 2 }
end
end
it "keeps later pair if new keys conflict" do
@hash.transform_keys! { |_| :a }.should == { a: 4 }
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys!
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:upcase).should == { A: 1, B: 2, C: 3, D: 4 }
end
end
describe "on frozen instance" do
before :each do
@hash = { a: 1, b: 2, c: 3, d: 4 }
@initial_pairs = @hash.dup
@hash.freeze
end
it "returns self" do
@hash.transform_keys!(&:succ).should equal(@hash)
it "raises a FrozenError on an empty hash" do
->{ {}.freeze.transform_keys!(&:upcase) }.should raise_error(FrozenError)
end
it "updates self as transformed values with the given block" do
@hash.transform_keys!(&:to_s)
@hash.should == { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 }
end
# https://bugs.ruby-lang.org/issues/14380
ruby_version_is ""..."2.5.1" do
it "does not prevent conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { e: 1 }
end
end
ruby_version_is "2.5.1" do
it "prevents conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { b: 1, c: 2, d: 3, e: 4 }
end
end
ruby_version_is ""..."2.5.1" do
it "partially modifies the contents if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
end
@hash.should == { c: 1, d: 4 }
end
end
ruby_version_is "2.5.1" do
it "returns the processed keys if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
end
@hash.should == { b: 1, c: 2 }
end
end
it "keeps later pair if new keys conflict" do
@hash.transform_keys! { |_| :a }.should == { a: 4 }
it "keeps pairs and raises a FrozenError" do
->{ @hash.transform_keys!(&:upcase) }.should raise_error(FrozenError)
@hash.should == @initial_pairs
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys!
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:upcase).should == { A: 1, B: 2, C: 3, D: 4 }
end
end
describe "on frozen instance" do
before :each do
@hash.freeze
end
it "raises a FrozenError on an empty hash" do
->{ {}.freeze.transform_keys!(&:upcase) }.should raise_error(FrozenError)
end
it "keeps pairs and raises a FrozenError" do
->{ @hash.transform_keys!(&:upcase) }.should raise_error(FrozenError)
@hash.should == @initial_pairs
end
context "when no block is given" do
it "does not raise an exception" do
@hash.transform_keys!.should be_an_instance_of(Enumerator)
end
it "does not raise an exception" do
@hash.transform_keys!.should be_an_instance_of(Enumerator)
end
end
end

View file

@ -1,39 +1,37 @@
require_relative '../../spec_helper'
ruby_version_is '2.5' do
describe "Integer#allbits?" do
it "returns true iff all the bits of the argument are set in the receiver" do
42.allbits?(42).should == true
0b1010_1010.allbits?(0b1000_0010).should == true
0b1010_1010.allbits?(0b1000_0001).should == false
0b1000_0010.allbits?(0b1010_1010).should == false
(0b1010_1010 | bignum_value).allbits?(0b1000_0010 | bignum_value).should == true
(0b1010_1010 | bignum_value).allbits?(0b1000_0001 | bignum_value).should == false
(0b1000_0010 | bignum_value).allbits?(0b1010_1010 | bignum_value).should == false
end
describe "Integer#allbits?" do
it "returns true iff all the bits of the argument are set in the receiver" do
42.allbits?(42).should == true
0b1010_1010.allbits?(0b1000_0010).should == true
0b1010_1010.allbits?(0b1000_0001).should == false
0b1000_0010.allbits?(0b1010_1010).should == false
(0b1010_1010 | bignum_value).allbits?(0b1000_0010 | bignum_value).should == true
(0b1010_1010 | bignum_value).allbits?(0b1000_0001 | bignum_value).should == false
(0b1000_0010 | bignum_value).allbits?(0b1010_1010 | bignum_value).should == false
end
it "handles negative values using two's complement notation" do
(~0b1).allbits?(42).should == true
(-42).allbits?(-42).should == true
(~0b1010_1010).allbits?(~0b1110_1011).should == true
(~0b1010_1010).allbits?(~0b1000_0010).should == false
(~(0b1010_1010 | bignum_value)).allbits?(~(0b1110_1011 | bignum_value)).should == true
(~(0b1010_1010 | bignum_value)).allbits?(~(0b1000_0010 | bignum_value)).should == false
end
it "handles negative values using two's complement notation" do
(~0b1).allbits?(42).should == true
(-42).allbits?(-42).should == true
(~0b1010_1010).allbits?(~0b1110_1011).should == true
(~0b1010_1010).allbits?(~0b1000_0010).should == false
(~(0b1010_1010 | bignum_value)).allbits?(~(0b1110_1011 | bignum_value)).should == true
(~(0b1010_1010 | bignum_value)).allbits?(~(0b1000_0010 | bignum_value)).should == false
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.allbits?(obj).should == true
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.allbits?(obj).should == true
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.allbits?(obj)
}.should raise_error(TypeError)
-> { 13.allbits?("10") }.should raise_error(TypeError)
-> { 13.allbits?(:symbol) }.should raise_error(TypeError)
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.allbits?(obj)
}.should raise_error(TypeError)
-> { 13.allbits?("10") }.should raise_error(TypeError)
-> { 13.allbits?(:symbol) }.should raise_error(TypeError)
end
end

View file

@ -1,38 +1,36 @@
require_relative '../../spec_helper'
ruby_version_is '2.5' do
describe "Integer#anybits?" do
it "returns true iff all the bits of the argument are set in the receiver" do
42.anybits?(42).should == true
0b1010_1010.anybits?(0b1000_0010).should == true
0b1010_1010.anybits?(0b1000_0001).should == true
0b1000_0010.anybits?(0b0010_1100).should == false
different_bignum = (2 * bignum_value) & (~bignum_value)
(0b1010_1010 | different_bignum).anybits?(0b1000_0010 | bignum_value).should == true
(0b1010_1010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == true
(0b1000_0010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == false
end
describe "Integer#anybits?" do
it "returns true iff all the bits of the argument are set in the receiver" do
42.anybits?(42).should == true
0b1010_1010.anybits?(0b1000_0010).should == true
0b1010_1010.anybits?(0b1000_0001).should == true
0b1000_0010.anybits?(0b0010_1100).should == false
different_bignum = (2 * bignum_value) & (~bignum_value)
(0b1010_1010 | different_bignum).anybits?(0b1000_0010 | bignum_value).should == true
(0b1010_1010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == true
(0b1000_0010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == false
end
it "handles negative values using two's complement notation" do
(~42).anybits?(42).should == false
(-42).anybits?(-42).should == true
(~0b100).anybits?(~0b1).should == true
(~(0b100 | bignum_value)).anybits?(~(0b1 | bignum_value)).should == true
end
it "handles negative values using two's complement notation" do
(~42).anybits?(42).should == false
(-42).anybits?(-42).should == true
(~0b100).anybits?(~0b1).should == true
(~(0b100 | bignum_value)).anybits?(~(0b1 | bignum_value)).should == true
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.anybits?(obj).should == true
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.anybits?(obj).should == true
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.anybits?(obj)
}.should raise_error(TypeError)
-> { 13.anybits?("10") }.should raise_error(TypeError)
-> { 13.anybits?(:symbol) }.should raise_error(TypeError)
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.anybits?(obj)
}.should raise_error(TypeError)
-> { 13.anybits?("10") }.should raise_error(TypeError)
-> { 13.anybits?(:symbol) }.should raise_error(TypeError)
end
end

View file

@ -124,23 +124,11 @@ describe "Integer#<=>" do
@big <=> @num
end
ruby_version_is ""..."2.5" do
it "returns nil if #coerce raises an exception" do
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError)
-> {
@result = (@big <=> @num)
}.should complain(/Numerical comparison operators will no more rescue exceptions/)
@result.should be_nil
end
end
ruby_version_is "2.5" do
it "lets the exception go through if #coerce raises an exception" do
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error"))
-> {
@big <=> @num
}.should raise_error(RuntimeError, "my error")
end
it "lets the exception go through if #coerce raises an exception" do
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error"))
-> {
@big <=> @num
}.should raise_error(RuntimeError, "my error")
end
it "raises an exception if #coerce raises a non-StandardError exception" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/arithmetic_coerce'
describe "Integer#/" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :/
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :/
end
it_behaves_like :integer_arithmetic_coerce_not_rescue, :/
context "fixnum" do
it "returns self divided by the given argument" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/comparison_coerce'
describe "Integer#>" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :>
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>
end
it_behaves_like :integer_comparison_coerce_not_rescue, :>
context "fixnum" do
it "returns true if self is greater than the given argument" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/comparison_coerce'
describe "Integer#>=" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :>=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>=
end
it_behaves_like :integer_comparison_coerce_not_rescue, :>=
context "fixnum" do
it "returns true if self is greater than or equal to the given argument" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/comparison_coerce'
describe "Integer#<" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :<
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<
end
it_behaves_like :integer_comparison_coerce_not_rescue, :<
context "fixnum" do
it "returns true if self is less than the given argument" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/comparison_coerce'
describe "Integer#<=" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :<=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<=
end
it_behaves_like :integer_comparison_coerce_not_rescue, :<=
context "fixnum" do
it "returns true if self is less than or equal to other" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/arithmetic_coerce'
describe "Integer#-" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :-
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :-
end
it_behaves_like :integer_arithmetic_coerce_not_rescue, :-
context "fixnum" do
it "returns self minus the given Integer" do

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/arithmetic_coerce'
describe "Integer#*" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :*
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :*
end
it_behaves_like :integer_arithmetic_coerce_not_rescue, :*
context "fixnum" do
it "returns self multiplied by the given Integer" do

View file

@ -1,38 +1,36 @@
require_relative '../../spec_helper'
ruby_version_is '2.5' do
describe "Integer#nobits?" do
it "returns true iff all no bits of the argument are set in the receiver" do
42.nobits?(42).should == false
0b1010_1010.nobits?(0b1000_0010).should == false
0b1010_1010.nobits?(0b1000_0001).should == false
0b0100_0101.nobits?(0b1010_1010).should == true
different_bignum = (2 * bignum_value) & (~bignum_value)
(0b1010_1010 | different_bignum).nobits?(0b1000_0010 | bignum_value).should == false
(0b1010_1010 | different_bignum).nobits?(0b1000_0001 | bignum_value).should == false
(0b0100_0101 | different_bignum).nobits?(0b1010_1010 | bignum_value).should == true
end
describe "Integer#nobits?" do
it "returns true iff all no bits of the argument are set in the receiver" do
42.nobits?(42).should == false
0b1010_1010.nobits?(0b1000_0010).should == false
0b1010_1010.nobits?(0b1000_0001).should == false
0b0100_0101.nobits?(0b1010_1010).should == true
different_bignum = (2 * bignum_value) & (~bignum_value)
(0b1010_1010 | different_bignum).nobits?(0b1000_0010 | bignum_value).should == false
(0b1010_1010 | different_bignum).nobits?(0b1000_0001 | bignum_value).should == false
(0b0100_0101 | different_bignum).nobits?(0b1010_1010 | bignum_value).should == true
end
it "handles negative values using two's complement notation" do
(~0b1101).nobits?(0b1101).should == true
(-42).nobits?(-42).should == false
(~0b1101).nobits?(~0b10).should == false
(~(0b1101 | bignum_value)).nobits?(~(0b10 | bignum_value)).should == false
end
it "handles negative values using two's complement notation" do
(~0b1101).nobits?(0b1101).should == true
(-42).nobits?(-42).should == false
(~0b1101).nobits?(~0b10).should == false
(~(0b1101 | bignum_value)).nobits?(~(0b10 | bignum_value)).should == false
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.nobits?(obj).should == false
end
it "coerces the rhs using to_int" do
obj = mock("the int 0b10")
obj.should_receive(:to_int).and_return(0b10)
0b110.nobits?(obj).should == false
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.nobits?(obj)
}.should raise_error(TypeError)
-> { 13.nobits?("10") }.should raise_error(TypeError)
-> { 13.nobits?(:symbol) }.should raise_error(TypeError)
end
it "raises a TypeError when given a non-Integer" do
-> {
(obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10])
13.nobits?(obj)
}.should raise_error(TypeError)
-> { 13.nobits?("10") }.should raise_error(TypeError)
-> { 13.nobits?(:symbol) }.should raise_error(TypeError)
end
end

View file

@ -2,13 +2,7 @@ require_relative '../../spec_helper'
require_relative 'shared/arithmetic_coerce'
describe "Integer#+" do
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :+
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :+
end
it_behaves_like :integer_arithmetic_coerce_not_rescue, :+
context "fixnum" do
it "returns self plus the given Integer" do

View file

@ -2,48 +2,46 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/exponent'
ruby_version_is "2.5" do
describe "Integer#pow" do
context "one argument is passed" do
it_behaves_like :integer_exponent, :pow
describe "Integer#pow" do
context "one argument is passed" do
it_behaves_like :integer_exponent, :pow
end
context "two arguments are passed" do
it "returns modulo of self raised to the given power" do
2.pow(5, 12).should == 8
2.pow(6, 13).should == 12
2.pow(7, 14).should == 2
2.pow(8, 15).should == 1
end
context "two arguments are passed" do
it "returns modulo of self raised to the given power" do
2.pow(5, 12).should == 8
2.pow(6, 13).should == 12
2.pow(7, 14).should == 2
2.pow(8, 15).should == 1
end
it "works well with bignums" do
2.pow(61, 5843009213693951).should eql 3697379018277258
2.pow(62, 5843009213693952).should eql 1551748822859776
2.pow(63, 5843009213693953).should eql 3103497645717974
2.pow(64, 5843009213693954).should eql 363986077738838
end
it "works well with bignums" do
2.pow(61, 5843009213693951).should eql 3697379018277258
2.pow(62, 5843009213693952).should eql 1551748822859776
2.pow(63, 5843009213693953).should eql 3103497645717974
2.pow(64, 5843009213693954).should eql 363986077738838
end
it "handles sign like #divmod does" do
2.pow(5, 12).should == 8
2.pow(5, -12).should == -4
-2.pow(5, 12).should == 4
-2.pow(5, -12).should == -8
end
it "handles sign like #divmod does" do
2.pow(5, 12).should == 8
2.pow(5, -12).should == -4
-2.pow(5, 12).should == 4
-2.pow(5, -12).should == -8
end
it "ensures all arguments are integers" do
-> { 2.pow(5, 12.0) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
-> { 2.pow(5, Rational(12, 1)) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
end
it "ensures all arguments are integers" do
-> { 2.pow(5, 12.0) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
-> { 2.pow(5, Rational(12, 1)) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
end
it "raises TypeError for non-numeric value" do
-> { 2.pow(5, "12") }.should raise_error(TypeError)
-> { 2.pow(5, []) }.should raise_error(TypeError)
-> { 2.pow(5, nil) }.should raise_error(TypeError)
end
it "raises TypeError for non-numeric value" do
-> { 2.pow(5, "12") }.should raise_error(TypeError)
-> { 2.pow(5, []) }.should raise_error(TypeError)
-> { 2.pow(5, nil) }.should raise_error(TypeError)
end
it "raises a ZeroDivisionError when the given argument is 0" do
-> { 2.pow(5, 0) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the given argument is 0" do
-> { 2.pow(5, 0) }.should raise_error(ZeroDivisionError)
end
end
end

View file

@ -6,14 +6,6 @@ describe "Integer#round" do
it_behaves_like :integer_to_i, :round
it_behaves_like :integer_rounding_positive_precision, :round
ruby_version_is ""..."2.5" do # Not just since 2.4
it "rounds itself as a float if passed a positive precision" do
[2, -4, 10**70, -10**100].each do |v|
v.round(42).should eql(v.to_f)
end
end
end
# redmine:5228
it "returns itself rounded if passed a negative value" do
+249.round(-2).should eql(+200)
@ -78,20 +70,10 @@ describe "Integer#round" do
(-25).round(-1, half: nil).should eql(-30)
end
ruby_version_is "2.4"..."2.5" do
it "returns itself as a float if passed a positive precision and the half option" do
35.round(1, half: :up).should eql(35.0)
35.round(1, half: :down).should eql(35.0)
35.round(1, half: :even).should eql(35.0)
end
end
ruby_version_is "2.5" do
it "returns itself if passed a positive precision and the half option" do
35.round(1, half: :up).should eql(35)
35.round(1, half: :down).should eql(35)
35.round(1, half: :even).should eql(35)
end
it "returns itself if passed a positive precision and the half option" do
35.round(1, half: :up).should eql(35)
35.round(1, half: :down).should eql(35)
35.round(1, half: :even).should eql(35)
end
it "raises ArgumentError for an unknown rounding mode" do

View file

@ -1,25 +1,5 @@
require_relative '../fixtures/classes'
describe :integer_arithmetic_coerce_rescue, shared: true do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises TypeError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(TypeError, /MockObject can't be coerced into Integer/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(exception)
end
end
end
describe :integer_arithmetic_coerce_not_rescue, shared: true do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")

View file

@ -11,19 +11,9 @@ describe :integer_rounding_positive_precision, shared: true do
end
end
ruby_version_is "2.4"..."2.5" do
it "returns itself as a float if passed a positive precision" do
[2, -4, 10**70, -10**100].each do |v|
v.send(@method, 42).should eql(v.to_f)
end
end
end
ruby_version_is "2.5" do
it "returns itself if passed a positive precision" do
[2, -4, 10**70, -10**100].each do |v|
v.send(@method, 42).should eql(v)
end
it "returns itself if passed a positive precision" do
[2, -4, 10**70, -10**100].each do |v|
v.send(@method, 42).should eql(v)
end
end
end

View file

@ -1,33 +1,31 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Integer.sqrt" do
it "returns an integer" do
Integer.sqrt(10).should be_kind_of(Integer)
end
describe "Integer.sqrt" do
it "returns an integer" do
Integer.sqrt(10).should be_kind_of(Integer)
end
it "returns the integer square root of the argument" do
Integer.sqrt(0).should == 0
Integer.sqrt(1).should == 1
Integer.sqrt(24).should == 4
Integer.sqrt(25).should == 5
Integer.sqrt(10**400).should == 10**200
end
it "returns the integer square root of the argument" do
Integer.sqrt(0).should == 0
Integer.sqrt(1).should == 1
Integer.sqrt(24).should == 4
Integer.sqrt(25).should == 5
Integer.sqrt(10**400).should == 10**200
end
it "raises a Math::DomainError if the argument is negative" do
-> { Integer.sqrt(-4) }.should raise_error(Math::DomainError)
end
it "raises a Math::DomainError if the argument is negative" do
-> { Integer.sqrt(-4) }.should raise_error(Math::DomainError)
end
it "accepts any argument that can be coerced to Integer" do
Integer.sqrt(10.0).should == 3
end
it "accepts any argument that can be coerced to Integer" do
Integer.sqrt(10.0).should == 3
end
it "converts the argument with #to_int" do
Integer.sqrt(mock_int(10)).should == 3
end
it "converts the argument with #to_int" do
Integer.sqrt(mock_int(10)).should == 3
end
it "raises a TypeError if the argument cannot be coerced to Integer" do
-> { Integer.sqrt("test") }.should raise_error(TypeError)
end
it "raises a TypeError if the argument cannot be coerced to Integer" do
-> { Integer.sqrt("test") }.should raise_error(TypeError)
end
end

View file

@ -44,22 +44,20 @@ describe "IO#close" do
@io.close.should be_nil
end
ruby_version_is '2.5' do
it 'raises an IOError with a clear message' do
read_io, write_io = IO.pipe
going_to_read = false
thread = Thread.new do
-> do
going_to_read = true
read_io.read
end.should raise_error(IOError, 'stream closed in another thread')
end
Thread.pass until going_to_read && thread.stop?
read_io.close
thread.join
write_io.close
it 'raises an IOError with a clear message' do
read_io, write_io = IO.pipe
going_to_read = false
thread = Thread.new do
-> do
going_to_read = true
read_io.read
end.should raise_error(IOError, 'stream closed in another thread')
end
Thread.pass until going_to_read && thread.stop?
read_io.close
thread.join
write_io.close
end
end

View file

@ -1,52 +1,50 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
ruby_version_is "2.5" do
platform_is_not :windows do
describe "IO#pread" do
before :each do
@fname = tmp("io_pread.txt")
@contents = "1234567890"
touch(@fname) { |f| f.write @contents }
@file = File.open(@fname, "r+")
end
platform_is_not :windows do
describe "IO#pread" do
before :each do
@fname = tmp("io_pread.txt")
@contents = "1234567890"
touch(@fname) { |f| f.write @contents }
@file = File.open(@fname, "r+")
end
after :each do
@file.close
rm_r @fname
end
after :each do
@file.close
rm_r @fname
end
it "accepts a length, and an offset" do
@file.pread(4, 0).should == "1234"
@file.pread(3, 4).should == "567"
end
it "accepts a length, and an offset" do
@file.pread(4, 0).should == "1234"
@file.pread(3, 4).should == "567"
end
it "accepts a length, an offset, and an output buffer" do
buffer = "foo"
@file.pread(3, 4, buffer)
buffer.should == "567"
end
it "accepts a length, an offset, and an output buffer" do
buffer = "foo"
@file.pread(3, 4, buffer)
buffer.should == "567"
end
it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
end
it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
end
it "raises EOFError if end-of-file is reached" do
-> { @file.pread(1, 10) }.should raise_error(EOFError)
end
it "raises EOFError if end-of-file is reached" do
-> { @file.pread(1, 10) }.should raise_error(EOFError)
end
it "raises IOError when file is not open in read mode" do
File.open(@fname, "w") do |file|
-> { file.pread(1, 1) }.should raise_error(IOError)
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "r+")
file.close
it "raises IOError when file is not open in read mode" do
File.open(@fname, "w") do |file|
-> { file.pread(1, 1) }.should raise_error(IOError)
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "r+")
file.close
-> { file.pread(1, 1) }.should raise_error(IOError)
end
end
end

View file

@ -1,45 +1,43 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
ruby_version_is "2.5" do
platform_is_not :windows do
describe "IO#pwrite" do
before :each do
@fname = tmp("io_pwrite.txt")
@file = File.open(@fname, "w+")
end
platform_is_not :windows do
describe "IO#pwrite" do
before :each do
@fname = tmp("io_pwrite.txt")
@file = File.open(@fname, "w+")
end
after :each do
@file.close
rm_r @fname
end
after :each do
@file.close
rm_r @fname
end
it "returns the number of bytes written" do
@file.pwrite("foo", 0).should == 3
end
it "returns the number of bytes written" do
@file.pwrite("foo", 0).should == 3
end
it "accepts a string and an offset" do
@file.pwrite("foo", 2)
@file.pread(3, 2).should == "foo"
end
it "accepts a string and an offset" do
@file.pwrite("foo", 2)
@file.pread(3, 2).should == "foo"
end
it "does not advance the pointer in the file" do
@file.pwrite("bar", 3)
@file.write("foo")
@file.pread(6, 0).should == "foobar"
end
it "does not advance the pointer in the file" do
@file.pwrite("bar", 3)
@file.write("foo")
@file.pread(6, 0).should == "foobar"
end
it "raises IOError when file is not open in write mode" do
File.open(@fname, "r") do |file|
-> { file.pwrite("foo", 1) }.should raise_error(IOError)
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "w+")
file.close
it "raises IOError when file is not open in write mode" do
File.open(@fname, "r") do |file|
-> { file.pwrite("foo", 1) }.should raise_error(IOError)
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "w+")
file.close
-> { file.pwrite("foo", 1) }.should raise_error(IOError)
end
end
end

View file

@ -126,14 +126,12 @@ end
describe "IO#write" do
it_behaves_like :io_write, :write
ruby_version_is "2.5" do
it "accepts multiple arguments" do
IO.pipe do |r, w|
w.write("foo", "bar")
w.close
it "accepts multiple arguments" do
IO.pipe do |r, w|
w.write("foo", "bar")
w.close
r.read.should == "foobar"
end
r.read.should == "foobar"
end
end
end

View file

@ -51,21 +51,19 @@ describe "Kernel#freeze" do
end
end
ruby_version_is "2.5" do
describe "on a Complex" do
it "has no effect since it is already frozen" do
c = Complex(1.3, 3.1)
c.frozen?.should be_true
c.freeze
end
describe "on a Complex" do
it "has no effect since it is already frozen" do
c = Complex(1.3, 3.1)
c.frozen?.should be_true
c.freeze
end
end
describe "on a Rational" do
it "has no effect since it is already frozen" do
r = Rational(1, 3)
r.frozen?.should be_true
r.freeze
end
describe "on a Rational" do
it "has no effect since it is already frozen" do
r = Rational(1, 3)
r.frozen?.should be_true
r.freeze
end
end

View file

@ -50,29 +50,27 @@ describe "Kernel#frozen?" do
end
end
ruby_version_is "2.5" do
describe "on a Complex" do
it "returns true" do
c = Complex(1.3, 3.1)
c.frozen?.should be_true
end
it "literal returns true" do
c = eval "1.3i"
c.frozen?.should be_true
end
describe "on a Complex" do
it "returns true" do
c = Complex(1.3, 3.1)
c.frozen?.should be_true
end
describe "on a Rational" do
it "returns true" do
r = Rational(1, 3)
r.frozen?.should be_true
end
it "literal returns true" do
c = eval "1.3i"
c.frozen?.should be_true
end
end
it "literal returns true" do
r = eval "1/3r"
r.frozen?.should be_true
end
describe "on a Rational" do
it "returns true" do
r = Rational(1, 3)
r.frozen?.should be_true
end
it "literal returns true" do
r = eval "1/3r"
r.frozen?.should be_true
end
end
end

View file

@ -1,11 +1,9 @@
require_relative '../../spec_helper'
ruby_version_is "2.5" do
describe "Kernel#pp" do
it "lazily loads the 'pp' library and delegates the call to that library" do
# Run in child process to ensure 'pp' hasn't been loaded yet.
output = ruby_exe("pp [1, 2, 3]")
output.should == "[1, 2, 3]\n"
end
describe "Kernel#pp" do
it "lazily loads the 'pp' library and delegates the call to that library" do
# Run in child process to ensure 'pp' hasn't been loaded yet.
output = ruby_exe("pp [1, 2, 3]")
output.should == "[1, 2, 3]\n"
end
end

View file

@ -103,27 +103,13 @@ describe :kernel_dup_clone, shared: true do
:my_symbol.send(@method).should == :my_symbol
end
ruby_version_is ''...'2.5' do
it "raises a TypeError for Complex" do
c = Complex(1.3, 3.1)
-> { c.send(@method) }.should raise_error(TypeError)
end
it "raises a TypeError for Rational" do
r = Rational(1, 3)
-> { r.send(@method) }.should raise_error(TypeError)
end
it "returns self for Complex" do
c = Complex(1.3, 3.1)
c.send(@method).should equal c
end
ruby_version_is '2.5' do
it "returns self for Complex" do
c = Complex(1.3, 3.1)
c.send(@method).should equal c
end
it "returns self for Rational" do
r = Rational(1, 3)
r.send(@method).should equal r
end
it "returns self for Rational" do
r = Rational(1, 3)
r.send(@method).should equal r
end
end

View file

@ -354,26 +354,13 @@ describe :kernel_require, shared: true do
rm_r @dir, @symlink_to_dir
end
ruby_version_is ""..."2.4.4" do
it "canonicalizes neither the entry in $LOAD_PATH nor the filename passed to #require" do
$LOAD_PATH.unshift(@symlink_to_dir)
@object.require("symfile").should be_true
loaded_feature = "#{@symlink_to_dir}/symfile.rb"
ScratchPad.recorded.should == [loaded_feature]
$".last.should == loaded_feature
$LOAD_PATH[0].should == @symlink_to_dir
end
end
ruby_version_is "2.4.4" do
it "canonicalizes the entry in $LOAD_PATH but not the filename passed to #require" do
$LOAD_PATH.unshift(@symlink_to_dir)
@object.require("symfile").should be_true
loaded_feature = "#{@dir}/symfile.rb"
ScratchPad.recorded.should == [loaded_feature]
$".last.should == loaded_feature
$LOAD_PATH[0].should == @symlink_to_dir
end
it "canonicalizes the entry in $LOAD_PATH but not the filename passed to #require" do
$LOAD_PATH.unshift(@symlink_to_dir)
@object.require("symfile").should be_true
loaded_feature = "#{@dir}/symfile.rb"
ScratchPad.recorded.should == [loaded_feature]
$".last.should == loaded_feature
$LOAD_PATH[0].should == @symlink_to_dir
end
end
end
@ -527,41 +514,25 @@ describe :kernel_require, shared: true do
ScratchPad.recorded.should == []
end
ruby_version_is ""..."2.5" do
it "complex, enumerator, rational, thread and unicode_normalize are already required" do
provided = %w[complex enumerator rational thread unicode_normalize]
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
provided.each { |feature|
features.should =~ /\b#{feature}\.(rb|so|jar)$/
}
it "complex, enumerator, rational and thread are already required" do
provided = %w[complex enumerator rational thread]
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
provided.each { |feature|
features.should =~ /\b#{feature}\.(rb|so|jar)$/
}
code = provided.map { |f| "puts require #{f.inspect}\n" }.join
required = ruby_exe(code, options: '--disable-gems')
required.should == "false\n" * provided.size
end
code = provided.map { |f| "puts require #{f.inspect}\n" }.join
required = ruby_exe(code, options: '--disable-gems')
required.should == "false\n" * provided.size
end
ruby_version_is "2.5" do
it "complex, enumerator, rational and thread are already required" do
provided = %w[complex enumerator rational thread]
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
provided.each { |feature|
features.should =~ /\b#{feature}\.(rb|so|jar)$/
}
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")
}
code = provided.map { |f| "puts require #{f.inspect}\n" }.join
required = ruby_exe(code, options: '--disable-gems')
required.should == "false\n" * provided.size
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
-> { @object.require("unicode_normalize") }.should raise_error(LoadError)
end
end

View file

@ -345,18 +345,10 @@ describe :kernel_sprintf, shared: true do
end
describe "%" do
ruby_version_is ""..."2.5" do
it "alone displays the percent sign" do
@method.call("%").should == "%"
end
end
ruby_version_is "2.5" do
it "alone raises an ArgumentError" do
-> {
@method.call("%")
}.should raise_error(ArgumentError)
end
it "alone raises an ArgumentError" do
-> {
@method.call("%")
}.should raise_error(ArgumentError)
end
it "is escaped by %" do
@ -876,22 +868,20 @@ describe :kernel_sprintf, shared: true do
}.should raise_error(KeyError)
end
ruby_version_is "2.5" do
it "sets the Hash as the receiver of KeyError" do
-> {
@method.call("%<foo>s", @object)
}.should raise_error(KeyError) { |err|
err.receiver.should equal(@object)
}
end
it "sets the Hash as the receiver of KeyError" do
-> {
@method.call("%<foo>s", @object)
}.should raise_error(KeyError) { |err|
err.receiver.should equal(@object)
}
end
it "sets the unmatched key as the key of KeyError" do
-> {
@method.call("%<foo>s", @object)
}.should raise_error(KeyError) { |err|
err.key.to_s.should == 'foo'
}
end
it "sets the unmatched key as the key of KeyError" do
-> {
@method.call("%<foo>s", @object)
}.should raise_error(KeyError) { |err|
err.key.to_s.should == 'foo'
}
end
end
end

View file

@ -87,71 +87,69 @@ describe "Kernel#warn" do
}.should output(nil, "to_s called\n")
end
ruby_version_is "2.5" do
describe ":uplevel keyword argument" do
before :each do
$VERBOSE = true
end
it "prepends a message with specified line from the backtrace" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("foo", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: foo|)
-> { w.f4("foo", 1) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f1_call_lineno}: warning: foo|)
-> { w.f4("foo", 2) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f2_call_lineno}: warning: foo|)
-> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
end
it "converts first arg using to_s" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4(false, 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: false|)
-> { w.f4(nil, 1) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f1_call_lineno}: warning: |)
obj = mock("obj")
obj.should_receive(:to_s).and_return("to_s called")
-> { w.f4(obj, 2) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f2_call_lineno}: warning: to_s called|)
end
it "does not prepend caller information if the uplevel argument is too large" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("foo", 100) }.should output(nil, "warning: foo\n")
end
it "prepends even if a message is empty or nil" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
-> { w.f4(nil, 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
end
it "converts value to Integer" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4(0.1) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
-> { w.f4(Rational(1, 2)) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
end
it "raises ArgumentError if passed negative value" do
-> { warn "", uplevel: -2 }.should raise_error(ArgumentError)
-> { warn "", uplevel: -100 }.should raise_error(ArgumentError)
end
it "raises ArgumentError if passed -1" do
-> { warn "", uplevel: -1 }.should raise_error(ArgumentError)
end
it "raises TypeError if passed not Integer" do
-> { warn "", uplevel: "" }.should raise_error(TypeError)
-> { warn "", uplevel: [] }.should raise_error(TypeError)
-> { warn "", uplevel: {} }.should raise_error(TypeError)
-> { warn "", uplevel: Object.new }.should raise_error(TypeError)
end
describe ":uplevel keyword argument" do
before :each do
$VERBOSE = true
end
it "treats empty hash as no keyword argument" do
h = {}
-> { warn(**h) }.should_not complain(verbose: true)
-> { warn('foo', **h) }.should complain("foo\n")
it "prepends a message with specified line from the backtrace" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("foo", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: foo|)
-> { w.f4("foo", 1) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f1_call_lineno}: warning: foo|)
-> { w.f4("foo", 2) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f2_call_lineno}: warning: foo|)
-> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
end
it "converts first arg using to_s" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4(false, 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: false|)
-> { w.f4(nil, 1) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f1_call_lineno}: warning: |)
obj = mock("obj")
obj.should_receive(:to_s).and_return("to_s called")
-> { w.f4(obj, 2) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f2_call_lineno}: warning: to_s called|)
end
it "does not prepend caller information if the uplevel argument is too large" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("foo", 100) }.should output(nil, "warning: foo\n")
end
it "prepends even if a message is empty or nil" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4("", 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
-> { w.f4(nil, 0) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.warn_call_lineno}: warning: \n$|)
end
it "converts value to Integer" do
w = KernelSpecs::WarnInNestedCall.new
-> { w.f4(0.1) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
-> { w.f4(Rational(1, 2)) }.should output(nil, %r|classes.rb:#{w.warn_call_lineno}:|)
end
it "raises ArgumentError if passed negative value" do
-> { warn "", uplevel: -2 }.should raise_error(ArgumentError)
-> { warn "", uplevel: -100 }.should raise_error(ArgumentError)
end
it "raises ArgumentError if passed -1" do
-> { warn "", uplevel: -1 }.should raise_error(ArgumentError)
end
it "raises TypeError if passed not Integer" do
-> { warn "", uplevel: "" }.should raise_error(TypeError)
-> { warn "", uplevel: [] }.should raise_error(TypeError)
-> { warn "", uplevel: {} }.should raise_error(TypeError)
-> { warn "", uplevel: Object.new }.should raise_error(TypeError)
end
end
it "treats empty hash as no keyword argument" do
h = {}
-> { warn(**h) }.should_not complain(verbose: true)
-> { warn('foo', **h) }.should complain("foo\n")
end
end

View file

@ -1,8 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/then'
ruby_version_is "2.5" do
describe "Kernel#yield_self" do
it_behaves_like :kernel_then, :yield_self
end
describe "Kernel#yield_self" do
it_behaves_like :kernel_then, :yield_self
end

View file

@ -2,8 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/call'
ruby_version_is "2.5" do
describe "Method#===" do
it_behaves_like :method_call, :===
end
describe "Method#===" do
it_behaves_like :method_call, :===
end

View file

@ -81,15 +81,8 @@ describe "Module#alias_method" do
-> { @class.make_alias mock('x'), :public_one }.should raise_error(TypeError)
end
ruby_version_is ''...'2.5' do
it "is a private method" do
-> { @class.alias_method :ichi, :public_one }.should raise_error(NoMethodError)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:alias_method, false)
end
it "is a public method" do
Module.should have_public_instance_method(:alias_method, false)
end
it "returns self" do

View file

@ -63,15 +63,8 @@ describe "Module#attr_accessor" do
-> { c.new.foo=1 }.should raise_error(NoMethodError)
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:attr_accessor, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:attr_accessor, false)
end
it "is a public method" do
Module.should have_public_instance_method(:attr_accessor, false)
end
describe "on immediates" do

View file

@ -58,14 +58,7 @@ describe "Module#attr_reader" do
-> { c.new.foo }.should raise_error(NoMethodError)
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:attr_reader, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:attr_reader, false)
end
it "is a public method" do
Module.should have_public_instance_method(:attr_reader, false)
end
end

View file

@ -142,14 +142,7 @@ describe "Module#attr" do
}.should complain(/boolean argument is obsoleted/, verbose: true)
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:attr, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:attr, false)
end
it "is a public method" do
Module.should have_public_instance_method(:attr, false)
end
end

View file

@ -58,14 +58,7 @@ describe "Module#attr_writer" do
-> { c.new.foo=1 }.should raise_error(NoMethodError)
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:attr_writer, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:attr_writer, false)
end
it "is a public method" do
Module.should have_public_instance_method(:attr_writer, false)
end
end

View file

@ -355,15 +355,8 @@ describe "Module#define_method" do
klass.new.string_test.should == "string_test result"
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:define_method)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:define_method)
end
it "is a public method" do
Module.should have_public_instance_method(:define_method)
end
it "returns its symbol" do

View file

@ -393,44 +393,22 @@ describe "Module#refine" do
end
end
ruby_version_is "" ... "2.5" do
it "is not honored by string interpolation" do
refinement = Module.new do
refine Integer do
def to_s
"foo"
end
it "is honored by string interpolation" do
refinement = Module.new do
refine Integer do
def to_s
"foo"
end
end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "1"
end
end
ruby_version_is "2.5" do
it "is honored by string interpolation" do
refinement = Module.new do
refine Integer do
def to_s
"foo"
end
end
end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "foo"
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "foo"
end
it "is honored by Kernel#binding" do

View file

@ -20,15 +20,8 @@ describe "Module#remove_method" do
@module = Module.new { def method_to_remove; end }
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:remove_method, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:remove_method, false)
end
it "is a public method" do
Module.should have_public_instance_method(:remove_method, false)
end
it "removes the method from a class" do

View file

@ -18,15 +18,8 @@ describe "Module#undef_method" do
@module = Module.new { def method_to_undef; end }
end
ruby_version_is ''...'2.5' do
it "is a private method" do
Module.should have_private_instance_method(:undef_method, false)
end
end
ruby_version_is '2.5' do
it "is a public method" do
Module.should have_public_instance_method(:undef_method, false)
end
it "is a public method" do
Module.should have_public_instance_method(:undef_method, false)
end
it "requires multiple arguments" do

View file

@ -224,33 +224,25 @@ describe :numeric_step, :shared => true do
end
describe "when step is a String" do
error = nil
ruby_version_is "2.4"..."2.5" do
error = TypeError
end
ruby_version_is "2.5" do
error = ArgumentError
end
describe "with self and stop as Fixnums" do
it "raises an #{error} when step is a numeric representation" do
-> { @step.call(1, 5, "1") {} }.should raise_error(error)
-> { @step.call(1, 5, "0.1") {} }.should raise_error(error)
-> { @step.call(1, 5, "1/3") {} }.should raise_error(error)
it "raises an ArgumentError when step is a numeric representation" do
-> { @step.call(1, 5, "1") {} }.should raise_error(ArgumentError)
-> { @step.call(1, 5, "0.1") {} }.should raise_error(ArgumentError)
-> { @step.call(1, 5, "1/3") {} }.should raise_error(ArgumentError)
end
it "raises an #{error} with step as an alphanumeric string" do
-> { @step.call(1, 5, "foo") {} }.should raise_error(error)
it "raises an ArgumentError with step as an alphanumeric string" do
-> { @step.call(1, 5, "foo") {} }.should raise_error(ArgumentError)
end
end
describe "with self and stop as Floats" do
it "raises an #{error} when step is a numeric representation" do
-> { @step.call(1.1, 5.1, "1") {} }.should raise_error(error)
-> { @step.call(1.1, 5.1, "0.1") {} }.should raise_error(error)
-> { @step.call(1.1, 5.1, "1/3") {} }.should raise_error(error)
it "raises an ArgumentError when step is a numeric representation" do
-> { @step.call(1.1, 5.1, "1") {} }.should raise_error(ArgumentError)
-> { @step.call(1.1, 5.1, "0.1") {} }.should raise_error(ArgumentError)
-> { @step.call(1.1, 5.1, "1/3") {} }.should raise_error(ArgumentError)
end
it "raises an #{error} with step as an alphanumeric string" do
-> { @step.call(1.1, 5.1, "foo") {} }.should raise_error(error)
it "raises an ArgumentError with step as an alphanumeric string" do
-> { @step.call(1.1, 5.1, "foo") {} }.should raise_error(ArgumentError)
end
end
end
@ -302,33 +294,25 @@ describe :numeric_step, :shared => true do
describe "returned Enumerator" do
describe "size" do
describe "when step is a String" do
error = nil
ruby_version_is "2.4"..."2.5" do
error = TypeError
end
ruby_version_is "2.5" do
error = ArgumentError
end
describe "with self and stop as Fixnums" do
it "raises an #{error} when step is a numeric representation" do
-> { @step.call(1, 5, "1").size }.should raise_error(error)
-> { @step.call(1, 5, "0.1").size }.should raise_error(error)
-> { @step.call(1, 5, "1/3").size }.should raise_error(error)
it "raises an ArgumentError when step is a numeric representation" do
-> { @step.call(1, 5, "1").size }.should raise_error(ArgumentError)
-> { @step.call(1, 5, "0.1").size }.should raise_error(ArgumentError)
-> { @step.call(1, 5, "1/3").size }.should raise_error(ArgumentError)
end
it "raises an #{error} with step as an alphanumeric string" do
-> { @step.call(1, 5, "foo").size }.should raise_error(error)
it "raises an ArgumentError with step as an alphanumeric string" do
-> { @step.call(1, 5, "foo").size }.should raise_error(ArgumentError)
end
end
describe "with self and stop as Floats" do
it "raises an #{error} when step is a numeric representation" do
-> { @step.call(1.1, 5.1, "1").size }.should raise_error(error)
-> { @step.call(1.1, 5.1, "0.1").size }.should raise_error(error)
-> { @step.call(1.1, 5.1, "1/3").size }.should raise_error(error)
it "raises an ArgumentError when step is a numeric representation" do
-> { @step.call(1.1, 5.1, "1").size }.should raise_error(ArgumentError)
-> { @step.call(1.1, 5.1, "0.1").size }.should raise_error(ArgumentError)
-> { @step.call(1.1, 5.1, "1/3").size }.should raise_error(ArgumentError)
end
it "raises an #{error} with step as an alphanumeric string" do
-> { @step.call(1.1, 5.1, "foo").size }.should raise_error(error)
it "raises an ArgumentError with step as an alphanumeric string" do
-> { @step.call(1.1, 5.1, "foo").size }.should raise_error(ArgumentError)
end
end
end

View file

@ -1,20 +1,18 @@
require_relative '../../spec_helper'
ruby_version_is '2.5' do
describe 'Process#last_status' do
it 'returns the status of the last executed child process in the current thread' do
pid = Process.wait Process.spawn("exit 0")
Process.last_status.pid.should == pid
end
describe 'Process#last_status' do
it 'returns the status of the last executed child process in the current thread' do
pid = Process.wait Process.spawn("exit 0")
Process.last_status.pid.should == pid
end
it 'returns nil if no child process has been ever executed in the current thread' do
Thread.new do
Process.last_status.should == nil
end.join
end
it 'returns nil if no child process has been ever executed in the current thread' do
Thread.new do
Process.last_status.should == nil
end.join
end
it 'raises an ArgumentError if any arguments are provided' do
-> { Process.last_status(1) }.should raise_error(ArgumentError)
end
it 'raises an ArgumentError if any arguments are provided' do
-> { Process.last_status(1) }.should raise_error(ArgumentError)
end
end

View file

@ -13,25 +13,23 @@ describe "Process.times" do
Process.times.utime.should > user
end
ruby_version_is "2.5" do
platform_is_not :windows do
it "uses getrusage when available to improve precision beyond milliseconds" do
max = 10_000
has_getrusage = max.times.find do
time = Process.clock_gettime(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID)
('%.6f' % time).end_with?('000')
end
unless has_getrusage
skip "getrusage is not supported on this environment"
end
found = (max * 100).times.find do
time = Process.times.utime
('%.6f' % time).end_with?('000')
end
found.should_not == nil
platform_is_not :windows do
it "uses getrusage when available to improve precision beyond milliseconds" do
max = 10_000
has_getrusage = max.times.find do
time = Process.clock_gettime(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID)
('%.6f' % time).end_with?('000')
end
unless has_getrusage
skip "getrusage is not supported on this environment"
end
found = (max * 100).times.find do
time = Process.times.utime
('%.6f' % time).end_with?('000')
end
found.should_not == nil
end
end
end

View file

@ -1,9 +1,6 @@
# -*- encoding: binary -*-
require_relative '../../spec_helper'
require_relative 'shared/urandom'
ruby_version_is "2.5" do
describe "Random.urandom" do
it_behaves_like :random_urandom, :urandom
end
describe "Random.urandom" do
it_behaves_like :random_urandom, :urandom
end

View file

@ -1,9 +0,0 @@
# -*- encoding: binary -*-
require_relative '../../spec_helper'
require_relative 'shared/urandom'
ruby_version_is ""..."2.5" do
describe "Random.raw_seed" do
it_behaves_like :random_urandom, :raw_seed
end
end

View file

@ -33,14 +33,12 @@ describe "Range.new" do
-> { Range.new(a, b) }.should raise_error(ArgumentError)
end
ruby_version_is "2.5" do
it "does not rescue exception raised in #<=> when compares the given start and end" do
b = mock('a')
a = mock('b')
a.should_receive(:<=>).with(b).and_raise(RangeSpecs::ComparisonError)
it "does not rescue exception raised in #<=> when compares the given start and end" do
b = mock('a')
a = mock('b')
a.should_receive(:<=>).with(b).and_raise(RangeSpecs::ComparisonError)
-> { Range.new(a, b) }.should raise_error(RangeSpecs::ComparisonError)
end
-> { Range.new(a, b) }.should raise_error(RangeSpecs::ComparisonError)
end
describe "beginless/endless range" do

View file

@ -25,16 +25,8 @@ describe "String#casecmp independent of case" do
"abc".casecmp(other).should == 0
end
ruby_version_is ""..."2.5" do
it "raises a TypeError if other can't be converted to a string" do
-> { "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
it "returns nil if other can't be converted to a string" do
"abc".casecmp(mock('abc')).should be_nil
end
it "returns nil if incompatible encodings" do
@ -196,15 +188,7 @@ describe 'String#casecmp? independent of case' 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
-> { "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
it "returns nil if other can't be converted to a string" do
"abc".casecmp?(mock('abc')).should be_nil
end
end

View file

@ -2,82 +2,80 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
ruby_version_is '2.5' do
describe "String#delete_prefix" do
it "returns a copy of the string, with the given prefix removed" do
'hello'.delete_prefix('hell').should == 'o'
'hello'.delete_prefix('hello').should == ''
end
describe "String#delete_prefix" do
it "returns a copy of the string, with the given prefix removed" do
'hello'.delete_prefix('hell').should == 'o'
'hello'.delete_prefix('hello').should == ''
end
it "returns a copy of the string, when the prefix isn't found" do
s = 'hello'
r = s.delete_prefix('hello!')
r.should_not equal s
r.should == s
r = s.delete_prefix('ell')
r.should_not equal s
r.should == s
r = s.delete_prefix('')
r.should_not equal s
r.should == s
end
it "returns a copy of the string, when the prefix isn't found" do
s = 'hello'
r = s.delete_prefix('hello!')
r.should_not equal s
r.should == s
r = s.delete_prefix('ell')
r.should_not equal s
r.should == s
r = s.delete_prefix('')
r.should_not equal s
r.should == s
end
ruby_version_is ''...'2.7' do
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_prefix('hell').tainted?.should == true
'hello'.taint.delete_prefix('').tainted?.should == true
end
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_prefix('hell')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'hell'
'hello'.delete_prefix(o).should == 'o'
end
it "returns a subclass instance when called on a subclass instance" do
s = StringSpecs::MyString.new('hello')
s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString)
ruby_version_is ''...'2.7' do
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_prefix('hell').tainted?.should == true
'hello'.taint.delete_prefix('').tainted?.should == true
end
end
describe "String#delete_prefix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_prefix!('hell').should equal(s)
s.should == 'o'
end
it "doesn't set $~" do
$~ = nil
it "returns nil if no change is made" do
s = 'hello'
s.delete_prefix!('ell').should == nil
s.delete_prefix!('').should == nil
end
'hello'.delete_prefix('hell')
$~.should == nil
end
it "doesn't set $~" do
$~ = nil
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'hell'
'hello'.delete_prefix(o).should == 'o'
end
'hello'.delete_prefix!('hell')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'hell'
'hello'.delete_prefix!(o).should == 'o'
end
it "raises a FrozenError when self is frozen" do
-> { 'hello'.freeze.delete_prefix!('hell') }.should raise_error(FrozenError)
-> { 'hello'.freeze.delete_prefix!('') }.should raise_error(FrozenError)
-> { ''.freeze.delete_prefix!('') }.should raise_error(FrozenError)
end
it "returns a subclass instance when called on a subclass instance" do
s = StringSpecs::MyString.new('hello')
s.delete_prefix('hell').should be_an_instance_of(StringSpecs::MyString)
end
end
describe "String#delete_prefix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_prefix!('hell').should equal(s)
s.should == 'o'
end
it "returns nil if no change is made" do
s = 'hello'
s.delete_prefix!('ell').should == nil
s.delete_prefix!('').should == nil
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_prefix!('hell')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'hell'
'hello'.delete_prefix!(o).should == 'o'
end
it "raises a FrozenError when self is frozen" do
-> { 'hello'.freeze.delete_prefix!('hell') }.should raise_error(FrozenError)
-> { 'hello'.freeze.delete_prefix!('') }.should raise_error(FrozenError)
-> { ''.freeze.delete_prefix!('') }.should raise_error(FrozenError)
end
end

View file

@ -2,82 +2,80 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
ruby_version_is '2.5' do
describe "String#delete_suffix" do
it "returns a copy of the string, with the given suffix removed" do
'hello'.delete_suffix('ello').should == 'h'
'hello'.delete_suffix('hello').should == ''
end
describe "String#delete_suffix" do
it "returns a copy of the string, with the given suffix removed" do
'hello'.delete_suffix('ello').should == 'h'
'hello'.delete_suffix('hello').should == ''
end
it "returns a copy of the string, when the suffix isn't found" do
s = 'hello'
r = s.delete_suffix('!hello')
r.should_not equal s
r.should == s
r = s.delete_suffix('ell')
r.should_not equal s
r.should == s
r = s.delete_suffix('')
r.should_not equal s
r.should == s
end
it "returns a copy of the string, when the suffix isn't found" do
s = 'hello'
r = s.delete_suffix('!hello')
r.should_not equal s
r.should == s
r = s.delete_suffix('ell')
r.should_not equal s
r.should == s
r = s.delete_suffix('')
r.should_not equal s
r.should == s
end
ruby_version_is ''...'2.7' do
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_suffix('ello').tainted?.should == true
'hello'.taint.delete_suffix('').tainted?.should == true
end
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_suffix('ello')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'ello'
'hello'.delete_suffix(o).should == 'h'
end
it "returns a subclass instance when called on a subclass instance" do
s = StringSpecs::MyString.new('hello')
s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString)
ruby_version_is ''...'2.7' do
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_suffix('ello').tainted?.should == true
'hello'.taint.delete_suffix('').tainted?.should == true
end
end
describe "String#delete_suffix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_suffix!('ello').should equal(s)
s.should == 'h'
end
it "doesn't set $~" do
$~ = nil
it "returns nil if no change is made" do
s = 'hello'
s.delete_suffix!('ell').should == nil
s.delete_suffix!('').should == nil
end
'hello'.delete_suffix('ello')
$~.should == nil
end
it "doesn't set $~" do
$~ = nil
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'ello'
'hello'.delete_suffix(o).should == 'h'
end
'hello'.delete_suffix!('ello')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'ello'
'hello'.delete_suffix!(o).should == 'h'
end
it "raises a FrozenError when self is frozen" do
-> { 'hello'.freeze.delete_suffix!('ello') }.should raise_error(FrozenError)
-> { 'hello'.freeze.delete_suffix!('') }.should raise_error(FrozenError)
-> { ''.freeze.delete_suffix!('') }.should raise_error(FrozenError)
end
it "returns a subclass instance when called on a subclass instance" do
s = StringSpecs::MyString.new('hello')
s.delete_suffix('ello').should be_an_instance_of(StringSpecs::MyString)
end
end
describe "String#delete_suffix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_suffix!('ello').should equal(s)
s.should == 'h'
end
it "returns nil if no change is made" do
s = 'hello'
s.delete_suffix!('ell').should == nil
s.delete_suffix!('').should == nil
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_suffix!('ello')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'ello'
'hello'.delete_suffix!(o).should == 'h'
end
it "raises a FrozenError when self is frozen" do
-> { 'hello'.freeze.delete_suffix!('ello') }.should raise_error(FrozenError)
-> { 'hello'.freeze.delete_suffix!('') }.should raise_error(FrozenError)
-> { ''.freeze.delete_suffix!('') }.should raise_error(FrozenError)
end
end

View file

@ -2,10 +2,8 @@ require_relative 'shared/chars'
require_relative 'shared/grapheme_clusters'
require_relative 'shared/each_char_without_block'
ruby_version_is "2.5" do
describe "String#each_grapheme_cluster" do
it_behaves_like :string_chars, :each_grapheme_cluster
it_behaves_like :string_grapheme_clusters, :each_grapheme_cluster
it_behaves_like :string_each_char_without_block, :each_grapheme_cluster
end
describe "String#each_grapheme_cluster" do
it_behaves_like :string_chars, :each_grapheme_cluster
it_behaves_like :string_grapheme_clusters, :each_grapheme_cluster
it_behaves_like :string_each_char_without_block, :each_grapheme_cluster
end

View file

@ -1,15 +1,13 @@
require_relative 'shared/chars'
require_relative 'shared/grapheme_clusters'
ruby_version_is "2.5" do
describe "String#grapheme_clusters" do
it_behaves_like :string_chars, :grapheme_clusters
it_behaves_like :string_grapheme_clusters, :grapheme_clusters
describe "String#grapheme_clusters" do
it_behaves_like :string_chars, :grapheme_clusters
it_behaves_like :string_grapheme_clusters, :grapheme_clusters
it "returns an array when no block given" do
string = "ab\u{1f3f3}\u{fe0f}\u{200d}\u{1f308}\u{1F43E}"
string.grapheme_clusters.should == ['a', 'b', "\u{1f3f3}\u{fe0f}\u{200d}\u{1f308}", "\u{1F43E}"]
it "returns an array when no block given" do
string = "ab\u{1f3f3}\u{fe0f}\u{200d}\u{1f308}\u{1F43E}"
string.grapheme_clusters.should == ['a', 'b', "\u{1f3f3}\u{fe0f}\u{200d}\u{1f308}", "\u{1F43E}"]
end
end
end

View file

@ -50,18 +50,9 @@ describe "String#%" do
end
end
ruby_version_is ""..."2.5" do
it "formats single % character at the end as literal %" do
("%" % []).should == "%"
("foo%" % []).should == "foo%"
end
end
ruby_version_is "2.5" do
it "raises an error if single % appears at the end" do
-> { ("%" % []) }.should raise_error(ArgumentError)
-> { ("foo%" % [])}.should raise_error(ArgumentError)
end
it "raises an error if single % appears at the end" do
-> { ("%" % []) }.should raise_error(ArgumentError)
-> { ("foo%" % [])}.should raise_error(ArgumentError)
end
it "formats single % character before a newline as literal %" do

View file

@ -54,28 +54,14 @@ describe :string_each_line, shared: true do
a.should == ["one\ntwo\r\nthree"]
end
ruby_version_is ''...'2.5' do
it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n"]
it "yields paragraphs (broken by 2 or more successive newlines) when passed '' and replaces multiple newlines with only two ones" do
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"]
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n", "dog"]
end
end
ruby_version_is '2.5' do
it "yields paragraphs (broken by 2 or more successive newlines) when passed '' and replaces multiple newlines with only two ones" do
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"]
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"]
end
a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"]
end
describe "uses $/" do

View file

@ -43,34 +43,32 @@ describe "String#start_with?" do
"céréale".should.start_with?("cér")
end
ruby_version_is "2.5" do
it "supports regexps" do
regexp = /[h1]/
"hello".should.start_with?(regexp)
"1337".should.start_with?(regexp)
"foxes are 1337".should_not.start_with?(regexp)
"chunky\n12bacon".should_not.start_with?(/12/)
end
it "supports regexps" do
regexp = /[h1]/
"hello".should.start_with?(regexp)
"1337".should.start_with?(regexp)
"foxes are 1337".should_not.start_with?(regexp)
"chunky\n12bacon".should_not.start_with?(/12/)
end
it "supports regexps with ^ and $ modifiers" do
regexp1 = /^\d{2}/
regexp2 = /\d{2}$/
"12test".should.start_with?(regexp1)
"test12".should_not.start_with?(regexp1)
"12test".should_not.start_with?(regexp2)
"test12".should_not.start_with?(regexp2)
end
it "supports regexps with ^ and $ modifiers" do
regexp1 = /^\d{2}/
regexp2 = /\d{2}$/
"12test".should.start_with?(regexp1)
"test12".should_not.start_with?(regexp1)
"12test".should_not.start_with?(regexp2)
"test12".should_not.start_with?(regexp2)
end
it "sets Regexp.last_match if it returns true" do
regexp = /test-(\d+)/
"test-1337".start_with?(regexp).should be_true
Regexp.last_match.should_not be_nil
Regexp.last_match[1].should == "1337"
$1.should == "1337"
it "sets Regexp.last_match if it returns true" do
regexp = /test-(\d+)/
"test-1337".start_with?(regexp).should be_true
Regexp.last_match.should_not be_nil
Regexp.last_match[1].should == "1337"
$1.should == "1337"
"test-asdf".start_with?(regexp).should be_false
Regexp.last_match.should be_nil
$1.should be_nil
end
"test-asdf".start_with?(regexp).should be_false
Regexp.last_match.should be_nil
$1.should be_nil
end
end

View file

@ -18,22 +18,20 @@ describe 'String#-@' do
output.should == 'foo'
end
ruby_version_is "2.5" do
it "returns the same object for equal unfrozen strings" do
origin = "this is a string"
dynamic = %w(this is a string).join(' ')
it "returns the same object for equal unfrozen strings" do
origin = "this is a string"
dynamic = %w(this is a string).join(' ')
origin.should_not equal(dynamic)
(-origin).should equal(-dynamic)
end
it "returns the same object when it's called on the same String literal" do
(-"unfrozen string").should equal(-"unfrozen string")
(-"unfrozen string").should_not equal(-"another unfrozen string")
end
origin.should_not equal(dynamic)
(-origin).should equal(-dynamic)
end
ruby_version_is "2.5"..."2.6" do
it "returns the same object when it's called on the same String literal" do
(-"unfrozen string").should equal(-"unfrozen string")
(-"unfrozen string").should_not equal(-"another unfrozen string")
end
ruby_version_is ""..."2.6" do
it "does not deduplicate already frozen strings" do
dynamic = %w(this string is frozen).join(' ').freeze

View file

@ -2,452 +2,450 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
ruby_version_is '2.5' do
describe "String#undump" do
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
'"foo"'.taint.undump.tainted?.should == true
end
it "untrusts the result if self is untrusted" do
'"foo"'.untrust.undump.untrusted?.should == true
end
describe "String#undump" do
ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do
'"foo"'.taint.undump.tainted?.should == true
end
it "does not take into account if a string is frozen" do
'"foo"'.freeze.undump.frozen?.should == false
it "untrusts the result if self is untrusted" do
'"foo"'.untrust.undump.untrusted?.should == true
end
end
it "does not take into account if a string is frozen" do
'"foo"'.freeze.undump.frozen?.should == false
end
it "always returns String instance" do
StringSpecs::MyString.new('"foo"').undump.should be_an_instance_of(String)
end
it "strips outer \"" do
'"foo"'.undump.should == 'foo'
end
it "returns a string with special characters in \\<char> notation replaced with the characters" do
[ ['"\\a"', "\a"],
['"\\b"', "\b"],
['"\\t"', "\t"],
['"\\n"', "\n"],
['"\\v"', "\v"],
['"\\f"', "\f"],
['"\\r"', "\r"],
['"\\e"', "\e"]
].should be_computed_by(:undump)
end
it "returns a string with unescaped sequences \" and \\" do
[ ['"\\""' , "\""],
['"\\\\"', "\\"]
].should be_computed_by(:undump)
end
it "returns a string with unescaped sequences \\#<char> when # is followed by $, @, {" do
[ ['"\\#$PATH"', "\#$PATH"],
['"\\#@a"', "\#@a"],
['"\\#@@a"', "\#@@a"],
['"\\#{a}"', "\#{a}"]
].should be_computed_by(:undump)
end
it "returns a string with # not escaped when followed by any other character" do
[ ['"#"', '#'],
['"#1"', '#1']
].should be_computed_by(:undump)
end
it "returns a string with printable non-alphanumeric characters" do
[ ['" "', ' '],
['"!"', '!'],
['"$"', '$'],
['"%"', '%'],
['"&"', '&'],
['"\'"', '\''],
['"("', '('],
['")"', ')'],
['"*"', '*'],
['"+"', '+'],
['","', ','],
['"-"', '-'],
['"."', '.'],
['"/"', '/'],
['":"', ':'],
['";"', ';'],
['"<"', '<'],
['"="', '='],
['">"', '>'],
['"?"', '?'],
['"@"', '@'],
['"["', '['],
['"]"', ']'],
['"^"', '^'],
['"_"', '_'],
['"`"', '`'],
['"{"', '{'],
['"|"', '|'],
['"}"', '}'],
['"~"', '~']
].should be_computed_by(:undump)
end
it "returns a string with numeric characters unescaped" do
[ ['"0"', "0"],
['"1"', "1"],
['"2"', "2"],
['"3"', "3"],
['"4"', "4"],
['"5"', "5"],
['"6"', "6"],
['"7"', "7"],
['"8"', "8"],
['"9"', "9"],
].should be_computed_by(:undump)
end
it "returns a string with upper-case alpha characters unescaped" do
[ ['"A"', 'A'],
['"B"', 'B'],
['"C"', 'C'],
['"D"', 'D'],
['"E"', 'E'],
['"F"', 'F'],
['"G"', 'G'],
['"H"', 'H'],
['"I"', 'I'],
['"J"', 'J'],
['"K"', 'K'],
['"L"', 'L'],
['"M"', 'M'],
['"N"', 'N'],
['"O"', 'O'],
['"P"', 'P'],
['"Q"', 'Q'],
['"R"', 'R'],
['"S"', 'S'],
['"T"', 'T'],
['"U"', 'U'],
['"V"', 'V'],
['"W"', 'W'],
['"X"', 'X'],
['"Y"', 'Y'],
['"Z"', 'Z']
].should be_computed_by(:undump)
end
it "returns a string with lower-case alpha characters unescaped" do
[ ['"a"', 'a'],
['"b"', 'b'],
['"c"', 'c'],
['"d"', 'd'],
['"e"', 'e'],
['"f"', 'f'],
['"g"', 'g'],
['"h"', 'h'],
['"i"', 'i'],
['"j"', 'j'],
['"k"', 'k'],
['"l"', 'l'],
['"m"', 'm'],
['"n"', 'n'],
['"o"', 'o'],
['"p"', 'p'],
['"q"', 'q'],
['"r"', 'r'],
['"s"', 's'],
['"t"', 't'],
['"u"', 'u'],
['"v"', 'v'],
['"w"', 'w'],
['"x"', 'x'],
['"y"', 'y'],
['"z"', 'z']
].should be_computed_by(:undump)
end
it "returns a string with \\x notation replaced with non-printing ASCII character" do
[ ['"\\x00"', 0000.chr.force_encoding('utf-8')],
['"\\x01"', 0001.chr.force_encoding('utf-8')],
['"\\x02"', 0002.chr.force_encoding('utf-8')],
['"\\x03"', 0003.chr.force_encoding('utf-8')],
['"\\x04"', 0004.chr.force_encoding('utf-8')],
['"\\x05"', 0005.chr.force_encoding('utf-8')],
['"\\x06"', 0006.chr.force_encoding('utf-8')],
['"\\x0E"', 0016.chr.force_encoding('utf-8')],
['"\\x0F"', 0017.chr.force_encoding('utf-8')],
['"\\x10"', 0020.chr.force_encoding('utf-8')],
['"\\x11"', 0021.chr.force_encoding('utf-8')],
['"\\x12"', 0022.chr.force_encoding('utf-8')],
['"\\x13"', 0023.chr.force_encoding('utf-8')],
['"\\x14"', 0024.chr.force_encoding('utf-8')],
['"\\x15"', 0025.chr.force_encoding('utf-8')],
['"\\x16"', 0026.chr.force_encoding('utf-8')],
['"\\x17"', 0027.chr.force_encoding('utf-8')],
['"\\x18"', 0030.chr.force_encoding('utf-8')],
['"\\x19"', 0031.chr.force_encoding('utf-8')],
['"\\x1A"', 0032.chr.force_encoding('utf-8')],
['"\\x1C"', 0034.chr.force_encoding('utf-8')],
['"\\x1D"', 0035.chr.force_encoding('utf-8')],
['"\\x1E"', 0036.chr.force_encoding('utf-8')],
['"\\x1F"', 0037.chr.force_encoding('utf-8')],
['"\\x7F"', 0177.chr.force_encoding('utf-8')],
['"\\x80"', 0200.chr.force_encoding('utf-8')],
['"\\x81"', 0201.chr.force_encoding('utf-8')],
['"\\x82"', 0202.chr.force_encoding('utf-8')],
['"\\x83"', 0203.chr.force_encoding('utf-8')],
['"\\x84"', 0204.chr.force_encoding('utf-8')],
['"\\x85"', 0205.chr.force_encoding('utf-8')],
['"\\x86"', 0206.chr.force_encoding('utf-8')],
['"\\x87"', 0207.chr.force_encoding('utf-8')],
['"\\x88"', 0210.chr.force_encoding('utf-8')],
['"\\x89"', 0211.chr.force_encoding('utf-8')],
['"\\x8A"', 0212.chr.force_encoding('utf-8')],
['"\\x8B"', 0213.chr.force_encoding('utf-8')],
['"\\x8C"', 0214.chr.force_encoding('utf-8')],
['"\\x8D"', 0215.chr.force_encoding('utf-8')],
['"\\x8E"', 0216.chr.force_encoding('utf-8')],
['"\\x8F"', 0217.chr.force_encoding('utf-8')],
['"\\x90"', 0220.chr.force_encoding('utf-8')],
['"\\x91"', 0221.chr.force_encoding('utf-8')],
['"\\x92"', 0222.chr.force_encoding('utf-8')],
['"\\x93"', 0223.chr.force_encoding('utf-8')],
['"\\x94"', 0224.chr.force_encoding('utf-8')],
['"\\x95"', 0225.chr.force_encoding('utf-8')],
['"\\x96"', 0226.chr.force_encoding('utf-8')],
['"\\x97"', 0227.chr.force_encoding('utf-8')],
['"\\x98"', 0230.chr.force_encoding('utf-8')],
['"\\x99"', 0231.chr.force_encoding('utf-8')],
['"\\x9A"', 0232.chr.force_encoding('utf-8')],
['"\\x9B"', 0233.chr.force_encoding('utf-8')],
['"\\x9C"', 0234.chr.force_encoding('utf-8')],
['"\\x9D"', 0235.chr.force_encoding('utf-8')],
['"\\x9E"', 0236.chr.force_encoding('utf-8')],
['"\\x9F"', 0237.chr.force_encoding('utf-8')],
['"\\xA0"', 0240.chr.force_encoding('utf-8')],
['"\\xA1"', 0241.chr.force_encoding('utf-8')],
['"\\xA2"', 0242.chr.force_encoding('utf-8')],
['"\\xA3"', 0243.chr.force_encoding('utf-8')],
['"\\xA4"', 0244.chr.force_encoding('utf-8')],
['"\\xA5"', 0245.chr.force_encoding('utf-8')],
['"\\xA6"', 0246.chr.force_encoding('utf-8')],
['"\\xA7"', 0247.chr.force_encoding('utf-8')],
['"\\xA8"', 0250.chr.force_encoding('utf-8')],
['"\\xA9"', 0251.chr.force_encoding('utf-8')],
['"\\xAA"', 0252.chr.force_encoding('utf-8')],
['"\\xAB"', 0253.chr.force_encoding('utf-8')],
['"\\xAC"', 0254.chr.force_encoding('utf-8')],
['"\\xAD"', 0255.chr.force_encoding('utf-8')],
['"\\xAE"', 0256.chr.force_encoding('utf-8')],
['"\\xAF"', 0257.chr.force_encoding('utf-8')],
['"\\xB0"', 0260.chr.force_encoding('utf-8')],
['"\\xB1"', 0261.chr.force_encoding('utf-8')],
['"\\xB2"', 0262.chr.force_encoding('utf-8')],
['"\\xB3"', 0263.chr.force_encoding('utf-8')],
['"\\xB4"', 0264.chr.force_encoding('utf-8')],
['"\\xB5"', 0265.chr.force_encoding('utf-8')],
['"\\xB6"', 0266.chr.force_encoding('utf-8')],
['"\\xB7"', 0267.chr.force_encoding('utf-8')],
['"\\xB8"', 0270.chr.force_encoding('utf-8')],
['"\\xB9"', 0271.chr.force_encoding('utf-8')],
['"\\xBA"', 0272.chr.force_encoding('utf-8')],
['"\\xBB"', 0273.chr.force_encoding('utf-8')],
['"\\xBC"', 0274.chr.force_encoding('utf-8')],
['"\\xBD"', 0275.chr.force_encoding('utf-8')],
['"\\xBE"', 0276.chr.force_encoding('utf-8')],
['"\\xBF"', 0277.chr.force_encoding('utf-8')],
['"\\xC0"', 0300.chr.force_encoding('utf-8')],
['"\\xC1"', 0301.chr.force_encoding('utf-8')],
['"\\xC2"', 0302.chr.force_encoding('utf-8')],
['"\\xC3"', 0303.chr.force_encoding('utf-8')],
['"\\xC4"', 0304.chr.force_encoding('utf-8')],
['"\\xC5"', 0305.chr.force_encoding('utf-8')],
['"\\xC6"', 0306.chr.force_encoding('utf-8')],
['"\\xC7"', 0307.chr.force_encoding('utf-8')],
['"\\xC8"', 0310.chr.force_encoding('utf-8')],
['"\\xC9"', 0311.chr.force_encoding('utf-8')],
['"\\xCA"', 0312.chr.force_encoding('utf-8')],
['"\\xCB"', 0313.chr.force_encoding('utf-8')],
['"\\xCC"', 0314.chr.force_encoding('utf-8')],
['"\\xCD"', 0315.chr.force_encoding('utf-8')],
['"\\xCE"', 0316.chr.force_encoding('utf-8')],
['"\\xCF"', 0317.chr.force_encoding('utf-8')],
['"\\xD0"', 0320.chr.force_encoding('utf-8')],
['"\\xD1"', 0321.chr.force_encoding('utf-8')],
['"\\xD2"', 0322.chr.force_encoding('utf-8')],
['"\\xD3"', 0323.chr.force_encoding('utf-8')],
['"\\xD4"', 0324.chr.force_encoding('utf-8')],
['"\\xD5"', 0325.chr.force_encoding('utf-8')],
['"\\xD6"', 0326.chr.force_encoding('utf-8')],
['"\\xD7"', 0327.chr.force_encoding('utf-8')],
['"\\xD8"', 0330.chr.force_encoding('utf-8')],
['"\\xD9"', 0331.chr.force_encoding('utf-8')],
['"\\xDA"', 0332.chr.force_encoding('utf-8')],
['"\\xDB"', 0333.chr.force_encoding('utf-8')],
['"\\xDC"', 0334.chr.force_encoding('utf-8')],
['"\\xDD"', 0335.chr.force_encoding('utf-8')],
['"\\xDE"', 0336.chr.force_encoding('utf-8')],
['"\\xDF"', 0337.chr.force_encoding('utf-8')],
['"\\xE0"', 0340.chr.force_encoding('utf-8')],
['"\\xE1"', 0341.chr.force_encoding('utf-8')],
['"\\xE2"', 0342.chr.force_encoding('utf-8')],
['"\\xE3"', 0343.chr.force_encoding('utf-8')],
['"\\xE4"', 0344.chr.force_encoding('utf-8')],
['"\\xE5"', 0345.chr.force_encoding('utf-8')],
['"\\xE6"', 0346.chr.force_encoding('utf-8')],
['"\\xE7"', 0347.chr.force_encoding('utf-8')],
['"\\xE8"', 0350.chr.force_encoding('utf-8')],
['"\\xE9"', 0351.chr.force_encoding('utf-8')],
['"\\xEA"', 0352.chr.force_encoding('utf-8')],
['"\\xEB"', 0353.chr.force_encoding('utf-8')],
['"\\xEC"', 0354.chr.force_encoding('utf-8')],
['"\\xED"', 0355.chr.force_encoding('utf-8')],
['"\\xEE"', 0356.chr.force_encoding('utf-8')],
['"\\xEF"', 0357.chr.force_encoding('utf-8')],
['"\\xF0"', 0360.chr.force_encoding('utf-8')],
['"\\xF1"', 0361.chr.force_encoding('utf-8')],
['"\\xF2"', 0362.chr.force_encoding('utf-8')],
['"\\xF3"', 0363.chr.force_encoding('utf-8')],
['"\\xF4"', 0364.chr.force_encoding('utf-8')],
['"\\xF5"', 0365.chr.force_encoding('utf-8')],
['"\\xF6"', 0366.chr.force_encoding('utf-8')],
['"\\xF7"', 0367.chr.force_encoding('utf-8')],
['"\\xF8"', 0370.chr.force_encoding('utf-8')],
['"\\xF9"', 0371.chr.force_encoding('utf-8')],
['"\\xFA"', 0372.chr.force_encoding('utf-8')],
['"\\xFB"', 0373.chr.force_encoding('utf-8')],
['"\\xFC"', 0374.chr.force_encoding('utf-8')],
['"\\xFD"', 0375.chr.force_encoding('utf-8')],
['"\\xFE"', 0376.chr.force_encoding('utf-8')],
['"\\xFF"', 0377.chr.force_encoding('utf-8')]
].should be_computed_by(:undump)
end
it "returns a string with \\u{} notation replaced with multi-byte UTF-8 characters" do
[ ['"\u{80}"', 0200.chr('utf-8')],
['"\u{81}"', 0201.chr('utf-8')],
['"\u{82}"', 0202.chr('utf-8')],
['"\u{83}"', 0203.chr('utf-8')],
['"\u{84}"', 0204.chr('utf-8')],
['"\u{86}"', 0206.chr('utf-8')],
['"\u{87}"', 0207.chr('utf-8')],
['"\u{88}"', 0210.chr('utf-8')],
['"\u{89}"', 0211.chr('utf-8')],
['"\u{8a}"', 0212.chr('utf-8')],
['"\u{8b}"', 0213.chr('utf-8')],
['"\u{8c}"', 0214.chr('utf-8')],
['"\u{8d}"', 0215.chr('utf-8')],
['"\u{8e}"', 0216.chr('utf-8')],
['"\u{8f}"', 0217.chr('utf-8')],
['"\u{90}"', 0220.chr('utf-8')],
['"\u{91}"', 0221.chr('utf-8')],
['"\u{92}"', 0222.chr('utf-8')],
['"\u{93}"', 0223.chr('utf-8')],
['"\u{94}"', 0224.chr('utf-8')],
['"\u{95}"', 0225.chr('utf-8')],
['"\u{96}"', 0226.chr('utf-8')],
['"\u{97}"', 0227.chr('utf-8')],
['"\u{98}"', 0230.chr('utf-8')],
['"\u{99}"', 0231.chr('utf-8')],
['"\u{9a}"', 0232.chr('utf-8')],
['"\u{9b}"', 0233.chr('utf-8')],
['"\u{9c}"', 0234.chr('utf-8')],
['"\u{9d}"', 0235.chr('utf-8')],
['"\u{9e}"', 0236.chr('utf-8')],
['"\u{9f}"', 0237.chr('utf-8')],
].should be_computed_by(:undump)
end
it "returns a string with \\uXXXX notation replaced with multi-byte UTF-8 characters" do
[ ['"\u0080"', 0200.chr('utf-8')],
['"\u0081"', 0201.chr('utf-8')],
['"\u0082"', 0202.chr('utf-8')],
['"\u0083"', 0203.chr('utf-8')],
['"\u0084"', 0204.chr('utf-8')],
['"\u0086"', 0206.chr('utf-8')],
['"\u0087"', 0207.chr('utf-8')],
['"\u0088"', 0210.chr('utf-8')],
['"\u0089"', 0211.chr('utf-8')],
['"\u008a"', 0212.chr('utf-8')],
['"\u008b"', 0213.chr('utf-8')],
['"\u008c"', 0214.chr('utf-8')],
['"\u008d"', 0215.chr('utf-8')],
['"\u008e"', 0216.chr('utf-8')],
['"\u008f"', 0217.chr('utf-8')],
['"\u0090"', 0220.chr('utf-8')],
['"\u0091"', 0221.chr('utf-8')],
['"\u0092"', 0222.chr('utf-8')],
['"\u0093"', 0223.chr('utf-8')],
['"\u0094"', 0224.chr('utf-8')],
['"\u0095"', 0225.chr('utf-8')],
['"\u0096"', 0226.chr('utf-8')],
['"\u0097"', 0227.chr('utf-8')],
['"\u0098"', 0230.chr('utf-8')],
['"\u0099"', 0231.chr('utf-8')],
['"\u009a"', 0232.chr('utf-8')],
['"\u009b"', 0233.chr('utf-8')],
['"\u009c"', 0234.chr('utf-8')],
['"\u009d"', 0235.chr('utf-8')],
['"\u009e"', 0236.chr('utf-8')],
['"\u009f"', 0237.chr('utf-8')],
].should be_computed_by(:undump)
end
it "undumps correctly string produced from non ASCII-compatible one" do
s = "\u{876}".encode('utf-16be')
s.dump.undump.should == s
'"\\bv".force_encoding("UTF-16BE")'.undump.should == "\u0876".encode('utf-16be')
end
it "keeps origin encoding" do
'"foo"'.encode("ISO-8859-1").undump.encoding.should == Encoding::ISO_8859_1
'"foo"'.encode('windows-1251').undump.encoding.should == Encoding::Windows_1251
end
describe "Limitations" do
it "cannot undump non ASCII-compatible string" do
-> { '"foo"'.encode('utf-16le').undump }.should raise_error(Encoding::CompatibilityError)
end
end
describe "invalid dump" do
it "raises RuntimeError exception if wrapping \" are missing" do
-> { 'foo'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { '"foo'.undump }.should raise_error(RuntimeError, /unterminated dumped string/)
-> { 'foo"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { "'foo'".undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
it "always returns String instance" do
StringSpecs::MyString.new('"foo"').undump.should be_an_instance_of(String)
it "raises RuntimeError if there is incorrect \\x sequence" do
-> { '"\x"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
-> { '"\\x3y"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
end
it "strips outer \"" do
'"foo"'.undump.should == 'foo'
it "raises RuntimeError in there is incorrect \\u sequence" do
-> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u{"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u{3042"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
end
it "returns a string with special characters in \\<char> notation replaced with the characters" do
[ ['"\\a"', "\a"],
['"\\b"', "\b"],
['"\\t"', "\t"],
['"\\n"', "\n"],
['"\\v"', "\v"],
['"\\f"', "\f"],
['"\\r"', "\r"],
['"\\e"', "\e"]
].should be_computed_by(:undump)
it "raises RuntimeError if there is malformed dump of non ASCII-compatible string" do
-> { '"".force_encoding("BINARY"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { '"".force_encoding("Unknown")'.undump }.should raise_error(RuntimeError, /dumped string has unknown encoding name/)
-> { '"".force_encoding()'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
it "returns a string with unescaped sequences \" and \\" do
[ ['"\\""' , "\""],
['"\\\\"', "\\"]
].should be_computed_by(:undump)
it "raises RuntimeError if string contains \0 character" do
-> { "\"foo\0\"".undump }.should raise_error(RuntimeError, /string contains null byte/)
end
it "returns a string with unescaped sequences \\#<char> when # is followed by $, @, {" do
[ ['"\\#$PATH"', "\#$PATH"],
['"\\#@a"', "\#@a"],
['"\\#@@a"', "\#@@a"],
['"\\#{a}"', "\#{a}"]
].should be_computed_by(:undump)
it "raises RuntimeError if string contains non ASCII character" do
-> { "\"\u3042\"".undump }.should raise_error(RuntimeError, /non-ASCII character detected/)
end
it "returns a string with # not escaped when followed by any other character" do
[ ['"#"', '#'],
['"#1"', '#1']
].should be_computed_by(:undump)
end
it "returns a string with printable non-alphanumeric characters" do
[ ['" "', ' '],
['"!"', '!'],
['"$"', '$'],
['"%"', '%'],
['"&"', '&'],
['"\'"', '\''],
['"("', '('],
['")"', ')'],
['"*"', '*'],
['"+"', '+'],
['","', ','],
['"-"', '-'],
['"."', '.'],
['"/"', '/'],
['":"', ':'],
['";"', ';'],
['"<"', '<'],
['"="', '='],
['">"', '>'],
['"?"', '?'],
['"@"', '@'],
['"["', '['],
['"]"', ']'],
['"^"', '^'],
['"_"', '_'],
['"`"', '`'],
['"{"', '{'],
['"|"', '|'],
['"}"', '}'],
['"~"', '~']
].should be_computed_by(:undump)
end
it "returns a string with numeric characters unescaped" do
[ ['"0"', "0"],
['"1"', "1"],
['"2"', "2"],
['"3"', "3"],
['"4"', "4"],
['"5"', "5"],
['"6"', "6"],
['"7"', "7"],
['"8"', "8"],
['"9"', "9"],
].should be_computed_by(:undump)
end
it "returns a string with upper-case alpha characters unescaped" do
[ ['"A"', 'A'],
['"B"', 'B'],
['"C"', 'C'],
['"D"', 'D'],
['"E"', 'E'],
['"F"', 'F'],
['"G"', 'G'],
['"H"', 'H'],
['"I"', 'I'],
['"J"', 'J'],
['"K"', 'K'],
['"L"', 'L'],
['"M"', 'M'],
['"N"', 'N'],
['"O"', 'O'],
['"P"', 'P'],
['"Q"', 'Q'],
['"R"', 'R'],
['"S"', 'S'],
['"T"', 'T'],
['"U"', 'U'],
['"V"', 'V'],
['"W"', 'W'],
['"X"', 'X'],
['"Y"', 'Y'],
['"Z"', 'Z']
].should be_computed_by(:undump)
end
it "returns a string with lower-case alpha characters unescaped" do
[ ['"a"', 'a'],
['"b"', 'b'],
['"c"', 'c'],
['"d"', 'd'],
['"e"', 'e'],
['"f"', 'f'],
['"g"', 'g'],
['"h"', 'h'],
['"i"', 'i'],
['"j"', 'j'],
['"k"', 'k'],
['"l"', 'l'],
['"m"', 'm'],
['"n"', 'n'],
['"o"', 'o'],
['"p"', 'p'],
['"q"', 'q'],
['"r"', 'r'],
['"s"', 's'],
['"t"', 't'],
['"u"', 'u'],
['"v"', 'v'],
['"w"', 'w'],
['"x"', 'x'],
['"y"', 'y'],
['"z"', 'z']
].should be_computed_by(:undump)
end
it "returns a string with \\x notation replaced with non-printing ASCII character" do
[ ['"\\x00"', 0000.chr.force_encoding('utf-8')],
['"\\x01"', 0001.chr.force_encoding('utf-8')],
['"\\x02"', 0002.chr.force_encoding('utf-8')],
['"\\x03"', 0003.chr.force_encoding('utf-8')],
['"\\x04"', 0004.chr.force_encoding('utf-8')],
['"\\x05"', 0005.chr.force_encoding('utf-8')],
['"\\x06"', 0006.chr.force_encoding('utf-8')],
['"\\x0E"', 0016.chr.force_encoding('utf-8')],
['"\\x0F"', 0017.chr.force_encoding('utf-8')],
['"\\x10"', 0020.chr.force_encoding('utf-8')],
['"\\x11"', 0021.chr.force_encoding('utf-8')],
['"\\x12"', 0022.chr.force_encoding('utf-8')],
['"\\x13"', 0023.chr.force_encoding('utf-8')],
['"\\x14"', 0024.chr.force_encoding('utf-8')],
['"\\x15"', 0025.chr.force_encoding('utf-8')],
['"\\x16"', 0026.chr.force_encoding('utf-8')],
['"\\x17"', 0027.chr.force_encoding('utf-8')],
['"\\x18"', 0030.chr.force_encoding('utf-8')],
['"\\x19"', 0031.chr.force_encoding('utf-8')],
['"\\x1A"', 0032.chr.force_encoding('utf-8')],
['"\\x1C"', 0034.chr.force_encoding('utf-8')],
['"\\x1D"', 0035.chr.force_encoding('utf-8')],
['"\\x1E"', 0036.chr.force_encoding('utf-8')],
['"\\x1F"', 0037.chr.force_encoding('utf-8')],
['"\\x7F"', 0177.chr.force_encoding('utf-8')],
['"\\x80"', 0200.chr.force_encoding('utf-8')],
['"\\x81"', 0201.chr.force_encoding('utf-8')],
['"\\x82"', 0202.chr.force_encoding('utf-8')],
['"\\x83"', 0203.chr.force_encoding('utf-8')],
['"\\x84"', 0204.chr.force_encoding('utf-8')],
['"\\x85"', 0205.chr.force_encoding('utf-8')],
['"\\x86"', 0206.chr.force_encoding('utf-8')],
['"\\x87"', 0207.chr.force_encoding('utf-8')],
['"\\x88"', 0210.chr.force_encoding('utf-8')],
['"\\x89"', 0211.chr.force_encoding('utf-8')],
['"\\x8A"', 0212.chr.force_encoding('utf-8')],
['"\\x8B"', 0213.chr.force_encoding('utf-8')],
['"\\x8C"', 0214.chr.force_encoding('utf-8')],
['"\\x8D"', 0215.chr.force_encoding('utf-8')],
['"\\x8E"', 0216.chr.force_encoding('utf-8')],
['"\\x8F"', 0217.chr.force_encoding('utf-8')],
['"\\x90"', 0220.chr.force_encoding('utf-8')],
['"\\x91"', 0221.chr.force_encoding('utf-8')],
['"\\x92"', 0222.chr.force_encoding('utf-8')],
['"\\x93"', 0223.chr.force_encoding('utf-8')],
['"\\x94"', 0224.chr.force_encoding('utf-8')],
['"\\x95"', 0225.chr.force_encoding('utf-8')],
['"\\x96"', 0226.chr.force_encoding('utf-8')],
['"\\x97"', 0227.chr.force_encoding('utf-8')],
['"\\x98"', 0230.chr.force_encoding('utf-8')],
['"\\x99"', 0231.chr.force_encoding('utf-8')],
['"\\x9A"', 0232.chr.force_encoding('utf-8')],
['"\\x9B"', 0233.chr.force_encoding('utf-8')],
['"\\x9C"', 0234.chr.force_encoding('utf-8')],
['"\\x9D"', 0235.chr.force_encoding('utf-8')],
['"\\x9E"', 0236.chr.force_encoding('utf-8')],
['"\\x9F"', 0237.chr.force_encoding('utf-8')],
['"\\xA0"', 0240.chr.force_encoding('utf-8')],
['"\\xA1"', 0241.chr.force_encoding('utf-8')],
['"\\xA2"', 0242.chr.force_encoding('utf-8')],
['"\\xA3"', 0243.chr.force_encoding('utf-8')],
['"\\xA4"', 0244.chr.force_encoding('utf-8')],
['"\\xA5"', 0245.chr.force_encoding('utf-8')],
['"\\xA6"', 0246.chr.force_encoding('utf-8')],
['"\\xA7"', 0247.chr.force_encoding('utf-8')],
['"\\xA8"', 0250.chr.force_encoding('utf-8')],
['"\\xA9"', 0251.chr.force_encoding('utf-8')],
['"\\xAA"', 0252.chr.force_encoding('utf-8')],
['"\\xAB"', 0253.chr.force_encoding('utf-8')],
['"\\xAC"', 0254.chr.force_encoding('utf-8')],
['"\\xAD"', 0255.chr.force_encoding('utf-8')],
['"\\xAE"', 0256.chr.force_encoding('utf-8')],
['"\\xAF"', 0257.chr.force_encoding('utf-8')],
['"\\xB0"', 0260.chr.force_encoding('utf-8')],
['"\\xB1"', 0261.chr.force_encoding('utf-8')],
['"\\xB2"', 0262.chr.force_encoding('utf-8')],
['"\\xB3"', 0263.chr.force_encoding('utf-8')],
['"\\xB4"', 0264.chr.force_encoding('utf-8')],
['"\\xB5"', 0265.chr.force_encoding('utf-8')],
['"\\xB6"', 0266.chr.force_encoding('utf-8')],
['"\\xB7"', 0267.chr.force_encoding('utf-8')],
['"\\xB8"', 0270.chr.force_encoding('utf-8')],
['"\\xB9"', 0271.chr.force_encoding('utf-8')],
['"\\xBA"', 0272.chr.force_encoding('utf-8')],
['"\\xBB"', 0273.chr.force_encoding('utf-8')],
['"\\xBC"', 0274.chr.force_encoding('utf-8')],
['"\\xBD"', 0275.chr.force_encoding('utf-8')],
['"\\xBE"', 0276.chr.force_encoding('utf-8')],
['"\\xBF"', 0277.chr.force_encoding('utf-8')],
['"\\xC0"', 0300.chr.force_encoding('utf-8')],
['"\\xC1"', 0301.chr.force_encoding('utf-8')],
['"\\xC2"', 0302.chr.force_encoding('utf-8')],
['"\\xC3"', 0303.chr.force_encoding('utf-8')],
['"\\xC4"', 0304.chr.force_encoding('utf-8')],
['"\\xC5"', 0305.chr.force_encoding('utf-8')],
['"\\xC6"', 0306.chr.force_encoding('utf-8')],
['"\\xC7"', 0307.chr.force_encoding('utf-8')],
['"\\xC8"', 0310.chr.force_encoding('utf-8')],
['"\\xC9"', 0311.chr.force_encoding('utf-8')],
['"\\xCA"', 0312.chr.force_encoding('utf-8')],
['"\\xCB"', 0313.chr.force_encoding('utf-8')],
['"\\xCC"', 0314.chr.force_encoding('utf-8')],
['"\\xCD"', 0315.chr.force_encoding('utf-8')],
['"\\xCE"', 0316.chr.force_encoding('utf-8')],
['"\\xCF"', 0317.chr.force_encoding('utf-8')],
['"\\xD0"', 0320.chr.force_encoding('utf-8')],
['"\\xD1"', 0321.chr.force_encoding('utf-8')],
['"\\xD2"', 0322.chr.force_encoding('utf-8')],
['"\\xD3"', 0323.chr.force_encoding('utf-8')],
['"\\xD4"', 0324.chr.force_encoding('utf-8')],
['"\\xD5"', 0325.chr.force_encoding('utf-8')],
['"\\xD6"', 0326.chr.force_encoding('utf-8')],
['"\\xD7"', 0327.chr.force_encoding('utf-8')],
['"\\xD8"', 0330.chr.force_encoding('utf-8')],
['"\\xD9"', 0331.chr.force_encoding('utf-8')],
['"\\xDA"', 0332.chr.force_encoding('utf-8')],
['"\\xDB"', 0333.chr.force_encoding('utf-8')],
['"\\xDC"', 0334.chr.force_encoding('utf-8')],
['"\\xDD"', 0335.chr.force_encoding('utf-8')],
['"\\xDE"', 0336.chr.force_encoding('utf-8')],
['"\\xDF"', 0337.chr.force_encoding('utf-8')],
['"\\xE0"', 0340.chr.force_encoding('utf-8')],
['"\\xE1"', 0341.chr.force_encoding('utf-8')],
['"\\xE2"', 0342.chr.force_encoding('utf-8')],
['"\\xE3"', 0343.chr.force_encoding('utf-8')],
['"\\xE4"', 0344.chr.force_encoding('utf-8')],
['"\\xE5"', 0345.chr.force_encoding('utf-8')],
['"\\xE6"', 0346.chr.force_encoding('utf-8')],
['"\\xE7"', 0347.chr.force_encoding('utf-8')],
['"\\xE8"', 0350.chr.force_encoding('utf-8')],
['"\\xE9"', 0351.chr.force_encoding('utf-8')],
['"\\xEA"', 0352.chr.force_encoding('utf-8')],
['"\\xEB"', 0353.chr.force_encoding('utf-8')],
['"\\xEC"', 0354.chr.force_encoding('utf-8')],
['"\\xED"', 0355.chr.force_encoding('utf-8')],
['"\\xEE"', 0356.chr.force_encoding('utf-8')],
['"\\xEF"', 0357.chr.force_encoding('utf-8')],
['"\\xF0"', 0360.chr.force_encoding('utf-8')],
['"\\xF1"', 0361.chr.force_encoding('utf-8')],
['"\\xF2"', 0362.chr.force_encoding('utf-8')],
['"\\xF3"', 0363.chr.force_encoding('utf-8')],
['"\\xF4"', 0364.chr.force_encoding('utf-8')],
['"\\xF5"', 0365.chr.force_encoding('utf-8')],
['"\\xF6"', 0366.chr.force_encoding('utf-8')],
['"\\xF7"', 0367.chr.force_encoding('utf-8')],
['"\\xF8"', 0370.chr.force_encoding('utf-8')],
['"\\xF9"', 0371.chr.force_encoding('utf-8')],
['"\\xFA"', 0372.chr.force_encoding('utf-8')],
['"\\xFB"', 0373.chr.force_encoding('utf-8')],
['"\\xFC"', 0374.chr.force_encoding('utf-8')],
['"\\xFD"', 0375.chr.force_encoding('utf-8')],
['"\\xFE"', 0376.chr.force_encoding('utf-8')],
['"\\xFF"', 0377.chr.force_encoding('utf-8')]
].should be_computed_by(:undump)
end
it "returns a string with \\u{} notation replaced with multi-byte UTF-8 characters" do
[ ['"\u{80}"', 0200.chr('utf-8')],
['"\u{81}"', 0201.chr('utf-8')],
['"\u{82}"', 0202.chr('utf-8')],
['"\u{83}"', 0203.chr('utf-8')],
['"\u{84}"', 0204.chr('utf-8')],
['"\u{86}"', 0206.chr('utf-8')],
['"\u{87}"', 0207.chr('utf-8')],
['"\u{88}"', 0210.chr('utf-8')],
['"\u{89}"', 0211.chr('utf-8')],
['"\u{8a}"', 0212.chr('utf-8')],
['"\u{8b}"', 0213.chr('utf-8')],
['"\u{8c}"', 0214.chr('utf-8')],
['"\u{8d}"', 0215.chr('utf-8')],
['"\u{8e}"', 0216.chr('utf-8')],
['"\u{8f}"', 0217.chr('utf-8')],
['"\u{90}"', 0220.chr('utf-8')],
['"\u{91}"', 0221.chr('utf-8')],
['"\u{92}"', 0222.chr('utf-8')],
['"\u{93}"', 0223.chr('utf-8')],
['"\u{94}"', 0224.chr('utf-8')],
['"\u{95}"', 0225.chr('utf-8')],
['"\u{96}"', 0226.chr('utf-8')],
['"\u{97}"', 0227.chr('utf-8')],
['"\u{98}"', 0230.chr('utf-8')],
['"\u{99}"', 0231.chr('utf-8')],
['"\u{9a}"', 0232.chr('utf-8')],
['"\u{9b}"', 0233.chr('utf-8')],
['"\u{9c}"', 0234.chr('utf-8')],
['"\u{9d}"', 0235.chr('utf-8')],
['"\u{9e}"', 0236.chr('utf-8')],
['"\u{9f}"', 0237.chr('utf-8')],
].should be_computed_by(:undump)
end
it "returns a string with \\uXXXX notation replaced with multi-byte UTF-8 characters" do
[ ['"\u0080"', 0200.chr('utf-8')],
['"\u0081"', 0201.chr('utf-8')],
['"\u0082"', 0202.chr('utf-8')],
['"\u0083"', 0203.chr('utf-8')],
['"\u0084"', 0204.chr('utf-8')],
['"\u0086"', 0206.chr('utf-8')],
['"\u0087"', 0207.chr('utf-8')],
['"\u0088"', 0210.chr('utf-8')],
['"\u0089"', 0211.chr('utf-8')],
['"\u008a"', 0212.chr('utf-8')],
['"\u008b"', 0213.chr('utf-8')],
['"\u008c"', 0214.chr('utf-8')],
['"\u008d"', 0215.chr('utf-8')],
['"\u008e"', 0216.chr('utf-8')],
['"\u008f"', 0217.chr('utf-8')],
['"\u0090"', 0220.chr('utf-8')],
['"\u0091"', 0221.chr('utf-8')],
['"\u0092"', 0222.chr('utf-8')],
['"\u0093"', 0223.chr('utf-8')],
['"\u0094"', 0224.chr('utf-8')],
['"\u0095"', 0225.chr('utf-8')],
['"\u0096"', 0226.chr('utf-8')],
['"\u0097"', 0227.chr('utf-8')],
['"\u0098"', 0230.chr('utf-8')],
['"\u0099"', 0231.chr('utf-8')],
['"\u009a"', 0232.chr('utf-8')],
['"\u009b"', 0233.chr('utf-8')],
['"\u009c"', 0234.chr('utf-8')],
['"\u009d"', 0235.chr('utf-8')],
['"\u009e"', 0236.chr('utf-8')],
['"\u009f"', 0237.chr('utf-8')],
].should be_computed_by(:undump)
end
it "undumps correctly string produced from non ASCII-compatible one" do
s = "\u{876}".encode('utf-16be')
s.dump.undump.should == s
'"\\bv".force_encoding("UTF-16BE")'.undump.should == "\u0876".encode('utf-16be')
end
it "keeps origin encoding" do
'"foo"'.encode("ISO-8859-1").undump.encoding.should == Encoding::ISO_8859_1
'"foo"'.encode('windows-1251').undump.encoding.should == Encoding::Windows_1251
end
describe "Limitations" do
it "cannot undump non ASCII-compatible string" do
-> { '"foo"'.encode('utf-16le').undump }.should raise_error(Encoding::CompatibilityError)
end
end
describe "invalid dump" do
it "raises RuntimeError exception if wrapping \" are missing" do
-> { 'foo'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { '"foo'.undump }.should raise_error(RuntimeError, /unterminated dumped string/)
-> { 'foo"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { "'foo'".undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
it "raises RuntimeError if there is incorrect \\x sequence" do
-> { '"\x"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
-> { '"\\x3y"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
end
it "raises RuntimeError in there is incorrect \\u sequence" do
-> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u{"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u{3042"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
-> { '"\\u"'.undump }.should raise_error(RuntimeError, /invalid Unicode escape/)
end
it "raises RuntimeError if there is malformed dump of non ASCII-compatible string" do
-> { '"".force_encoding("BINARY"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
-> { '"".force_encoding("Unknown")'.undump }.should raise_error(RuntimeError, /dumped string has unknown encoding name/)
-> { '"".force_encoding()'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
it "raises RuntimeError if string contains \0 character" do
-> { "\"foo\0\"".undump }.should raise_error(RuntimeError, /string contains null byte/)
end
it "raises RuntimeError if string contains non ASCII character" do
-> { "\"\u3042\"".undump }.should raise_error(RuntimeError, /non-ASCII character detected/)
end
it "raises RuntimeError if there are some excessive \"" do
-> { '" "" "'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
it "raises RuntimeError if there are some excessive \"" do
-> { '" "" "'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
end
end
end

View file

@ -25,14 +25,12 @@ describe "Struct#hash" do
s1.hash.should_not == s2.hash
end
ruby_version_is "2.5" do
it "returns different hashes for structs with different values when using keyword_init: true" do
key = :"1 non symbol member"
struct_class = Struct.new(key, keyword_init: true)
t1 = struct_class.new(key => 1)
t2 = struct_class.new(key => 2)
t1.hash.should_not == t2.hash
end
it "returns different hashes for structs with different values when using keyword_init: true" do
key = :"1 non symbol member"
struct_class = Struct.new(key, keyword_init: true)
t1 = struct_class.new(key => 1)
t2 = struct_class.new(key => 2)
t1.hash.should_not == t2.hash
end
it "allows for overriding methods in an included module" do

View file

@ -62,16 +62,8 @@ describe "Struct.new" do
-> { Struct.new(:animal, ['chris', 'evan']) }.should raise_error(TypeError)
end
ruby_version_is ""..."2.5" do
it "raises a TypeError if an argument is a Hash" do
-> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(TypeError)
end
end
ruby_version_is "2.5" do
it "raises a ArgumentError if passed a Hash with an unknown key" do
-> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
end
it "raises a ArgumentError if passed a Hash with an unknown key" do
-> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
end
it "raises ArgumentError when there is a duplicate member" do
@ -147,71 +139,69 @@ describe "Struct.new" do
end
end
ruby_version_is "2.5" do
context "keyword_init: true option" do
before :all do
@struct_with_kwa = Struct.new(:name, :legs, keyword_init: true)
end
it "creates a class that accepts keyword arguments to initialize" do
obj = @struct_with_kwa.new(name: "elefant", legs: 4)
obj.name.should == "elefant"
obj.legs.should == 4
end
it "raises when there is a duplicate member" do
-> { Struct.new(:foo, :foo, keyword_init: true) }.should raise_error(ArgumentError, "duplicate member: foo")
end
describe "new class instantiation" do
it "accepts arguments as hash as well" do
obj = @struct_with_kwa.new({name: "elefant", legs: 4})
obj.name.should == "elefant"
obj.legs.should == 4
end
it "allows missing arguments" do
obj = @struct_with_kwa.new(name: "elefant")
obj.name.should == "elefant"
obj.legs.should be_nil
end
it "allows no arguments" do
obj = @struct_with_kwa.new
obj.name.should be_nil
obj.legs.should be_nil
end
it "raises ArgumentError when passed not declared keyword argument" do
-> {
@struct_with_kwa.new(name: "elefant", legs: 4, foo: "bar")
}.should raise_error(ArgumentError, /unknown keywords: foo/)
end
it "raises ArgumentError when passed a list of arguments" do
-> {
@struct_with_kwa.new("elefant", 4)
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
it "raises ArgumentError when passed a single non-hash argument" do
-> {
@struct_with_kwa.new("elefant")
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
end
context "keyword_init: true option" do
before :all do
@struct_with_kwa = Struct.new(:name, :legs, keyword_init: true)
end
context "keyword_init: false option" do
before :all do
@struct_without_kwa = Struct.new(:name, :legs, keyword_init: false)
end
it "creates a class that accepts keyword arguments to initialize" do
obj = @struct_with_kwa.new(name: "elefant", legs: 4)
obj.name.should == "elefant"
obj.legs.should == 4
end
it "behaves like it does without :keyword_init option" do
obj = @struct_without_kwa.new("elefant", 4)
it "raises when there is a duplicate member" do
-> { Struct.new(:foo, :foo, keyword_init: true) }.should raise_error(ArgumentError, "duplicate member: foo")
end
describe "new class instantiation" do
it "accepts arguments as hash as well" do
obj = @struct_with_kwa.new({name: "elefant", legs: 4})
obj.name.should == "elefant"
obj.legs.should == 4
end
it "allows missing arguments" do
obj = @struct_with_kwa.new(name: "elefant")
obj.name.should == "elefant"
obj.legs.should be_nil
end
it "allows no arguments" do
obj = @struct_with_kwa.new
obj.name.should be_nil
obj.legs.should be_nil
end
it "raises ArgumentError when passed not declared keyword argument" do
-> {
@struct_with_kwa.new(name: "elefant", legs: 4, foo: "bar")
}.should raise_error(ArgumentError, /unknown keywords: foo/)
end
it "raises ArgumentError when passed a list of arguments" do
-> {
@struct_with_kwa.new("elefant", 4)
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
it "raises ArgumentError when passed a single non-hash argument" do
-> {
@struct_with_kwa.new("elefant")
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
end
end
context "keyword_init: false option" do
before :all do
@struct_without_kwa = Struct.new(:name, :legs, keyword_init: false)
end
it "behaves like it does without :keyword_init option" do
obj = @struct_without_kwa.new("elefant", 4)
obj.name.should == "elefant"
obj.legs.should == 4
end
end
end

View file

@ -1,38 +1,36 @@
require_relative '../../spec_helper'
ruby_version_is '2.5' do
describe 'Thread#fetch' do
describe 'with 2 arguments' do
it 'returns the value of the fiber-local variable if value has been assigned' do
th = Thread.new { Thread.current[:cat] = 'meow' }
th.join
th.fetch(:cat, true).should == 'meow'
end
it "returns the default value if fiber-local variable hasn't been assigned" do
th = Thread.new {}
th.join
th.fetch(:cat, true).should == true
end
describe 'Thread#fetch' do
describe 'with 2 arguments' do
it 'returns the value of the fiber-local variable if value has been assigned' do
th = Thread.new { Thread.current[:cat] = 'meow' }
th.join
th.fetch(:cat, true).should == 'meow'
end
describe 'with 1 argument' do
it 'raises a KeyError when the Thread does not have a fiber-local variable of the same name' do
th = Thread.new {}
th.join
-> { th.fetch(:cat) }.should raise_error(KeyError)
end
it 'returns the value of the fiber-local variable if value has been assigned' do
th = Thread.new { Thread.current[:cat] = 'meow' }
th.join
th.fetch(:cat).should == 'meow'
end
end
it 'raises an ArgumentError when not passed one or two arguments' do
-> { Thread.current.fetch() }.should raise_error(ArgumentError)
-> { Thread.current.fetch(1, 2, 3) }.should raise_error(ArgumentError)
it "returns the default value if fiber-local variable hasn't been assigned" do
th = Thread.new {}
th.join
th.fetch(:cat, true).should == true
end
end
describe 'with 1 argument' do
it 'raises a KeyError when the Thread does not have a fiber-local variable of the same name' do
th = Thread.new {}
th.join
-> { th.fetch(:cat) }.should raise_error(KeyError)
end
it 'returns the value of the fiber-local variable if value has been assigned' do
th = Thread.new { Thread.current[:cat] = 'meow' }
th.join
th.fetch(:cat).should == 'meow'
end
end
it 'raises an ArgumentError when not passed one or two arguments' do
-> { Thread.current.fetch() }.should raise_error(ArgumentError)
-> { Thread.current.fetch(1, 2, 3) }.should raise_error(ArgumentError)
end
end

View file

@ -1,16 +1,8 @@
require_relative '../../spec_helper'
describe "Thread.report_on_exception" do
ruby_version_is "2.4"..."2.5" do
it "defaults to false" do
ruby_exe("p Thread.report_on_exception").should == "false\n"
end
end
ruby_version_is "2.5" do
it "defaults to true" do
ruby_exe("p Thread.report_on_exception").should == "true\n"
end
it "defaults to true" do
ruby_exe("p Thread.report_on_exception").should == "true\n"
end
end
@ -33,14 +25,12 @@ describe "Thread.report_on_exception=" do
end
describe "Thread#report_on_exception" do
ruby_version_is "2.5" do
it "returns true for the main Thread" do
Thread.current.report_on_exception.should == true
end
it "returns true for the main Thread" do
Thread.current.report_on_exception.should == true
end
it "returns true for new Threads" do
Thread.new { Thread.current.report_on_exception }.value.should == true
end
it "returns true for new Threads" do
Thread.new { Thread.current.report_on_exception }.value.should == true
end
it "returns whether the Thread will print a backtrace if it exits with an exception" do

View file

@ -1,8 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/to_s'
ruby_version_is "2.5" do
describe "Thread#to_s" do
it_behaves_like :thread_to_s, :to_s
end
describe "Thread#to_s" do
it_behaves_like :thread_to_s, :to_s
end

View file

@ -144,59 +144,57 @@ describe "Time.at" do
end
end
ruby_version_is "2.5" do
describe "passed [Time, Numeric, format]" do
context ":nanosecond format" do
it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nanosecond).nsec.should == 123456789
end
describe "passed [Time, Numeric, format]" do
context ":nanosecond format" do
it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nanosecond).nsec.should == 123456789
end
end
context ":nsec format" do
it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nsec).nsec.should == 123456789
end
end
context ":microsecond format" do
it "treats second argument as microseconds" do
Time.at(0, 123456, :microsecond).nsec.should == 123456000
end
end
context ":usec format" do
it "treats second argument as microseconds" do
Time.at(0, 123456, :usec).nsec.should == 123456000
end
end
context ":millisecond format" do
it "treats second argument as milliseconds" do
Time.at(0, 123, :millisecond).nsec.should == 123000000
end
end
context "not supported format" do
it "raises ArgumentError" do
-> { Time.at(0, 123456, 2) }.should raise_error(ArgumentError)
-> { Time.at(0, 123456, nil) }.should raise_error(ArgumentError)
-> { Time.at(0, 123456, :invalid) }.should raise_error(ArgumentError)
end
context ":nsec format" do
it "treats second argument as nanoseconds" do
Time.at(0, 123456789, :nsec).nsec.should == 123456789
end
it "does not try to convert format to Symbol with #to_sym" do
format = "usec"
format.should_not_receive(:to_sym)
-> { Time.at(0, 123456, format) }.should raise_error(ArgumentError)
end
end
context ":microsecond format" do
it "treats second argument as microseconds" do
Time.at(0, 123456, :microsecond).nsec.should == 123456000
end
end
context ":usec format" do
it "treats second argument as microseconds" do
Time.at(0, 123456, :usec).nsec.should == 123456000
end
end
context ":millisecond format" do
it "treats second argument as milliseconds" do
Time.at(0, 123, :millisecond).nsec.should == 123000000
end
end
context "not supported format" do
it "raises ArgumentError" do
-> { Time.at(0, 123456, 2) }.should raise_error(ArgumentError)
-> { Time.at(0, 123456, nil) }.should raise_error(ArgumentError)
-> { Time.at(0, 123456, :invalid) }.should raise_error(ArgumentError)
end
it "does not try to convert format to Symbol with #to_sym" do
format = "usec"
format.should_not_receive(:to_sym)
-> { Time.at(0, 123456, format) }.should raise_error(ArgumentError)
end
end
it "supports Float second argument" do
Time.at(0, 123456789.500, :nanosecond).nsec.should == 123456789
Time.at(0, 123456789.500, :nsec).nsec.should == 123456789
Time.at(0, 123456.500, :microsecond).nsec.should == 123456500
Time.at(0, 123456.500, :usec).nsec.should == 123456500
Time.at(0, 123.500, :millisecond).nsec.should == 123500000
end
it "supports Float second argument" do
Time.at(0, 123456789.500, :nanosecond).nsec.should == 123456789
Time.at(0, 123456789.500, :nsec).nsec.should == 123456789
Time.at(0, 123456.500, :microsecond).nsec.should == 123456500
Time.at(0, 123456.500, :usec).nsec.should == 123456500
Time.at(0, 123.500, :millisecond).nsec.should == 123500000
end
end

View file

@ -18,18 +18,16 @@ describe :time_now, shared: true do
end
end
guard_not -> { platform_is :windows and ruby_version_is ""..."2.5" } do
it "has at least microsecond precision" do
times = []
10_000.times do
times << Time.now.nsec
end
# The clock should not be less accurate than expected (times should
# not all be a multiple of the next precision up, assuming precisions
# are multiples of ten.)
expected = 1_000
times.select { |t| t % (expected * 10) == 0 }.size.should_not == times.size
it "has at least microsecond precision" do
times = []
10_000.times do
times << Time.now.nsec
end
# The clock should not be less accurate than expected (times should
# not all be a multiple of the next precision up, assuming precisions
# are multiples of ten.)
expected = 1_000
times.select { |t| t % (expected * 10) == 0 }.size.should_not == times.size
end
end

View file

@ -55,10 +55,8 @@ describe 'TracePoint.new' do
-> { TracePoint.new(o) {}}.should raise_error(TypeError)
end
ruby_version_is "2.5" do
it 'expects to be called with a block' do
-> { TracePoint.new(:line) }.should raise_error(ArgumentError, "must be called with a block")
end
it 'expects to be called with a block' do
-> { TracePoint.new(:line) }.should raise_error(ArgumentError, "must be called with a block")
end
it "raises a Argument error when the given argument doesn't match an event name" do

View file

@ -51,16 +51,14 @@ describe "Warning.warn" do
end
end
ruby_version_is "2.5" do
it "is called by Kernel.warn" do
Warning.should_receive(:warn).with("Chunky bacon!\n")
verbose = $VERBOSE
$VERBOSE = false
begin
Kernel.warn("Chunky bacon!")
ensure
$VERBOSE = verbose
end
it "is called by Kernel.warn" do
Warning.should_receive(:warn).with("Chunky bacon!\n")
verbose = $VERBOSE
$VERBOSE = false
begin
Kernel.warn("Chunky bacon!")
ensure
$VERBOSE = verbose
end
end
end

View file

@ -317,10 +317,8 @@ describe "A block" do
@y.s(0) { 1 }.should == 1
end
ruby_version_is "2.5" do
it "may include a rescue clause" do
eval("@y.z do raise ArgumentError; rescue ArgumentError; 7; end").should == 7
end
it "may include a rescue clause" do
eval("@y.z do raise ArgumentError; rescue ArgumentError; 7; end").should == 7
end
end
@ -333,10 +331,8 @@ describe "A block" do
@y.s(0) { || 1 }.should == 1
end
ruby_version_is "2.5" do
it "may include a rescue clause" do
eval('@y.z do || raise ArgumentError; rescue ArgumentError; 7; end').should == 7
end
it "may include a rescue clause" do
eval('@y.z do || raise ArgumentError; rescue ArgumentError; 7; end').should == 7
end
end
@ -364,10 +360,8 @@ describe "A block" do
@y.s([1, 2]) { |a| a }.should == [1, 2]
end
ruby_version_is "2.5" do
it "may include a rescue clause" do
eval('@y.s(1) do |x| raise ArgumentError; rescue ArgumentError; 7; end').should == 7
end
it "may include a rescue clause" do
eval('@y.s(1) do |x| raise ArgumentError; rescue ArgumentError; 7; end').should == 7
end
end

View file

@ -425,18 +425,8 @@ end
describe "top-level constant lookup" do
context "on a class" do
ruby_version_is "" ... "2.5" do
it "searches Object successfully after searching other scopes" do
-> {
String::Hash.should == Hash
}.should complain(/toplevel constant Hash referenced by/)
end
end
ruby_version_is "2.5" do
it "does not search Object after searching other scopes" do
-> { String::Hash }.should raise_error(NameError)
end
it "does not search Object after searching other scopes" do
-> { String::Hash }.should raise_error(NameError)
end
end

View file

@ -756,16 +756,8 @@ describe "The defined? keyword for a scoped constant" do
defined?(DefinedSpecs::String).should be_nil
end
ruby_version_is ""..."2.5" do
it "returns 'constant' when a constant is defined on top-level but not on the class" do
defined?(DefinedSpecs::Basic::String).should == 'constant'
end
end
ruby_version_is "2.5" do
it "returns nil when a constant is defined on top-level but not on the class" do
defined?(DefinedSpecs::Basic::String).should be_nil
end
it "returns nil when a constant is defined on top-level but not on the class" do
defined?(DefinedSpecs::Basic::String).should be_nil
end
it "returns 'constant' if the scoped-scoped constant is defined" do

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