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' -Wunused-variable'
- LDFLAGS=-Wno-unused-command-line-argument - LDFLAGS=-Wno-unused-command-line-argument
- &rubyspec24 - &rubyspec25
name: Check ruby/spec version guards on Ruby 2.4 name: Check ruby/spec version guards on Ruby 2.5
language: ruby language: ruby
rvm: 2.4.9 rvm: 2.5.7
before_install: before_install:
install: install:
before_script: chmod -R u+w spec/ruby before_script: chmod -R u+w spec/ruby
# -j randomly hangs. # -j randomly hangs.
script: ruby -C spec/ruby ../mspec/bin/mspec . script: ruby -C spec/ruby ../mspec/bin/mspec .
after_failure: 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 - &rubyspec27
name: Check ruby/spec version guards on Ruby 2.7 name: Check ruby/spec version guards on Ruby 2.7
@ -435,7 +435,7 @@ matrix:
- <<: *pedanticism - <<: *pedanticism
- <<: *assertions - <<: *assertions
- <<: *baseruby - <<: *baseruby
- <<: *rubyspec24 - <<: *rubyspec25
- <<: *rubyspec27 - <<: *rubyspec27
- <<: *dependency - <<: *dependency
# Build every commit (Allowed Failures): # Build every commit (Allowed Failures):

View file

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

View file

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

View file

@ -1,20 +1,6 @@
require 'mspec/guards/version' require 'mspec/guards/version'
if RUBY_ENGINE == "ruby" 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) def Warning.warn(message)
# Suppress any warning inside the method to prevent recursion # Suppress any warning inside the method to prevent recursion
verbose = $VERBOSE verbose = $VERBOSE

View file

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

View file

@ -133,12 +133,12 @@ Here is a list of the most commonly-used guards:
#### Version guards #### Version guards
```ruby ```ruby
ruby_version_is ""..."2.4" do ruby_version_is ""..."2.6 do
# Specs for RUBY_VERSION < 2.4 # Specs for RUBY_VERSION < 2.6
end end
ruby_version_is "2.4" do ruby_version_is "2.6 do
# Specs for RUBY_VERSION >= 2.4 # Specs for RUBY_VERSION >= 2.6
end end
``` ```
@ -185,11 +185,11 @@ end
#### Combining guards #### Combining guards
```ruby ```ruby
guard -> { platform_is :windows and ruby_version_is ""..."2.5" } do guard -> { platform_is :windows and ruby_version_is ""..."2.6" } do
# Windows and RUBY_VERSION < 2.5 # Windows and RUBY_VERSION < 2.6
end 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 # The opposite
end 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) * [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby)
* [Opal](https://github.com/opal/opal/tree/master/spec) * [Opal](https://github.com/opal/opal/tree/master/spec)
ruby/spec describes the behavior of Ruby 2.4 and more recent Ruby versions. 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.4.x, 2.5.x, 2.6.x, 2.7.x, etc), and those are tested in TravisCI. More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.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. The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby.
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs. Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
@ -49,6 +49,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.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed)
* Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3) * Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3)
* Ruby 2.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea) * 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 ### Running the specs

View file

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

View file

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

View file

@ -109,20 +109,10 @@ describe "Array#flatten" do
-> { [@obj].flatten }.should raise_error(TypeError) -> { [@obj].flatten }.should raise_error(TypeError)
end end
ruby_version_is ""..."2.5" do it "calls respond_to_missing?(:to_ary, true) to try coercing" do
it "calls respond_to_missing?(:to_ary, false) to try coercing" do def @obj.respond_to_missing?(*args) ScratchPad << args; false end
def @obj.respond_to_missing?(*args) ScratchPad << args; false end [@obj].flatten.should == [@obj]
[@obj].flatten.should == [@obj] ScratchPad.recorded.should == [[:to_ary, true]]
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
end end
it "does not call #to_ary if not defined when #respond_to_missing? returns false" do 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 'fixtures/classes'
require_relative 'shared/unshift' require_relative 'shared/unshift'
ruby_version_is "2.5" do describe "Array#prepend" do
describe "Array#prepend" do it_behaves_like :array_unshift, :prepend
it_behaves_like :array_unshift, :prepend
end
end end

View file

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

View file

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

View file

@ -3,71 +3,69 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/common' require_relative 'fixtures/common'
ruby_version_is "2.5" do describe "Dir.children" do
describe "Dir.children" do before :all do
before :all do DirSpecs.create_mock_dirs
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 end
children.first.encoding.should equal(Encoding.find("filesystem"))
end
before :each do it "returns children encoded with the specified encoding" do
@internal = Encoding.default_internal dir = File.join(DirSpecs.mock_dir, 'special')
end children = Dir.children(dir, encoding: "euc-jp").sort
children.first.encoding.should equal(Encoding::EUC_JP)
end
after :all do it "returns children transcoded to the default internal encoding" do
DirSpecs.delete_mock_dirs Encoding.default_internal = Encoding::EUC_KR
end children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
children.first.encoding.should equal(Encoding::EUC_KR)
end
after :each do it "raises a SystemCallError if called with a nonexistent directory" do
Encoding.default_internal = @internal -> { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError)
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
end end
end end

View file

@ -1,51 +1,49 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/common' require_relative 'fixtures/common'
ruby_version_is "2.5" do describe "Dir.each_child" do
describe "Dir.each_child" do before :all do
before :all do DirSpecs.create_mock_dirs
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 end
after :all do describe "returned Enumerator" do
DirSpecs.delete_mock_dirs describe "size" do
end it "should return nil" do
Dir.each_child(DirSpecs.mock_dir).size.should == nil
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
end end
end end
end end

View file

@ -291,74 +291,72 @@ describe :dir_glob, shared: true do
end end
end end
ruby_version_is "2.5" do context ":base option passed" do
context ":base option passed" do before :each do
before :each do @mock_dir = File.expand_path tmp('dir_glob_mock')
@mock_dir = File.expand_path tmp('dir_glob_mock')
%w[ %w[
a/b/x a/b/x
a/b/c/y a/b/c/y
a/b/c/d/z a/b/c/d/z
].each do |path| ].each do |path|
file = File.join @mock_dir, path file = File.join @mock_dir, path
mkdir_p File.dirname(file) mkdir_p File.dirname(file)
touch file touch file
end
end end
end
after :each do after :each do
rm_r @mock_dir 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
end
it "matches entries only from within the specified directory" do it "handles nil as current directory path" do
path = File.join(@mock_dir, "a/b/c") Dir.chdir @mock_dir do
Dir.send(@method, "*", base: path).sort.should == %w( d y ) Dir.send(@method, "*", base: nil).should == %w( a )
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
end end
end end
end end

View file

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

View file

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

View file

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

View file

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

View file

@ -1,94 +1,92 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.5" do describe "Exception#full_message" 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
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 = RuntimeError.new("Some runtime error")
e.set_backtrace(["a.rb:1", "b.rb:2"]) e.set_backtrace(["a.rb:1", "b.rb:2"])
full_message = e.full_message e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m
full_message.should include "RuntimeError" e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m
full_message.should include "Some runtime error"
full_message.should include "a.rb:1"
full_message.should include "b.rb:2"
end end
ruby_version_is "2.5.1" do it "shows the caller if the exception has no backtrace" do
it "supports :highlight option and adds escape sequences to highlight some strings" do e = RuntimeError.new("Some runtime error")
e = RuntimeError.new("Some runtime error") e.backtrace.should == nil
full_message = e.full_message(highlight: false, order: :top)
full_message = e.full_message(highlight: true, order: :bottom) full_message.should include("#{__FILE__}:#{__LINE__-1}:in `")
full_message.should include "\e[1mTraceback\e[m (most recent call last)" full_message.should include("': Some runtime error (RuntimeError)\n")
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
end end
ruby_version_is "2.6" do it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do
it "contains cause of exception" do begin
begin line = __LINE__; raise "first line\nsecond line"
begin rescue => e
raise 'the cause' full_message = e.full_message(highlight: false, order: :top).lines
rescue full_message[0].should include("#{__FILE__}:#{line}:in `")
raise 'main exception' full_message[0].should include(": first line (RuntimeError)\n")
end full_message[1].should == "second line\n"
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 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 end

View file

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

View file

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

View file

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

View file

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

View file

@ -623,12 +623,10 @@ describe "File.open" do
end end
end end
ruby_version_is "2.5" do it "raises ArgumentError if mixing :newline and binary mode" do
it "raises ArgumentError if mixing :newline and binary mode" do -> {
-> { File.open(@file, "rb", newline: :universal) {}
File.open(@file, "rb", newline: :universal) {} }.should raise_error(ArgumentError, "newline decorator with binary mode")
}.should raise_error(ArgumentError, "newline decorator with binary mode")
end
end end
ruby_version_is "2.6" do 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") @file.send(@method).encoding.should == Encoding.find("euc-jp")
end end
ruby_version_is "2.5" do platform_is :linux do
platform_is :linux do guard -> { defined?(File::TMPFILE) } do
guard -> { defined?(File::TMPFILE) } do before :each do
before :each do @dir = tmp("tmpfilespec")
@dir = tmp("tmpfilespec") mkdir_p @dir
mkdir_p @dir end
end
after :each do after :each do
rm_r @dir rm_r @dir
end end
it "raises IOError if file was opened with File::TMPFILE" do it "raises IOError if file was opened with File::TMPFILE" do
begin begin
File.open(@dir, File::RDWR | File::TMPFILE) do |f| File.open(@dir, File::RDWR | File::TMPFILE) do |f|
-> { f.send(@method) }.should raise_error(IOError) -> { f.send(@method) }.should raise_error(IOError)
end
rescue Errno::EOPNOTSUPP, Errno::EINVAL, Errno::EISDIR
skip "no support from the filesystem"
end end
rescue Errno::EOPNOTSUPP, Errno::EINVAL, Errno::EISDIR
skip "no support from the filesystem"
end end
end end
end end

View file

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

View file

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

View file

@ -1,35 +1,11 @@
require_relative '../fixtures/classes' require_relative '../fixtures/classes'
describe :float_comparison_exception_in_coerce, shared: true do describe :float_comparison_exception_in_coerce, shared: true do
ruby_version_is ""..."2.5" do it "does not rescue exception raised in other#coerce" do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises ArgumentError" do b = mock("numeric with failed #coerce")
b = mock("numeric with failed #coerce") b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
b.should_receive(:coerce).and_raise(FloatSpecs::CoerceError)
# e.g. 1.0 > b # e.g. 1.0 > b
-> { -> { 1.0.send(@method, b) }.should raise_error(FloatSpecs::CoerceError)
-> { 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
end end
end end

View file

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

View file

@ -1,131 +1,129 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
ruby_version_is "2.5" do describe "Hash#transform_keys" do
describe "Hash#transform_keys" do before :each do
before :each do @hash = { a: 1, b: 2, c: 3 }
@hash = { a: 1, b: 2, c: 3 } end
end
it "returns new hash" do it "returns new hash" do
ret = @hash.transform_keys(&:succ) ret = @hash.transform_keys(&:succ)
ret.should_not equal(@hash) ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash) ret.should be_an_instance_of(Hash)
end end
it "sets the result as transformed keys with the given block" do it "sets the result as transformed keys with the given block" do
@hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 } @hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 }
end end
it "keeps last pair if new keys conflict" do it "keeps last pair if new keys conflict" do
@hash.transform_keys { |_| :a }.should == { a: 3 } @hash.transform_keys { |_| :a }.should == { a: 3 }
end end
it "makes both hashes to share values" do it "makes both hashes to share values" do
value = [1, 2, 3] value = [1, 2, 3]
new_hash = { a: value }.transform_keys(&:upcase) new_hash = { a: value }.transform_keys(&:upcase)
new_hash[:A].should equal(value) new_hash[:A].should equal(value)
end end
context "when no block is given" do context "when no block is given" do
it "returns a sized Enumerator" do it "returns a sized Enumerator" do
enumerator = @hash.transform_keys enumerator = @hash.transform_keys
enumerator.should be_an_instance_of(Enumerator) enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size enumerator.size.should == @hash.size
enumerator.each(&:succ).should == { b: 1, c: 2, d: 3 } 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
end end
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 before :each do
@hash = { a: 1, b: 2, c: 3, d: 4 } @hash.freeze
@initial_pairs = @hash.dup
end end
it "returns self" do it "raises a FrozenError on an empty hash" do
@hash.transform_keys!(&:succ).should equal(@hash) ->{ {}.freeze.transform_keys!(&:upcase) }.should raise_error(FrozenError)
end end
it "updates self as transformed values with the given block" do it "keeps pairs and raises a FrozenError" do
@hash.transform_keys!(&:to_s) ->{ @hash.transform_keys!(&:upcase) }.should raise_error(FrozenError)
@hash.should == { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 } @hash.should == @initial_pairs
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 end
context "when no block is given" do context "when no block is given" do
it "returns a sized Enumerator" do it "does not raise an exception" do
enumerator = @hash.transform_keys! @hash.transform_keys!.should be_an_instance_of(Enumerator)
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
end end
end end
end end

View file

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

View file

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

View file

@ -124,23 +124,11 @@ describe "Integer#<=>" do
@big <=> @num @big <=> @num
end end
ruby_version_is ""..."2.5" do it "lets the exception go through if #coerce raises an exception" do
it "returns nil if #coerce raises an exception" do @num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error"))
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError) -> {
-> { @big <=> @num
@result = (@big <=> @num) }.should raise_error(RuntimeError, "my error")
}.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
end end
it "raises an exception if #coerce raises a non-StandardError exception" do 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' require_relative 'shared/arithmetic_coerce'
describe "Integer#/" do describe "Integer#/" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_arithmetic_coerce_not_rescue, :/
it_behaves_like :integer_arithmetic_coerce_rescue, :/
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :/
end
context "fixnum" do context "fixnum" do
it "returns self divided by the given argument" 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' require_relative 'shared/comparison_coerce'
describe "Integer#>" do describe "Integer#>" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_comparison_coerce_not_rescue, :>
it_behaves_like :integer_comparison_coerce_rescue, :>
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>
end
context "fixnum" do context "fixnum" do
it "returns true if self is greater than the given argument" 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' require_relative 'shared/comparison_coerce'
describe "Integer#>=" do describe "Integer#>=" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_comparison_coerce_not_rescue, :>=
it_behaves_like :integer_comparison_coerce_rescue, :>=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>=
end
context "fixnum" do context "fixnum" do
it "returns true if self is greater than or equal to the given argument" 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' require_relative 'shared/comparison_coerce'
describe "Integer#<" do describe "Integer#<" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_comparison_coerce_not_rescue, :<
it_behaves_like :integer_comparison_coerce_rescue, :<
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<
end
context "fixnum" do context "fixnum" do
it "returns true if self is less than the given argument" 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' require_relative 'shared/comparison_coerce'
describe "Integer#<=" do describe "Integer#<=" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_comparison_coerce_not_rescue, :<=
it_behaves_like :integer_comparison_coerce_rescue, :<=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<=
end
context "fixnum" do context "fixnum" do
it "returns true if self is less than or equal to other" 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' require_relative 'shared/arithmetic_coerce'
describe "Integer#-" do describe "Integer#-" do
ruby_version_is "2.4"..."2.5" do it_behaves_like :integer_arithmetic_coerce_not_rescue, :-
it_behaves_like :integer_arithmetic_coerce_rescue, :-
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :-
end
context "fixnum" do context "fixnum" do
it "returns self minus the given Integer" do it "returns self minus the given Integer" do

View file

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

View file

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

View file

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

View file

@ -6,14 +6,6 @@ describe "Integer#round" do
it_behaves_like :integer_to_i, :round it_behaves_like :integer_to_i, :round
it_behaves_like :integer_rounding_positive_precision, :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 # redmine:5228
it "returns itself rounded if passed a negative value" do it "returns itself rounded if passed a negative value" do
+249.round(-2).should eql(+200) +249.round(-2).should eql(+200)
@ -78,20 +70,10 @@ describe "Integer#round" do
(-25).round(-1, half: nil).should eql(-30) (-25).round(-1, half: nil).should eql(-30)
end end
ruby_version_is "2.4"..."2.5" do it "returns itself if passed a positive precision and the half option" 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)
35.round(1, half: :up).should eql(35.0) 35.round(1, half: :down).should eql(35)
35.round(1, half: :down).should eql(35.0) 35.round(1, half: :even).should eql(35)
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
end end
it "raises ArgumentError for an unknown rounding mode" do it "raises ArgumentError for an unknown rounding mode" do

View file

@ -1,25 +1,5 @@
require_relative '../fixtures/classes' 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 describe :integer_arithmetic_coerce_not_rescue, shared: true do
it "does not rescue exception raised in other#coerce" do it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce") b = mock("numeric with failed #coerce")

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -87,71 +87,69 @@ describe "Kernel#warn" do
}.should output(nil, "to_s called\n") }.should output(nil, "to_s called\n")
end end
ruby_version_is "2.5" do describe ":uplevel keyword argument" do
describe ":uplevel keyword argument" do before :each do
before :each do $VERBOSE = true
$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
end end
it "treats empty hash as no keyword argument" do it "prepends a message with specified line from the backtrace" do
h = {} w = KernelSpecs::WarnInNestedCall.new
-> { warn(**h) }.should_not complain(verbose: true)
-> { warn('foo', **h) }.should complain("foo\n") -> { 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
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 end

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -393,44 +393,22 @@ describe "Module#refine" do
end end
end end
ruby_version_is "" ... "2.5" do it "is honored by string interpolation" do
it "is not honored by string interpolation" do refinement = Module.new do
refinement = Module.new do refine Integer do
refine Integer do def to_s
def to_s "foo"
"foo"
end
end end
end end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "1"
end end
end
ruby_version_is "2.5" do result = nil
it "is honored by string interpolation" do Module.new do
refinement = Module.new do using refinement
refine Integer do result = "#{1}"
def to_s
"foo"
end
end
end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "foo"
end end
result.should == "foo"
end end
it "is honored by Kernel#binding" do 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 } @module = Module.new { def method_to_remove; end }
end end
ruby_version_is ''...'2.5' do it "is a public method" do
it "is a private method" do Module.should have_public_instance_method(:remove_method, false)
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
end end
it "removes the method from a class" do 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 } @module = Module.new { def method_to_undef; end }
end end
ruby_version_is ''...'2.5' do it "is a public method" do
it "is a private method" do Module.should have_public_instance_method(:undef_method, false)
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
end end
it "requires multiple arguments" do it "requires multiple arguments" do

View file

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

View file

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

View file

@ -13,25 +13,23 @@ describe "Process.times" do
Process.times.utime.should > user Process.times.utime.should > user
end end
ruby_version_is "2.5" do platform_is_not :windows do
platform_is_not :windows do it "uses getrusage when available to improve precision beyond milliseconds" do
it "uses getrusage when available to improve precision beyond milliseconds" do max = 10_000
max = 10_000 has_getrusage = max.times.find do
has_getrusage = max.times.find do time = Process.clock_gettime(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID)
time = Process.clock_gettime(:GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID) ('%.6f' % time).end_with?('000')
('%.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
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 end
end end

View file

@ -1,9 +1,6 @@
# -*- encoding: binary -*-
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'shared/urandom' require_relative 'shared/urandom'
ruby_version_is "2.5" do describe "Random.urandom" do
describe "Random.urandom" do it_behaves_like :random_urandom, :urandom
it_behaves_like :random_urandom, :urandom
end
end 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) -> { Range.new(a, b) }.should raise_error(ArgumentError)
end end
ruby_version_is "2.5" do it "does not rescue exception raised in #<=> when compares the given start and end" do
it "does not rescue exception raised in #<=> when compares the given start and end" do b = mock('a')
b = mock('a') a = mock('b')
a = mock('b') a.should_receive(:<=>).with(b).and_raise(RangeSpecs::ComparisonError)
a.should_receive(:<=>).with(b).and_raise(RangeSpecs::ComparisonError)
-> { Range.new(a, b) }.should raise_error(RangeSpecs::ComparisonError) -> { Range.new(a, b) }.should raise_error(RangeSpecs::ComparisonError)
end
end end
describe "beginless/endless range" do describe "beginless/endless range" do

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -50,18 +50,9 @@ describe "String#%" do
end end
end end
ruby_version_is ""..."2.5" do it "raises an error if single % appears at the end" do
it "formats single % character at the end as literal %" do -> { ("%" % []) }.should raise_error(ArgumentError)
("%" % []).should == "%" -> { ("foo%" % [])}.should raise_error(ArgumentError)
("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
end end
it "formats single % character before a newline as literal %" do 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"] a.should == ["one\ntwo\r\nthree"]
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
it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do a = []
a = [] "hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
"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.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n"]
a = [] a = []
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s } "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"] a.should == ["hello\nworld\n\n", "and\nuniverse\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
end end
describe "uses $/" do describe "uses $/" do

View file

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

View file

@ -18,22 +18,20 @@ describe 'String#-@' do
output.should == 'foo' output.should == 'foo'
end end
ruby_version_is "2.5" do it "returns the same object for equal unfrozen strings" do
it "returns the same object for equal unfrozen strings" do origin = "this is a string"
origin = "this is a string" dynamic = %w(this is a string).join(' ')
dynamic = %w(this is a string).join(' ')
origin.should_not equal(dynamic) origin.should_not equal(dynamic)
(-origin).should 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
end 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 it "does not deduplicate already frozen strings" do
dynamic = %w(this string is frozen).join(' ').freeze dynamic = %w(this string is frozen).join(' ').freeze

View file

@ -2,452 +2,450 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
ruby_version_is '2.5' do describe "String#undump" do
describe "String#undump" do ruby_version_is ''...'2.7' do
ruby_version_is ''...'2.7' do it "taints the result if self is tainted" do
it "taints the result if self is tainted" do '"foo"'.taint.undump.tainted?.should == true
'"foo"'.taint.undump.tainted?.should == true
end
it "untrusts the result if self is untrusted" do
'"foo"'.untrust.undump.untrusted?.should == true
end
end end
it "does not take into account if a string is frozen" do it "untrusts the result if self is untrusted" do
'"foo"'.freeze.undump.frozen?.should == false '"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 end
it "always returns String instance" do it "raises RuntimeError if there is incorrect \\x sequence" do
StringSpecs::MyString.new('"foo"').undump.should be_an_instance_of(String) -> { '"\x"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
-> { '"\\x3y"'.undump }.should raise_error(RuntimeError, /invalid hex escape/)
end end
it "strips outer \"" do it "raises RuntimeError in there is incorrect \\u sequence" do
'"foo"'.undump.should == 'foo' -> { '"\\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 end
it "returns a string with special characters in \\<char> notation replaced with the characters" do it "raises RuntimeError if there is malformed dump of non ASCII-compatible string" do
[ ['"\\a"', "\a"], -> { '"".force_encoding("BINARY"'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
['"\\b"', "\b"], -> { '"".force_encoding("Unknown")'.undump }.should raise_error(RuntimeError, /dumped string has unknown encoding name/)
['"\\t"', "\t"], -> { '"".force_encoding()'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
['"\\n"', "\n"],
['"\\v"', "\v"],
['"\\f"', "\f"],
['"\\r"', "\r"],
['"\\e"', "\e"]
].should be_computed_by(:undump)
end end
it "returns a string with unescaped sequences \" and \\" do it "raises RuntimeError if string contains \0 character" do
[ ['"\\""' , "\""], -> { "\"foo\0\"".undump }.should raise_error(RuntimeError, /string contains null byte/)
['"\\\\"', "\\"]
].should be_computed_by(:undump)
end end
it "returns a string with unescaped sequences \\#<char> when # is followed by $, @, {" do it "raises RuntimeError if string contains non ASCII character" do
[ ['"\\#$PATH"', "\#$PATH"], -> { "\"\u3042\"".undump }.should raise_error(RuntimeError, /non-ASCII character detected/)
['"\\#@a"', "\#@a"],
['"\\#@@a"', "\#@@a"],
['"\\#{a}"', "\#{a}"]
].should be_computed_by(:undump)
end end
it "returns a string with # not escaped when followed by any other character" do it "raises RuntimeError if there are some excessive \"" do
[ ['"#"', '#'], -> { '" "" "'.undump }.should raise_error(RuntimeError, /invalid dumped string/)
['"#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
end end
end end
end end

View file

@ -25,14 +25,12 @@ describe "Struct#hash" do
s1.hash.should_not == s2.hash s1.hash.should_not == s2.hash
end end
ruby_version_is "2.5" do it "returns different hashes for structs with different values when using keyword_init: true" do
it "returns different hashes for structs with different values when using keyword_init: true" do key = :"1 non symbol member"
key = :"1 non symbol member" struct_class = Struct.new(key, keyword_init: true)
struct_class = Struct.new(key, keyword_init: true) t1 = struct_class.new(key => 1)
t1 = struct_class.new(key => 1) t2 = struct_class.new(key => 2)
t2 = struct_class.new(key => 2) t1.hash.should_not == t2.hash
t1.hash.should_not == t2.hash
end
end end
it "allows for overriding methods in an included module" do 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) -> { Struct.new(:animal, ['chris', 'evan']) }.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
it "raises a TypeError if an argument is a Hash" do -> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
-> { 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
end end
it "raises ArgumentError when there is a duplicate member" do it "raises ArgumentError when there is a duplicate member" do
@ -147,71 +139,69 @@ describe "Struct.new" do
end end
end end
ruby_version_is "2.5" do context "keyword_init: true option" do
context "keyword_init: true option" do before :all do
before :all do @struct_with_kwa = Struct.new(:name, :legs, keyword_init: true)
@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
end end
context "keyword_init: false option" do it "creates a class that accepts keyword arguments to initialize" do
before :all do obj = @struct_with_kwa.new(name: "elefant", legs: 4)
@struct_without_kwa = Struct.new(:name, :legs, keyword_init: false) obj.name.should == "elefant"
end obj.legs.should == 4
end
it "behaves like it does without :keyword_init option" do it "raises when there is a duplicate member" do
obj = @struct_without_kwa.new("elefant", 4) -> { 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.name.should == "elefant"
obj.legs.should == 4 obj.legs.should == 4
end 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 end
end end

View file

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

View file

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

View file

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

View file

@ -18,18 +18,16 @@ describe :time_now, shared: true do
end end
end end
guard_not -> { platform_is :windows and ruby_version_is ""..."2.5" } do it "has at least microsecond precision" do
it "has at least microsecond precision" do times = []
times = [] 10_000.times do
10_000.times do times << Time.now.nsec
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
# 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
end end

View file

@ -55,10 +55,8 @@ describe 'TracePoint.new' do
-> { TracePoint.new(o) {}}.should raise_error(TypeError) -> { TracePoint.new(o) {}}.should raise_error(TypeError)
end end
ruby_version_is "2.5" do it 'expects to be called with a block' do
it 'expects to be called with a block' do -> { TracePoint.new(:line) }.should raise_error(ArgumentError, "must be called with a block")
-> { TracePoint.new(:line) }.should raise_error(ArgumentError, "must be called with a block")
end
end end
it "raises a Argument error when the given argument doesn't match an event name" do 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
end end
ruby_version_is "2.5" do it "is called by Kernel.warn" do
it "is called by Kernel.warn" do Warning.should_receive(:warn).with("Chunky bacon!\n")
Warning.should_receive(:warn).with("Chunky bacon!\n") verbose = $VERBOSE
verbose = $VERBOSE $VERBOSE = false
$VERBOSE = false begin
begin Kernel.warn("Chunky bacon!")
Kernel.warn("Chunky bacon!") ensure
ensure $VERBOSE = verbose
$VERBOSE = verbose
end
end end
end end
end end

View file

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

View file

@ -425,18 +425,8 @@ end
describe "top-level constant lookup" do describe "top-level constant lookup" do
context "on a class" do context "on a class" do
ruby_version_is "" ... "2.5" do it "does not search Object after searching other scopes" do
it "searches Object successfully after searching other scopes" do -> { String::Hash }.should raise_error(NameError)
-> {
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
end end
end end

View file

@ -756,16 +756,8 @@ describe "The defined? keyword for a scoped constant" do
defined?(DefinedSpecs::String).should be_nil defined?(DefinedSpecs::String).should be_nil
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
it "returns 'constant' when a constant is defined on top-level but not on the class" do defined?(DefinedSpecs::Basic::String).should be_nil
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
end end
it "returns 'constant' if the scoped-scoped constant is defined" do 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