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: Lint/UnneededRequireStatement:
Enabled: false Enabled: false
Lint/RescueWithoutErrorClass:
Enabled: false
Lint/UnifiedInteger: Lint/UnifiedInteger:
Enabled: false Enabled: false

View file

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

View file

@ -3,7 +3,7 @@ language: ruby
install: install:
- git clone https://github.com/ruby/mspec.git ../mspec - git clone https://github.com/ruby/mspec.git ../mspec
script: 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 - ../mspec/bin/mspec $MSPEC_OPTS
matrix: matrix:
include: 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://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) [![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. 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
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 it "returns a value based on the LC_ALL environment variable" do
old_lc_all = ENV['LC_ALL'] old_lc_all = ENV['LC_ALL']
ENV['LC_ALL'] = 'C' ENV['LC_ALL'] = 'C'
@ -25,7 +25,7 @@ with_feature :encoding do
end end
end end
platform_is :netbsd, :openbsd do platform_is :netbsd do
it "returns a value based on the LC_ALL environment variable" do it "returns a value based on the LC_ALL environment variable" do
old_lc_all = ENV['LC_ALL'] old_lc_all = ENV['LC_ALL']
ENV['LC_ALL'] = 'C' ENV['LC_ALL'] = 'C'

View file

@ -54,10 +54,20 @@ describe "Enumerable#all?" do
end end
it "gathers whole arrays as elements when each yields multiple" do 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 = EnumerableSpecs::YieldsMultiWithFalse.new
multi.all?.should be_true multi.all?.should be_true
end 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 end
describe "with block" do describe "with block" do
@ -116,6 +126,5 @@ describe "Enumerable#all?" do
multi.all? {|e, i| yielded << [e, i] } multi.all? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4], [6, 7]] yielded.should == [[1, 2], [3, 4], [6, 7]]
end end
end end
end end

View file

@ -13,9 +13,20 @@ describe "Enumerable#none?" do
end end
it "gathers whole arrays as elements when each yields multiple" do 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 = EnumerableSpecs::YieldsMultiWithFalse.new
multi.none?.should be_false multi.none?.should be_false
end 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 end
describe "Enumerable#none? with a block" do describe "Enumerable#none? with a block" do

View file

@ -16,6 +16,7 @@ describe "Enumerable#one?" do
end end
it "gathers initial args as elements when each yields multiple" do 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 = EnumerableSpecs::YieldsMulti.new
multi.one? {|e| e == 1 }.should be_true multi.one? {|e| e == 1 }.should be_true
end end
@ -26,6 +27,16 @@ describe "Enumerable#one?" do
multi.one? {|e, i| yielded << [e, i] } multi.one? {|e, i| yielded << [e, i] }
yielded.should == [[1, 2], [3, 4]] yielded.should == [[1, 2], [3, 4]]
end 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 end
describe "when not passed a block" do describe "when not passed a block" do

View file

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

View file

@ -1,13 +1,13 @@
require File.expand_path('../../../dir/fixtures/common', __FILE__) require File.expand_path('../../../dir/fixtures/common', __FILE__)
describe :file_read_directory, shared: true do 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 it "raises an Errno::EISDIR when passed a path that is a directory" do
lambda { @object.send(@method, ".") }.should raise_error(Errno::EISDIR) lambda { @object.send(@method, ".") }.should raise_error(Errno::EISDIR)
end end
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 it "does not raises any exception when passed a path that is a directory" do
lambda { @object.send(@method, ".") }.should_not raise_error lambda { @object.send(@method, ".") }.should_not raise_error
end 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 = "#<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 << ", 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}" 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. # Windows has File.birthtime but it's not here since already shown by ctime.
expected << ", birthtime=#{st.birthtime}" expected << ", birthtime=#{st.birthtime}"
end 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 } @hash.transform_values(&:succ).should == { a: 2, b: 3, c: 4 }
end 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 context "when no block is given" do
it "returns a sized Enumerator" do it "returns a sized Enumerator" do
enumerator = @hash.transform_values enumerator = @hash.transform_values

View file

@ -57,7 +57,7 @@ describe "Kernel#autoload" do
describe "when Object is frozen" do describe "when Object is frozen" do
it "raises a FrozenError before defining the constant" 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 end
end end

View file

@ -320,7 +320,7 @@ describe "Module#refine" do
result.should == "foo from subclass" result.should == "foo from subclass"
end end
context "for methods accesses indirectly" do context "for methods accessed indirectly" do
ruby_version_is "" ... "2.4" do ruby_version_is "" ... "2.4" do
it "is not honored by Kernel#send" do it "is not honored by Kernel#send" do
refinement = Module.new do refinement = Module.new do
@ -425,6 +425,46 @@ describe "Module#refine" do
end end
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 it "is honored by Kernel#binding" do
refinement = Module.new do refinement = Module.new do
refine String do refine String do

View file

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

View file

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

@ -30,7 +30,7 @@ describe "String#start_with?" do
"hello".start_with?().should be_false "hello".start_with?().should be_false
lambda { "hello".start_with?(1) }.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?(["h"]) }.should raise_error(TypeError)
lambda { "hello".start_with?(1, nil, "h").should }.should raise_error(TypeError) lambda { "hello".start_with?(1, nil, "h") }.should raise_error(TypeError)
end end
it "uses only the needed arguments" do it "uses only the needed arguments" do

View file

@ -60,8 +60,19 @@ describe "Struct.new" do
lambda { Struct.new(:animal, nil) }.should raise_error(TypeError) lambda { Struct.new(:animal, nil) }.should raise_error(TypeError)
lambda { Struct.new(:animal, true) }.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, ['chris', 'evan']) }.should raise_error(TypeError)
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) lambda { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
end end
end
it "raises a TypeError if object is not a Symbol" do it "raises a TypeError if object is not a Symbol" do
obj = mock(':ruby') obj = mock(':ruby')

View file

@ -142,4 +142,60 @@ describe "Time.at" do
lambda { Time.at(Time.now, 500000) }.should raise_error(TypeError) lambda { Time.at(Time.now, 500000) }.should raise_error(TypeError)
end end
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 end

View file

@ -425,6 +425,28 @@ describe "Constant resolution within a singleton class (class << obj)" do
end end
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 describe "Module#private_constant marked constants" do
it "remain private even when updated" do it "remain private even when updated" do

View file

@ -7,22 +7,19 @@ describe "An ensure block inside a begin block" do
end end
it "is executed when an exception is raised in it's corresponding begin block" do it "is executed when an exception is raised in it's corresponding begin block" do
begin
lambda { lambda {
begin begin
ScratchPad << :begin ScratchPad << :begin
raise "An exception occurred!" raise EnsureSpec::Error
ensure ensure
ScratchPad << :ensure ScratchPad << :ensure
end end
}.should raise_error(RuntimeError) }.should raise_error(EnsureSpec::Error)
ScratchPad.recorded.should == [:begin, :ensure] ScratchPad.recorded.should == [:begin, :ensure]
end end
end
it "is executed when an exception is raised and rescued in it's corresponding begin block" do it "is executed when an exception is raised and rescued in it's corresponding begin block" do
begin
begin begin
ScratchPad << :begin ScratchPad << :begin
raise "An exception occurred!" raise "An exception occurred!"
@ -34,10 +31,8 @@ describe "An ensure block inside a begin block" do
ScratchPad.recorded.should == [:begin, :rescue, :ensure] ScratchPad.recorded.should == [:begin, :rescue, :ensure]
end end
end
it "is executed even when a symbol is thrown in it's corresponding begin block" do it "is executed even when a symbol is thrown in it's corresponding begin block" do
begin
catch(:symbol) do catch(:symbol) do
begin begin
ScratchPad << :begin ScratchPad << :begin
@ -51,7 +46,6 @@ describe "An ensure block inside a begin block" do
ScratchPad.recorded.should == [:begin, :ensure] ScratchPad.recorded.should == [:begin, :ensure]
end end
end
it "is executed when nothing is raised or thrown in it's corresponding begin block" do it "is executed when nothing is raised or thrown in it's corresponding begin block" do
begin begin
@ -102,7 +96,7 @@ describe "An ensure block inside a method" do
end end
it "is executed when an exception is raised in the method" do 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] @obj.executed.should == [:method, :ensure]
end end
@ -124,3 +118,176 @@ describe "An ensure block inside a method" do
@obj.explicit_return_in_method_with_ensure.should == :ensure @obj.explicit_return_in_method_with_ensure.should == :ensure
end end
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 def raise_in_method_with_ensure
@executed << :method @executed << :method
raise "An Exception" raise EnsureSpec::Error
ensure ensure
@executed << :ensure @executed << :ensure
end end
@ -70,3 +70,8 @@ module EnsureSpec
end end
end end
end end
module EnsureSpec
class Error < RuntimeError
end
end

View file

@ -31,6 +31,28 @@ describe "The rescue keyword" do
end end
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 it "can rescue multiple raised exceptions with a single rescue block" do
[lambda{raise ArbitraryException}, lambda{raise SpecificExampleException}].map do |block| [lambda{raise ArbitraryException}, lambda{raise SpecificExampleException}].map do |block|
begin begin
@ -94,6 +116,32 @@ describe "The rescue keyword" do
end.should raise_error(OtherCustomException) end.should raise_error(OtherCustomException)
end 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 it "will execute an else block only if no exceptions were raised" do
result = begin result = begin
ScratchPad << :one ScratchPad << :one
@ -147,6 +195,20 @@ describe "The rescue keyword" do
ScratchPad.recorded.should == [:one, :else_ran, :ensure_ran, :outside_begin] ScratchPad.recorded.should == [:one, :else_ran, :ensure_ran, :outside_begin]
end 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 it "will not execute an else block if an exception was raised" do
result = begin result = begin
ScratchPad << :one ScratchPad << :one
@ -223,14 +285,31 @@ describe "The rescue keyword" do
a.should == 'ac' a.should == 'ac'
end end
it "without classes will not rescue Exception" do context "without rescue expression" do
lambda do it "will rescue only StandardError and its subclasses" do
begin begin
raise Exception raise StandardError
rescue rescue
'Exception wrongly rescued' ScratchPad << :caught
end
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
end.should raise_error(Exception)
end end
it "uses === to compare against rescued classes" do it "uses === to compare against rescued classes" do
@ -279,7 +358,7 @@ describe "The rescue keyword" do
invalid_rescuer = Object.new invalid_rescuer = Object.new
begin begin
:foo :foo
rescue rescuer rescue invalid_rescuer
end.should == :foo end.should == :foo
end end
@ -291,6 +370,44 @@ describe "The rescue keyword" do
end.should == :expected end.should == :expected
end 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 ruby_version_is ""..."2.4" do
it "fails when using 'rescue' in method arguments" do it "fails when using 'rescue' in method arguments" do
lambda { eval '1.+ (1 rescue 1)' }.should raise_error(SyntaxError) 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 it "requires the 'rescue' in method arguments to be wrapped in parens" do
lambda { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError) 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 end
end 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('../../../spec_helper', __FILE__)
require File.expand_path('../shared/inspect', __FILE__)
require 'set' require 'set'
describe "Set#inspect" do describe "Set#inspect" do
it "returns a String representation of self" do it_behaves_like :set_inspect, :inspect
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
end end

View file

@ -4,4 +4,26 @@ describe :set_include, shared: true do
set.send(@method, :a).should be_true set.send(@method, :a).should be_true
set.send(@method, :e).should be_false set.send(@method, :e).should be_false
end 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 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) @socket.should be_an_instance_of(UDPSocket)
end end
it 'raises Errno::EAFNOSUPPORT if unsupported family passed' do it 'raises Errno::EAFNOSUPPORT or Errno::EPROTONOSUPPORT if unsupported family passed' do
lambda { UDPSocket.new(-1) }.should raise_error(Errno::EAFNOSUPPORT) lambda { UDPSocket.new(-1) }.should raise_error(SystemCallError) { |e|
[Errno::EAFNOSUPPORT, Errno::EPROTONOSUPPORT].should include(e.class)
}
end end
end end