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@58718 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2017-05-14 14:09:56 +00:00
parent d593aed7b7
commit a5b83b03ad
47 changed files with 254 additions and 172 deletions

View file

@ -0,0 +1,19 @@
require File.expand_path('../../spec_helper', __FILE__)
describe 'The -S command line option' do
before :each do
@path = [ENV['PATH'], fixture(__FILE__, "bin")].join(':')
end
platform_is_not :windows do
it "runs launcher found in PATH, but only code after the first /\#!.*ruby.*/-ish line in target file" do
result = ruby_exe(nil, options: '-S hybrid_launcher.sh', env: { 'PATH' => @path }, args: '2>&1')
result.should == "success\n"
end
it "runs launcher found in PATH" do
result = ruby_exe(nil, options: '-S launcher.rb', env: { 'PATH' => @path }, args: '2>&1')
result.should == "success\n"
end
end
end

View file

@ -1,10 +1,19 @@
describe "The -x command line option" do describe "The -x command line option" do
before :each do it "runs code after the first /\#!.*ruby.*/-ish line in target file" do
@file = fixture __FILE__, "embedded_ruby.txt" embedded_ruby = fixture __FILE__, "bin/embedded_ruby.txt"
result = ruby_exe(embedded_ruby, options: '-x')
result.should == "success\n"
end end
it "runs code after the first /\#!.*ruby.*/-ish line in target file" do it "fails when /\#!.*ruby.*/-ish line in target file is not found" do
result = ruby_exe(@file, options: '-x') bad_embedded_ruby = fixture __FILE__, "bin/bad_embedded_ruby.txt"
result = ruby_exe(bad_embedded_ruby, options: '-x', args: '2>&1')
result.should include "no Ruby script found in input"
end
it "behaves as -x was set when non-ruby shebang is encountered on first line" do
embedded_ruby = fixture __FILE__, "bin/hybrid_launcher.sh"
result = ruby_exe(embedded_ruby)
result.should == "success\n" result.should == "success\n"
end end

View file

@ -0,0 +1,3 @@
@@@This line is not value Ruby
#!rub_y
puts 'success'

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
exec somehow this file
#!ruby
puts 'success'

View file

@ -0,0 +1,2 @@
#!ruby
puts 'success'

View file

@ -16,8 +16,8 @@ describe "Bignum#&" do
end end
it "returns self bitwise AND other when one operand is negative" do it "returns self bitwise AND other when one operand is negative" do
((2*bignum_value) & -1).should == 18446744073709551616 ((2*bignum_value) & -1).should == (2*bignum_value)
((4*bignum_value) & -1).should == 36893488147419103232 ((4*bignum_value) & -1).should == (4*bignum_value)
(@bignum & -0xffffffffffffff5).should == 9223372036854775809 (@bignum & -0xffffffffffffff5).should == 9223372036854775809
(@bignum & -@bignum).should == 1 (@bignum & -@bignum).should == 1
(@bignum & -0x8000000000000000).should == 9223372036854775808 (@bignum & -0x8000000000000000).should == 9223372036854775808

View file

@ -13,6 +13,16 @@ describe "Binding#eval" do
bind.eval("Inside.name").should == "BindingSpecs::Demo::Inside" bind.eval("Inside.name").should == "BindingSpecs::Demo::Inside"
end end
it "does not leak variables to cloned bindings" do
obj = BindingSpecs::Demo.new(1)
bind = obj.get_empty_binding
bind2 = bind.dup
bind.eval("x = 72")
bind.local_variables.should == [:x]
bind2.local_variables.should == []
end
describe "with a file given" do describe "with a file given" do
it "does not store the filename permanently" do it "does not store the filename permanently" do
obj = BindingSpecs::Demo.new(1) obj = BindingSpecs::Demo.new(1)

View file

@ -28,5 +28,13 @@ module BindingSpecs
def get_empty_binding def get_empty_binding
binding binding
end end
def get_binding_in_block
a = true
1.times do
b = false
return binding
end
end
end end
end end

View file

@ -42,4 +42,15 @@ describe "Binding#local_variable_get" do
bind.local_variable_get(:number).should == 10 bind.local_variable_get(:number).should == 10
end end
it "raises a NameError on global access" do
bind = binding
lambda { bind.local_variable_get(:$0) }.should raise_error(NameError)
end
it "raises a NameError on special variable access" do
bind = binding
lambda { bind.local_variable_get(:$~) }.should raise_error(NameError)
lambda { bind.local_variable_get(:$_) }.should raise_error(NameError)
end
end end

View file

@ -56,4 +56,16 @@ describe "Binding#local_variable_set" do
bind.local_variable_set(:number, 20) bind.local_variable_set(:number, 20)
bind.local_variable_get(:number).should == 20 bind.local_variable_get(:number).should == 20
end end
it "raises a NameError on global access" do
bind = binding
lambda { bind.local_variable_set(:$0, "") }.should raise_error(NameError)
end
it "raises a NameError on special variable access" do
bind = binding
lambda { bind.local_variable_set(:$~, "") }.should raise_error(NameError)
lambda { bind.local_variable_set(:$_, "") }.should raise_error(NameError)
end
end end

View file

@ -2,19 +2,33 @@ describe :binding_clone, shared: true do
before :each do before :each do
@b1 = BindingSpecs::Demo.new(99).get_binding @b1 = BindingSpecs::Demo.new(99).get_binding
@b2 = @b1.send(@method) @b2 = @b1.send(@method)
@b3 = BindingSpecs::Demo.new(99).get_binding_in_block
@b4 = @b3.send(@method)
end end
it "returns a copy of the Binding object" do it "returns a copy of the Binding object" do
@b1.should_not == @b2 [[@b1, @b2, "a"],
[@b3, @b4, "a", "b"]].each do |b1, b2, *vars|
b1.should_not == b2
eval("@secret", @b1).should == eval("@secret", @b2) eval("@secret", b1).should == eval("@secret", b2)
eval("square(2)", @b1).should == eval("square(2)", @b2) eval("square(2)", b1).should == eval("square(2)", b2)
eval("self.square(2)", @b1).should == eval("self.square(2)", @b2) eval("self.square(2)", b1).should == eval("self.square(2)", b2)
eval("a", @b1).should == eval("a", @b2) vars.each do |v|
eval("#{v}", b1).should == eval("#{v}", b2)
end
end
end end
it "is a shallow copy of the Binding object" do it "is a shallow copy of the Binding object" do
eval("a = false", @b1) [[@b1, @b2, "a"],
eval("a", @b2).should == false [@b3, @b4, "a", "b"]].each do |b1, b2, *vars|
vars.each do |v|
eval("#{v} = false", b1)
eval("#{v}", b2).should == false
end
b1.local_variable_set(:x, 37)
b2.local_variable_defined?(:x).should == false
end
end end
end end

View file

@ -29,6 +29,21 @@ with_feature :fiber do
fiber.resume :caller fiber.resume :caller
end end
it "does not propagate or reraise a rescued exception" do
fiber = Fiber.new do
begin
raise "an error in a Fiber"
rescue
Fiber.yield :first
end
:second
end
fiber.resume.should == :first
fiber.resume.should == :second
end
it "raises a FiberError if called from the root Fiber" do it "raises a FiberError if called from the root Fiber" do
lambda{ Fiber.yield }.should raise_error(FiberError) lambda{ Fiber.yield }.should raise_error(FiberError)
end end

View file

@ -1,6 +1,7 @@
module FileSpecs module FileSpecs
# Try to set up known locations of each filetype def self.configure_types
def self.reconfigure() return if @configured
@file = tmp("test.txt") @file = tmp("test.txt")
@dir = Dir.pwd @dir = Dir.pwd
@fifo = tmp("test_fifo") @fifo = tmp("test_fifo")
@ -15,45 +16,43 @@ module FileSpecs
@link = links.first @link = links.first
break break
end end
end
end end
# TODO: Automatic reload mechanism @configured = true
reconfigure end
def self.normal_file() def self.normal_file
File.open(@file, "w") {} # 'Touch' touch(@file)
yield @file yield @file
ensure ensure
rm_r @file rm_r @file
end end
def self.directory() def self.directory
yield @dir yield @dir
end end
# TODO: need a platform-independent helper here # TODO: need a platform-independent helper here
def self.fifo() def self.fifo
system "mkfifo #{@fifo} 2> /dev/null" system "mkfifo #{@fifo} 2> /dev/null"
yield @fifo yield @fifo
ensure ensure
rm_r @fifo rm_r @fifo
end end
def self.block_device() def self.block_device
yield @block yield @block
end end
def self.character_device() def self.character_device
yield @char yield @char
end end
def self.symlink() def self.symlink
yield @link yield @link
end end
def self.socket() def self.socket
require 'socket' require 'socket'
name = tmp("ftype_socket.socket") name = tmp("ftype_socket.socket")
rm_r name rm_r name

View file

@ -1,7 +1,11 @@
require "#{File.dirname(__FILE__)}/../../spec_helper" require "#{File.dirname(__FILE__)}/../../spec_helper"
require "#{File.dirname(__FILE__)}/fixtures/file_types.rb" require "#{File.dirname(__FILE__)}/fixtures/file_types"
describe "File.ftype" do describe "File.ftype" do
before :all do
FileSpecs.configure_types
end
it "raises ArgumentError if not given exactly one filename" do it "raises ArgumentError if not given exactly one filename" do
lambda { File.ftype }.should raise_error(ArgumentError) lambda { File.ftype }.should raise_error(ArgumentError)
lambda { File.ftype('blah', 'bleh') }.should raise_error(ArgumentError) lambda { File.ftype('blah', 'bleh') }.should raise_error(ArgumentError)

View file

@ -1,7 +1,11 @@
require "#{File.dirname(__FILE__)}/../../../spec_helper" require "#{File.dirname(__FILE__)}/../../../spec_helper"
require "#{File.dirname(__FILE__)}/../fixtures/file_types.rb" require "#{File.dirname(__FILE__)}/../fixtures/file_types"
describe "File::Stat#ftype" do describe "File::Stat#ftype" do
before :all do
FileSpecs.configure_types
end
it "returns a String" do it "returns a String" do
FileSpecs.normal_file do |file| FileSpecs.normal_file do |file|
File.lstat(file).ftype.should be_kind_of(String) File.lstat(file).ftype.should be_kind_of(String)
@ -62,4 +66,3 @@ describe "File::Stat#ftype" do
end end
end end
end end

View file

@ -8,6 +8,21 @@ describe "Fixnum#&" do
(0xffff & bignum_value + 0xffff_ffff).should == 65535 (0xffff & bignum_value + 0xffff_ffff).should == 65535
end end
it "returns self bitwise AND other when one operand is negative" do
((1 << 33) & -1).should == (1 << 33)
(-1 & (1 << 33)).should == (1 << 33)
((-(1<<33)-1) & 5).should == 5
(5 & (-(1<<33)-1)).should == 5
end
it "returns self bitwise AND other when both operands are negative" do
(-5 & -1).should == -5
(-3 & -4).should == -4
(-12 & -13).should == -16
(-13 & -12).should == -16
end
it "returns self bitwise AND a Bignum" do it "returns self bitwise AND a Bignum" do
(-1 & 2**64).should == 18446744073709551616 (-1 & 2**64).should == 18446744073709551616
end end

View file

@ -74,6 +74,7 @@ describe "IO#advise" do
end end
platform_is :linux do platform_is :linux do
it "supports the willneed advice type" do
require 'etc' require 'etc'
uname = if Etc.respond_to?(:uname) uname = if Etc.respond_to?(:uname)
Etc.uname[:release] Etc.uname[:release]
@ -82,8 +83,8 @@ describe "IO#advise" do
end end
if (uname.split('.').map(&:to_i) <=> [3,6]) < 0 if (uname.split('.').map(&:to_i) <=> [3,6]) < 0
# [ruby-core:65355] tmpfs is not supported # [ruby-core:65355] tmpfs is not supported
1.should == 1
else else
it "supports the willneed advice type" do
@io.advise(:willneed).should be_nil @io.advise(:willneed).should be_nil
end end
end end

View file

@ -22,7 +22,9 @@ describe "Process.exec" do
platform_is :windows do platform_is :windows do
it "raises Errno::EACCES or Errno::ENOEXEC when the file is not an executable file" do it "raises Errno::EACCES or Errno::ENOEXEC when the file is not an executable file" do
lambda { Process.exec __FILE__ }.should raise_error(->(e){[Errno::EACCES, Errno::ENOEXEC].find{|exc| exc === e}}) lambda { Process.exec __FILE__ }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::ENOEXEC].should include(e.class)
}
end end
end end
end end

View file

@ -576,7 +576,9 @@ describe "Process.spawn" do
platform_is :windows do platform_is :windows do
it "raises Errno::EACCES or Errno::ENOEXEC when the file is not an executable file" do it "raises Errno::EACCES or Errno::ENOEXEC when the file is not an executable file" do
lambda { Process.spawn __FILE__ }.should raise_error(->(e){[Errno::EACCES, Errno::ENOEXEC].find{|exc| exc === e}}) lambda { Process.spawn __FILE__ }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::ENOEXEC].should include(e.class)
}
end end
end end
end end

View file

@ -41,7 +41,7 @@ describe "Time#-" do
time.usec.should == 123456 time.usec.should == 123456
end end
it "tracks microseconds" do it "tracks microseconds from a Rational" do
time = Time.at(Rational(777_777, 1_000_000)) time = Time.at(Rational(777_777, 1_000_000))
time -= Rational(654_321, 1_000_000) time -= Rational(654_321, 1_000_000)
time.usec.should == 123_456 time.usec.should == 123_456
@ -63,12 +63,12 @@ describe "Time#-" do
end end
it "maintains microseconds precision" do it "maintains microseconds precision" do
time = Time.at(10) - Rational(1_000_000_000_000_001, 1_000_000_000_000_000) time = Time.at(10) - Rational(1, 1_000_000)
time.usec.should == 999_999 time.usec.should == 999_999
end end
it "maintains nanoseconds precision" do it "maintains nanoseconds precision" do
time = Time.at(10) - Rational(1_000_000_000_000_001, 1_000_000_000_000_000) time = Time.at(10) - Rational(1, 1_000_000_000)
time.nsec.should == 999_999_999 time.nsec.should == 999_999_999
end end

View file

@ -599,7 +599,7 @@ describe "A block" do
@y.m(1, 2) { |a, (b, (c, d))| [a, b, c, d] }.should == [1, 2, nil, nil] @y.m(1, 2) { |a, (b, (c, d))| [a, b, c, d] }.should == [1, 2, nil, nil]
end end
it "destructures a single multi-level Array value yielded" do it "destructures a nested Array value yielded" do
@y.m(1, [2, 3]) { |a, (b, (c, d))| [a, b, c, d] }.should == [1, 2, 3, nil] @y.m(1, [2, 3]) { |a, (b, (c, d))| [a, b, c, d] }.should == [1, 2, 3, nil]
end end
@ -617,7 +617,7 @@ describe "A block" do
@y.m(1, 2) { |a, ((b, c), d)| [a, b, c, d] }.should == [1, 2, nil, nil] @y.m(1, 2) { |a, ((b, c), d)| [a, b, c, d] }.should == [1, 2, nil, nil]
end end
it "destructures a single multi-level Array value yielded" do it "destructures a nested value yielded" do
@y.m(1, [2, 3]) { |a, ((b, c), d)| [a, b, c, d] }.should == [1, 2, nil, 3] @y.m(1, [2, 3]) { |a, ((b, c), d)| [a, b, c, d] }.should == [1, 2, nil, 3]
end end

View file

@ -881,49 +881,51 @@ end
describe "The defined? keyword for a variable scoped constant" do describe "The defined? keyword for a variable scoped constant" do
after :all do after :all do
if Object.class_variable_defined? :@@defined_specs_obj
Object.__send__(:remove_class_variable, :@@defined_specs_obj) Object.__send__(:remove_class_variable, :@@defined_specs_obj)
end end
end
it "returns nil if the scoped constant is not defined" do it "returns nil if the instance scoped constant is not defined" do
@defined_specs_obj = DefinedSpecs::Basic @defined_specs_obj = DefinedSpecs::Basic
defined?(@defined_specs_obj::Undefined).should be_nil defined?(@defined_specs_obj::Undefined).should be_nil
end end
it "returns 'constant' if the constant is defined in the scope of the variable reference" do it "returns 'constant' if the constant is defined in the scope of the instance variable" do
@defined_specs_obj = DefinedSpecs::Basic @defined_specs_obj = DefinedSpecs::Basic
defined?(@defined_specs_obj::A).should == "constant" defined?(@defined_specs_obj::A).should == "constant"
end end
it "returns nil if the scoped constant is not defined" do it "returns nil if the global scoped constant is not defined" do
$defined_specs_obj = DefinedSpecs::Basic $defined_specs_obj = DefinedSpecs::Basic
defined?($defined_specs_obj::Undefined).should be_nil defined?($defined_specs_obj::Undefined).should be_nil
end end
it "returns 'constant' if the constant is defined in the scope of the variable reference" do it "returns 'constant' if the constant is defined in the scope of the global variable" do
$defined_specs_obj = DefinedSpecs::Basic $defined_specs_obj = DefinedSpecs::Basic
defined?($defined_specs_obj::A).should == "constant" defined?($defined_specs_obj::A).should == "constant"
end end
it "returns nil if the scoped constant is not defined" do it "returns nil if the class scoped constant is not defined" do
-> { -> {
@@defined_specs_obj = DefinedSpecs::Basic @@defined_specs_obj = DefinedSpecs::Basic
defined?(@@defined_specs_obj::Undefined).should be_nil defined?(@@defined_specs_obj::Undefined).should be_nil
}.should complain(/class variable access from toplevel/) }.should complain(/class variable access from toplevel/)
end end
it "returns 'constant' if the constant is defined in the scope of the variable reference" do it "returns 'constant' if the constant is defined in the scope of the class variable" do
-> { -> {
@@defined_specs_obj = DefinedSpecs::Basic @@defined_specs_obj = DefinedSpecs::Basic
defined?(@@defined_specs_obj::A).should == "constant" defined?(@@defined_specs_obj::A).should == "constant"
}.should complain(/class variable access from toplevel/) }.should complain(/class variable access from toplevel/)
end end
it "returns nil if the scoped constant is not defined" do it "returns nil if the local scoped constant is not defined" do
defined_specs_obj = DefinedSpecs::Basic defined_specs_obj = DefinedSpecs::Basic
defined?(defined_specs_obj::Undefined).should be_nil defined?(defined_specs_obj::Undefined).should be_nil
end end
it "returns 'constant' if the constant is defined in the scope of the variable reference" do it "returns 'constant' if the constant is defined in the scope of the local variable" do
defined_specs_obj = DefinedSpecs::Basic defined_specs_obj = DefinedSpecs::Basic
defined?(defined_specs_obj::A).should == "constant" defined?(defined_specs_obj::A).should == "constant"
end end

View file

@ -69,12 +69,12 @@ HERE
SquigglyHeredocSpecs.unquoted.should == "unquoted interpolated\n" SquigglyHeredocSpecs.unquoted.should == "unquoted interpolated\n"
end end
it 'allows HEREDOC with <<"identifier", interpolated' do it 'allows HEREDOC with <<~"identifier", interpolated' do
require File.expand_path('../fixtures/squiggly_heredoc', __FILE__) require File.expand_path('../fixtures/squiggly_heredoc', __FILE__)
SquigglyHeredocSpecs.doublequoted.should == "doublequoted interpolated\n" SquigglyHeredocSpecs.doublequoted.should == "doublequoted interpolated\n"
end end
it "allows HEREDOC with <<'identifier', no interpolation" do it "allows HEREDOC with <<~'identifier', no interpolation" do
require File.expand_path('../fixtures/squiggly_heredoc', __FILE__) require File.expand_path('../fixtures/squiggly_heredoc', __FILE__)
SquigglyHeredocSpecs.singlequoted.should == "singlequoted \#{\"interpolated\"}\n" SquigglyHeredocSpecs.singlequoted.should == "singlequoted \#{\"interpolated\"}\n"
end end

View file

@ -167,10 +167,6 @@ describe "Regexp with character classes" do
"\u{36F}".match(/[[:blank:]]/).should be_nil "\u{36F}".match(/[[:blank:]]/).should be_nil
end end
it "doesn't match Unicode control characters with [[:blank:]]" do
"\u{16}".match(/[[:blank:]]/).should be_nil
end
it "doesn't Unicode letter characters with [[:cntrl:]]" do it "doesn't Unicode letter characters with [[:cntrl:]]" do
"à".match(/[[:cntrl:]]/).should be_nil "à".match(/[[:cntrl:]]/).should be_nil
end end
@ -393,9 +389,6 @@ describe "Regexp with character classes" do
it "matches Unicode Pf characters with [[:punct:]]" do it "matches Unicode Pf characters with [[:punct:]]" do
"\u{201D}".match(/[[:punct:]]/).to_a.should == ["\u{201D}"] "\u{201D}".match(/[[:punct:]]/).to_a.should == ["\u{201D}"]
end
it "matches Unicode Pf characters with [[:punct:]]" do
"\u{00BB}".match(/[[:punct:]]/).to_a.should == ["\u{00BB}"] "\u{00BB}".match(/[[:punct:]]/).to_a.should == ["\u{00BB}"]
end end

View file

@ -139,7 +139,7 @@ describe "Literal Regexps" do
pattern.should_not =~ 'T' pattern.should_not =~ 'T'
end end
it "supports conditional regular expressions with positional capture groups" do it "supports conditional regular expressions with named capture groups" do
pattern = /\A(?<word>foo)?(?(<word>)(T)|(F))\z/ pattern = /\A(?<word>foo)?(?(<word>)(T)|(F))\z/
pattern.should =~ 'fooT' pattern.should =~ 'fooT'

View file

@ -156,7 +156,7 @@ describe "Multiple assignment" do
[a, b, c].should == [1, [], 2] [a, b, c].should == [1, [], 2]
end end
it "raises a TypeError if #to_ary does not return an Array" do it "raises a TypeError if #to_ary does not return an Array with MLHS" do
x = mock("multi-assign splat") x = mock("multi-assign splat")
x.should_receive(:to_ary).and_return(1) x.should_receive(:to_ary).and_return(1)
@ -249,7 +249,7 @@ describe "Multiple assignment" do
[a, b].should == [1, 2] [a, b].should == [1, 2]
end end
it "raises a TypeError if #to_ary does not return an Array" do it "raises a TypeError if #to_ary does not return an Array on a single RHS" do
y = mock("multi-assign method return value") y = mock("multi-assign method return value")
y.should_receive(:to_ary).and_return(1) y.should_receive(:to_ary).and_return(1)
@ -359,6 +359,10 @@ describe "Multiple assignment" do
(* = *a).should == [1] (* = *a).should == [1]
end end
it "consumes values for a grouped anonymous splat" do
((*) = *1).should == [1]
end
it "assigns a single LHS splat" do it "assigns a single LHS splat" do
x = 1 x = 1
(*a = *x).should == [1] (*a = *x).should == [1]
@ -445,15 +449,7 @@ describe "Multiple assignment" do
a.should == [x] a.should == [x]
end end
it "calls #to_a to convert an Object RHS with a single LHS" do it "raises a TypeError if #to_a does not return an Array with a single LHS" do
x = mock("multi-assign splat")
x.should_receive(:to_a).and_return([1, 2])
a = *x
a.should == [1, 2]
end
it "raises a TypeError if #to_a does not return an Array" do
x = mock("multi-assign splat") x = mock("multi-assign splat")
x.should_receive(:to_a).and_return(1) x.should_receive(:to_a).and_return(1)
@ -468,7 +464,7 @@ describe "Multiple assignment" do
[a, b, c].should == [1, 2, nil] [a, b, c].should == [1, 2, nil]
end end
it "raises a TypeError if #to_a does not return an Array" do it "raises a TypeError if #to_a does not return an Array with a simple MLHS" do
x = mock("multi-assign splat") x = mock("multi-assign splat")
x.should_receive(:to_a).and_return(1) x.should_receive(:to_a).and_return(1)
@ -491,7 +487,7 @@ describe "Multiple assignment" do
[a, b, c].should == [1, [], 2] [a, b, c].should == [1, [], 2]
end end
it "raises a TypeError if #to_a does not return an Array" do it "raises a TypeError if #to_a does not return an Array with MLHS" do
x = mock("multi-assign splat") x = mock("multi-assign splat")
x.should_receive(:to_a).and_return(1) x.should_receive(:to_a).and_return(1)
@ -516,14 +512,6 @@ describe "Multiple assignment" do
[a, b, c, d, e, f, g].should == [1, [], nil, [], nil, [], nil] [a, b, c, d, e, f, g].should == [1, [], nil, [], nil, [], nil]
end end
it "consumes values for an anonymous splat" do
(* = *1).should == [1]
end
it "consumes values for a grouped anonymous splat" do
((*) = *1).should == [1]
end
it "does not mutate a RHS Array" do it "does not mutate a RHS Array" do
x = [1, 2, 3, 4] x = [1, 2, 3, 4]
a, *b, c, d = *x a, *b, c, d = *x
@ -544,6 +532,10 @@ describe "Multiple assignment" do
(* = 1, 2, 3).should == [1, 2, 3] (* = 1, 2, 3).should == [1, 2, 3]
end end
it "consumes values for a grouped anonymous splat" do
((*) = 1, 2, 3).should == [1, 2, 3]
end
it "consumes values for multiple '_' variables" do it "consumes values for multiple '_' variables" do
a, _, b, _, c = 1, 2, 3, 4, 5 a, _, b, _, c = 1, 2, 3, 4, 5
[a, b, c].should == [1, 3, 5] [a, b, c].should == [1, 3, 5]
@ -573,7 +565,7 @@ describe "Multiple assignment" do
[a, b].should == [1, [3, 4]] [a, b].should == [1, [3, 4]]
end end
it "raises a TypeError if #to_a does not return an Array" do it "raises a TypeError if #to_a does not return an Array with a splat MLHS" do
x = mock("multi-assign splat MRHS") x = mock("multi-assign splat MRHS")
x.should_receive(:to_a).and_return(1) x.should_receive(:to_a).and_return(1)
@ -588,7 +580,7 @@ describe "Multiple assignment" do
[a, b].should == [1, [x]] [a, b].should == [1, [x]]
end end
it "calls #to_a to convert a splatted Object as part of a MRHS with a splat MLHS" do it "calls #to_a to convert a splatted Object as part of a MRHS" do
x = mock("multi-assign splat MRHS") x = mock("multi-assign splat MRHS")
x.should_receive(:to_a).and_return([3, 4]) x.should_receive(:to_a).and_return([3, 4])
@ -596,14 +588,14 @@ describe "Multiple assignment" do
[a, b].should == [3, [4, 1]] [a, b].should == [3, [4, 1]]
end end
it "raises a TypeError if #to_a does not return an Array" do it "raises a TypeError if #to_a does not return an Array with a splat MRHS" do
x = mock("multi-assign splat MRHS") x = mock("multi-assign splat MRHS")
x.should_receive(:to_a).and_return(1) x.should_receive(:to_a).and_return(1)
lambda { a, *b = *x, 1 }.should raise_error(TypeError) lambda { a, *b = *x, 1 }.should raise_error(TypeError)
end end
it "does not call #to_ary to convert a splatted Object as part of a MRHS with a splat MRHS" do it "does not call #to_ary to convert a splatted Object with a splat MRHS" do
x = mock("multi-assign splat MRHS") x = mock("multi-assign splat MRHS")
x.should_not_receive(:to_ary) x.should_not_receive(:to_ary)
@ -627,24 +619,16 @@ describe "Multiple assignment" do
a.should == [1, 2, 3] a.should == [1, 2, 3]
end end
it "assigns a grouped LHS with splats from nested Arrays" do it "assigns a grouped LHS with splats from nested Arrays for simple values" do
(a, *b), c, (*d, (e, *f, g)) = 1, 2, 3, 4 (a, *b), c, (*d, (e, *f, g)) = 1, 2, 3, 4
[a, b, c, d, e, f, g].should == [1, [], 2, [], 3, [], nil] [a, b, c, d, e, f, g].should == [1, [], 2, [], 3, [], nil]
end end
it "assigns a grouped LHS with splats from nested Arrays" do it "assigns a grouped LHS with splats from nested Arrays for nested arrays" do
(a, *b), c, (*d, (e, *f, g)) = [1, [2, 3]], [4, 5], [6, 7, 8] (a, *b), c, (*d, (e, *f, g)) = [1, [2, 3]], [4, 5], [6, 7, 8]
[a, b, c, d, e, f, g].should == [1, [[2, 3]], [4, 5], [6, 7], 8, [], nil] [a, b, c, d, e, f, g].should == [1, [[2, 3]], [4, 5], [6, 7], 8, [], nil]
end end
it "consumes values for an anonymous splat" do
(* = 1, 2, 3).should == [1, 2, 3]
end
it "consumes values for a grouped anonymous splat" do
((*) = 1, 2, 3).should == [1, 2, 3]
end
it "calls #to_ary to convert an Object when the position receiving the value is a multiple assignment" do it "calls #to_ary to convert an Object when the position receiving the value is a multiple assignment" do
x = mock("multi-assign mixed RHS") x = mock("multi-assign mixed RHS")
x.should_receive(:to_ary).and_return([1, 2]) x.should_receive(:to_ary).and_return([1, 2])
@ -677,7 +661,7 @@ describe "Multiple assignment" do
[a, b, c, d].should == [1, [2, 3], 4, 5] [a, b, c, d].should == [1, [2, 3], 4, 5]
end end
it "raises a TypeError if #to_ary does not return an Array" do it "raises a TypeError if #to_ary does not return an Array in a MRHS" do
x = mock("multi-assign mixed splatted RHS") x = mock("multi-assign mixed splatted RHS")
x.should_receive(:to_ary).and_return(x) x.should_receive(:to_ary).and_return(x)

View file

@ -127,7 +127,7 @@ describe "The while expression" do
a.should == [1, 2] a.should == [1, 2]
end end
it "stops running body if interrupted by break in a parenthesized attribute op-assign-or value" do it "stops running body if interrupted by break with unless in a parenthesized attribute op-assign-or value" do
a = mock("attribute assignment break") a = mock("attribute assignment break")
a.should_receive(:m).twice.and_return(nil) a.should_receive(:m).twice.and_return(nil)
a.should_receive(:m=) a.should_receive(:m=)
@ -142,7 +142,7 @@ describe "The while expression" do
end.should be_nil end.should be_nil
end end
it "stops running body if interrupted by break in a begin ... end attribute op-assign-or value" do it "stops running body if interrupted by break with unless in a begin ... end attribute op-assign-or value" do
a = mock("attribute assignment break") a = mock("attribute assignment break")
a.should_receive(:m).twice.and_return(nil) a.should_receive(:m).twice.and_return(nil)
a.should_receive(:m=) a.should_receive(:m=)

View file

@ -51,7 +51,18 @@ module SocketSpecs
end end
def self.socket_path def self.socket_path
tmp("unix_server_spec.socket", false) path = tmp("unix.sock", false)
# Check for too long unix socket path (max 108 bytes including \0 => 107)
# Note that Linux accepts not null-terminated paths but the man page advises against it.
if path.bytesize > 107
path = "/tmp/unix_server_spec.socket"
end
rm_socket(path)
path
end
def self.rm_socket(path)
File.delete(path) if File.exist?(path)
end end
# TCPServer echo server accepting one connection # TCPServer echo server accepting one connection

View file

@ -6,8 +6,6 @@ describe "UNIXServer#accept_nonblock" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@client = UNIXSocket.open(@path) @client = UNIXSocket.open(@path)
@ -19,7 +17,7 @@ describe "UNIXServer#accept_nonblock" do
@socket.close @socket.close
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "accepts a connection in a non-blocking way" do it "accepts a connection in a non-blocking way" do

View file

@ -5,16 +5,15 @@ platform_is_not :windows do
describe "UNIXServer#accept" do describe "UNIXServer#accept" do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
end end
after :each do after :each do
rm_r @path SocketSpecs.rm_socket @path
end end
it "accepts what is written by the client" do it "accepts what is written by the client" do
server = UNIXServer.open(SocketSpecs.socket_path) server = UNIXServer.open(@path)
client = UNIXSocket.open(SocketSpecs.socket_path) client = UNIXSocket.open(@path)
client.send('hello', 0) client.send('hello', 0)

View file

@ -4,13 +4,13 @@ require File.expand_path('../../fixtures/classes', __FILE__)
platform_is_not :windows do platform_is_not :windows do
describe "UNIXServer#for_fd" do describe "UNIXServer#for_fd" do
before :each do before :each do
@unix_path = tmp("unix_socket") @unix_path = SocketSpecs.socket_path
@unix = UNIXServer.new(@unix_path) @unix = UNIXServer.new(@unix_path)
end end
after :each do after :each do
@unix.close if @unix @unix.close if @unix
rm_r @unix_path SocketSpecs.rm_socket @unix_path
end end
it "can calculate the path" do it "can calculate the path" do

View file

@ -6,14 +6,13 @@ describe "UNIXServer.open" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = tmp("unixserver_spec") @path = SocketSpecs.socket_path
rm_r @path
end end
after :each do after :each do
@server.close if @server @server.close if @server
@server = nil @server = nil
rm_r @path SocketSpecs.rm_socket @path
end end
it "yields the new UNIXServer object to the block, if given" do it "yields the new UNIXServer object to the block, if given" do

View file

@ -5,14 +5,13 @@ require 'tempfile'
describe :unixserver_new, shared: true do describe :unixserver_new, shared: true do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = tmp("unixserver_spec") @path = SocketSpecs.socket_path
rm_r @path
end end
after :each do after :each do
@server.close if @server @server.close if @server
@server = nil @server = nil
rm_r @path SocketSpecs.rm_socket @path
end end
it "creates a new UNIXServer" do it "creates a new UNIXServer" do

View file

@ -6,8 +6,6 @@ describe "UNIXSocket#addr" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@client = UNIXSocket.open(@path) @client = UNIXSocket.open(@path)
end end
@ -15,7 +13,7 @@ describe "UNIXSocket#addr" do
after :each do after :each do
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "returns the address family of this socket in an array" do it "returns the address family of this socket in an array" do

View file

@ -14,7 +14,7 @@ describe "UNIXSocket.open" do
after :each do after :each do
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "opens a unix socket on the specified file and yields it to the block" do it "opens a unix socket on the specified file and yields it to the block" do

View file

@ -7,7 +7,6 @@ platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@s1 = UNIXSocket.new(@path) @s1 = UNIXSocket.new(@path)
@s2 = @server.accept @s2 = @server.accept
@ -17,7 +16,7 @@ platform_is_not :windows do
@server.close @server.close
@s1.close @s1.close
@s2.close @s2.close
rm_r @path SocketSpecs.rm_socket @path
end end
it_should_behave_like "partially closable sockets" it_should_behave_like "partially closable sockets"

View file

@ -6,8 +6,6 @@ describe "UNIXSocket#path" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@client = UNIXSocket.open(@path) @client = UNIXSocket.open(@path)
end end
@ -15,7 +13,7 @@ describe "UNIXSocket#path" do
after :each do after :each do
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "returns the path of the socket if it's a server" do it "returns the path of the socket if it's a server" do

View file

@ -6,8 +6,6 @@ describe "UNIXSocket#peeraddr" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@client = UNIXSocket.open(@path) @client = UNIXSocket.open(@path)
end end
@ -15,7 +13,7 @@ describe "UNIXSocket#peeraddr" do
after :each do after :each do
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "returns the address familly and path of the server end of the connection" do it "returns the address familly and path of the server end of the connection" do

View file

@ -20,7 +20,7 @@ describe "UNIXSocket#recv_io" do
@file.close @file.close
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "reads an IO object across the socket" do it "reads an IO object across the socket" do

View file

@ -6,8 +6,6 @@ describe "UNIXSocket#recvfrom" do
platform_is_not :windows do platform_is_not :windows do
before :each do before :each do
@path = SocketSpecs.socket_path @path = SocketSpecs.socket_path
rm_r @path
@server = UNIXServer.open(@path) @server = UNIXServer.open(@path)
@client = UNIXSocket.open(@path) @client = UNIXSocket.open(@path)
end end
@ -15,7 +13,7 @@ describe "UNIXSocket#recvfrom" do
after :each do after :each do
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "receives len bytes from sock" do it "receives len bytes from sock" do

View file

@ -20,7 +20,7 @@ describe "UNIXSocket#send_io" do
@file.close @file.close
@client.close @client.close
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "sends the fd for an IO object across the socket" do it "sends the fd for an IO object across the socket" do

View file

@ -11,7 +11,7 @@ describe :unixsocket_new, shared: true do
after :each do after :each do
@client.close if @client @client.close if @client
@server.close @server.close
rm_r @path SocketSpecs.rm_socket @path
end end
it "opens a unix socket on the specified file" do it "opens a unix socket on the specified file" do

View file

@ -60,6 +60,7 @@ end
unless full_range_longs unless full_range_longs
it "wraps around if passed a negative bignum" do it "wraps around if passed a negative bignum" do
@s.rb_big2ulong(ensure_bignum(@min_long + 1)).should == -(@min_long - 1) @s.rb_big2ulong(ensure_bignum(@min_long + 1)).should == -(@min_long - 1)
@s.rb_big2ulong(ensure_bignum(@min_long)).should == -(@min_long)
end end
end end
@ -67,12 +68,6 @@ end
lambda { @s.rb_big2ulong(ensure_bignum(@max_ulong + 1)) }.should raise_error(RangeError) lambda { @s.rb_big2ulong(ensure_bignum(@max_ulong + 1)) }.should raise_error(RangeError)
lambda { @s.rb_big2ulong(ensure_bignum(@min_long - 1)) }.should raise_error(RangeError) lambda { @s.rb_big2ulong(ensure_bignum(@min_long - 1)) }.should raise_error(RangeError)
end end
unless full_range_longs
it "wraps around if passed a negative bignum" do
@s.rb_big2ulong(ensure_bignum(@min_long)).should == -(@min_long)
end
end
end end
describe "rb_big2dbl" do describe "rb_big2dbl" do

View file

@ -15,7 +15,7 @@ describe "C-API Mutex functions" do
end end
describe "rb_mutex_locked_p" do describe "rb_mutex_locked_p" do
it "returns true if the mutex is locked" do it "returns fakse if the mutex is not locked" do
@s.rb_mutex_locked_p(@m).should be_false @s.rb_mutex_locked_p(@m).should be_false
end end

View file

@ -6,7 +6,7 @@ require 'fileutils'
require 'tmpdir' require 'tmpdir'
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_NAME}/#{RUBY_VERSION}", __FILE__) OBJDIR ||= File.expand_path("../../../ext/#{RUBY_NAME}/#{RUBY_VERSION}", __FILE__)
FileUtils.makedirs(OBJDIR) mkdir_p(OBJDIR)
def extension_path def extension_path
File.expand_path("../ext", __FILE__) File.expand_path("../ext", __FILE__)
@ -111,24 +111,6 @@ ensure
ENV[preloadenv] = preload if preloadenv ENV[preloadenv] = preload if preloadenv
end end
def compile_extension_truffleruby(name)
sulong_config_file = File.join(extension_path, '.jruby-cext-build.yml')
output_file = File.join(object_path, "#{name}_spec.#{RbConfig::CONFIG['DLEXT']}")
File.open(sulong_config_file, 'w') do |f|
f.puts "src: #{name}_spec.c"
f.puts "out: #{output_file}"
end
command = ["#{RbConfig::CONFIG['bindir']}/../tool/jt.rb", 'cextc', extension_path]
system(*command)
raise "Compilation of #{extension_path} failed: #{$?}\n#{command.join(' ')}" unless $?.success?
output_file
ensure
File.delete(sulong_config_file) if File.exist?(sulong_config_file)
end
def compile_truffleruby_extconf_make(name, path, objdir) def compile_truffleruby_extconf_make(name, path, objdir)
ext = "#{name}_spec" ext = "#{name}_spec"
file = "#{ext}.c" file = "#{ext}.c"

View file

@ -101,11 +101,7 @@ describe :strftime_date, shared: true do
@d2000_4_6.strftime("%S").should == "00" @d2000_4_6.strftime("%S").should == "00"
end end
it "should be able to show the number of seconds with leading zeroes" do it "should be able to show the number of seconds since the unix epoch for a date" do
@d2000_4_6.strftime("%S").should == "00"
end
it "should be able to show the number of seconds since the unix epoch" do
@d2000_4_6.strftime("%s").should == "954979200" @d2000_4_6.strftime("%s").should == "954979200"
end end
@ -171,7 +167,7 @@ describe :strftime_date, shared: true do
@d2000_4_10.strftime("%u").should == "1" @d2000_4_10.strftime("%u").should == "1"
end end
it "should be able to show the commercial week" do it "should be able to show the commercial week with %V" do
@d2000_4_9.strftime("%V").should == "14" @d2000_4_9.strftime("%V").should == "14"
@d2000_4_10.strftime("%V").should == "15" @d2000_4_10.strftime("%V").should == "15"
end end
@ -218,12 +214,12 @@ describe :strftime_date, shared: true do
@d2000_4_6.strftime("%F").should == @d2000_4_6.strftime('%Y-%m-%d') @d2000_4_6.strftime("%F").should == @d2000_4_6.strftime('%Y-%m-%d')
end end
it "should be able to show HH:MM" do it "should be able to show HH:MM for a date" do
@d2000_4_6.strftime("%R").should == "00:00" @d2000_4_6.strftime("%R").should == "00:00"
@d2000_4_6.strftime("%R").should == @d2000_4_6.strftime('%H:%M') @d2000_4_6.strftime("%R").should == @d2000_4_6.strftime('%H:%M')
end end
it "should be able to show HH:MM:SS AM/PM" do it "should be able to show HH:MM:SS AM/PM for a date" do
@d2000_4_6.strftime("%r").should == "12:00:00 AM" @d2000_4_6.strftime("%r").should == "12:00:00 AM"
@d2000_4_6.strftime("%r").should == @d2000_4_6.strftime('%I:%M:%S %p') @d2000_4_6.strftime("%r").should == @d2000_4_6.strftime('%I:%M:%S %p')
end end