1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61285 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-12-15 17:44:37 +00:00
parent f941bdf263
commit 30ed82e772
39 changed files with 1078 additions and 105 deletions

View file

@ -32,9 +32,6 @@ Lint/LiteralAsCondition:
Lint/UnneededRequireStatement:
Enabled: false
Lint/RescueWithoutErrorClass:
Enabled: false
Lint/UnifiedInteger:
Enabled: false

View file

@ -1,18 +1,11 @@
# This configuration was generated by
# `rubocop --auto-gen-config`
# on 2017-10-09 20:22:01 +0200 using RuboCop version 0.50.0.
# on 2017-12-15 22:14:22 +0900 using RuboCop version 0.52.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 3
Lint/CircularArgumentReference:
Exclude:
- 'language/block_spec.rb'
- 'language/def_spec.rb'
- 'language/lambda_spec.rb'
# Offense count: 2
Lint/DuplicateCaseCondition:
Exclude:
@ -44,15 +37,13 @@ Lint/FloatOutOfRange:
Exclude:
- 'core/string/modulo_spec.rb'
# Offense count: 43
# Offense count: 107
Lint/FormatParameterMismatch:
Exclude:
- 'core/kernel/sprintf_spec.rb'
- 'core/string/modulo_spec.rb'
- 'core/kernel/shared/sprintf.rb'
- 'core/kernel/shared/sprintf_encoding.rb'
- 'core/string/modulo_spec.rb'
# Offense count: 25
# Offense count: 28
Lint/HandleExceptions:
Enabled: false
@ -70,7 +61,7 @@ Lint/IneffectiveAccessModifier:
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# Configuration parameters: EnforcedStyle.
# SupportedStyles: runtime_error, standard_error
Lint/InheritException:
Exclude:
@ -84,6 +75,7 @@ Lint/LiteralInInterpolation:
Exclude:
- 'language/defined_spec.rb'
- 'language/fixtures/squiggly_heredoc.rb'
- 'core/module/refine_spec.rb'
# Offense count: 16
Lint/Loop:
@ -112,7 +104,13 @@ Lint/ParenthesesAsGroupedExpression:
- 'language/method_spec.rb'
- 'library/socket/socket/getaddrinfo_spec.rb'
# Offense count: 22
# Offense count: 1
# Cop supports --auto-correct.
Lint/RedundantWithIndex:
Exclude:
- 'core/enumerator/with_index_spec.rb'
# Offense count: 24
Lint/RescueException:
Exclude:
- 'command_line/fixtures/debug_info.rb'
@ -136,6 +134,12 @@ Lint/ScriptPermission:
Exclude:
- 'command_line/fixtures/bin/launcher.rb'
# Offense count: 2
# Configuration parameters: IgnoreImplicitReferences.
Lint/ShadowedArgument:
Exclude:
- 'language/fixtures/super.rb'
# Offense count: 10
Lint/ShadowingOuterLocalVariable:
Exclude:
@ -156,12 +160,11 @@ Lint/UnderscorePrefixedVariableName:
- 'core/io/popen_spec.rb'
- 'language/block_spec.rb'
# Offense count: 91
# Offense count: 90
# Cop supports --auto-correct.
Lint/UnneededSplatExpansion:
Exclude:
- 'core/array/element_reference_spec.rb'
- 'core/array/unshift_spec.rb'
- 'core/enumerable/fixtures/classes.rb'
- 'core/enumerable/max_by_spec.rb'
- 'core/enumerable/min_by_spec.rb'
@ -176,7 +179,7 @@ Lint/UnneededSplatExpansion:
- 'language/send_spec.rb'
- 'language/variables_spec.rb'
# Offense count: 55
# Offense count: 54
Lint/UnreachableCode:
Exclude:
- 'core/enumerator/lazy/fixtures/classes.rb'

View file

@ -3,7 +3,7 @@ language: ruby
install:
- git clone https://github.com/ruby/mspec.git ../mspec
script:
- if [ -n "$RUBOCOP" ]; then gem install rubocop -v 0.51.0 && rubocop; fi
- if [ -n "$RUBOCOP" ]; then gem install rubocop -v 0.52.0 && rubocop; fi
- ../mspec/bin/mspec $MSPEC_OPTS
matrix:
include:

View file

@ -2,6 +2,7 @@
[![Build Status](https://travis-ci.org/ruby/spec.svg)](https://travis-ci.org/ruby/spec)
[![Build Status](https://ci.appveyor.com/api/projects/status/1gs6f399320o44b1?svg=true)](https://ci.appveyor.com/project/eregon/spec-x948i)
[![Gitter](https://badges.gitter.im/ruby/spec.svg)](https://gitter.im/ruby/spec)
The Ruby Spec Suite is a test suite for the behavior of the Ruby programming language.

View file

@ -0,0 +1,72 @@
# encoding: utf-8
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/common', __FILE__)
ruby_version_is "2.5" do
describe "Dir.children" do
before :all do
DirSpecs.create_mock_dirs
end
before :each do
@internal = Encoding.default_internal
end
after :all do
DirSpecs.delete_mock_dirs
end
after :each do
Encoding.default_internal = @internal
end
it "returns an Array of filenames in an existing directory including dotfiles" do
a = Dir.children(DirSpecs.mock_dir).sort
a.should == DirSpecs.expected_paths - %w[. ..]
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested").sort
a.should == %w|.dotfile.ext directory|
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.children(p)
end
it "accepts an options Hash" do
a = Dir.children("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort
a.should == %w|.dotfile.ext directory|
end
it "returns children encoded with the filesystem encoding by default" do
# This spec depends on the locale not being US-ASCII because if it is, the
# children that are not ascii_only? will be ASCII-8BIT encoded.
children = Dir.children(File.join(DirSpecs.mock_dir, 'special')).sort
encoding = Encoding.find("filesystem")
encoding = Encoding::ASCII_8BIT 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 diretory" do
lambda { Dir.children DirSpecs.nonexistent }.should raise_error(SystemCallError)
end
end
end

View file

@ -0,0 +1,53 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/common', __FILE__)
ruby_version_is "2.5" do
describe "Dir.each_child" do
before :all do
DirSpecs.create_mock_dirs
end
after :all do
DirSpecs.delete_mock_dirs
end
it "yields all names in an existing directory to the provided block" do
a, b = [], []
Dir.each_child(DirSpecs.mock_dir) {|f| a << f}
Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested") {|f| b << f}
a.sort.should == DirSpecs.expected_paths - %w[. ..]
b.sort.should == %w|.dotfile.ext directory|
end
it "returns nil when successful" do
Dir.each_child(DirSpecs.mock_dir) {|f| f}.should == nil
end
it "calls #to_path on non-String arguments" do
p = mock('path')
p.should_receive(:to_path).and_return(DirSpecs.mock_dir)
Dir.each_child(p).to_a
end
it "raises a SystemCallError if passed a nonexistent directory" do
lambda { 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

View file

@ -16,7 +16,7 @@ with_feature :encoding do
end
end
platform_is :freebsd, :darwin do
platform_is :freebsd, :openbsd, :darwin do
it "returns a value based on the LC_ALL environment variable" do
old_lc_all = ENV['LC_ALL']
ENV['LC_ALL'] = 'C'
@ -25,7 +25,7 @@ with_feature :encoding do
end
end
platform_is :netbsd, :openbsd do
platform_is :netbsd do
it "returns a value based on the LC_ALL environment variable" do
old_lc_all = ENV['LC_ALL']
ENV['LC_ALL'] = 'C'

View file

@ -54,10 +54,20 @@ describe "Enumerable#all?" do
end
it "gathers whole arrays as elements when each yields multiple" do
# This spec doesn't spec what it says it does
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.all?.should be_true
end
ruby_version_is "2.5" do
describe "given a pattern argument" do
# This spec should be replaced by more extensive ones
it "returns true iff all match that pattern" do
@enum.all?(Integer).should == true
@enum2.all?(NilClass).should == false
end
end
end
end
describe "with block" do
@ -116,6 +126,5 @@ describe "Enumerable#all?" do
multi.all? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4], [6, 7]]
end
end
end

View file

@ -13,9 +13,20 @@ describe "Enumerable#none?" do
end
it "gathers whole arrays as elements when each yields multiple" do
# This spec doesn't spec what it says it does
multi = EnumerableSpecs::YieldsMultiWithFalse.new
multi.none?.should be_false
end
ruby_version_is "2.5" do
describe "given a pattern argument" do
# This spec should be replaced by more extensive ones
it "returns true iff none match that pattern" do
EnumerableSpecs::Numerous.new.none?(Float).should == true
[nil, false, true].none?(NilClass).should == false
end
end
end
end
describe "Enumerable#none? with a block" do

View file

@ -16,6 +16,7 @@ describe "Enumerable#one?" do
end
it "gathers initial args as elements when each yields multiple" do
# This spec doesn't spec what it says it does
multi = EnumerableSpecs::YieldsMulti.new
multi.one? {|e| e == 1 }.should be_true
end
@ -26,6 +27,16 @@ describe "Enumerable#one?" do
multi.one? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4]]
end
ruby_version_is "2.5" do
describe "given a pattern argument" do
# This spec should be replaced by more extensive ones
it "returns true iff none match that pattern" do
EnumerableSpecs::Numerous.new.one?(Integer).should == false
[nil, false, true].one?(NilClass).should == true
end
end
end
end
describe "when not passed a block" do

View file

@ -91,17 +91,17 @@ describe "File#chown" do
as_superuser do
platform_is :windows do
it "does not modify the owner id of the file" do
File.chown 0, nil, @fname
File.stat(@fname).uid.should == 0
File.chown 501, nil, @fname
File.stat(@fname).uid.should == 0
@file.chown 0, nil
@file.stat.uid.should == 0
@file.chown 501, nil
@file.stat.uid.should == 0
end
it "does not modify the group id of the file" do
File.chown nil, 0, @fname
File.stat(@fname).gid.should == 0
File.chown nil, 501, @fname
File.stat(@fname).gid.should == 0
@file.chown nil, 0
@file.stat.gid.should == 0
@file.chown nil, 501
@file.stat.gid.should == 0
end
end

View file

@ -1,13 +1,13 @@
require File.expand_path('../../../dir/fixtures/common', __FILE__)
describe :file_read_directory, shared: true do
platform_is :darwin, :linux, :windows do
platform_is :darwin, :linux, :openbsd, :windows do
it "raises an Errno::EISDIR when passed a path that is a directory" do
lambda { @object.send(@method, ".") }.should raise_error(Errno::EISDIR)
end
end
platform_is :bsd do
platform_is :freebsd, :netbsd do
it "does not raises any exception when passed a path that is a directory" do
lambda { @object.send(@method, ".") }.should_not raise_error
end

View file

@ -16,7 +16,7 @@ describe "File::Stat#inspect" do
expected = "#<File::Stat dev=0x#{st.dev.to_s(16)}, ino=#{st.ino}, mode=#{sprintf("%07o", st.mode)}, nlink=#{st.nlink}"
expected << ", uid=#{st.uid}, gid=#{st.gid}, rdev=0x#{st.rdev.to_s(16)}, size=#{st.size}, blksize=#{st.blksize.inspect}"
expected << ", blocks=#{st.blocks.inspect}, atime=#{st.atime}, mtime=#{st.mtime}, ctime=#{st.ctime}"
platform_is :bsd, :darwin do
platform_is :netbsd, :freebsd, :darwin do
# Windows has File.birthtime but it's not here since already shown by ctime.
expected << ", birthtime=#{st.birthtime}"
end

View file

@ -0,0 +1,36 @@
require File.expand_path('../../../spec_helper', __FILE__)
ruby_version_is "2.5" do
describe "Hash#slice" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
it "returns new hash" do
ret = @hash.slice
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
end
it "returns the requested subset" do
@hash.slice(:c, :a).should == { c: 3, a: 1 }
end
it "returns a hash ordered in the order of the requested keys" do
@hash.slice(:c, :a).keys.should == [:c, :a]
end
it "returns only the keys of the original hash" do
@hash.slice(:a, :chunky_bacon).should == { a: 1 }
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:foo] = 42
r = h.slice(:foo)
r.should == {foo: 42}
r.class.should == Hash
end
end
end

View file

@ -0,0 +1,110 @@
require File.expand_path('../../../spec_helper', __FILE__)
ruby_version_is "2.5" do
describe "Hash#transform_keys" do
before :each do
@hash = { a: 1, b: 2, c: 3 }
end
it "returns new hash" do
ret = @hash.transform_keys(&:succ)
ret.should_not equal(@hash)
ret.should be_an_instance_of(Hash)
end
it "sets the result as transformed keys with the given block" do
@hash.transform_keys(&:succ).should == { b: 1, c: 2, d: 3 }
end
it "keeps last pair if new keys conflict" do
@hash.transform_keys { |_| :a }.should == { a: 3 }
end
it "makes both hashes to share values" do
value = [1, 2, 3]
new_hash = { a: value }.transform_keys(&:upcase)
new_hash[:A].should equal(value)
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:succ).should == { b: 1, c: 2, d: 3 }
end
end
it "returns a Hash instance, even on subclasses" do
klass = Class.new(Hash)
h = klass.new
h[:foo] = 42
r = h.transform_keys{|v| :"x#{v}"}
r.keys.should == [:xfoo]
r.class.should == Hash
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
it "does not prevent conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { e: 1 }
end
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
it "keeps later pair if new keys conflict" do
@hash.transform_keys! { |_| :a }.should == { a: 4 }
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_keys!
enumerator.should be_an_instance_of(Enumerator)
enumerator.size.should == @hash.size
enumerator.each(&:upcase).should == { A: 1, B: 2, C: 3, D: 4 }
end
end
describe "on frozen instance" do
before :each do
@hash.freeze
end
it "raises a RuntimeError on an empty hash" do
->{ {}.freeze.transform_keys!(&:upcase) }.should raise_error(RuntimeError)
end
it "keeps pairs and raises a RuntimeError" do
->{ @hash.transform_keys!(&:upcase) }.should raise_error(RuntimeError)
@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

View file

@ -16,6 +16,13 @@ ruby_version_is "2.4" do
@hash.transform_values(&:succ).should == { a: 2, b: 3, c: 4 }
end
it "makes both hashes to share keys" do
key = [1, 2, 3]
new_hash = { key => 1 }.transform_values(&:succ)
new_hash[key].should == 2
new_hash.keys[0].should equal(key)
end
context "when no block is given" do
it "returns a sized Enumerator" do
enumerator = @hash.transform_values
@ -47,7 +54,7 @@ ruby_version_is "2.4" do
it "updates self as transformed values with the given block" do
@hash.transform_values!(&:succ)
@hash.should == { a: 2, b: 3, c: 4 }
@hash.should == { a: 2, b: 3, c: 4 }
end
it "partially modifies the contents if we broke from the block" do

View file

@ -57,7 +57,7 @@ describe "Kernel#autoload" do
describe "when Object is frozen" do
it "raises a FrozenError before defining the constant" do
ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "FrozenError - nil"
ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "#{frozen_error_class} - nil"
end
end
end

View file

@ -4,9 +4,9 @@ require File.expand_path('../fixtures/classes', __FILE__)
describe "Module#included_modules" do
it "returns a list of modules included in self" do
ModuleSpecs.included_modules.should == []
ModuleSpecs::Child.included_modules.should include(ModuleSpecs::Super, ModuleSpecs::Basic, Kernel)
ModuleSpecs::Child.included_modules.should include(ModuleSpecs::Super, ModuleSpecs::Basic, Kernel)
ModuleSpecs::Parent.included_modules.should include(Kernel)
ModuleSpecs::Basic.included_modules.should == []
ModuleSpecs::Super.included_modules.should include(ModuleSpecs::Basic)
ModuleSpecs::Super.included_modules.should include(ModuleSpecs::Basic)
end
end

View file

@ -320,7 +320,7 @@ describe "Module#refine" do
result.should == "foo from subclass"
end
context "for methods accesses indirectly" do
context "for methods accessed indirectly" do
ruby_version_is "" ... "2.4" do
it "is not honored by Kernel#send" do
refinement = Module.new do
@ -425,6 +425,46 @@ describe "Module#refine" do
end
end
ruby_version_is "" ... "2.5" do
it "is not honored by string interpolation" do
refinement = Module.new do
refine Integer do
def to_s
"foo"
end
end
end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "1"
end
end
ruby_version_is "2.5" do
it "is honored by string interpolation" do
refinement = Module.new do
refine Integer do
def to_s
"foo"
end
end
end
result = nil
Module.new do
using refinement
result = "#{1}"
end
result.should == "foo"
end
end
it "is honored by Kernel#binding" do
refinement = Module.new do
refine String do

View file

@ -22,7 +22,7 @@ describe "Process.setsid" do
read2.close
pgid_child = Integer(read.gets)
read.close
platform_is_not :aix do
platform_is_not :aix, :openbsd do
# AIX does not allow Process.getsid(pid)
# if pid is in a different session.
pgid = Process.getsid(pid)

View file

@ -595,8 +595,10 @@ describe "Process.spawn" do
end
end
it "raises an Errno::EACCES when passed a directory" do
lambda { Process.spawn File.dirname(__FILE__) }.should raise_error(Errno::EACCES)
it "raises an Errno::EACCES or Errno::EISDIR when passed a directory" do
lambda { Process.spawn File.dirname(__FILE__) }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::EISDIR].should include(e.class)
}
end
it "raises an ArgumentError when passed a string key in options" do

View file

@ -0,0 +1,81 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes.rb', __FILE__)
ruby_version_is '2.5' do
describe "String#delete_prefix" do
it "returns a copy of the string, with the given prefix removed" do
'hello'.delete_prefix('hell').should == 'o'
'hello'.delete_prefix('hello').should == ''
end
it "returns a copy of the string, when the prefix isn't found" do
s = 'hello'
r = s.delete_prefix('hello!')
r.should_not equal s
r.should == s
r = s.delete_prefix('ell')
r.should_not equal s
r.should == s
r = s.delete_prefix('')
r.should_not equal s
r.should == s
end
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_prefix('hell').tainted?.should == true
'hello'.taint.delete_prefix('').tainted?.should == true
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
describe "String#delete_prefix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_prefix!('hell').should equal(s)
s.should == 'o'
end
it "returns nil if no change is made" do
s = 'hello'
s.delete_prefix!('ell').should == nil
s.delete_prefix!('').should == nil
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_prefix!('hell')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'hell'
'hello'.delete_prefix!(o).should == 'o'
end
it "raises a RuntimeError when self is frozen" do
lambda { 'hello'.freeze.delete_prefix!('hell') }.should raise_error(RuntimeError)
lambda { 'hello'.freeze.delete_prefix!('') }.should raise_error(RuntimeError)
lambda { ''.freeze.delete_prefix!('') }.should raise_error(RuntimeError)
end
end
end

View file

@ -0,0 +1,81 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes.rb', __FILE__)
ruby_version_is '2.5' do
describe "String#delete_suffix" do
it "returns a copy of the string, with the given suffix removed" do
'hello'.delete_suffix('ello').should == 'h'
'hello'.delete_suffix('hello').should == ''
end
it "returns a copy of the string, when the suffix isn't found" do
s = 'hello'
r = s.delete_suffix('!hello')
r.should_not equal s
r.should == s
r = s.delete_suffix('ell')
r.should_not equal s
r.should == s
r = s.delete_suffix('')
r.should_not equal s
r.should == s
end
it "taints resulting strings when other is tainted" do
'hello'.taint.delete_suffix('ello').tainted?.should == true
'hello'.taint.delete_suffix('').tainted?.should == true
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
describe "String#delete_suffix!" do
it "removes the found prefix" do
s = 'hello'
s.delete_suffix!('ello').should equal(s)
s.should == 'h'
end
it "returns nil if no change is made" do
s = 'hello'
s.delete_suffix!('ell').should == nil
s.delete_suffix!('').should == nil
end
it "doesn't set $~" do
$~ = nil
'hello'.delete_suffix!('ello')
$~.should == nil
end
it "calls to_str on its argument" do
o = mock('x')
o.should_receive(:to_str).and_return 'ello'
'hello'.delete_suffix!(o).should == 'h'
end
it "raises a RuntimeError when self is frozen" do
lambda { 'hello'.freeze.delete_suffix!('ello') }.should raise_error(RuntimeError)
lambda { 'hello'.freeze.delete_suffix!('') }.should raise_error(RuntimeError)
lambda { ''.freeze.delete_suffix!('') }.should raise_error(RuntimeError)
end
end
end

View file

@ -28,9 +28,9 @@ describe "String#start_with?" do
it "ignores arguments not convertible to string" do
"hello".start_with?().should be_false
lambda { "hello".start_with?(1) }.should raise_error(TypeError)
lambda { "hello".start_with?(["h"]) }.should raise_error(TypeError)
lambda { "hello".start_with?(1, nil, "h").should }.should raise_error(TypeError)
lambda { "hello".start_with?(1) }.should raise_error(TypeError)
lambda { "hello".start_with?(["h"]) }.should raise_error(TypeError)
lambda { "hello".start_with?(1, nil, "h") }.should raise_error(TypeError)
end
it "uses only the needed arguments" do

View file

@ -60,7 +60,18 @@ describe "Struct.new" do
lambda { Struct.new(:animal, nil) }.should raise_error(TypeError)
lambda { Struct.new(:animal, true) }.should raise_error(TypeError)
lambda { Struct.new(:animal, ['chris', 'evan']) }.should raise_error(TypeError)
lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
end
ruby_version_is ""..."2.5" do
it "raises a TypeError if an argument is a Hash" do
lambda { 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
lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
end
end
it "raises a TypeError if object is not a Symbol" do

View file

@ -142,4 +142,60 @@ describe "Time.at" do
lambda { Time.at(Time.now, 500000) }.should raise_error(TypeError)
end
end
ruby_version_is "2.5" do
describe "passed [Time, Numeric, format]" do
context ":nanosecond format" do
it "traits second argument as nanoseconds" do
Time.at(0, 123456789, :nanosecond).nsec.should == 123456789
end
end
context ":nsec format" do
it "traits second argument as nanoseconds" do
Time.at(0, 123456789, :nsec).nsec.should == 123456789
end
end
context ":microsecond format" do
it "traits second argument as microseconds" do
Time.at(0, 123456, :microsecond).nsec.should == 123456000
end
end
context ":usec format" do
it "traits second argument as microseconds" do
Time.at(0, 123456, :usec).nsec.should == 123456000
end
end
context ":millisecond format" do
it "traits 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

View file

@ -425,6 +425,28 @@ describe "Constant resolution within a singleton class (class << obj)" do
end
end
describe "top-level constant lookup" do
context "on a class" do
ruby_version_is "" ... "2.5" do
it "searches Object successfully after searching other scopes" do
->() {
String::Hash.should == Hash
}.should complain(/toplevel constant Hash referenced by/)
end
end
ruby_version_is "2.5" do
it "does not search Object after searching other scopes" do
->() { String::Hash }.should raise_error(NameError)
end
end
end
it "searches Object unsuccessfully when searches on a module" do
->() { Enumerable::Hash }.should raise_error(NameError)
end
end
describe "Module#private_constant marked constants" do
it "remain private even when updated" do

View file

@ -7,50 +7,44 @@ describe "An ensure block inside a begin block" do
end
it "is executed when an exception is raised in it's corresponding begin block" do
begin
lambda {
begin
ScratchPad << :begin
raise "An exception occurred!"
ensure
ScratchPad << :ensure
end
}.should raise_error(RuntimeError)
lambda {
begin
ScratchPad << :begin
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:begin, :ensure]
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when an exception is raised and rescued in it's corresponding begin block" do
begin
ScratchPad << :begin
raise "An exception occurred!"
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
catch(:symbol) do
begin
ScratchPad << :begin
raise "An exception occurred!"
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
begin
catch(:symbol) do
begin
ScratchPad << :begin
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
end
ScratchPad.recorded.should == [:begin, :ensure]
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when nothing is raised or thrown in it's corresponding begin block" do
@ -102,7 +96,7 @@ describe "An ensure block inside a method" do
end
it "is executed when an exception is raised in the method" do
lambda { @obj.raise_in_method_with_ensure }.should raise_error(RuntimeError)
lambda { @obj.raise_in_method_with_ensure }.should raise_error(EnsureSpec::Error)
@obj.executed.should == [:method, :ensure]
end
@ -124,3 +118,176 @@ describe "An ensure block inside a method" do
@obj.explicit_return_in_method_with_ensure.should == :ensure
end
end
describe "An ensure block inside a class" do
before :each do
ScratchPad.record []
end
it "is executed when an exception is raised" do
lambda {
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
ruby
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:class, :ensure]
end
it "is executed when an exception is raised and rescued" do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
raise
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:class, :rescue, :ensure]
end
it "is executed even when a symbol is thrown" do
catch(:symbol) do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
end
ScratchPad.recorded.should == [:class, :ensure]
end
it "is executed when nothing is raised or thrown" do
eval <<-ruby
class EnsureInClassExample
ScratchPad << :class
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:class, :ensure]
end
it "has no return value" do
result = eval <<-ruby
class EnsureInClassExample
:class
ensure
:ensure
end
ruby
result.should == :class
end
end
describe "An ensure block inside {} block" do
it "is not allowed" do
lambda {
eval <<-ruby
lambda {
raise
ensure
}
ruby
}.should raise_error(SyntaxError)
end
end
ruby_version_is "2.5" do
describe "An ensure block inside 'do end' block" do
before :each do
ScratchPad.record []
end
it "is executed when an exception is raised in it's corresponding begin block" do
lambda {
eval(<<-ruby).call
lambda do
ScratchPad << :begin
raise EnsureSpec::Error
ensure
ScratchPad << :ensure
end
ruby
}.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when an exception is raised and rescued in it's corresponding begin block" do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
raise "An exception occurred!"
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do
catch(:symbol) do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
throw(:symbol)
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
end
ScratchPad.recorded.should == [:begin, :ensure]
end
it "is executed when nothing is raised or thrown in it's corresponding begin block" do
eval(<<-ruby).call
lambda do
ScratchPad << :begin
rescue
ScratchPad << :rescue
ensure
ScratchPad << :ensure
end
ruby
ScratchPad.recorded.should == [:begin, :ensure]
end
it "has no return value" do
result = eval(<<-ruby).call
lambda do
:begin
ensure
:ensure
end
ruby
result.should == :begin
end
end
end

View file

@ -8,7 +8,7 @@ module EnsureSpec
def raise_in_method_with_ensure
@executed << :method
raise "An Exception"
raise EnsureSpec::Error
ensure
@executed << :ensure
end
@ -70,3 +70,8 @@ module EnsureSpec
end
end
end
module EnsureSpec
class Error < RuntimeError
end
end

View file

@ -31,6 +31,28 @@ describe "The rescue keyword" do
end
end
it "returns value from `rescue` if an exception was raised" do
begin
raise
rescue
:caught
end.should == :caught
end
it "returns value from `else` section if no exceptions were raised" do
result = begin
:begin
rescue
:rescue
else
:else
ensure
:ensure
end
result.should == :else
end
it "can rescue multiple raised exceptions with a single rescue block" do
[lambda{raise ArbitraryException}, lambda{raise SpecificExampleException}].map do |block|
begin
@ -94,6 +116,32 @@ describe "The rescue keyword" do
end.should raise_error(OtherCustomException)
end
it "can rescue different types of exceptions in different ways" do
begin
raise Exception
rescue RuntimeError
rescue StandardError
rescue Exception
ScratchPad << :exception
end
ScratchPad.recorded.should == [:exception]
end
it "rescues exception within the first suitable section in order of declaration" do
begin
raise StandardError
rescue RuntimeError
ScratchPad << :runtime_error
rescue StandardError
ScratchPad << :standard_error
rescue Exception
ScratchPad << :exception
end
ScratchPad.recorded.should == [:standard_error]
end
it "will execute an else block only if no exceptions were raised" do
result = begin
ScratchPad << :one
@ -147,6 +195,20 @@ describe "The rescue keyword" do
ScratchPad.recorded.should == [:one, :else_ran, :ensure_ran, :outside_begin]
end
it "will execute an else block even without rescue and ensure" do
lambda {
eval <<-ruby
begin
ScratchPad << :begin
else
ScratchPad << :else
end
ruby
}.should complain(/else without rescue is useless/)
ScratchPad.recorded.should == [:begin, :else]
end
it "will not execute an else block if an exception was raised" do
result = begin
ScratchPad << :one
@ -223,14 +285,31 @@ describe "The rescue keyword" do
a.should == 'ac'
end
it "without classes will not rescue Exception" do
lambda do
context "without rescue expression" do
it "will rescue only StandardError and its subclasses" do
begin
raise Exception
raise StandardError
rescue
'Exception wrongly rescued'
ScratchPad << :caught
end
end.should raise_error(Exception)
ScratchPad.recorded.should == [:caught]
end
it "will not rescue exceptions except StandardError" do
[ Exception.new, NoMemoryError.new, ScriptError.new, SecurityError.new,
SignalException.new('INT'), SystemExit.new, SystemStackError.new
].each do |exception|
lambda {
begin
raise exception
rescue
ScratchPad << :caught
end
}.should raise_error(exception.class)
end
ScratchPad.recorded.should == []
end
end
it "uses === to compare against rescued classes" do
@ -279,7 +358,7 @@ describe "The rescue keyword" do
invalid_rescuer = Object.new
begin
:foo
rescue rescuer
rescue invalid_rescuer
end.should == :foo
end
@ -291,6 +370,44 @@ describe "The rescue keyword" do
end.should == :expected
end
it "allows rescue in class" do
eval <<-ruby
class RescueInClassExample
raise SpecificExampleException
rescue SpecificExampleException
ScratchPad << :caught
end
ruby
ScratchPad.recorded.should == [:caught]
end
it "does not allow rescue in {} block" do
lambda {
eval <<-ruby
lambda {
raise SpecificExampleException
rescue SpecificExampleException
:caught
}
ruby
}.should raise_error(SyntaxError)
end
ruby_version_is "2.5" do
it "allows rescue in 'do end' block" do
lambda = eval <<-ruby
lambda do
raise SpecificExampleException
rescue SpecificExampleException
ScratchPad << :caught
end.call
ruby
ScratchPad.recorded.should == [:caught]
end
end
ruby_version_is ""..."2.4" do
it "fails when using 'rescue' in method arguments" do
lambda { eval '1.+ (1 rescue 1)' }.should raise_error(SyntaxError)
@ -305,6 +422,31 @@ describe "The rescue keyword" do
it "requires the 'rescue' in method arguments to be wrapped in parens" do
lambda { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError)
eval('1.+((1 rescue 1))').should == 2
end
end
describe "inline form" do
it "can be inlined" do
a = 1/0 rescue 1
a.should == 1
end
it "doesn't except rescue expression" do
lambda {
eval <<-ruby
a = 1 rescue RuntimeError 2
ruby
}.should raise_error(SyntaxError)
end
it "rescues only StandardError and its subclasses" do
a = raise(StandardError) rescue 1
a.should == 1
lambda {
a = raise(Exception) rescue 1
}.should raise_error(Exception)
end
end
end

View file

@ -1,8 +1,8 @@
describe :date_valid_jd?, shared: true do
it "returns true if passed any value other than nil" do
Date.send(@method, -100).should be_true
Date.send(@method, :number).should be_true
Date.send(@method, Rational(1,2)).should be_true
Date.send(@method, :number).should be_true
Date.send(@method, Rational(1,2)).should be_true
end
it "returns false if passed nil" do

View file

@ -24,7 +24,7 @@ describe "Matrix.build" do
it "returns an Enumerator is no block is given" do
enum = Matrix.build(2, 1)
enum.should be_an_instance_of(Enumerator)
enum.should be_an_instance_of(Enumerator)
enum.each{1}.should == Matrix[[1], [1]]
end

View file

@ -0,0 +1,15 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/include', __FILE__)
require 'set'
ruby_version_is "2.5" do
describe "Set#===" do
it_behaves_like :set_include, :===
it "is an alias for include?" do
set = Set.new
set.method(:===).should == set.method(:include?)
end
end
end

View file

@ -1,18 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/inspect', __FILE__)
require 'set'
describe "Set#inspect" do
it "returns a String representation of self" do
Set[].inspect.should be_kind_of(String)
Set[nil, false, true].inspect.should be_kind_of(String)
Set[1, 2, 3].inspect.should be_kind_of(String)
Set["1", "2", "3"].inspect.should be_kind_of(String)
Set[:a, "b", Set[?c]].inspect.should be_kind_of(String)
end
it "correctly handles self-references" do
(set = Set[]) << set
set.inspect.should be_kind_of(String)
set.inspect.should include("#<Set: {...}>")
end
it_behaves_like :set_inspect, :inspect
end

View file

@ -4,4 +4,26 @@ describe :set_include, shared: true do
set.send(@method, :a).should be_true
set.send(@method, :e).should be_false
end
describe "member equality" do
it "is checked using both #hash and #eql?" do
obj = Object.new
obj_another = Object.new
def obj.hash; 42 end
def obj_another.hash; 42 end
def obj_another.eql?(o) hash == o.hash end
set = Set["a", "b", "c", obj]
set.send(@method, obj_another).should == true
end
it "is not checked using #==" do
obj = Object.new
set = Set["a", "b", "c"]
obj.should_not_receive(:==)
set.send(@method, obj)
end
end
end

View file

@ -0,0 +1,15 @@
describe "set_inspect", shared: true do
it "returns a String representation of self" do
Set[].send(@method).should be_kind_of(String)
Set[nil, false, true].send(@method).should be_kind_of(String)
Set[1, 2, 3].send(@method).should be_kind_of(String)
Set["1", "2", "3"].send(@method).should be_kind_of(String)
Set[:a, "b", Set[?c]].send(@method).should be_kind_of(String)
end
it "correctly handles self-references" do
(set = Set[]) << set
set.send(@method).should be_kind_of(String)
set.send(@method).should include("#<Set: {...}>")
end
end

View file

@ -0,0 +1,13 @@
require File.expand_path('../shared/inspect', __FILE__)
require 'set'
ruby_version_is "2.5" do
describe "Set#to_s" do
it_behaves_like :set_inspect, :to_s
it "is an alias of inspect" do
set = Set.new
set.method(:to_s).should == set.method(:inspect)
end
end
end

View file

@ -26,7 +26,9 @@ describe 'UDPSocket.new' do
@socket.should be_an_instance_of(UDPSocket)
end
it 'raises Errno::EAFNOSUPPORT if unsupported family passed' do
lambda { UDPSocket.new(-1) }.should raise_error(Errno::EAFNOSUPPORT)
it 'raises Errno::EAFNOSUPPORT or Errno::EPROTONOSUPPORT if unsupported family passed' do
lambda { UDPSocket.new(-1) }.should raise_error(SystemCallError) { |e|
[Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT].should include(e.class)
}
end
end

View file

@ -17,7 +17,7 @@ describe "StringIO#pos=" do
end
it "raises an EINVAL if given a negative argument" do
lambda { @io.pos = -10 }.should raise_error(Errno::EINVAL)
lambda { @io.pos = -10 }.should raise_error(Errno::EINVAL)
end
it "updates the current byte offset after reaching EOF" do