Skip to content

Commit

Permalink
Merge branch 'master' into ffi-io
Browse files Browse the repository at this point in the history
Fixed a conflict in io.rb with #write_nonblock and a
conflict in spec/ruby/core/io/read_nonblock_spec.rb.
chuckremes committed Jan 22, 2016
2 parents 685a4a5 + 9da9d6a commit 910d9f8
Showing 59 changed files with 848 additions and 209 deletions.
2 changes: 1 addition & 1 deletion Gemfile.installed
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ gem "daedalus-core", "~> 0.1"
gem "rubinius-build_tools", "~> 2.0"
gem "rubinius-developer_tools", "~> 2.0"

gem "rubysl", "~> 2.0"
gem "rubysl", "~> 2.2"
gem "rubysl-test-unit", "~> 2.0"
gem "minitest", "~> 4.7"
gem "racc", "~> 1.4"
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/
specs:
daedalus-core (0.5.0)
rake (10.4.2)
rake (10.5.0)
redcard (1.1.0)
rubinius-ast (2.3.2)
rubinius-bridge (1.1.0)
6 changes: 6 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -78,6 +78,7 @@ class Configure
@dtrace_const = false
@have_lchmod = false
@have_lchown = false
@have_mkfifo = false
@debug_build = false
@include_dirs = []
@lib_dirs = []
@@ -1290,6 +1291,10 @@ int main() { return tgetnum(""); }
if has_function("lchown", ["sys/stat.h", "unistd.h"])
@have_lchown = true
end

if has_function("mkfifo", ["sys/stat.h", "sys/types.h"])
@have_mkfifo = true
end
end

def detect_structures
@@ -1656,6 +1661,7 @@ int main() { return tgetnum(""); }
#define RBX_LIBC "#{@libc}"
#define RBX_HAVE_LCHMOD #{@have_lchmod}
#define RBX_HAVE_LCHOWN #{@have_lchown}
#define RBX_HAVE_MKFIFO #{@have_mkfifo}
#define RBX_DEBUG_BUILD #{@debug_build.inspect}
EOC

8 changes: 0 additions & 8 deletions dockerfiles/ubuntu/14.04/Dockerfile

This file was deleted.

8 changes: 0 additions & 8 deletions dockerfiles/ubuntu/15.10/Dockerfile

This file was deleted.

7 changes: 4 additions & 3 deletions gems_list.txt
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ json-1.8.3.gem
minitest-4.7.5.gem
psych-2.0.17.gem
racc-1.4.14.gem
rake-10.4.2.gem
rake-10.5.0.gem
rb-readline-0.5.3.gem
rdoc-4.2.1.gem
redcard-1.1.0.gem
@@ -20,7 +20,7 @@ rubinius-melbourne-2.3.1.0.gem
rubinius-processor-2.3.0.gem
rubinius-profiler-2.0.2.gem
rubinius-toolset-2.3.1.gem
rubysl-2.1.0.gem
rubysl-2.2.0.gem
rubysl-abbrev-2.0.4.gem
rubysl-base64-2.0.0.gem
rubysl-benchmark-2.0.1.gem
@@ -70,9 +70,9 @@ rubysl-net-smtp-2.0.1.gem
rubysl-net-telnet-2.0.0.gem
rubysl-nkf-2.0.1.gem
rubysl-observer-2.0.0.gem
rubysl-open-uri-2.0.0.gem
rubysl-open3-2.0.0.gem
rubysl-openssl-2.8.0.gem
rubysl-open-uri-2.0.0.gem
rubysl-optparse-2.0.1.gem
rubysl-ostruct-2.1.0.gem
rubysl-pathname-2.1.0.gem
@@ -107,6 +107,7 @@ rubysl-timeout-2.0.0.gem
rubysl-tmpdir-2.0.1.gem
rubysl-tsort-2.0.1.gem
rubysl-un-2.0.0.gem
rubysl-unicode_normalize-2.0.gem
rubysl-uri-2.0.0.gem
rubysl-weakref-2.0.0.gem
rubysl-webrick-2.0.0.gem
22 changes: 22 additions & 0 deletions kernel/common/argf.rb
Original file line number Diff line number Diff line change
@@ -330,6 +330,7 @@ def readbyte
def read(bytes=nil, output=nil)
# The user might try to pass in nil, so we have to check here
output ||= default_value
output.clear

if bytes
bytes_left = bytes
@@ -401,6 +402,27 @@ def readlines(sep=$/)

alias_method :to_a, :readlines

def readpartial(maxlen, output=nil)
output ||= default_value

unless advance!
output.clear
raise EOFError, "ARGF at end"
end

begin
@stream.readpartial(maxlen, output)
rescue EOFError => e
raise e if @use_stdin_only

@stream.close
@advance = true
advance! or raise e
end

return output
end

#
# Rewind the stream to its beginning.
#
8 changes: 4 additions & 4 deletions kernel/common/array.rb
Original file line number Diff line number Diff line change
@@ -597,13 +597,13 @@ def delete_if
self
end

def dig(*sequence)
item = self[sequence.shift]
return item if sequence.empty? || item.nil?
def dig(index, *remaining_indeces)
item = self[index]
return item if remaining_indeces.empty? || item.nil?

raise TypeError, "#{item.class} does not have #dig method" unless item.respond_to?(:dig)

item.dig(*sequence)
item.dig(*remaining_indeces)
end

def each_index
67 changes: 39 additions & 28 deletions kernel/common/enumerable.rb
Original file line number Diff line number Diff line change
@@ -4,19 +4,13 @@
# these methods can be written *in those classes* to override these.

module Enumerable
def chunk(initial_state = nil, &original_block)
def chunk
raise ArgumentError, "no block given" unless block_given?
::Enumerator.new do |yielder|
previous = nil
accumulate = []
block = if initial_state.nil?
original_block
else
duplicated_initial_state = initial_state.dup
Proc.new{ |val| original_block.yield(val, duplicated_initial_state)}
end
each do |element|
key = block.yield(element)
key = yield(element)
if key.nil? || (key.is_a?(Symbol) && key.to_s[0, 1] == "_")
yielder.yield [previous, accumulate] unless accumulate.empty?
accumulate = []
@@ -136,18 +130,18 @@ def group_by
h
end

def slice_before(arg = undefined, &block)
if block_given?
has_init = !(undefined.equal? arg)
else
raise ArgumentError, "wrong number of arguments (0 for 1)" if undefined.equal? arg
block = Proc.new{ |elem| arg === elem }
end
def slice_before(pattern = undefined, &block)
pattern_given = !(undefined.equal? pattern)

raise ArgumentError, "cannot pass both pattern and block" if pattern_given && block_given?
raise ArgumentError, "a pattern or a block must be provided" if !pattern_given && !block_given?

block = Proc.new{ |elem| pattern === elem } if pattern_given

Enumerator.new do |yielder|
init = arg.dup if has_init
accumulator = nil
each do |element|
start_new = has_init ? block.yield(element, init) : block.yield(element)
start_new = block.yield(element)
if start_new
yielder.yield accumulator if accumulator
accumulator = [element]
@@ -164,7 +158,7 @@ def slice_after(pattern = undefined, &block)
pattern_given = !undefined.equal?(pattern)

raise ArgumentError, "cannot pass both pattern and block" if pattern_given && block_given?
raise ArgumentError, "wrong number of arguments (0 for 1)" if !pattern_given && !block_given?
raise ArgumentError, "a pattern or a block must be provided" if !pattern_given && !block_given?

block = Proc.new { |elem| pattern === elem } if pattern_given

@@ -212,6 +206,12 @@ def slice_when(&block)
end
end

def chunk_while(&block)
raise ArgumentError, "no block given" unless block_given?

slice_when { |before, after| !(yield before, after) }
end

def to_a(*arg)
ary = []
each(*arg) do
@@ -293,19 +293,30 @@ def each_with_index(*args)
def grep(pattern)
ary = []

if block_given?
each do
element = Rubinius.single_block_arg
if pattern === element
Regexp.set_block_last_match
each do
element = Rubinius.single_block_arg
if pattern === element
Regexp.set_block_last_match
if block_given?
ary << yield(element)
else
ary << element
end
end
else
each do
element = Rubinius.single_block_arg
if pattern === element
Regexp.set_block_last_match
end

ary
end

def grep_v(pattern)
ary = []

each do
element = Rubinius.single_block_arg
unless pattern === element
if block_given?
ary << yield(element)
else
ary << element
end
end
30 changes: 20 additions & 10 deletions kernel/common/enumerator.rb
Original file line number Diff line number Diff line change
@@ -347,19 +347,29 @@ def reject
end

def grep(pattern)
if block_given?
Lazy.new(self, nil) do |yielder, *args|
val = args.length >= 2 ? args : args.first
if pattern === val
Regexp.set_block_last_match
Lazy.new(self, nil) do |yielder, *args|
val = args.length >= 2 ? args : args.first

if pattern === val
Regexp.set_block_last_match

if block_given?
yielder.yield yield(val)
else
yielder.yield val
end
end
else
Lazy.new(self, nil) do |yielder, *args|
val = args.length >= 2 ? args : args.first
if pattern === val
Regexp.set_block_last_match
end
end

def grep_v(pattern)
Lazy.new(self, nil) do |yielder, *args|
val = args.length >= 2 ? args : args.first

unless pattern === val
if block_given?
yielder.yield yield(val)
else
yielder.yield val
end
end
15 changes: 15 additions & 0 deletions kernel/common/file.rb
Original file line number Diff line number Diff line change
@@ -1195,6 +1195,21 @@ def self.sticky?(file_name)
return false
end

def self.mkfifo(file_name, mode = 0666)
raise NotImplementedError, "mkfifo is not implemented on this platform" unless Rubinius::HAVE_MKFIFO

file_name = file_name.to_path if file_name.respond_to?(:to_path)
file_name = StringValue(file_name)

ret = POSIX.mkfifo(file_name, mode)

if ret == 0
ret
else
Errno.handle(file_name)
end
end

class << self
alias_method :delete, :unlink
alias_method :exists?, :exist?
43 changes: 39 additions & 4 deletions kernel/common/hash.rb
Original file line number Diff line number Diff line change
@@ -252,6 +252,37 @@ def ==(other)
true
end

def <(other)
other = Rubinius::Type.coerce_to(other, Hash, :to_hash)
other > self
end

def <=(other)
other = Rubinius::Type.coerce_to(other, Hash, :to_hash)
other >= self
end

def >(other)
other = Rubinius::Type.coerce_to(other, Hash, :to_hash)

return false if size <= other.size

self >= other
end

def >=(other)
other = Rubinius::Type.coerce_to(other, Hash, :to_hash)

return false if size < other.size

other.each do |other_key, other_val|
val = fetch(other_key, undefined)
return false if undefined.equal?(val) || val != other_val
end

true
end

def assoc(key)
each_item { |e| return e.key, e.value if key == e.key }
end
@@ -322,13 +353,13 @@ def delete(key)
return yield(key) if block_given?
end

def dig(*sequence)
item = self[sequence.shift]
return item if sequence.empty? || item.nil?
def dig(key, *remaining_keys)
item = self[key]
return item if remaining_keys.empty? || item.nil?

raise TypeError, "#{item.class} does not have #dig method" unless item.respond_to?(:dig)

item.dig(*sequence)
item.dig(*remaining_keys)
end

def each_item
@@ -367,6 +398,10 @@ def fetch(key, default=undefined)
raise KeyError, "key #{key} not found"
end

def fetch_values(*keys, &block)
keys.map { |key| fetch(key, &block) }
end

# Searches for an item matching +key+. Returns the item
# if found. Otherwise returns +nil+.
def find_item(key)
25 changes: 21 additions & 4 deletions kernel/common/io.rb
Original file line number Diff line number Diff line change
@@ -2722,22 +2722,35 @@ def read_if_available(bytes)
#
# If the read buffer is not empty, read_nonblock reads from the
# buffer like readpartial. In this case, read(2) is not called.
def read_nonblock(size, buffer=nil)
def read_nonblock(size, buffer=nil, opts={})
raise ArgumentError, "illegal read size" if size < 0
ensure_open

if buffer.is_a?(Hash)
opts = buffer
buffer = nil
end

buffer = StringValue buffer if buffer

unless @fd.blocking?
@fd.set_nonblock
nonblock_reset = true
end

if str = read_if_available(size)
begin
str = read_if_available(size)
rescue EAGAINWaitReadable => exc
raise exc unless opts[:exception] == false

return :wait_readable
end

if str
buffer.replace(str) if buffer
return str
else
raise EOFError, "stream closed"
raise EOFError, "stream closed" unless opts[:exception] == false
end
ensure
@fd.clear_nonblock if nonblock_reset
@@ -3293,13 +3306,17 @@ def write(data)
data.bytesize
end

def write_nonblock(data)
def write_nonblock(data, opts={})
ensure_open_and_writable

data = String data
return 0 if data.bytesize == 0

@fd.write_nonblock(data)
rescue EAGAINWaitWritable => exc
raise exc unless opts[:exception] == false

return :wait_writable
end

def close
3 changes: 2 additions & 1 deletion kernel/common/string.rb
Original file line number Diff line number Diff line change
@@ -42,8 +42,9 @@ def clone
alias_method :dup, :clone
end

def initialize(arg = undefined)
def initialize(arg = undefined, encoding: nil)
replace arg unless undefined.equal?(arg)
self.force_encoding(encoding) if encoding
self
end

14 changes: 7 additions & 7 deletions kernel/common/struct.rb
Original file line number Diff line number Diff line change
@@ -181,17 +181,17 @@ def []=(var, obj)
return instance_variable_set(:"@#{var}", obj)
end

def dig(*sequence)
def dig(key, *remaining_keys)
item = begin
self[sequence.shift]
rescue NameError
nil
end
return item if sequence.empty? || item.nil?
self[key]
rescue NameError
nil
end
return item if remaining_keys.empty? || item.nil?

raise TypeError, "#{item.class} does not have #dig method" unless item.respond_to?(:dig)

item.dig(*sequence)
item.dig(*remaining_keys)
end

def eql?(other)
1 change: 1 addition & 0 deletions kernel/platform/posix.rb
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ module FFI::Platform::POSIX
attach_function :readlink, [:string, :pointer, :size_t], :ssize_t
attach_function :rename, [:string, :string], :int
attach_function :utimes, [:string, :pointer], :int
attach_function :mkfifo, [:string, :mode_t], :int

# directories
attach_function :chdir, [:string], :int
11 changes: 8 additions & 3 deletions scripts/deploy.sh
Original file line number Diff line number Diff line change
@@ -254,21 +254,26 @@ function rbx_deploy_docker_release {
echo "Deploying Docker release $(rbx_revision_version)..."

local version release file url response sha
local -a paths=("15.10" "14.04")
local -a paths=("12.04")

version=$(rbx_revision_version)
release=$(rbx_release_name)
file="Dockerfile"

for path in "${paths[@]}"; do
url="https://api.github.com/repos/rubinius/rubinius/contents/dockerfiles/ubuntu/$path/$file"
url="https://api.github.com/repos/rubinius/docker/contents/ubuntu/$path/$file"
response=$(curl "$url?access_token=$GITHUB_OAUTH_TOKEN")

cat > "$file" <<EOF
FROM ubuntu:$path
RUN apt-get update && apt-get install -y \
bzip2 \
libyaml-0-2 \
libssl1.0.0
ADD https://rubinius-binaries-rubinius-com.s3-us-west-2.amazonaws.com/ubuntu/$path/x86_64/$release /tmp/rubinius.tar.bz2
RUN apt-get -y install bzip2 && cd /opt && tar xvjf /tmp/rubinius.tar.bz2
RUN cd /opt && tar xvjf /tmp/rubinius.tar.bz2
ENV PATH /opt/rubinius/$version/bin:/opt/rubinius/$version/gems/bin:\$PATH
4 changes: 4 additions & 0 deletions scripts/tag.sh
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@ __dir__="$(cd "$(dirname "$0")" && pwd)"
source "$__dir__/configuration.sh"

function rbx_tag_release {
git fetch --all -p

IFS="." read -r -a array <<< "$(rbx_revision_version)"

let major=${array[0]}
@@ -31,6 +33,8 @@ EOM
rbx_tag_usage
fi

git fetch --all -p

IFS="." read -r -a array <<< "$(rbx_revision_version)"

let major=${array[0]}
44 changes: 3 additions & 41 deletions spec/ruby/core/argf/read_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/read', __FILE__)

describe "ARGF.read" do
it_behaves_like :argf_read, :read

before :each do

@file1_name = fixture __FILE__, "file1.txt"
@@ -28,34 +31,6 @@
end
end

it "treats second nil argument as no output buffer" do
argv [@file1_name] do
ARGF.read(nil, nil).should == @file1
end
end

it "treats second argument as an output buffer" do
argv [@file1_name] do
buffer = ""
ARGF.read(nil, buffer)
buffer.should == @file1
end
end

it "reads a number of bytes from the first file" do
argv [@file1_name] do
ARGF.read(5).should == @file1[0,5]
end
end

it "reads from a single file consecutively" do
argv [@file1_name] do
ARGF.read(1).should == @file1[0,1]
ARGF.read(2).should == @file1[1,2]
ARGF.read(3).should == @file1[3,3]
end
end

it "reads the contents of two files" do
argv [@file1_name, @file2_name] do
ARGF.read.should == @file1 + @file2
@@ -81,11 +56,6 @@
stdin.should == @stdin
end

it "reads a number of bytes from stdin" do
stdin = ruby_exe("print ARGF.read(10)", :args => "< #{@stdin_name}")
stdin.should == @stdin[0,10]
end

it "reads the contents of one file and stdin" do
stdin = ruby_exe("print ARGF.read", :args => "#{@file1_name} - < #{@stdin_name}")
stdin.should == @file1 + @stdin
@@ -97,14 +67,6 @@
end
end

platform_is_not :windows do
it "reads the contents of a special device file" do
argv ['/dev/zero'] do
ARGF.read(100).should == "\000" * 100
end
end
end

with_feature :encoding do

before :each do
75 changes: 75 additions & 0 deletions spec/ruby/core/argf/readpartial_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/read', __FILE__)

describe "ARGF.readpartial" do
it_behaves_like :argf_read, :readpartial

before :each do
@file1_name = fixture __FILE__, "file1.txt"
@file2_name = fixture __FILE__, "file2.txt"
@stdin_name = fixture __FILE__, "stdin.txt"

@file1 = File.read @file1_name
@file2 = File.read @file2_name
@stdin = File.read @stdin_name
end

it "raises an ArgumentError if called without a maximum read length" do
argv [@file1_name] do
lambda { ARGF.readpartial }.should raise_error(ArgumentError)
end
end

it "reads maximum number of bytes from one file at a time" do
argv [@file1_name, @file2_name] do
len = @file1.size + @file2.size
ARGF.readpartial(len).should == @file1
end
end

it "clears output buffer even if EOFError is raised because ARGF is at end" do
begin
output = "to be cleared"

argv [@file1_name] do
ARGF.read
ARGF.readpartial(1, output)
end
rescue EOFError
output.should == ""
end
end

it "reads maximum number of bytes from one file at a time" do
argv [@file1_name, @file2_name] do
len = @file1.size + @file2.size
ARGF.readpartial(len).should == @file1
end
end

it "returns an empty string if EOFError is raised while reading any but the last file" do
argv [@file1_name, @file2_name] do
ARGF.readpartial(@file1.size)
ARGF.readpartial(1).should == ""
end
end

it "raises an EOFError if the exception was raised while reading the last file" do
argv [@file1_name, @file2_name] do
ARGF.readpartial(@file1.size)
ARGF.readpartial(1)
ARGF.readpartial(@file2.size)
lambda { ARGF.readpartial(1) }.should raise_error(EOFError)
lambda { ARGF.readpartial(1) }.should raise_error(EOFError)
end
end

it "raises an EOFError if the exception was raised while reading STDIN" do
ruby_str = <<-STR
print ARGF.readpartial(#{@stdin.size})
ARGF.readpartial(1) rescue print $!.class
STR
stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}", escape: true)
stdin.should == @stdin + "EOFError"
end
end
62 changes: 62 additions & 0 deletions spec/ruby/core/argf/shared/read.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
describe :argf_read, shared: true do
before :each do
@file1_name = fixture __FILE__, "file1.txt"
@stdin_name = fixture __FILE__, "stdin.txt"

@file1 = File.read @file1_name
@stdin = File.read @stdin_name
end

after :each do
ARGF.close unless ARGF.closed?
end

it "treats second nil argument as no output buffer" do
argv [@file1_name] do
ARGF.send(@method, @file1.size, nil).should == @file1
end
end

it "treats second argument as an output buffer" do
argv [@file1_name] do
buffer = ""
ARGF.send(@method, @file1.size, buffer)
buffer.should == @file1
end
end

it "clears output buffer before appending to it" do
argv [@file1_name] do
buffer = "to be cleared"
ARGF.send(@method, @file1.size, buffer)
buffer.should == @file1
end
end

it "reads a number of bytes from the first file" do
argv [@file1_name] do
ARGF.send(@method, 5).should == @file1[0, 5]
end
end

it "reads from a single file consecutively" do
argv [@file1_name] do
ARGF.send(@method, 1).should == @file1[0, 1]
ARGF.send(@method, 2).should == @file1[1, 2]
ARGF.send(@method, 3).should == @file1[3, 3]
end
end

it "reads a number of bytes from stdin" do
stdin = ruby_exe("print ARGF.#{@method}(10)", :args => "< #{@stdin_name}")
stdin.should == @stdin[0, 10]
end

platform_is_not :windows do
it "reads the contents of a special device file" do
argv ['/dev/zero'] do
ARGF.send(@method, 100).should == "\000" * 100
end
end
end
end
6 changes: 6 additions & 0 deletions spec/ruby/core/array/dig_spec.rb
Original file line number Diff line number Diff line change
@@ -19,6 +19,12 @@
lambda { a.dig(0, 1) }.should raise_error(TypeError)
end

it "raises an ArgumentError if no arguments provided" do
a = []

lambda { a.dig }.should raise_error(ArgumentError)
end

it "returns nil if any intermediate step is nil" do
a = [[1, [2, 3]]]

24 changes: 5 additions & 19 deletions spec/ruby/core/enumerable/chunk_spec.rb
Original file line number Diff line number Diff line change
@@ -12,6 +12,11 @@
end.should raise_error(ArgumentError)
end

it 'raises an ArgumentError if called with an argument' do
e = EnumerableSpecs::Numerous.new(1, 2, 3, 2, 1)
lambda { e.chunk(42) { |x| x == 2 }.to_a }.should raise_error(ArgumentError)
end

it "returns an Enumerator if given a block" do
EnumerableSpecs::Numerous.new.chunk {}.should be_an_instance_of(enumerator_class)
end
@@ -51,25 +56,6 @@
lambda { e.chunk { |x| :_arbitrary }.to_a }.should raise_error(RuntimeError)
end

describe "with [initial_state]" do
it "yields an element and an object value-equal but not identical to the object passed to #chunk" do
e = EnumerableSpecs::Numerous.new(1)
value = "value"

e.chunk(value) do |x, v|
x.should == 1
v.should == value
v.should_not equal(value)
end.to_a
end

it "does not yield the object passed to #chunk if it is nil" do
e = EnumerableSpecs::Numerous.new(1)
e.chunk(nil) { |*x| ScratchPad << x }.to_a
ScratchPad.recorded.should == [[1]]
end
end

it 'returned Enumerator size returns nil' do
e = EnumerableSpecs::NumerousWithSize.new(1, 2, 3, 2, 1)
enum = e.chunk { |x| true }
36 changes: 36 additions & 0 deletions spec/ruby/core/enumerable/chunk_while_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Enumerable#chunk_while" do
before :each do
ary = [10, 9, 7, 6, 4, 3, 2, 1]
@enum = EnumerableSpecs::Numerous.new *ary
@result = @enum.chunk_while { |i, j| i - 1 == j }
@enum_length = ary.length
end

context "when given a block" do
it "returns an enumerator" do
@result.should be_an_instance_of(enumerator_class)
end

it "splits chunks between adjacent elements i and j where the block returns false" do
@result.to_a.should == [[10, 9], [7, 6], [4, 3, 2, 1]]
end

it "calls the block for length of the receiver enumerable minus one times" do
times_called = 0
@enum.chunk_while do |i, j|
times_called += 1
i - 1 != j
end.to_a
times_called.should == (@enum_length - 1)
end
end

context "when not given a block" do
it "raises an ArgumentError" do
lambda { @enum.chunk_while }.should raise_error(ArgumentError)
end
end
end
34 changes: 34 additions & 0 deletions spec/ruby/core/enumerable/grep_v_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Enumerable#grep_v" do
it "returns an array of all elements not equal to the pattern when called without a block" do
pattern_cls = Class.new do
def ===(obj)
obj == '2'
end
end
enum = EnumerableSpecs::Numerous.new('2', 'a', 'nil', '3', false)

enum.grep_v(pattern_cls.new).should == ['a', 'nil', '3', false]
end

it "returns an array of all elements not equal to the pattern passed through the block" do
pattern_cls = Class.new do
def ===(obj)
/^ca/ =~ obj
end
end
enum = EnumerableSpecs::Numerous.new("cat", "coat", "car", "cadr", "cost")

enum.grep_v(pattern_cls.new) { |i| i.upcase }.should == ["COAT", "COST"]
end

it "calls the block with an array when yielded with multiple arguments" do
yields = []
EnumerableSpecs::YieldsMixed.new.grep_v(nil) { |v| yields << v }

yields.should == [1, [2], [3, 4], [5, 6, 7], [8, 9], []]
EnumerableSpecs::YieldsMixed.new.grep_v(nil).should == yields
end
end
28 changes: 2 additions & 26 deletions spec/ruby/core/enumerable/slice_before_spec.rb
Original file line number Diff line number Diff line change
@@ -41,32 +41,8 @@
end

describe "and an argument" do
it "calls the block with a copy of that argument" do
arg = [:foo]
first = nil
e = @enum.slice_before(arg) do |i, init|
init.should == arg
init.should_not equal(arg)
first = init
i == 6 || i == 2
end
e.should be_an_instance_of(enumerator_class)
e.to_a.should == [[7], [6, 5, 4, 3], [2, 1]]
e = @enum.slice_before(arg) do |i, init|
init.should_not equal(first)
end
e.to_a
end

quarantine! do # need to double-check with ruby-core. Might be wrong or too specific
it "duplicates the argument directly without calling dup" do
arg = EnumerableSpecs::Undupable.new
e = @enum.slice_before(arg) do |i, init|
init.initialize_dup_called.should be_true
false
end
e.to_a.should == [[7, 6, 5, 4, 3, 2, 1]]
end
it "raises an ArgumentError" do
lambda { @enum.slice_before("one") { |i| i == 6 } }.should raise_error(ArgumentError)
end
end
end
4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/drop_while_spec.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.drop_while { |v| v }.size.should == nil
end

@@ -44,7 +44,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take(20).drop_while { |v| v }.size.should == nil
end

4 changes: 4 additions & 0 deletions spec/ruby/core/enumerator/lazy/fixtures/classes.rb
Original file line number Diff line number Diff line change
@@ -12,6 +12,10 @@ def self.gathered_yields
[nil, 0, [0, 1], [0, 1, 2], [0, 1, 2], nil, :default_arg, [], [], [0], [0, 1], [0, 1, 2]]
end

def self.gathered_non_array_yields
[nil, 0, nil, :default_arg]
end

def self.gathered_yields_with_args(arg, *args)
[nil, 0, [0, 1], [0, 1, 2], [0, 1, 2], nil, arg, args, [], [0], [0, 1], [0, 1, 2]]
end
4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/grep_spec.rb
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.grep(Object) {}.size.should == nil
enumerator_class::Lazy.new(Object.new, 100) {}.grep(Object).size.should == nil
end
@@ -58,7 +58,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.grep(Object) {}.size.should == nil
enumerator_class::Lazy.new(Object.new, 100) {}.grep(Object).size.should == nil
end
84 changes: 84 additions & 0 deletions spec/ruby/core/enumerator/lazy/grep_v_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
require File.expand_path('../../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)

describe "Enumerator::Lazy#grep_v" do
before(:each) do
@yieldsmixed = EnumeratorLazySpecs::YieldsMixed.new.to_enum.lazy
@eventsmixed = EnumeratorLazySpecs::EventsMixed.new.to_enum.lazy
ScratchPad.record []
end

after(:each) do
ScratchPad.clear
end

it "requires an argument" do
enumerator_class::Lazy.instance_method(:grep_v).arity.should == 1
end

it "returns a new instance of Enumerator::Lazy" do
ret = @yieldsmixed.grep_v(Object) {}
ret.should be_an_instance_of(enumerator_class::Lazy)
ret.should_not equal(@yieldsmixed)

ret = @yieldsmixed.grep_v(Object)
ret.should be_an_instance_of(enumerator_class::Lazy)
ret.should_not equal(@yieldsmixed)
end

it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.grep_v(Object) {}.size.should == nil
enumerator_class::Lazy.new(Object.new, 100) {}.grep_v(Object).size.should == nil
end

describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
it "stops after specified times when not given a block" do
(0..Float::INFINITY).lazy.grep_v(3..5).first(3).should == [0, 1, 2]

@eventsmixed.grep_v(Symbol).first(1)
ScratchPad.recorded.should == [:before_yield]
end

it "stops after specified times when given a block" do
(0..Float::INFINITY).lazy.grep_v(4..8, &:succ).first(3).should == [1, 2, 3]

@eventsmixed.grep_v(Symbol) {}.first(1)
ScratchPad.recorded.should == [:before_yield]
end
end

it "calls the block with a gathered array when yield with multiple arguments" do
yields = []
@yieldsmixed.grep_v(Array) { |v| yields << v }.force
yields.should == EnumeratorLazySpecs::YieldsMixed.gathered_non_array_yields

@yieldsmixed.grep_v(Array).force.should == yields
end

describe "on a nested Lazy" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object) {}.size.should == nil
enumerator_class::Lazy.new(Object.new, 100) {}.grep_v(Object).grep_v(Object).size.should == nil
end

describe "when the returned lazy enumerator is evaluated by Enumerable#first" do
it "stops after specified times when not given a block" do
(0..Float::INFINITY).lazy.grep_v(3..5).grep_v(6..10).first(3).should == [0, 1, 2]

@eventsmixed.grep_v(Symbol).grep_v(String).first(1)
ScratchPad.recorded.should == [:before_yield]
end

it "stops after specified times when given a block" do
(0..Float::INFINITY).lazy
.grep_v(1..2) { |n| n > 3 ? n : false }
.grep_v(false) { |n| n.even? ? n : false }
.first(3)
.should == [4, false, 6]

@eventsmixed.grep_v(Symbol) {}.grep_v(String) {}.first(1)
ScratchPad.recorded.should == [:before_yield]
end
end
end
end
4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/initialize_spec.rb
Original file line number Diff line number Diff line change
@@ -31,11 +31,11 @@ def receiver.each
end
end

it "sets nil to size if not given a size" do
it "sets #size to nil if not given a size" do
@uninitialized.send(:initialize, @receiver) {}.size.should be_nil
end

it "sets nil to size if given size is nil" do
it "sets #size to nil if given size is nil" do
@uninitialized.send(:initialize, @receiver, nil) {}.size.should be_nil
end

4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/reject_spec.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.reject {}.size.should == nil
end

@@ -44,7 +44,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take(20).reject {}.size.should == nil
end

4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/shared/collect_concat.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.send(@method) { true }.size.should == nil
end

@@ -50,7 +50,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take(50) {}.send(@method) {}.size.should == nil
end

4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/shared/select.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.send(@method) { true }.size.should == nil
end

@@ -44,7 +44,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take(50) {}.send(@method) { true }.size.should == nil
end

2 changes: 1 addition & 1 deletion spec/ruby/core/enumerator/lazy/shared/to_enum.rb
Original file line number Diff line number Diff line change
@@ -17,7 +17,7 @@
ret.should_not equal(@infinite)
end

it "sets nil to size when not given a block" do
it "sets #size to nil when not given a block" do
enumerator_class::Lazy.new(Object.new, 100) {}.send(@method).size.should == nil
end

4 changes: 2 additions & 2 deletions spec/ruby/core/enumerator/lazy/take_while_spec.rb
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@
ret.should_not equal(@yieldsmixed)
end

it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take_while { true }.size.should == nil
end

@@ -44,7 +44,7 @@
end

describe "on a nested Lazy" do
it "sets nil to size" do
it "sets #size to nil" do
enumerator_class::Lazy.new(Object.new, 100) {}.take(20).take_while { true }.size.should == nil
end

10 changes: 10 additions & 0 deletions spec/ruby/core/exception/receiver_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require File.expand_path('../../../spec_helper', __FILE__)

describe "NameError#receiver" do
it "returns the receiver of the method call where the error occurred" do
receiver = 'receiver'
exception = receiver.doesnt_exist rescue $!

exception.receiver.should equal(receiver)
end
end
4 changes: 2 additions & 2 deletions spec/ruby/core/exception/system_call_error_spec.rb
Original file line number Diff line number Diff line change
@@ -62,12 +62,12 @@ def initialize
end

it "returns the errno given as optional argument to new" do
SystemCallError.new("message", -2**30).errno.should == -2**30
SystemCallError.new("message", -2**20).errno.should == -2**20
SystemCallError.new("message", -1).errno.should == -1
SystemCallError.new("message", 0).errno.should == 0
SystemCallError.new("message", 1).errno.should == 1
SystemCallError.new("message", 42).errno.should == 42
SystemCallError.new("message", 2**30).errno.should == 2**30
SystemCallError.new("message", 2**20).errno.should == 2**20
end
end

51 changes: 51 additions & 0 deletions spec/ruby/core/file/mkfifo_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require File.expand_path('../../../spec_helper', __FILE__)

describe "File.mkfifo" do
platform_is_not os: [:windows] do
before do
@path = tmp('fifo')
end

after do
rm_r(@path)
end

context "when path passed responds to :to_path" do
it "creates a FIFO file at the path specified" do
File.mkfifo(@path)
File.ftype(@path).should == "fifo"
end
end

context "when path passed is not a String value" do
it "raises a TypeError" do
lambda { File.mkfifo(:"/tmp/fifo") }.should raise_error(TypeError)
end
end

context "when path does not exist" do
it "raises an Errno::ENOENT exception" do
lambda { File.mkfifo("/bogus/path") }.should raise_error(Errno::ENOENT)
end
end

it "creates a FIFO file at the passed path" do
File.mkfifo(@path.to_s)
File.ftype(@path).should == "fifo"
end

it "creates a FIFO file with passed mode & ~umask" do
File.mkfifo(@path, 0755)
File.stat(@path).mode.should == 010755 & ~File.umask
end

it "creates a FIFO file with a default mode of 0666 & ~umask" do
File.mkfifo(@path)
File.stat(@path).mode.should == 010666 & ~File.umask
end

it "returns 0 after creating the FIFO file" do
File.mkfifo(@path).should == 0
end
end
end
6 changes: 6 additions & 0 deletions spec/ruby/core/hash/dig_spec.rb
Original file line number Diff line number Diff line change
@@ -25,6 +25,12 @@
lambda { h.dig(:foo, 3) }.should raise_error(TypeError)
end

it "raises an ArgumentError if no arguments provided" do
h = {}

lambda { h.dig }.should raise_error(ArgumentError)
end

it "calls #dig on any intermediate step with the rest of the sequence as arguments" do
o = Object.new
h = new_hash(foo: o)
31 changes: 31 additions & 0 deletions spec/ruby/core/hash/fetch_values_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require File.expand_path('../../../spec_helper', __FILE__)

describe "Hash#fetch_values" do
before do
@h = new_hash(foo: 1, bar: 2, baz: 3)
end

it "returns an array containing the values associated with the given keys" do
@h.fetch_values(:foo, :baz).should == [1, 3]
end

context "when one of the given keys does not exist" do
context "when no block is given" do
it "raises a KeyError" do
lambda { @h.fetch_values(:foo, :foobar) }.should raise_error(KeyError)
end
end

context "when a block is given" do
it "returns the value of the block for the missing key" do
@h.fetch_values(:foo, :foobar) { |k| k.length }.should == [1, 6]
end
end
end

context "when called with no arguments" do
it "returns an empty array" do
@h.fetch_values.should == []
end
end
end
13 changes: 13 additions & 0 deletions spec/ruby/core/hash/greater_than_or_equal_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison', __FILE__)
require File.expand_path('../shared/greater_than', __FILE__)

describe "Hash#>=" do
it_behaves_like :hash_comparison, :>=
it_behaves_like :hash_greater_than, :>=

it "returns true if both hashes are identical" do
h = new_hash(a: 1, b: 2)
(h >= h).should be_true
end
end
13 changes: 13 additions & 0 deletions spec/ruby/core/hash/greater_than_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison', __FILE__)
require File.expand_path('../shared/greater_than', __FILE__)

describe "Hash#>" do
it_behaves_like :hash_comparison, :>
it_behaves_like :hash_greater_than, :>

it "returns false if both hashes are identical" do
h = new_hash(a: 1, b: 2)
(h > h).should be_false
end
end
13 changes: 13 additions & 0 deletions spec/ruby/core/hash/less_than_or_equal_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison', __FILE__)
require File.expand_path('../shared/less_than', __FILE__)

describe "Hash#<=" do
it_behaves_like :hash_comparison, :<=
it_behaves_like :hash_less_than, :<=

it "returns true if both hashes are identical" do
h = new_hash(a: 1, b: 2)
(h <= h).should be_true
end
end
13 changes: 13 additions & 0 deletions spec/ruby/core/hash/less_than_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison', __FILE__)
require File.expand_path('../shared/less_than', __FILE__)

describe "Hash#<" do
it_behaves_like :hash_comparison, :<
it_behaves_like :hash_less_than, :<

it "returns false if both hashes are identical" do
h = new_hash(a: 1, b: 2)
(h < h).should be_false
end
end
15 changes: 15 additions & 0 deletions spec/ruby/core/hash/shared/comparison.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
describe :hash_comparison, shared: true do
it "raises a TypeError if the right operand is not a hash" do
lambda { new_hash(a: 1).send(@method, 1) }.should raise_error(TypeError)
lambda { new_hash(a: 1).send(@method, nil) }.should raise_error(TypeError)
lambda { new_hash(a: 1).send(@method, []) }.should raise_error(TypeError)
end

it "returns false if both hashes have the same keys but different values" do
h1 = new_hash(a: 1)
h2 = new_hash(a: 2)

h1.send(@method, h2).should be_false
h2.send(@method, h1).should be_false
end
end
23 changes: 23 additions & 0 deletions spec/ruby/core/hash/shared/greater_than.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
describe :hash_greater_than, shared: true do
before do
@h1 = new_hash(a: 1, b: 2, c: 3)
@h2 = new_hash(a: 1, b: 2)
end

it "returns true if the other hash is a subset of self" do
@h1.send(@method, @h2).should be_true
end

it "returns false if the other hash is not a subset of self" do
@h2.send(@method, @h1).should be_false
end

it "converts the right operand to a hash before comparing" do
o = Object.new
def o.to_hash
new_hash(a: 1, b: 2)
end

@h1.send(@method, o).should be_true
end
end
23 changes: 23 additions & 0 deletions spec/ruby/core/hash/shared/less_than.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
describe :hash_less_than, shared: true do
before do
@h1 = new_hash(a: 1, b: 2)
@h2 = new_hash(a: 1, b: 2, c: 3)
end

it "returns true if self is a subset of the other hash" do
@h1.send(@method, @h2).should be_true
end

it "returns false if self is not a subset of the other hash" do
@h2.send(@method, @h1).should be_false
end

it "converts the right operand to a hash before comparing" do
o = Object.new
def o.to_hash
new_hash(a: 1, b: 2, c: 3)
end

@h1.send(@method, o).should be_true
end
end
64 changes: 49 additions & 15 deletions spec/ruby/core/io/read_nonblock_spec.rb
Original file line number Diff line number Diff line change
@@ -11,8 +11,42 @@
@write.close rescue nil
end

it "raises IO::EAGAINWaitReadable when there is no data" do
lambda { @read.read_nonblock(5) }.should raise_error(IO::EAGAINWaitReadable)
context "when exception option is not passed" do
context "when there is no data" do
it "raises IO::EAGAINWaitReadable" do
lambda { @read.read_nonblock(5) }.should raise_error(IO::EAGAINWaitReadable)
end
end

context "when the end is reached" do
it "raises EOFError" do
@write << "hello"
@write.close

@read.read_nonblock(5)

lambda { @read.read_nonblock(5) }.should raise_error(EOFError)
end
end
end

context "when exception option is set to false" do
context "when there is no data" do
it "returns :wait_readable" do
@read.read_nonblock(5, exception: false).should == :wait_readable
end
end

context "when the end is reached" do
it "returns nil" do
@write << "hello"
@write.close

@read.read_nonblock(5)

@read.read_nonblock(5, exception: false).should be_nil
end
end
end

it "returns at most the number of bytes requested" do
@@ -35,22 +69,22 @@
@read.read_nonblock(1).should == "1"
end

it "returns any buffered data in addition to reading new data" do
@write << "hello"
@read.ungetc("a")
@read.read_nonblock(10).should == "ahello"
it "reads into the passed buffer" do
buffer = ""
@write.write("1")
@read.read_nonblock(1, buffer)
buffer.should == "1"
end

it "raises IOError on closed stream" do
lambda { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError)
not_compliant_on :rubinius, :jruby do
# TODO: Fix this.
#
# This feature was changed in 1.9
# see also: [ruby-dev:25101] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/25101
# and #2469 http://redmine.ruby-lang.org/issues/show/2469
end

it "raises EOFError when the end is reached" do
@write << "hello"
@write.close

@read.read_nonblock(5)

lambda { @read.read_nonblock(5) }.should raise_error(EOFError)
it "raises IOError on closed stream" do
lambda { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError)
end
end
16 changes: 13 additions & 3 deletions spec/ruby/core/io/write_nonblock_spec.rb
Original file line number Diff line number Diff line change
@@ -44,9 +44,19 @@
@write.close
end

it 'raises IO::EAGAINWaitWritable when the operation would block' do
proc { loop { @write.write_nonblock('a' * 10_000) } }
.should raise_error(IO::EAGAINWaitWritable)
context "when the operation would block" do
context "when exception option is not passed" do
it "raises IO::EAGAINWaitWritable" do
lambda { loop { @write.write_nonblock("a" * 10_000) } }.should raise_error(IO::EAGAINWaitWritable)
end
end

context "when exception option is set to false" do
it "returns :wait_writable" do
loop { break if @write.write_nonblock("a" * 10_000, exception: false) == :wait_writable }
1.should == 1
end
end
end
end

6 changes: 6 additions & 0 deletions spec/ruby/core/string/new_spec.rb
Original file line number Diff line number Diff line change
@@ -7,6 +7,12 @@
str.should be_an_instance_of(String)
end

it "accepts an encoding argument" do
str = String.new("\xA4\xA2", encoding: 'euc-jp')

str.encoding.should == Encoding::EUC_JP
end

it "returns a fully-formed String" do
str = String.new
str.size.should == 0
4 changes: 4 additions & 0 deletions spec/ruby/core/struct/dig_spec.rb
Original file line number Diff line number Diff line change
@@ -24,6 +24,10 @@
lambda { instance.dig(:a, 3) }.should raise_error(TypeError)
end

it "raises an ArgumentError if no arguments provided" do
lambda { @instance.dig }.should raise_error(ArgumentError)
end

it "calls #dig on any intermediate step with the rest of the sequence as arguments" do
obj = Object.new
instance = @klass.new(obj)
14 changes: 14 additions & 0 deletions spec/ruby/language/fixtures/super.rb
Original file line number Diff line number Diff line change
@@ -327,4 +327,18 @@ class AnonymousModuleIncludedTwice < AnonymousModuleIncludedTwiceBase
whatever
whatever
end

module KeywordArguments
class A
def foo(**args)
args
end
end

class B < A
def foo(**)
super
end
end
end
end
14 changes: 14 additions & 0 deletions spec/ruby/language/super_spec.rb
Original file line number Diff line number Diff line change
@@ -158,4 +158,18 @@ def a(arg)
it "invokes methods from a chain of anonymous modules" do
Super::AnonymousModuleIncludedTwice.new.a([]).should == ["anon", "anon", "non-anon"]
end

describe 'when using keyword arguments' do
it 'passes any given keyword arguments to the parent' do
b = Super::KeywordArguments::B.new

b.foo(:number => 10).should == {:number => 10}
end

it 'does not pass any keyword arguments to the parent when none are given' do
b = Super::KeywordArguments::B.new

b.foo.should == {}
end
end
end
10 changes: 4 additions & 6 deletions spec/ruby/optional/capi/numeric_spec.rb
Original file line number Diff line number Diff line change
@@ -156,18 +156,16 @@
@s.rb_int2num(4.2).should == 4
end

it "converts a Bignum" do
@s.rb_int2num(0x7fff_ffff).should == 0x7fff_ffff
it "raises a RangeError when passed a BigNum" do
lambda { @s.rb_int2num(bignum_value) }.should raise_error(RangeError)
end

it "converts a Fixnum" do
@s.rb_int2num(5).should == 5
end

# INT2NUM used to use `long` prior to MRI 1.9. With 1.9 it has been changed
# to use `int` instead.
it "converts 0xFFFFFFFF to -1" do
@s.rb_int2num(0xFFFFFFFF).should == -1
it "converts a negative Fixnum" do
@s.rb_int2num(-11).should == -11
end
end

1 change: 1 addition & 0 deletions spec/tags/ruby/core/exception/receiver_tags.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fails:NameError#receiver returns the receiver of the method call where the error occurred
1 change: 1 addition & 0 deletions spec/tags/ruby/language/super_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
fails:The super keyword raises a RuntimeError when called with implicit arguments from a method defined with define_method
fails:The super keyword invokes methods from a chain of anonymous modules
fails:The super keyword when using keyword arguments does not pass any keyword arguments to the parent when none are given
8 changes: 8 additions & 0 deletions vm/capi/bignum.cpp
Original file line number Diff line number Diff line change
@@ -133,6 +133,14 @@ extern "C" {
VALUE rb_dbl2big(double num) {
NativeMethodEnvironment* env = NativeMethodEnvironment::get();

// We have to handle exceptional cases here so that a C++ exception is not
// thrown when we call into C++ code.
if(isinf(num)) {
rb_raise(rb_eFloatDomainError, num < 0 ? "-Infinity" : "Infinity");
} else if(isnan(num)) {
rb_raise(rb_eFloatDomainError, "NaN");
}

Integer* bignum = Bignum::from_double(env->state(), num);

return env->get_handle(bignum);
1 change: 1 addition & 0 deletions vm/ontology.cpp
Original file line number Diff line number Diff line change
@@ -518,6 +518,7 @@ namespace rubinius {

G(rubinius)->set_const(state, "HAVE_LCHMOD", RBX_HAVE_LCHMOD ? cTrue : cFalse);
G(rubinius)->set_const(state, "HAVE_LCHOWN", RBX_HAVE_LCHOWN ? cTrue : cFalse);
G(rubinius)->set_const(state, "HAVE_MKFIFO", RBX_HAVE_MKFIFO ? cTrue : cFalse);

#ifdef RBX_LITTLE_ENDIAN
G(rubinius)->set_const(state, "ENDIAN", state->symbol("little"));

0 comments on commit 910d9f8

Please sign in to comment.