mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@cd1b911
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5ccf36c7ec
commit
2bdce358e6
53 changed files with 319 additions and 426 deletions
|
@ -7,11 +7,12 @@ environment:
|
|||
install:
|
||||
- SET PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH%
|
||||
- ruby --version
|
||||
- call "C:\Ruby23-x64\DevKit\devkitvars.bat"
|
||||
- git clone https://github.com/ruby/mspec.git ../mspec
|
||||
build: off
|
||||
test_script:
|
||||
- SET CHECK_LEAKS=true
|
||||
- ../mspec/bin/mspec -ff command_line language core library
|
||||
- ../mspec/bin/mspec -ff
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
|
|
@ -213,22 +213,6 @@ module KernelSpecs
|
|||
end
|
||||
end
|
||||
|
||||
module KernelBlockGiven
|
||||
def self.accept_block
|
||||
Kernel.block_given?
|
||||
end
|
||||
|
||||
def self.accept_block_as_argument(&block)
|
||||
Kernel.block_given?
|
||||
end
|
||||
|
||||
class << self
|
||||
define_method(:defined_block) do
|
||||
Kernel.block_given?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module SelfBlockGiven
|
||||
def self.accept_block
|
||||
self.send(:block_given?)
|
||||
|
|
26
spec/rubyspec/core/kernel/yield_self_spec.rb
Normal file
26
spec/rubyspec/core/kernel/yield_self_spec.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
has_yield_self = VersionGuard.new("2.5").match? || PlatformGuard.implementation?(:truffleruby)
|
||||
|
||||
if has_yield_self
|
||||
describe "Kernel#yield_self" do
|
||||
it "yields self" do
|
||||
object = Object.new
|
||||
object.yield_self { |o| o.should equal object }
|
||||
end
|
||||
|
||||
it "returns the block return value" do
|
||||
object = Object.new
|
||||
object.yield_self { 42 }.should equal 42
|
||||
end
|
||||
|
||||
it "returns a sized Enumerator when no block given" do
|
||||
object = Object.new
|
||||
enum = object.yield_self
|
||||
enum.should be_an_instance_of Enumerator
|
||||
enum.size.should equal 1
|
||||
enum.peek.should equal object
|
||||
enum.first.should equal object
|
||||
end
|
||||
end
|
||||
end
|
|
@ -300,6 +300,10 @@ describe "String#split with Regexp" do
|
|||
"AabB".split(/([a-z])+/).should == ["A", "b", "B"]
|
||||
end
|
||||
|
||||
it "applies the limit to the number of split substrings, without counting captures" do
|
||||
"aBaBa".split(/(B)()()/, 2).should == ["a", "B", "", "", "aBa"]
|
||||
end
|
||||
|
||||
it "does not include non-matching captures in the result array" do
|
||||
"hello".split(/(el)|(xx)/).should == ["h", "el", "lo"]
|
||||
end
|
||||
|
|
|
@ -8,9 +8,9 @@ module NetFTPSpecs
|
|||
# port number
|
||||
attr_reader :server_port
|
||||
|
||||
def initialize(hostname = "localhost", server_port = 0)
|
||||
@hostname = hostname
|
||||
@server = TCPServer.new(@hostname, server_port)
|
||||
def initialize
|
||||
@hostname = "localhost"
|
||||
@server = TCPServer.new(@hostname, 0)
|
||||
@server_port = @server.addr[1]
|
||||
|
||||
@handlers = {}
|
||||
|
|
|
@ -47,7 +47,8 @@ module NetHTTPSpecs
|
|||
@server_thread = nil
|
||||
|
||||
def port
|
||||
@server ? @server.config[:Port] : 3333
|
||||
raise "server not started" unless @server
|
||||
@server.config[:Port]
|
||||
end
|
||||
|
||||
def start_server
|
||||
|
@ -79,9 +80,11 @@ module NetHTTPSpecs
|
|||
rescue Errno::EPIPE
|
||||
# Because WEBrick is not thread-safe and only catches IOError
|
||||
end
|
||||
@server = nil
|
||||
end
|
||||
if @server_thread
|
||||
@server_thread.join
|
||||
@server_thread = nil
|
||||
end
|
||||
timeout = WEBrick::Utils::TimeoutHandler
|
||||
timeout.terminate if timeout.respond_to?(:terminate)
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
unless MSpec.retrieve(:features).key?(:readline)
|
||||
begin
|
||||
require 'readline'
|
||||
rescue LoadError
|
||||
else
|
||||
# rb-readline behaves quite differently
|
||||
if $".grep(/\brbreadline\.rb$/).empty?
|
||||
MSpec.enable_feature :readline
|
||||
end
|
||||
begin
|
||||
require 'readline'
|
||||
rescue LoadError
|
||||
else
|
||||
# rb-readline behaves quite differently
|
||||
unless defined?(RbReadline)
|
||||
MSpec.enable_feature :readline
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'socket'
|
|||
describe "Addrinfo#bind" do
|
||||
|
||||
before :each do
|
||||
@addrinfo = Addrinfo.tcp("127.0.0.1", SocketSpecs.port)
|
||||
@addrinfo = Addrinfo.tcp("127.0.0.1", 0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "Socket::BasicSocket#close_read" do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.port)
|
||||
@server = TCPServer.new(0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "Socket::BasicSocket#close_write" do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.port)
|
||||
@server = TCPServer.new(0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "BasicSocket.do_not_reverse_lookup" do
|
||||
before :each do
|
||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
@port = @server.addr[1]
|
||||
@socket = TCPSocket.new('127.0.0.1', @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -21,7 +22,7 @@ describe "BasicSocket.do_not_reverse_lookup" do
|
|||
it "causes 'peeraddr' to avoid name lookups" do
|
||||
@socket.do_not_reverse_lookup = true
|
||||
BasicSocket.do_not_reverse_lookup = true
|
||||
@socket.peeraddr.should == ["AF_INET", SocketSpecs.port, "127.0.0.1", "127.0.0.1"]
|
||||
@socket.peeraddr.should == ["AF_INET", @port, "127.0.0.1", "127.0.0.1"]
|
||||
end
|
||||
|
||||
it "looks for hostnames when set to false" do
|
||||
|
|
|
@ -4,7 +4,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "BasicSocket#for_fd" do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.port)
|
||||
@server = TCPServer.new(0)
|
||||
@s2 = nil
|
||||
end
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "Socket::BasicSocket#getpeername" do
|
||||
|
||||
before :each do
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
@client = TCPSocket.new("127.0.0.1", @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -14,7 +15,7 @@ describe "Socket::BasicSocket#getpeername" do
|
|||
end
|
||||
|
||||
it "returns the sockaddr of the other end of the connection" do
|
||||
server_sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
||||
server_sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1")
|
||||
@client.getpeername.should == server_sockaddr
|
||||
end
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@ describe "Socket::BasicSocket#getsockname" do
|
|||
end
|
||||
|
||||
it "returns the sockaddr associacted with the socket" do
|
||||
@socket = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@socket = TCPServer.new("127.0.0.1", 0)
|
||||
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||
sockaddr.should == [SocketSpecs.port, "127.0.0.1"]
|
||||
sockaddr.should == [@socket.addr[1], "127.0.0.1"]
|
||||
end
|
||||
|
||||
it "works on sockets listening in ipaddr_any" do
|
||||
@socket = TCPServer.new(SocketSpecs.port)
|
||||
@socket = TCPServer.new(0)
|
||||
sockaddr = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||
["::", "0.0.0.0", "::ffff:0.0.0.0"].include?(sockaddr[1]).should be_true
|
||||
sockaddr[0].should == SocketSpecs.port
|
||||
sockaddr[0].should == @socket.addr[1]
|
||||
end
|
||||
|
||||
it "returns empty sockaddr for unbinded sockets" do
|
||||
|
|
|
@ -5,7 +5,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "BasicSocket#recv" do
|
||||
|
||||
before :each do
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
@port = @server.addr[1]
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -23,7 +24,7 @@ describe "BasicSocket#recv" do
|
|||
Thread.pass while t.status and t.status != "sleep"
|
||||
t.status.should_not be_nil
|
||||
|
||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
socket = TCPSocket.new('127.0.0.1', @port)
|
||||
socket.send('hello', 0)
|
||||
socket.close
|
||||
|
||||
|
@ -46,7 +47,7 @@ describe "BasicSocket#recv" do
|
|||
Thread.pass while t.status and t.status != "sleep"
|
||||
t.status.should_not be_nil
|
||||
|
||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
socket = TCPSocket.new('127.0.0.1', @port)
|
||||
socket.send('helloU', Socket::MSG_OOB)
|
||||
socket.shutdown(1)
|
||||
t.join
|
||||
|
@ -67,7 +68,7 @@ describe "BasicSocket#recv" do
|
|||
Thread.pass while t.status and t.status != "sleep"
|
||||
t.status.should_not be_nil
|
||||
|
||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
socket = TCPSocket.new('127.0.0.1', @port)
|
||||
socket.write("firstline\377secondline\377")
|
||||
socket.close
|
||||
|
||||
|
@ -77,7 +78,7 @@ describe "BasicSocket#recv" do
|
|||
|
||||
ruby_version_is "2.3" do
|
||||
it "allows an output buffer as third argument" do
|
||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
socket = TCPSocket.new('127.0.0.1', @port)
|
||||
socket.write("data")
|
||||
|
||||
client = @server.accept
|
||||
|
|
|
@ -3,8 +3,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "BasicSocket#send" do
|
||||
before :each do
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
@port = @server.addr[1]
|
||||
@socket = TCPSocket.new('127.0.0.1', @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -74,7 +75,7 @@ describe "BasicSocket#send" do
|
|||
Thread.pass while t.status and t.status != "sleep"
|
||||
t.status.should_not be_nil
|
||||
|
||||
sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
||||
sockaddr = Socket.pack_sockaddr_in(@port, "127.0.0.1")
|
||||
@socket.send('hello', 0, sockaddr).should == 5
|
||||
@socket.shutdown # indicate, that we are done sending
|
||||
|
||||
|
|
|
@ -23,29 +23,6 @@ module SocketSpecs
|
|||
Socket.getaddrinfo(host, nil)[0][3]
|
||||
end
|
||||
|
||||
def self.find_available_port
|
||||
begin
|
||||
s = TCPServer.open(0)
|
||||
port = s.addr[1]
|
||||
s.close
|
||||
port
|
||||
rescue
|
||||
43191
|
||||
end
|
||||
end
|
||||
|
||||
def self.port
|
||||
@port ||= find_available_port
|
||||
end
|
||||
|
||||
def self.str_port
|
||||
port.to_s
|
||||
end
|
||||
|
||||
def self.local_port
|
||||
find_available_port
|
||||
end
|
||||
|
||||
def self.reserved_unused_port
|
||||
# https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
|
||||
0
|
||||
|
|
|
@ -4,7 +4,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "Socket::IPSocket#addr" do
|
||||
before :each do
|
||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||
@socket = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@socket = TCPServer.new("127.0.0.1", 0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -17,7 +17,7 @@ describe "Socket::IPSocket#addr" do
|
|||
BasicSocket.do_not_reverse_lookup = false
|
||||
addrinfo = @socket.addr
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should be_kind_of(Integer)
|
||||
addrinfo[2].should == SocketSpecs.hostname
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
@ -27,7 +27,7 @@ describe "Socket::IPSocket#addr" do
|
|||
BasicSocket.do_not_reverse_lookup = true
|
||||
addrinfo = @socket.addr
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should be_kind_of(Integer)
|
||||
addrinfo[2].should == "127.0.0.1"
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
@ -35,7 +35,7 @@ describe "Socket::IPSocket#addr" do
|
|||
it "returns an address in the array if passed false" do
|
||||
addrinfo = @socket.addr(false)
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should be_kind_of(Integer)
|
||||
addrinfo[2].should == "127.0.0.1"
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "Socket::IPSocket#peeraddr" do
|
||||
before :each do
|
||||
@do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
@client = TCPSocket.new("127.0.0.1", @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -23,7 +24,7 @@ describe "Socket::IPSocket#peeraddr" do
|
|||
BasicSocket.do_not_reverse_lookup = false
|
||||
addrinfo = @client.peeraddr
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should == @port
|
||||
addrinfo[2].should == SocketSpecs.hostname
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
@ -33,7 +34,7 @@ describe "Socket::IPSocket#peeraddr" do
|
|||
BasicSocket.do_not_reverse_lookup = true
|
||||
addrinfo = @client.peeraddr
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should == @port
|
||||
addrinfo[2].should == "127.0.0.1"
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
@ -41,7 +42,7 @@ describe "Socket::IPSocket#peeraddr" do
|
|||
it "returns an IP instead of hostname if passed false" do
|
||||
addrinfo = @client.peeraddr(false)
|
||||
addrinfo[0].should == "AF_INET"
|
||||
addrinfo[1].should == SocketSpecs.port
|
||||
addrinfo[1].should == @port
|
||||
addrinfo[2].should == "127.0.0.1"
|
||||
addrinfo[3].should == "127.0.0.1"
|
||||
end
|
||||
|
|
|
@ -4,8 +4,9 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "Socket::IPSocket#recvfrom" do
|
||||
|
||||
before :each do
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@client = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
@client = TCPSocket.new("127.0.0.1", @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
describe "partially closable sockets", shared: true do
|
||||
specify "if the write end is closed then the other side can read past EOF without blocking" do
|
||||
it "if the write end is closed then the other side can read past EOF without blocking" do
|
||||
@s1.write("foo")
|
||||
@s1.close_write
|
||||
@s2.read("foo".size + 1).should == "foo"
|
||||
end
|
||||
|
||||
specify "closing the write end ensures that the other side can read until EOF" do
|
||||
it "closing the write end ensures that the other side can read until EOF" do
|
||||
@s1.write("hello world")
|
||||
@s1.close_write
|
||||
@s2.read.should == "hello world"
|
||||
|
|
|
@ -10,7 +10,7 @@ describe :socket_recv_nonblock, shared: true do
|
|||
end
|
||||
|
||||
it "raises an exception extending IO::WaitReadable if there's no data available" do
|
||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
||||
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
lambda {
|
||||
@s1.recv_nonblock(5)
|
||||
}.should raise_error(IO::WaitReadable) { |e|
|
||||
|
@ -24,7 +24,7 @@ describe :socket_recv_nonblock, shared: true do
|
|||
end
|
||||
|
||||
it "receives data after it's ready" do
|
||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
||||
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
@s2.send("aaa", 0, @s1.getsockname)
|
||||
IO.select([@s1], nil, nil, 2)
|
||||
@s1.recv_nonblock(5).should == "aaa"
|
||||
|
@ -32,7 +32,7 @@ describe :socket_recv_nonblock, shared: true do
|
|||
|
||||
ruby_version_is "2.3" do
|
||||
it "allows an output buffer as third argument" do
|
||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
||||
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
@s2.send("data", 0, @s1.getsockname)
|
||||
IO.select([@s1], nil, nil, 2)
|
||||
|
||||
|
@ -43,7 +43,7 @@ describe :socket_recv_nonblock, shared: true do
|
|||
end
|
||||
|
||||
it "does not block if there's no data available" do
|
||||
@s1.bind(Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1"))
|
||||
@s1.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
@s2.send("a", 0, @s1.getsockname)
|
||||
IO.select([@s1], nil, nil, 2)
|
||||
@s1.recv_nonblock(1).should == "a"
|
||||
|
|
|
@ -5,8 +5,8 @@ include Socket::Constants
|
|||
|
||||
describe "Socket#bind on SOCK_DGRAM socket" do
|
||||
before :each do
|
||||
@sock = Socket.new(AF_INET, SOCK_DGRAM, 0);
|
||||
@sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1");
|
||||
@sock = Socket.new(AF_INET, SOCK_DGRAM, 0)
|
||||
@sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -22,30 +22,30 @@ describe "Socket#bind on SOCK_DGRAM socket" do
|
|||
@sock.bind(@sockaddr).should == 0
|
||||
end
|
||||
|
||||
it "raises Errno::EINVAL when binding to an already bound port" do
|
||||
@sock.bind(@sockaddr);
|
||||
it "raises Errno::EINVAL when already bound" do
|
||||
@sock.bind(@sockaddr)
|
||||
|
||||
lambda { @sock.bind(@sockaddr); }.should raise_error(Errno::EINVAL);
|
||||
lambda { @sock.bind(@sockaddr) }.should raise_error(Errno::EINVAL)
|
||||
end
|
||||
|
||||
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
||||
sockaddr1 = Socket.pack_sockaddr_in(SocketSpecs.port, "4.3.2.1");
|
||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
sockaddr1 = Socket.pack_sockaddr_in(0, "4.3.2.1")
|
||||
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
end
|
||||
|
||||
platform_is_not :windows, :cygwin do
|
||||
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1");
|
||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EACCES)
|
||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1")
|
||||
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EACCES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Socket#bind on SOCK_STREAM socket" do
|
||||
before :each do
|
||||
@sock = Socket.new(AF_INET, SOCK_STREAM, 0);
|
||||
@sock = Socket.new(AF_INET, SOCK_STREAM, 0)
|
||||
@sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, true)
|
||||
@sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1");
|
||||
@sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -61,21 +61,21 @@ describe "Socket#bind on SOCK_STREAM socket" do
|
|||
@sock.bind(@sockaddr).should == 0
|
||||
end
|
||||
|
||||
it "raises Errno::EINVAL when binding to an already bound port" do
|
||||
@sock.bind(@sockaddr);
|
||||
it "raises Errno::EINVAL when already bound" do
|
||||
@sock.bind(@sockaddr)
|
||||
|
||||
lambda { @sock.bind(@sockaddr); }.should raise_error(Errno::EINVAL);
|
||||
lambda { @sock.bind(@sockaddr) }.should raise_error(Errno::EINVAL)
|
||||
end
|
||||
|
||||
it "raises Errno::EADDRNOTAVAIL when the specified sockaddr is not available from the local machine" do
|
||||
sockaddr1 = Socket.pack_sockaddr_in(SocketSpecs.port, "4.3.2.1");
|
||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
sockaddr1 = Socket.pack_sockaddr_in(0, "4.3.2.1")
|
||||
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
end
|
||||
|
||||
platform_is_not :windows, :cygwin do
|
||||
it "raises Errno::EACCES when the current user does not have permission to bind" do
|
||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1");
|
||||
lambda { @sock.bind(sockaddr1); }.should raise_error(Errno::EACCES)
|
||||
sockaddr1 = Socket.pack_sockaddr_in(1, "127.0.0.1")
|
||||
lambda { @sock.bind(sockaddr1) }.should raise_error(Errno::EACCES)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,8 @@ require 'socket'
|
|||
describe "Socket#connect_nonblock" do
|
||||
before :each do
|
||||
@hostname = "127.0.0.1"
|
||||
@addr = Socket.sockaddr_in(SocketSpecs.port, @hostname)
|
||||
@server = TCPServer.new(@hostname, 0) # started, but no accept
|
||||
@addr = Socket.sockaddr_in(@server.addr[1], @hostname)
|
||||
@socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
||||
@thread = nil
|
||||
end
|
||||
|
@ -17,27 +18,31 @@ describe "Socket#connect_nonblock" do
|
|||
end
|
||||
|
||||
it "connects the socket to the remote side" do
|
||||
ready = false
|
||||
port = nil
|
||||
accept = false
|
||||
@thread = Thread.new do
|
||||
server = TCPServer.new(@hostname, SocketSpecs.port)
|
||||
ready = true
|
||||
server = TCPServer.new(@hostname, 0)
|
||||
port = server.addr[1]
|
||||
Thread.pass until accept
|
||||
conn = server.accept
|
||||
conn << "hello!"
|
||||
conn.close
|
||||
server.close
|
||||
end
|
||||
|
||||
Thread.pass while (@thread.status and @thread.status != 'sleep') or !ready
|
||||
Thread.pass until port
|
||||
|
||||
addr = Socket.sockaddr_in(port, @hostname)
|
||||
begin
|
||||
@socket.connect_nonblock(@addr)
|
||||
@socket.connect_nonblock(addr)
|
||||
rescue Errno::EINPROGRESS
|
||||
end
|
||||
|
||||
accept = true
|
||||
IO.select nil, [@socket]
|
||||
|
||||
begin
|
||||
@socket.connect_nonblock(@addr)
|
||||
@socket.connect_nonblock(addr)
|
||||
rescue Errno::EISCONN
|
||||
# Not all OS's use this errno, so we trap and ignore it
|
||||
end
|
||||
|
|
|
@ -4,8 +4,9 @@ require 'socket'
|
|||
|
||||
describe "Socket.for_fd" do
|
||||
before :each do
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@client = TCPSocket.open("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
@client = TCPSocket.open("127.0.0.1", @port)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -14,9 +14,9 @@ describe "Socket.getnameinfo" do
|
|||
end
|
||||
|
||||
it "gets the name information and don't resolve it" do
|
||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
||||
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
||||
name_info.should == ['127.0.0.1', "3333"]
|
||||
end
|
||||
|
||||
def should_be_valid_dns_name(name)
|
||||
|
@ -28,10 +28,10 @@ describe "Socket.getnameinfo" do
|
|||
end
|
||||
|
||||
it "gets the name information and resolve the host" do
|
||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
||||
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||
name_info = Socket.getnameinfo(sockaddr, Socket::NI_NUMERICSERV)
|
||||
should_be_valid_dns_name(name_info[0])
|
||||
name_info[1].should == SocketSpecs.port.to_s
|
||||
name_info[1].should == 3333.to_s
|
||||
end
|
||||
|
||||
it "gets the name information and resolves the service" do
|
||||
|
@ -44,8 +44,8 @@ describe "Socket.getnameinfo" do
|
|||
end
|
||||
|
||||
it "gets a 3-element array and doesn't resolve hostname" do
|
||||
name_info = Socket.getnameinfo(["AF_INET", SocketSpecs.port, '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
||||
name_info = Socket.getnameinfo(["AF_INET", 3333, '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||
name_info.should == ['127.0.0.1', "3333"]
|
||||
end
|
||||
|
||||
it "gets a 3-element array and resolves the service" do
|
||||
|
@ -54,8 +54,8 @@ describe "Socket.getnameinfo" do
|
|||
end
|
||||
|
||||
it "gets a 4-element array and doesn't resolve hostname" do
|
||||
name_info = Socket.getnameinfo(["AF_INET", SocketSpecs.port, 'foo', '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||
name_info.should == ['127.0.0.1', "#{SocketSpecs.port}"]
|
||||
name_info = Socket.getnameinfo(["AF_INET", 3333, 'foo', '127.0.0.1'], Socket::NI_NUMERICHOST | Socket::NI_NUMERICSERV)
|
||||
name_info.should == ['127.0.0.1', "3333"]
|
||||
end
|
||||
|
||||
it "gets a 4-element array and resolves the service" do
|
||||
|
|
|
@ -14,7 +14,7 @@ describe "Socket#listen" do
|
|||
end
|
||||
|
||||
it "verifies we can listen for incoming connections" do
|
||||
sockaddr = Socket.pack_sockaddr_in(SocketSpecs.port, "127.0.0.1")
|
||||
sockaddr = Socket.pack_sockaddr_in(0, "127.0.0.1")
|
||||
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
||||
@socket.bind(sockaddr)
|
||||
@socket.listen(1).should == 0
|
||||
|
|
|
@ -5,13 +5,13 @@ require 'socket'
|
|||
describe "Socket.unpack_sockaddr_in" do
|
||||
|
||||
it "decodes the host name and port number of a packed sockaddr_in" do
|
||||
sockaddr = Socket.sockaddr_in SocketSpecs.port, '127.0.0.1'
|
||||
Socket.unpack_sockaddr_in(sockaddr).should == [SocketSpecs.port, '127.0.0.1']
|
||||
sockaddr = Socket.sockaddr_in 3333, '127.0.0.1'
|
||||
Socket.unpack_sockaddr_in(sockaddr).should == [3333, '127.0.0.1']
|
||||
end
|
||||
|
||||
it "gets the hostname and port number from a passed Addrinfo" do
|
||||
addrinfo = Addrinfo.tcp('127.0.0.1', SocketSpecs.port)
|
||||
Socket.unpack_sockaddr_in(addrinfo).should == [SocketSpecs.port, '127.0.0.1']
|
||||
addrinfo = Addrinfo.tcp('127.0.0.1', 3333)
|
||||
Socket.unpack_sockaddr_in(addrinfo).should == [3333, '127.0.0.1']
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
|
|
@ -14,12 +14,12 @@ describe 'Socket.unpack_sockaddr_un' do
|
|||
end
|
||||
|
||||
it 'raises an ArgumentError when the sin_family is not AF_UNIX' do
|
||||
sockaddr = Socket.sockaddr_in(SocketSpecs.port, '127.0.0.1')
|
||||
sockaddr = Socket.sockaddr_in(0, '127.0.0.1')
|
||||
lambda { Socket.unpack_sockaddr_un(sockaddr) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it 'raises an ArgumentError when passed addrinfo is not AF_UNIX' do
|
||||
addrinfo = Addrinfo.tcp('127.0.0.1', SocketSpecs.port)
|
||||
addrinfo = Addrinfo.tcp('127.0.0.1', 0)
|
||||
lambda { Socket.unpack_sockaddr_un(addrinfo) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "Socket::TCPServer.accept_nonblock" do
|
||||
before :each do
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -16,13 +17,13 @@ describe "Socket::TCPServer.accept_nonblock" do
|
|||
@server.accept_nonblock
|
||||
}.should raise_error(IO::WaitReadable)
|
||||
|
||||
c = TCPSocket.new("127.0.0.1", SocketSpecs.port)
|
||||
c = TCPSocket.new("127.0.0.1", @port)
|
||||
sleep 0.1
|
||||
s = @server.accept_nonblock
|
||||
|
||||
port, address = Socket.unpack_sockaddr_in(s.getsockname)
|
||||
|
||||
port.should == SocketSpecs.port
|
||||
port.should == @port
|
||||
address.should == "127.0.0.1"
|
||||
s.should be_kind_of(TCPSocket)
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "TCPServer#accept" do
|
||||
before :each do
|
||||
@server = TCPServer.new("127.0.0.1", SocketSpecs.port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@port = @server.addr[1]
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -22,7 +23,7 @@ describe "TCPServer#accept" do
|
|||
end
|
||||
Thread.pass while t.status and t.status != "sleep"
|
||||
|
||||
socket = TCPSocket.new('127.0.0.1', SocketSpecs.port)
|
||||
socket = TCPSocket.new('127.0.0.1', @port)
|
||||
socket.write('hello')
|
||||
socket.shutdown(1) # we are done with sending
|
||||
socket.read.should == 'goodbye'
|
||||
|
@ -38,14 +39,12 @@ describe "TCPServer#accept" do
|
|||
|
||||
# kill thread, ensure it dies in a reasonable amount of time
|
||||
t.kill
|
||||
a = 1
|
||||
while a < 2000
|
||||
break unless t.alive?
|
||||
Thread.pass
|
||||
sleep 0.2
|
||||
a = 0
|
||||
while t.alive? and a < 5000
|
||||
sleep 0.001
|
||||
a += 1
|
||||
end
|
||||
a.should < 2000
|
||||
a.should < 5000
|
||||
end
|
||||
|
||||
it "can be interrupted by Thread#raise" do
|
||||
|
|
|
@ -3,7 +3,7 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "TCPServer#gets" do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'socket'
|
|||
|
||||
describe 'TCPServer#listen' do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
|
|
@ -7,7 +7,7 @@ describe "TCPServer.new" do
|
|||
end
|
||||
|
||||
it "binds to a host and a port" do
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
addr = @server.addr
|
||||
addr[0].should == 'AF_INET'
|
||||
addr[1].should be_kind_of(Fixnum)
|
||||
|
@ -18,53 +18,52 @@ describe "TCPServer.new" do
|
|||
end
|
||||
|
||||
it "binds to localhost and a port with either IPv4 or IPv6" do
|
||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||
addr = @server.addr
|
||||
addr[1].should be_kind_of(Fixnum)
|
||||
if addr[0] == 'AF_INET'
|
||||
addr[1].should == SocketSpecs.port
|
||||
addr[2].should =~ /^#{SocketSpecs.hostname}\b/
|
||||
addr[3].should == '127.0.0.1'
|
||||
else
|
||||
addr[1].should == SocketSpecs.port
|
||||
addr[2].should =~ /^#{SocketSpecs.hostnamev6}\b/
|
||||
addr[3].should == '::1'
|
||||
end
|
||||
end
|
||||
|
||||
it "binds to INADDR_ANY if the hostname is empty" do
|
||||
@server = TCPServer.new('', SocketSpecs.port)
|
||||
@server = TCPServer.new('', 0)
|
||||
addr = @server.addr
|
||||
addr[0].should == 'AF_INET'
|
||||
addr[1].should == SocketSpecs.port
|
||||
addr[1].should be_kind_of(Fixnum)
|
||||
addr[2].should == '0.0.0.0'
|
||||
addr[3].should == '0.0.0.0'
|
||||
end
|
||||
|
||||
it "binds to INADDR_ANY if the hostname is empty and the port is a string" do
|
||||
@server = TCPServer.new('', SocketSpecs.port.to_s)
|
||||
@server = TCPServer.new('', 0)
|
||||
addr = @server.addr
|
||||
addr[0].should == 'AF_INET'
|
||||
addr[1].should == SocketSpecs.port
|
||||
addr[1].should be_kind_of(Fixnum)
|
||||
addr[2].should == '0.0.0.0'
|
||||
addr[3].should == '0.0.0.0'
|
||||
end
|
||||
|
||||
it "coerces port to string, then determines port from that number or service name" do
|
||||
t = Object.new
|
||||
lambda { TCPServer.new(SocketSpecs.hostname, t) }.should raise_error(TypeError)
|
||||
lambda { TCPServer.new(SocketSpecs.hostname, Object.new) }.should raise_error(TypeError)
|
||||
|
||||
def t.to_str; SocketSpecs.port.to_s; end
|
||||
port = Object.new
|
||||
port.should_receive(:to_str).and_return("0")
|
||||
|
||||
@server = TCPServer.new(SocketSpecs.hostname, t)
|
||||
@server = TCPServer.new(SocketSpecs.hostname, port)
|
||||
addr = @server.addr
|
||||
addr[1].should == SocketSpecs.port
|
||||
addr[1].should be_kind_of(Fixnum)
|
||||
|
||||
# TODO: This should also accept strings like 'https', but I don't know how to
|
||||
# pick such a service port that will be able to reliably bind...
|
||||
end
|
||||
|
||||
it "raises Errno::EADDRNOTAVAIL when the adress is unknown" do
|
||||
lambda { TCPServer.new("1.2.3.4", 4000) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
lambda { TCPServer.new("1.2.3.4", 0) }.should raise_error(Errno::EADDRNOTAVAIL)
|
||||
end
|
||||
|
||||
# There is no way to make this fail-proof on all machines, because
|
||||
|
@ -73,15 +72,15 @@ describe "TCPServer.new" do
|
|||
quarantine! do
|
||||
it "raises a SocketError when the host is unknown" do
|
||||
lambda {
|
||||
TCPServer.new("--notavalidname", 4000)
|
||||
TCPServer.new("--notavalidname", 0)
|
||||
}.should raise_error(SocketError)
|
||||
end
|
||||
end
|
||||
|
||||
it "raises Errno::EADDRINUSE when address is already in use" do
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
lambda {
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', @server.addr[1])
|
||||
}.should raise_error(Errno::EADDRINUSE)
|
||||
end
|
||||
|
||||
|
@ -89,7 +88,7 @@ describe "TCPServer.new" do
|
|||
# A known bug in AIX. getsockopt(2) does not properly set
|
||||
# the fifth argument for SO_REUSEADDR.
|
||||
it "sets SO_REUSEADDR on the resulting server" do
|
||||
@server = TCPServer.new('127.0.0.1', SocketSpecs.port)
|
||||
@server = TCPServer.new('127.0.0.1', 0)
|
||||
@server.getsockopt(:SOCKET, :REUSEADDR).data.should_not == "\x00\x00\x00\x00"
|
||||
@server.getsockopt(:SOCKET, :REUSEADDR).int.should_not == 0
|
||||
end
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe "TCPServer#<<" do
|
||||
after :each do
|
||||
@server.close if @server
|
||||
@socket.close if @socket
|
||||
end
|
||||
end
|
|
@ -1,9 +0,0 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe "TCPServer#readpartial" do
|
||||
after :each do
|
||||
@server.close if @server
|
||||
@socket.close if @socket
|
||||
end
|
||||
end
|
|
@ -5,7 +5,8 @@ require 'socket'
|
|||
|
||||
describe "TCPServer#sysaccept" do
|
||||
before :each do
|
||||
@server = TCPServer.new(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||
@port = @server.addr[1]
|
||||
end
|
||||
|
||||
after :each do
|
||||
|
@ -18,7 +19,7 @@ describe "TCPServer#sysaccept" do
|
|||
|
||||
it 'returns file descriptor of an accepted connection' do
|
||||
begin
|
||||
sock = TCPSocket.new(SocketSpecs.hostname, SocketSpecs.port)
|
||||
sock = TCPSocket.new(SocketSpecs.hostname, @port)
|
||||
|
||||
fd = @server.sysaccept
|
||||
|
||||
|
|
|
@ -5,9 +5,8 @@ require File.expand_path('../../shared/partially_closable_sockets', __FILE__)
|
|||
describe "TCPSocket partial closability" do
|
||||
|
||||
before :each do
|
||||
port = SocketSpecs.find_available_port
|
||||
@server = TCPServer.new("127.0.0.1", port)
|
||||
@s1 = TCPSocket.new("127.0.0.1", port)
|
||||
@server = TCPServer.new("127.0.0.1", 0)
|
||||
@s1 = TCPSocket.new("127.0.0.1", @server.addr[1])
|
||||
@s2 = @server.accept
|
||||
end
|
||||
|
||||
|
|
|
@ -44,8 +44,14 @@ describe :tcpsocket_new, shared: true do
|
|||
end
|
||||
|
||||
it "connects to a server when passed local_host and local_port arguments" do
|
||||
server = TCPServer.new(SocketSpecs.hostname, 0)
|
||||
begin
|
||||
available_port = server.addr[1]
|
||||
ensure
|
||||
server.close
|
||||
end
|
||||
@socket = TCPSocket.send(@method, @hostname, @server.port,
|
||||
@hostname, SocketSpecs.local_port)
|
||||
@hostname, available_port)
|
||||
@socket.should be_an_instance_of(TCPSocket)
|
||||
end
|
||||
|
||||
|
|
|
@ -12,24 +12,31 @@ describe "UDPSocket.bind" do
|
|||
end
|
||||
|
||||
it "binds the socket to a port" do
|
||||
@socket.bind(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@socket.bind(SocketSpecs.hostname, 0)
|
||||
@socket.addr[1].should be_kind_of(Integer)
|
||||
end
|
||||
|
||||
lambda { @socket.bind(SocketSpecs.hostname, SocketSpecs.port) }.should raise_error
|
||||
it "raises Errno::EINVAL when already bound" do
|
||||
@socket.bind(SocketSpecs.hostname, 0)
|
||||
|
||||
lambda {
|
||||
@socket.bind(SocketSpecs.hostname, @socket.addr[1])
|
||||
}.should raise_error(Errno::EINVAL)
|
||||
end
|
||||
|
||||
it "receives a hostname and a port" do
|
||||
@socket.bind(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@socket.bind(SocketSpecs.hostname, 0)
|
||||
|
||||
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||
|
||||
host.should == "127.0.0.1"
|
||||
port.should == SocketSpecs.port
|
||||
port.should == @socket.addr[1]
|
||||
end
|
||||
|
||||
it "binds to INADDR_ANY if the hostname is empty" do
|
||||
@socket.bind("", SocketSpecs.port)
|
||||
@socket.bind("", 0)
|
||||
port, host = Socket.unpack_sockaddr_in(@socket.getsockname)
|
||||
host.should == "0.0.0.0"
|
||||
port.should == SocketSpecs.port
|
||||
port.should == @socket.addr[1]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
@ -1,2 +0,0 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
|
@ -3,12 +3,12 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
|
||||
describe "UDPSocket.send" do
|
||||
before :each do
|
||||
@ready = false
|
||||
@port = nil
|
||||
@server_thread = Thread.new do
|
||||
@server = UDPSocket.open
|
||||
begin
|
||||
@server.bind(nil, SocketSpecs.port)
|
||||
@ready = true
|
||||
@server.bind(nil, 0)
|
||||
@port = @server.addr[1]
|
||||
begin
|
||||
@msg = @server.recvfrom_nonblock(64)
|
||||
rescue IO::WaitReadable
|
||||
|
@ -19,12 +19,16 @@ describe "UDPSocket.send" do
|
|||
@server.close if !@server.closed?
|
||||
end
|
||||
end
|
||||
Thread.pass while @server_thread.status and !@ready
|
||||
Thread.pass while @server_thread.status and !@port
|
||||
end
|
||||
|
||||
after :each do
|
||||
@server_thread.join
|
||||
end
|
||||
|
||||
it "sends data in ad hoc mode" do
|
||||
@socket = UDPSocket.open
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.port)
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port)
|
||||
@socket.close
|
||||
@server_thread.join
|
||||
|
||||
|
@ -36,7 +40,7 @@ describe "UDPSocket.send" do
|
|||
|
||||
it "sends data in ad hoc mode (with port given as a String)" do
|
||||
@socket = UDPSocket.open
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.str_port)
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port.to_s)
|
||||
@socket.close
|
||||
@server_thread.join
|
||||
|
||||
|
@ -48,7 +52,7 @@ describe "UDPSocket.send" do
|
|||
|
||||
it "sends data in connection mode" do
|
||||
@socket = UDPSocket.open
|
||||
@socket.connect(SocketSpecs.hostname, SocketSpecs.port)
|
||||
@socket.connect(SocketSpecs.hostname, @port)
|
||||
@socket.send("connection-based", 0)
|
||||
@socket.close
|
||||
@server_thread.join
|
||||
|
@ -63,10 +67,10 @@ describe "UDPSocket.send" do
|
|||
@socket = UDPSocket.open
|
||||
begin
|
||||
lambda do
|
||||
@socket.send('1' * 100_000, 0, SocketSpecs.hostname, SocketSpecs.str_port)
|
||||
@socket.send('1' * 100_000, 0, SocketSpecs.hostname, @port.to_s)
|
||||
end.should raise_error(Errno::EMSGSIZE)
|
||||
ensure
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, SocketSpecs.port)
|
||||
@socket.send("ad hoc", 0, SocketSpecs.hostname, @port)
|
||||
@socket.close
|
||||
@server_thread.join
|
||||
end
|
||||
|
|
|
@ -4,11 +4,11 @@ require File.expand_path('../../fixtures/classes', __FILE__)
|
|||
describe "UDPSocket#write" do
|
||||
it "raises EMSGSIZE if msg is too long" do
|
||||
begin
|
||||
host, port = SocketSpecs.hostname, SocketSpecs.port
|
||||
host = SocketSpecs.hostname
|
||||
s1 = UDPSocket.new
|
||||
s1.bind(host, port)
|
||||
s1.bind(host, 0)
|
||||
s2 = UDPSocket.new
|
||||
s2.connect(host, port)
|
||||
s2.connect(host, s1.addr[1])
|
||||
|
||||
lambda do
|
||||
s2.write('1' * 100_000)
|
||||
|
|
|
@ -5,53 +5,50 @@ platform_is_not :windows do
|
|||
describe "UNIXServer#accept" do
|
||||
before :each do
|
||||
@path = SocketSpecs.socket_path
|
||||
@server = UNIXServer.open(@path)
|
||||
end
|
||||
|
||||
after :each do
|
||||
@server.close if @server
|
||||
SocketSpecs.rm_socket @path
|
||||
end
|
||||
|
||||
it "accepts what is written by the client" do
|
||||
server = UNIXServer.open(@path)
|
||||
client = UNIXSocket.open(@path)
|
||||
|
||||
client.send('hello', 0)
|
||||
|
||||
sock = server.accept
|
||||
data, info = sock.recvfrom(5)
|
||||
sock = @server.accept
|
||||
begin
|
||||
data, info = sock.recvfrom(5)
|
||||
|
||||
data.should == 'hello'
|
||||
info.should_not be_empty
|
||||
|
||||
server.close
|
||||
client.close
|
||||
sock.close
|
||||
data.should == 'hello'
|
||||
info.should_not be_empty
|
||||
ensure
|
||||
sock.close
|
||||
client.close
|
||||
end
|
||||
end
|
||||
|
||||
it "can be interrupted by Thread#kill" do
|
||||
server = UNIXServer.new(@path)
|
||||
t = Thread.new {
|
||||
server.accept
|
||||
@server.accept
|
||||
}
|
||||
Thread.pass while t.status and t.status != "sleep"
|
||||
|
||||
# kill thread, ensure it dies in a reasonable amount of time
|
||||
t.kill
|
||||
a = 1
|
||||
while a < 2000
|
||||
break unless t.alive?
|
||||
Thread.pass
|
||||
sleep 0.2
|
||||
a = 0
|
||||
while t.alive? and a < 5000
|
||||
sleep 0.001
|
||||
a += 1
|
||||
end
|
||||
a.should < 2000
|
||||
server.close
|
||||
a.should < 5000
|
||||
end
|
||||
|
||||
it "can be interrupted by Thread#raise" do
|
||||
server = UNIXServer.new(@path)
|
||||
t = Thread.new {
|
||||
server.accept
|
||||
@server.accept
|
||||
}
|
||||
Thread.pass while t.status and t.status != "sleep"
|
||||
|
||||
|
@ -59,7 +56,6 @@ platform_is_not :windows do
|
|||
ex = Exception.new
|
||||
t.raise ex
|
||||
lambda { t.join }.should raise_error(Exception)
|
||||
server.close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#ifndef RUBYSPEC_CAPI_JRUBY_H
|
||||
#define RUBYSPEC_CAPI_JRUBY_H
|
||||
|
||||
/* #undef any HAVE_ defines that JRuby does not have. */
|
||||
#undef HAVE_RB_DEFINE_HOOKED_VARIABLE
|
||||
#undef HAVE_RB_DEFINE_VARIABLE
|
||||
|
||||
#undef HAVE_RB_EXEC_RECURSIVE
|
||||
|
||||
#endif
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef RUBYSPEC_CAPI_RUBINIUS_H
|
||||
#define RUBYSPEC_CAPI_RUBINIUS_H
|
||||
|
||||
/* #undef any HAVE_ defines that Rubinius does not have. */
|
||||
#undef HAVE_RB_DEFINE_HOOKED_VARIABLE
|
||||
#undef HAVE_RB_DEFINE_VARIABLE
|
||||
|
||||
#endif
|
|
@ -595,19 +595,4 @@
|
|||
/* Util */
|
||||
#define HAVE_RB_SCAN_ARGS 1
|
||||
|
||||
/* Now, create the differential set. The format of the preprocessor directives
|
||||
* is significant. The alternative implementations should define RUBY because
|
||||
* some extensions depend on that. But only one alternative implementation
|
||||
* macro should be defined at a time. The conditional is structured so that if
|
||||
* no alternative implementation is defined then MRI is assumed.
|
||||
*/
|
||||
|
||||
#if defined(RUBINIUS)
|
||||
#include "rubinius.h"
|
||||
#elif defined(JRUBY)
|
||||
#include "jruby.h"
|
||||
#elif defined(TRUFFLERUBY)
|
||||
#include "truffleruby.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef RUBYSPEC_CAPI_TRUFFLERUBY_H
|
||||
#undef RUBYSPEC_CAPI_TRUFFLERUBY_H
|
||||
|
||||
// All features are available
|
||||
|
||||
#endif
|
|
@ -62,16 +62,18 @@ describe "CApiModule" do
|
|||
mod = @m.rb_define_module_under(CApiModuleSpecs, "ModuleSpecsModuleUnder2")
|
||||
mod.name.should == "CApiModuleSpecs::ModuleSpecsModuleUnder2"
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_define_module_under" do
|
||||
before :each do
|
||||
compile_extension("module_under_autoload")
|
||||
end
|
||||
|
||||
it "defines a module for an existing Autoload with an extension" do
|
||||
compile_extension("module_under_autoload")
|
||||
|
||||
CApiModuleSpecs::ModuleUnderAutoload.name.should == "CApiModuleSpecs::ModuleUnderAutoload"
|
||||
end
|
||||
|
||||
it "defines a module for an existing Autoload with a ruby object" do
|
||||
compile_extension("module_under_autoload")
|
||||
|
||||
CApiModuleSpecs::RubyUnderAutoload.name.should == "CApiModuleSpecs::RubyUnderAutoload"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
require File.expand_path('../../../spec_helper', __FILE__)
|
||||
|
||||
# MRI magic to use built but not installed ruby
|
||||
$extmk = false
|
||||
|
||||
require 'rbconfig'
|
||||
|
||||
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_NAME}/#{RUBY_VERSION}", __FILE__)
|
||||
OBJDIR ||= File.expand_path("../../../ext/#{RUBY_ENGINE}/#{RUBY_VERSION}", __FILE__)
|
||||
mkdir_p(OBJDIR)
|
||||
|
||||
def extension_path
|
||||
|
@ -15,130 +17,59 @@ def object_path
|
|||
end
|
||||
|
||||
def compile_extension(name)
|
||||
preloadenv = RbConfig::CONFIG["PRELOADENV"] || "LD_PRELOAD"
|
||||
preload, ENV[preloadenv] = ENV[preloadenv], nil if preloadenv
|
||||
debug = false
|
||||
run_mkmf_in_process = RUBY_ENGINE == 'truffleruby'
|
||||
|
||||
path = extension_path
|
||||
objdir = object_path
|
||||
|
||||
# TODO use rakelib/ext_helper.rb?
|
||||
arch_hdrdir = nil
|
||||
|
||||
if RUBY_NAME == 'rbx'
|
||||
hdrdir = RbConfig::CONFIG["rubyhdrdir"]
|
||||
elsif RUBY_NAME =~ /^ruby/
|
||||
hdrdir = RbConfig::CONFIG["rubyhdrdir"]
|
||||
arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"]
|
||||
elsif RUBY_NAME == 'jruby'
|
||||
require 'mkmf'
|
||||
hdrdir = $hdrdir
|
||||
elsif RUBY_NAME == "maglev"
|
||||
require 'mkmf'
|
||||
hdrdir = $hdrdir
|
||||
elsif RUBY_NAME == 'truffleruby'
|
||||
return compile_truffleruby_extconf_make(name, path, objdir)
|
||||
else
|
||||
raise "Don't know how to build C extensions with #{RUBY_NAME}"
|
||||
end
|
||||
|
||||
ext = "#{name}_spec"
|
||||
source = File.join(path, "#{ext}.c")
|
||||
obj = File.join(objdir, "#{ext}.#{RbConfig::CONFIG['OBJEXT']}")
|
||||
lib = File.join(objdir, "#{ext}.#{RbConfig::CONFIG['DLEXT']}")
|
||||
|
||||
ruby_header = File.join(hdrdir, "ruby.h")
|
||||
rubyspec_header = File.join(path, "rubyspec.h")
|
||||
|
||||
return lib if File.exist?(lib) and File.mtime(lib) > File.mtime(source) and
|
||||
File.mtime(lib) > File.mtime(ruby_header) and
|
||||
File.mtime(lib) > File.mtime(rubyspec_header) and
|
||||
true # sentinel
|
||||
|
||||
# avoid problems where compilation failed but previous shlib exists
|
||||
File.delete lib if File.exist? lib
|
||||
|
||||
cc = RbConfig::CONFIG["CC"]
|
||||
cflags = (ENV["CFLAGS"] || RbConfig::CONFIG["CFLAGS"]).dup
|
||||
cflags += " #{RbConfig::CONFIG["ARCH_FLAG"]}" if RbConfig::CONFIG["ARCH_FLAG"]
|
||||
cflags += " #{RbConfig::CONFIG["CCDLFLAGS"]}" if RbConfig::CONFIG["CCDLFLAGS"]
|
||||
cppflags = (ENV["CPPFLAGS"] || RbConfig::CONFIG["CPPFLAGS"]).dup
|
||||
incflags = "-I#{path}"
|
||||
incflags << " -I#{arch_hdrdir}" if arch_hdrdir
|
||||
incflags << " -I#{hdrdir}"
|
||||
csrcflag = RbConfig::CONFIG["CSRCFLAG"]
|
||||
coutflag = RbConfig::CONFIG["COUTFLAG"]
|
||||
|
||||
compile_cmd = "#{cc} #{incflags} #{cflags} #{cppflags} #{coutflag}#{obj} -c #{csrcflag}#{source}"
|
||||
output = `#{compile_cmd}`
|
||||
|
||||
unless $?.success? and File.exist?(obj)
|
||||
puts "\nERROR:\n#{compile_cmd}\n#{output}"
|
||||
puts "incflags=#{incflags}"
|
||||
puts "cflags=#{cflags}"
|
||||
puts "cppflags=#{cppflags}"
|
||||
raise "Unable to compile \"#{source}\""
|
||||
end
|
||||
|
||||
ldshared = RbConfig::CONFIG["LDSHARED"]
|
||||
ldshared += " #{RbConfig::CONFIG["ARCH_FLAG"]}" if RbConfig::CONFIG["ARCH_FLAG"]
|
||||
libs = RbConfig::CONFIG["LIBS"]
|
||||
dldflags = "#{RbConfig::CONFIG["LDFLAGS"]} #{RbConfig::CONFIG["DLDFLAGS"]} #{RbConfig::CONFIG["EXTDLDFLAGS"]}"
|
||||
dldflags.sub!(/-Wl,-soname,\S+/, '')
|
||||
|
||||
if /mswin/ =~ RUBY_PLATFORM
|
||||
dldflags.sub!("$(LIBPATH)", RbConfig::CONFIG["LIBPATHFLAG"] % path)
|
||||
libs += RbConfig::CONFIG["LIBRUBY"]
|
||||
outflag = RbConfig::CONFIG["OUTFLAG"]
|
||||
|
||||
link_cmd = "#{ldshared} #{outflag}#{lib} #{obj} #{libs} -link #{dldflags} /export:Init_#{ext}"
|
||||
else
|
||||
libpath = "-L#{path}"
|
||||
dldflags.sub!("$(TARGET_ENTRY)", "Init_#{ext}")
|
||||
|
||||
link_cmd = "#{ldshared} #{obj} #{libpath} #{dldflags} #{libs} -o #{lib}"
|
||||
end
|
||||
output = `#{link_cmd}`
|
||||
|
||||
unless $?.success?
|
||||
puts "\nERROR:\n#{link_cmd}\n#{output}"
|
||||
raise "Unable to link \"#{source}\""
|
||||
end
|
||||
|
||||
lib
|
||||
ensure
|
||||
ENV[preloadenv] = preload if preloadenv
|
||||
end
|
||||
|
||||
def compile_truffleruby_extconf_make(name, path, objdir)
|
||||
ext = "#{name}_spec"
|
||||
file = "#{ext}.c"
|
||||
source = "#{path}/#{ext}.c"
|
||||
lib = "#{objdir}/#{ext}.#{RbConfig::CONFIG['DLEXT']}"
|
||||
lib = "#{object_path}/#{ext}.#{RbConfig::CONFIG['DLEXT']}"
|
||||
ruby_header = "#{RbConfig::CONFIG['rubyhdrdir']}/ruby.h"
|
||||
|
||||
return lib if File.exist?(lib) and
|
||||
File.mtime(lib) > File.mtime("#{extension_path}/rubyspec.h") and
|
||||
File.mtime(lib) > File.mtime("#{extension_path}/#{ext}.c") and
|
||||
File.mtime(lib) > File.mtime(ruby_header) and
|
||||
true # sentinel
|
||||
|
||||
# Copy needed source files to tmpdir
|
||||
tmpdir = tmp("cext_#{name}")
|
||||
Dir.mkdir tmpdir
|
||||
Dir.mkdir(tmpdir)
|
||||
begin
|
||||
["rubyspec.h", "truffleruby.h", "#{ext}.c"].each do |file|
|
||||
cp "#{path}/#{file}", "#{tmpdir}/#{file}"
|
||||
["rubyspec.h", "#{ext}.c"].each do |file|
|
||||
cp "#{extension_path}/#{file}", "#{tmpdir}/#{file}"
|
||||
end
|
||||
|
||||
Dir.chdir(tmpdir) do
|
||||
required = require 'mkmf'
|
||||
# Reinitialize mkmf if already required
|
||||
init_mkmf unless required
|
||||
create_makefile(ext, tmpdir)
|
||||
system "make"
|
||||
|
||||
copy_exts = RbConfig::CONFIG.values_at('OBJEXT', 'DLEXT')
|
||||
Dir.glob("*.{#{copy_exts.join(',')}}") do |file|
|
||||
cp file, "#{objdir}/#{file}"
|
||||
if run_mkmf_in_process
|
||||
required = require 'mkmf'
|
||||
# Reinitialize mkmf if already required
|
||||
init_mkmf unless required
|
||||
create_makefile(ext, tmpdir)
|
||||
else
|
||||
File.write("extconf.rb", "require 'mkmf'\n" +
|
||||
"$ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')\n" +
|
||||
# MRI magic to consider building non-bundled extensions
|
||||
"$extout = nil\n" +
|
||||
"create_makefile(#{ext.inspect})\n")
|
||||
output = ruby_exe("extconf.rb")
|
||||
raise "extconf failed:\n#{output}" unless $?.success?
|
||||
$stderr.puts output if debug
|
||||
end
|
||||
|
||||
make = RbConfig::CONFIG['host_os'].include?("mswin") ? "nmake" : "make"
|
||||
ENV.delete "MAKEFLAGS" # Fix make warning when invoked with -j in MRI
|
||||
|
||||
# Do not capture stderr as we want to show compiler warnings
|
||||
output = `#{make} V=1`
|
||||
raise "#{make} failed:\n#{output}" unless $?.success?
|
||||
$stderr.puts output if debug
|
||||
|
||||
cp File.basename(lib), lib
|
||||
end
|
||||
ensure
|
||||
rm_r tmpdir
|
||||
end
|
||||
|
||||
File.chmod(0755, lib)
|
||||
lib
|
||||
end
|
||||
|
||||
|
|
|
@ -501,7 +501,7 @@ describe "C-API String function" do
|
|||
describe "rb_str_hash" do
|
||||
it "hashes the string into a number" do
|
||||
s = "hello"
|
||||
@s.rb_str_hash(s).should == s.hash
|
||||
@s.rb_str_hash(s).should be_kind_of(Integer)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -165,28 +165,30 @@ describe "CApiTimeSpecs" do
|
|||
usec.should == 500000
|
||||
end
|
||||
|
||||
it "creates a timeval for a negative Fixnum" do
|
||||
sec, usec = @s.rb_time_timeval(-1232141421)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -1232141421
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 0
|
||||
end
|
||||
platform_is_not :mingw32 do
|
||||
it "creates a timeval for a negative Fixnum" do
|
||||
sec, usec = @s.rb_time_timeval(-1232141421)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -1232141421
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 0
|
||||
end
|
||||
|
||||
it "creates a timeval for a negative Float" do
|
||||
sec, usec = @s.rb_time_timeval(-1.5)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 500000
|
||||
end
|
||||
it "creates a timeval for a negative Float" do
|
||||
sec, usec = @s.rb_time_timeval(-1.5)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 500000
|
||||
end
|
||||
|
||||
it "creates a timeval for a negative Rational" do
|
||||
sec, usec = @s.rb_time_timeval(Rational(-3, 2))
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 500000
|
||||
it "creates a timeval for a negative Rational" do
|
||||
sec, usec = @s.rb_time_timeval(Rational(-3, 2))
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
usec.should be_kind_of(Integer)
|
||||
usec.should == 500000
|
||||
end
|
||||
end
|
||||
|
||||
it "creates a timeval from a Time object" do
|
||||
|
@ -222,28 +224,30 @@ describe "CApiTimeSpecs" do
|
|||
nsec.should == 500000000
|
||||
end
|
||||
|
||||
it "creates a timespec for a negative Fixnum" do
|
||||
sec, nsec = @s.rb_time_timespec(-1232141421)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -1232141421
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 0
|
||||
end
|
||||
platform_is_not :mingw32 do
|
||||
it "creates a timespec for a negative Fixnum" do
|
||||
sec, nsec = @s.rb_time_timespec(-1232141421)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -1232141421
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 0
|
||||
end
|
||||
|
||||
it "creates a timespec for a negative Float" do
|
||||
sec, nsec = @s.rb_time_timespec(-1.5)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 500000000
|
||||
end
|
||||
it "creates a timespec for a negative Float" do
|
||||
sec, nsec = @s.rb_time_timespec(-1.5)
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 500000000
|
||||
end
|
||||
|
||||
it "creates a timespec for a negative Rational" do
|
||||
sec, nsec = @s.rb_time_timespec(Rational(-3, 2))
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 500000000
|
||||
it "creates a timespec for a negative Rational" do
|
||||
sec, nsec = @s.rb_time_timespec(Rational(-3, 2))
|
||||
sec.should be_kind_of(Integer)
|
||||
sec.should == -2
|
||||
nsec.should be_kind_of(Integer)
|
||||
nsec.should == 500000000
|
||||
end
|
||||
end
|
||||
|
||||
it "creates a timespec from a Time object" do
|
||||
|
|
Loading…
Add table
Reference in a new issue