git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66041 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2018-11-27 20:38:57 +00:00
parent 49cd16bfaf
commit 50441014ff
102 changed files with 771 additions and 426 deletions

View File

@ -88,9 +88,9 @@ In similar fashion, the following commands run the respective specs:
$ ../mspec/bin/mspec :library $ ../mspec/bin/mspec :library
$ ../mspec/bin/mspec :capi $ ../mspec/bin/mspec :capi
### Contributing ### Contributing and Writing Specs
See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md). See [CONTRIBUTING.md](https://github.com/ruby/spec/blob/master/CONTRIBUTING.md) for documentation about contributing and writing specs (guards, matchers, etc).
### Socket specs from rubysl-socket ### Socket specs from rubysl-socket

View File

@ -1,6 +1,6 @@
--- ---
version: "{build}" version: "{build}"
clone_depth: 5 clone_depth: 100
init: init:
# To avoid duplicated executables in PATH, see https://github.com/ruby/spec/pull/468 # To avoid duplicated executables in PATH, see https://github.com/ruby/spec/pull/468
- set PATH=C:\Ruby%ruby_version%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows - set PATH=C:\Ruby%ruby_version%\bin;C:\Program Files\7-Zip;C:\Program Files\AppVeyor\BuildAgent;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Program Files;C:\Windows

View File

@ -15,8 +15,8 @@ describe "Dir.home" do
end end
platform_is_not :windows do platform_is_not :windows do
it "returns the named user's home directory as a string if called with an argument" do it "returns the named user's home directory, from the user database, as a string if called with an argument" do
Dir.home(ENV['USER']).should == ENV['HOME'] Dir.home(ENV['USER']).should == `echo ~#{ENV['USER']}`.chomp
end end
end end

View File

@ -88,7 +88,8 @@ describe "File.expand_path" do
platform_is_not :windows do platform_is_not :windows do
before do before do
@home = ENV['HOME'].chomp('/') @var_home = ENV['HOME'].chomp('/')
@db_home = `echo ~#{ENV['USER']}`.chomp
end end
# FIXME: these are insane! # FIXME: these are insane!
@ -107,9 +108,9 @@ describe "File.expand_path" do
File.expand_path('./////').should == Dir.pwd File.expand_path('./////').should == Dir.pwd
File.expand_path('.').should == Dir.pwd File.expand_path('.').should == Dir.pwd
File.expand_path(Dir.pwd).should == Dir.pwd File.expand_path(Dir.pwd).should == Dir.pwd
File.expand_path('~/').should == @home File.expand_path('~/').should == @var_home
File.expand_path('~/..badfilename').should == "#{@home}/..badfilename" File.expand_path('~/..badfilename').should == "#{@var_home}/..badfilename"
File.expand_path('~/a','~/b').should == "#{@home}/a" File.expand_path('~/a','~/b').should == "#{@var_home}/a"
File.expand_path('..').should == File.dirname(Dir.pwd) File.expand_path('..').should == File.dirname(Dir.pwd)
end end
@ -126,8 +127,11 @@ describe "File.expand_path" do
end end
it "expands ~ENV['USER'] to the user's home directory" do it "expands ~ENV['USER'] to the user's home directory" do
File.expand_path("~#{ENV['USER']}").should == @home File.expand_path("~#{ENV['USER']}").should == @db_home
File.expand_path("~#{ENV['USER']}/a").should == "#{@home}/a" end
it "expands ~ENV['USER']/a to a in the user's home directory" do
File.expand_path("~#{ENV['USER']}/a").should == "#{@db_home}/a"
end end
it "does not expand ~ENV['USER'] when it's not at the start" do it "does not expand ~ENV['USER'] when it's not at the start" do
@ -135,7 +139,7 @@ describe "File.expand_path" do
end end
it "expands ../foo with ~/dir as base dir to /path/to/user/home/foo" do it "expands ../foo with ~/dir as base dir to /path/to/user/home/foo" do
File.expand_path('../foo', '~/dir').should == "#{@home}/foo" File.expand_path('../foo', '~/dir').should == "#{@var_home}/foo"
end end
end end
@ -239,4 +243,19 @@ platform_is_not :windows do
lambda { File.expand_path("~") }.should raise_error(ArgumentError) lambda { File.expand_path("~") }.should raise_error(ArgumentError)
end end
end end
describe "File.expand_path with a non-absolute HOME" do
before :each do
@home = ENV["HOME"]
end
after :each do
ENV["HOME"] = @home
end
it "raises an ArgumentError" do
ENV["HOME"] = "non-absolute"
lambda { File.expand_path("~") }.should raise_error(ArgumentError, 'non-absolute home')
end
end
end end

View File

@ -4,4 +4,14 @@ describe "GC.count" do
it "returns an integer" do it "returns an integer" do
GC.count.should be_kind_of(Integer) GC.count.should be_kind_of(Integer)
end end
it "increases as collections are run" do
count_before = GC.count
i = 0
while GC.count <= count_before and i < 10
GC.start
i += 1
end
GC.count.should > count_before
end
end end

View File

@ -61,4 +61,19 @@ describe "Hash#shift" do
lambda { HashSpecs.frozen_hash.shift }.should raise_error(frozen_error_class) lambda { HashSpecs.frozen_hash.shift }.should raise_error(frozen_error_class)
lambda { HashSpecs.empty_frozen_hash.shift }.should raise_error(frozen_error_class) lambda { HashSpecs.empty_frozen_hash.shift }.should raise_error(frozen_error_class)
end end
it "works when the hash is at capacity" do
# We try a wide range of sizes in hopes that this will cover all implementationss base Hash size.
results = []
1.upto(100) do |n|
h = {}
n.times do |i|
h[i] = i
end
h.shift
results << h.size
end
results.should == 0.upto(99).to_a
end
end end

View File

@ -43,6 +43,17 @@ describe "Integer#gcd" do
bignum.gcd(99).should == 99 bignum.gcd(99).should == 99
end end
it "doesn't cause an integer overflow" do
[2 ** (1.size * 8 - 2), 0x8000000000000000].each do |max|
[max - 1, max, max + 1].each do |num|
num.gcd(num).should == num
(-num).gcd(num).should == num
(-num).gcd(-num).should == num
num.gcd(-num).should == num
end
end
end
it "raises an ArgumentError if not given an argument" do it "raises an ArgumentError if not given an argument" do
lambda { 12.gcd }.should raise_error(ArgumentError) lambda { 12.gcd }.should raise_error(ArgumentError)
end end

View File

@ -55,7 +55,7 @@ describe "IO#syswrite on a pipe" do
r, w = IO.pipe r, w = IO.pipe
begin begin
w.nonblock = true w.nonblock = true
larger_than_pipe_capacity = 100 * 1024 larger_than_pipe_capacity = 2 * 1024 * 1024
written = w.syswrite("a"*larger_than_pipe_capacity) written = w.syswrite("a"*larger_than_pipe_capacity)
written.should > 0 written.should > 0
written.should < larger_than_pipe_capacity written.should < larger_than_pipe_capacity

View File

@ -50,7 +50,7 @@ describe "IO#ungetbyte" do
end end
ruby_version_is '2.6' do ruby_version_is '2.6' do
it "is an RangeError if the integr is not in 8bit" do it "is an RangeError if the integer is not in 8bit" do
for i in [4095, 0x4f7574206f6620636861722072616e6765] do for i in [4095, 0x4f7574206f6620636861722072616e6765] do
lambda { @io.ungetbyte(i) }.should raise_error(RangeError) lambda { @io.ungetbyte(i) }.should raise_error(RangeError)
end end

View File

@ -6,6 +6,7 @@ describe "main.using" do
lambda do lambda do
eval('using', TOPLEVEL_BINDING) eval('using', TOPLEVEL_BINDING)
end.should raise_error(ArgumentError) end.should raise_error(ArgumentError)
lambda do lambda do
eval('using "foo"', TOPLEVEL_BINDING) eval('using "foo"', TOPLEVEL_BINDING)
end.should raise_error(TypeError) end.should raise_error(TypeError)

View File

@ -717,4 +717,19 @@ describe "Module#refine" do
result.should == "hello from refinement" result.should == "hello from refinement"
end end
end end
it 'does not list methods defined only in refinement' do
refine_object = Module.new do
refine Object do
def refinement_only_method
end
end
end
spec = self
klass = Class.new { instance_methods.should_not spec.send(:include, :refinement_only_method) }
instance = klass.new
instance.methods.should_not include :refinement_only_method
instance.respond_to?(:refinement_only_method).should == false
-> { instance.method :refinement_only_method }.should raise_error(NameError)
end
end end

View File

@ -11,22 +11,15 @@ describe "Mutex#lock" do
m.unlock m.unlock
end end
it "waits if the lock is not available" do it "blocks the caller if already locked" do
m = Mutex.new m = Mutex.new
m.lock m.lock
lambda { m.lock }.should block_caller
th = Thread.new do
m.lock
ScratchPad.record :after_lock
end end
Thread.pass while th.status and th.status != "sleep" it "does not block the caller if not locked" do
m = Mutex.new
ScratchPad.recorded.should be_nil lambda { m.lock }.should_not block_caller
m.unlock
th.join
ScratchPad.recorded.should == :after_lock
end end
# Unable to find a specific ticket but behavior change may be # Unable to find a specific ticket but behavior change may be

View File

@ -24,4 +24,43 @@ describe "Mutex#synchronize" do
th.join th.join
m1.locked?.should be_false m1.locked?.should be_false
end end
it "blocks the caller if already locked" do
m = Mutex.new
m.lock
lambda { m.synchronize { } }.should block_caller
end
it "does not block the caller if not locked" do
m = Mutex.new
lambda { m.synchronize { } }.should_not block_caller
end
it "blocks the caller if another thread is also in the synchronize block" do
m = Mutex.new
q1 = Queue.new
q2 = Queue.new
t = Thread.new {
m.synchronize {
q1.push :ready
q2.pop
}
}
q1.pop.should == :ready
lambda { m.synchronize { } }.should block_caller
q2.push :done
t.join
end
it "is not recursive" do
m = Mutex.new
m.synchronize do
lambda { m.synchronize { } }.should raise_error(ThreadError)
end
end
end end

View File

@ -0,0 +1,35 @@
require_relative '../../spec_helper'
describe "Process.clock_gettime" do
describe 'time units' do
it 'handles a fixed set of time units' do
[:nanosecond, :microsecond, :millisecond, :second].each do |unit|
Process.clock_gettime(Process::CLOCK_MONOTONIC, unit).should be_kind_of(Integer)
end
[:float_microsecond, :float_millisecond, :float_second].each do |unit|
Process.clock_gettime(Process::CLOCK_MONOTONIC, unit).should be_an_instance_of(Float)
end
end
it 'raises an ArgumentError for an invalid time unit' do
lambda { Process.clock_gettime(Process::CLOCK_MONOTONIC, :bad) }.should raise_error(ArgumentError)
end
it 'defaults to :float_second' do
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
t1.should be_an_instance_of(Float)
t2.should be_close(t1, 2.0) # 2.0 is chosen arbitrarily to allow for time skew without admitting failure cases, which would be off by an order of magnitude.
end
it 'uses the default time unit (:float_second) when passed nil' do
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC, nil)
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
t1.should be_an_instance_of(Float)
t2.should be_close(t1, 2.0) # 2.0 is chosen arbitrarily to allow for time skew without admitting failure cases, which would be off by an order of magnitude.
end
end
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
describe "Queue#<<" do
it_behaves_like :queue_enq, :<<, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/clear'
describe "Queue#clear" do
it_behaves_like :queue_clear, :clear, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/close'
describe "Queue#close" do
it_behaves_like :queue_close, :close, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/closed'
describe "Queue#closed?" do
it_behaves_like :queue_closed?, :closed?, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "Queue#deq" do
it_behaves_like :queue_deq, :deq, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/empty'
describe "Queue#empty?" do
it_behaves_like :queue_empty?, :empty?, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
describe "Queue#enq" do
it_behaves_like :queue_enq, :enq, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/length'
describe "Queue#length" do
it_behaves_like :queue_length, :length, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/num_waiting'
describe "Queue#num_waiting" do
it_behaves_like :queue_num_waiting, :num_waiting, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "Queue#pop" do
it_behaves_like :queue_deq, :pop, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
describe "Queue#push" do
it_behaves_like :queue_enq, :push, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "Queue#shift" do
it_behaves_like :queue_deq, :shift, -> { Queue.new }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/length'
describe "Queue#size" do
it_behaves_like :queue_length, :size, -> { Queue.new }
end

View File

@ -61,4 +61,8 @@ describe "Signal.list" do
it "includes the EXIT key with a value of zero" do it "includes the EXIT key with a value of zero" do
Signal.list["EXIT"].should == 0 Signal.list["EXIT"].should == 0
end end
it "includes the KILL key with a value of nine" do
Signal.list["KILL"].should == 9
end
end end

View File

@ -0,0 +1,11 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
describe "SizedQueue#<<" do
it_behaves_like :queue_enq, :<<, -> { SizedQueue.new(10) }
end
describe "SizedQueue#<<" do
it_behaves_like :sizedqueue_enq, :<<, ->(n) { SizedQueue.new(n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/clear'
describe "SizedQueue#clear" do
it_behaves_like :queue_clear, :clear, -> { SizedQueue.new(10) }
end

View File

@ -1,6 +1,5 @@
require_relative '../../../spec_helper' require_relative '../../spec_helper'
require 'thread' require_relative '../../shared/queue/close'
require_relative '../shared/queue/close'
describe "SizedQueue#close" do describe "SizedQueue#close" do
it_behaves_like :queue_close, :close, -> { SizedQueue.new(10) } it_behaves_like :queue_close, :close, -> { SizedQueue.new(10) }

View File

@ -1,6 +1,5 @@
require_relative '../../../spec_helper' require_relative '../../spec_helper'
require 'thread' require_relative '../../shared/queue/closed'
require_relative '../shared/queue/closed'
describe "SizedQueue#closed?" do describe "SizedQueue#closed?" do
it_behaves_like :queue_closed?, :closed?, -> { SizedQueue.new(10) } it_behaves_like :queue_closed?, :closed?, -> { SizedQueue.new(10) }

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "SizedQueue#deq" do
it_behaves_like :queue_deq, :deq, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/empty'
describe "SizedQueue#empty?" do
it_behaves_like :queue_empty?, :empty?, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,11 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
describe "SizedQueue#enq" do
it_behaves_like :queue_enq, :enq, -> { SizedQueue.new(10) }
end
describe "SizedQueue#enq" do
it_behaves_like :sizedqueue_enq, :enq, ->(n) { SizedQueue.new(n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/length'
describe "SizedQueue#length" do
it_behaves_like :queue_length, :length, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,10 @@
require_relative '../../spec_helper'
require_relative '../../shared/sizedqueue/max'
describe "SizedQueue#max" do
it_behaves_like :sizedqueue_max, :max, ->(n) { SizedQueue.new(n) }
end
describe "SizedQueue#max=" do
it_behaves_like :sizedqueue_max=, :max=, ->(n) { SizedQueue.new(n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/sizedqueue/new'
describe "SizedQueue.new" do
it_behaves_like :sizedqueue_new, :new, ->(*n) { SizedQueue.new(*n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/sizedqueue/num_waiting'
describe "SizedQueue#num_waiting" do
it_behaves_like :sizedqueue_num_waiting, :new, ->(n) { SizedQueue.new(n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "SizedQueue#pop" do
it_behaves_like :queue_deq, :pop, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,11 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/enque'
require_relative '../../shared/sizedqueue/enque'
describe "SizedQueue#push" do
it_behaves_like :queue_enq, :push, -> { SizedQueue.new(10) }
end
describe "SizedQueue#push" do
it_behaves_like :sizedqueue_enq, :push, ->(n) { SizedQueue.new(n) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/deque'
describe "SizedQueue#shift" do
it_behaves_like :queue_deq, :shift, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,6 @@
require_relative '../../spec_helper'
require_relative '../../shared/queue/length'
describe "SizedQueue#size" do
it_behaves_like :queue_length, :size, -> { SizedQueue.new(10) }
end

View File

@ -130,6 +130,17 @@ describe "Struct.new" do
it "fails with too many arguments" do it "fails with too many arguments" do
lambda { StructClasses::Ruby.new('2.0', 'i686', true) }.should raise_error(ArgumentError) lambda { StructClasses::Ruby.new('2.0', 'i686', true) }.should raise_error(ArgumentError)
end end
it "passes a hash as a normal argument" do
type = Struct.new(:args)
obj = type.new(keyword: :arg)
obj2 = type.new(*[{keyword: :arg}])
obj.should == obj2
obj.args.should == {keyword: :arg}
obj2.args.should == {keyword: :arg}
end
end end
ruby_version_is "2.5" do ruby_version_is "2.5" do
@ -163,6 +174,12 @@ describe "Struct.new" do
@struct_with_kwa.new("elefant", 4) @struct_with_kwa.new("elefant", 4)
}.should raise_error(ArgumentError, /wrong number of arguments/) }.should raise_error(ArgumentError, /wrong number of arguments/)
end end
it "raises ArgumentError when passed a single non-hash argument" do
-> {
@struct_with_kwa.new("elefant")
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
end end
end end

View File

@ -14,5 +14,29 @@ describe "Thread.exclusive" do
Thread.exclusive { :result }.should == :result Thread.exclusive { :result }.should == :result
end end
it "needs to be reviewed for spec completeness" it "blocks the caller if another thread is also in an exclusive block" do
m = Mutex.new
q1 = Queue.new
q2 = Queue.new
t = Thread.new {
Thread.exclusive {
q1.push :ready
q2.pop
}
}
q1.pop.should == :ready
lambda { Thread.exclusive { } }.should block_caller
q2.push :done
t.join
end
it "is not recursive" do
Thread.exclusive do
lambda { Thread.exclusive { } }.should raise_error(ThreadError)
end
end
end end

View File

@ -78,6 +78,30 @@ describe "Thread#raise on a sleeping thread" do
end end
-> { t.value }.should raise_error(RuntimeError) -> { t.value }.should raise_error(RuntimeError)
end end
it "re-raises a previously rescued exception without overwriting the backtrace" do
t = Thread.new do
-> { # To make sure there is at least one entry in the call stack
begin
sleep
rescue => e
e
end
}.call
end
ThreadSpecs.spin_until_sleeping(t)
begin
initial_raise_line = __LINE__; raise 'raised'
rescue => raised
raise_again_line = __LINE__; t.raise raised
raised_again = t.value
raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:")
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
end
end
end end
describe "Thread#raise on a running thread" do describe "Thread#raise on a running thread" do

View File

@ -24,4 +24,8 @@ describe "Time#nsec" do
it "returns the nanoseconds part of a Time constructed with an Rational number of microseconds" do it "returns the nanoseconds part of a Time constructed with an Rational number of microseconds" do
Time.at(0, Rational(99, 10)).nsec.should == 9900 Time.at(0, Rational(99, 10)).nsec.should == 9900
end end
it "returns a positive value for dates before the epoch" do
Time.utc(1969, 11, 12, 13, 18, 57, 404240).nsec.should == 404240000
end
end end

View File

@ -230,6 +230,10 @@ describe :time_params_microseconds, shared: true do
t.usec.should == 123 t.usec.should == 123
end end
it "raises an ArgumentError for out of range microsecond" do
lambda { Time.send(@method, 2000, 1, 1, 20, 15, 1, 1000000) }.should raise_error(ArgumentError)
end
it "handles fractional microseconds as a Float" do it "handles fractional microseconds as a Float" do
t = Time.send(@method, 2000, 1, 1, 20, 15, 1, 1.75) t = Time.send(@method, 2000, 1, 1, 20, 15, 1, 1.75)
t.usec.should == 1 t.usec.should == 1

View File

@ -36,4 +36,8 @@ describe "Time#usec" do
it "returns the microseconds for time created by Time#local" do it "returns the microseconds for time created by Time#local" do
Time.local(1,2,3,4,5,Rational(6.78)).usec.should == 780000 Time.local(1,2,3,4,5,Rational(6.78)).usec.should == 780000
end end
it "returns a positive value for dates before the epoch" do
Time.utc(1969, 11, 12, 13, 18, 57, 404240).usec.should == 404240
end
end end

View File

@ -8,6 +8,14 @@ describe "Warning.warn" do
}.should complain("Chunky bacon!") }.should complain("Chunky bacon!")
end end
it "does not add a newline" do
ruby_exe("Warning.warn('test')", args: "2>&1").should == "test"
end
it "returns nil" do
ruby_exe("p Warning.warn('test')", args: "2>&1").should == "testnil\n"
end
it "extends itself" do it "extends itself" do
Warning.singleton_class.ancestors.should include(Warning) Warning.singleton_class.ancestors.should include(Warning)
end end

View File

@ -79,6 +79,18 @@ describe "Defining a method" do
end end
end end
describe "An instance method" do
it "raises an error with too few arguments" do
def foo(a, b); end
lambda { foo 1 }.should raise_error(ArgumentError, 'wrong number of arguments (given 1, expected 2)')
end
it "raises an error with too many arguments" do
def foo(a); end
lambda { foo 1, 2 }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)')
end
end
describe "An instance method definition with a splat" do describe "An instance method definition with a splat" do
it "accepts an unnamed '*' argument" do it "accepts an unnamed '*' argument" do
def foo(*); end; def foo(*); end;
@ -106,7 +118,7 @@ describe "An instance method definition with a splat" do
it "requires the presence of any arguments that precede the *" do it "requires the presence of any arguments that precede the *" do
def foo(a, b, *c); end def foo(a, b, *c); end
lambda { foo 1 }.should raise_error(ArgumentError) lambda { foo 1 }.should raise_error(ArgumentError, 'wrong number of arguments (given 1, expected 2+)')
end end
end end
@ -139,7 +151,7 @@ describe "An instance method with a default argument" do
def foo(a, b = 2) def foo(a, b = 2)
[a,b] [a,b]
end end
lambda { foo }.should raise_error(ArgumentError) lambda { foo }.should raise_error(ArgumentError, 'wrong number of arguments (given 0, expected 1..2)')
foo(1).should == [1, 2] foo(1).should == [1, 2]
end end
@ -147,7 +159,7 @@ describe "An instance method with a default argument" do
def foo(a, b = 2, *c) def foo(a, b = 2, *c)
[a,b,c] [a,b,c]
end end
lambda { foo }.should raise_error(ArgumentError) lambda { foo }.should raise_error(ArgumentError, 'wrong number of arguments (given 0, expected 1+)')
foo(1).should == [1,2,[]] foo(1).should == [1,2,[]]
end end
@ -717,7 +729,7 @@ describe "a method definition that sets more than one default parameter all to t
end end
it "only allows overriding the default value of the first such parameter in each set" do it "only allows overriding the default value of the first such parameter in each set" do
lambda { foo(1,2) }.should raise_error(ArgumentError) lambda { foo(1,2) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 0..1)')
end end
def bar(a=b=c=1,d=2) def bar(a=b=c=1,d=2)
@ -728,7 +740,7 @@ describe "a method definition that sets more than one default parameter all to t
bar.should == [1,1,1,2] bar.should == [1,1,1,2]
bar(3).should == [3,nil,nil,2] bar(3).should == [3,nil,nil,2]
bar(3,4).should == [3,nil,nil,4] bar(3,4).should == [3,nil,nil,4]
lambda { bar(3,4,5) }.should raise_error(ArgumentError) lambda { bar(3,4,5) }.should raise_error(ArgumentError, 'wrong number of arguments (given 3, expected 0..2)')
end end
end end

View File

@ -1281,6 +1281,19 @@ describe "A method" do
result.should == [1, nil, nil, {foo: :bar}, nil, {}] result.should == [1, nil, nil, {foo: :bar}, nil, {}]
end end
end end
context "assigns keyword arguments from a passed Hash without modifying it" do
evaluate <<-ruby do
def m(a: nil); a; end
ruby
options = {a: 1}.freeze
lambda do
m(options).should == 1
end.should_not raise_error
options.should == {a: 1}
end
end
end end
describe "A method call with a space between method name and parentheses" do describe "A method call with a space between method name and parentheses" do

View File

@ -38,14 +38,9 @@ END
ruby_version_is "2.6" do ruby_version_is "2.6" do
it "warns invalid trim_mode" do it "warns invalid trim_mode" do
begin
$VERBOSE, verbose = false, $VERBOSE # Some other specs make $VERBOSE `nil`.
lambda do lambda do
ERBSpecs.new_erb(@eruby_str, trim_mode: '') ERBSpecs.new_erb(@eruby_str, trim_mode: '')
end.should output(nil, /Invalid ERB trim mode/) end.should complain(/Invalid ERB trim mode/)
ensure
$VERBOSE = verbose
end
end end
end end

View File

@ -14,6 +14,14 @@ describe "Set#initialize" do
s.should include(3) s.should include(3)
end end
it "should initialize with empty array and set" do
s = Set.new([])
s.size.should eql(0)
s = Set.new({})
s.size.should eql(0)
end
it "preprocesses all elements by a passed block before adding to self" do it "preprocesses all elements by a passed block before adding to self" do
s = Set.new([1, 2, 3]) { |x| x * x } s = Set.new([1, 2, 3]) { |x| x * x }
s.size.should eql(3) s.size.should eql(3)
@ -21,4 +29,20 @@ describe "Set#initialize" do
s.should include(4) s.should include(4)
s.should include(9) s.should include(9)
end end
it "should initialize with empty array and block" do
s = Set.new([]) { |x| x * x }
s.size.should eql(0)
end
it "should initialize with empty set and block" do
s = Set.new(Set.new) { |x| x * x }
s.size.should eql(0)
end
it "should initialize with just block" do
s = Set.new { |x| x * x }
s.size.should eql(0)
s.should eql(Set.new)
end
end end

View File

@ -99,7 +99,6 @@ describe 'Socket#connect_nonblock' do
end end
end end
platform_is_not :freebsd, :solaris do
describe 'using a STREAM socket' do describe 'using a STREAM socket' do
before do before do
@server = Socket.new(family, :STREAM) @server = Socket.new(family, :STREAM)
@ -112,6 +111,31 @@ describe 'Socket#connect_nonblock' do
@server.close @server.close
end end
platform_is_not :windows do
it 'raises Errno::EISCONN when already connected' do
@server.listen(1)
@client.connect(@server.getsockname).should == 0
lambda {
@client.connect_nonblock(@server.getsockname)
# A second call needed if non-blocking sockets become default
# XXX honestly I don't expect any real code to care about this spec
# as it's too implementation-dependent and checking for connect()
# errors is futile anyways because of TOCTOU
@client.connect_nonblock(@server.getsockname)
}.should raise_error(Errno::EISCONN)
end
it 'returns 0 when already connected in exceptionless mode' do
@server.listen(1)
@client.connect(@server.getsockname).should == 0
@client.connect_nonblock(@server.getsockname, exception: false).should == 0
end
end
platform_is_not :freebsd, :solaris do
it 'raises IO:EINPROGRESSWaitWritable when the connection would block' do it 'raises IO:EINPROGRESSWaitWritable when the connection would block' do
@server.bind(@sockaddr) @server.bind(@sockaddr)

View File

@ -41,6 +41,14 @@ describe "Tempfile.open" do
Tempfile.open(["specs", ".tt"]) { |tempfile| @tempfile = tempfile } Tempfile.open(["specs", ".tt"]) { |tempfile| @tempfile = tempfile }
@tempfile.path.should =~ /specs.*\.tt$/ @tempfile.path.should =~ /specs.*\.tt$/
end end
it "passes the third argument (options) to open" do
Tempfile.open("specs", Dir.tmpdir, encoding: "IBM037:IBM037", binmode: true) do |tempfile|
@tempfile = tempfile
tempfile.external_encoding.should == Encoding.find("IBM037")
tempfile.binmode?.should be_true
end
end
end end
describe "Tempfile.open when passed a block" do describe "Tempfile.open when passed a block" do

View File

@ -1,12 +0,0 @@
require_relative '../../spec_helper'
require 'thread'
describe "Thread.exclusive" do
before :each do
ScratchPad.clear
end
it "returns the result of yielding" do
Thread.exclusive { :result }.should == :result
end
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
describe "Thread::Queue#<<" do
it_behaves_like :queue_enq, :<<, -> { Queue.new }
end

View File

@ -1,9 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/clear'
describe "Thread::Queue#clear" do
it_behaves_like :queue_clear, :clear, -> { Queue.new }
# TODO: test for atomicity of Queue#clear
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/close'
describe "Queue#close" do
it_behaves_like :queue_close, :close, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/closed'
describe "Queue#closed?" do
it_behaves_like :queue_closed?, :closed?, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::Queue#deq" do
it_behaves_like :queue_deq, :deq, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/empty'
describe "Thread::Queue#empty?" do
it_behaves_like :queue_empty?, :empty?, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
describe "Thread::Queue#enq" do
it_behaves_like :queue_enq, :enq, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/length'
describe "Thread::Queue#length" do
it_behaves_like :queue_length, :length, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/num_waiting'
describe "Thread::Queue#num_waiting" do
it_behaves_like :queue_num_waiting, :num_waiting, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::Queue#pop" do
it_behaves_like :queue_deq, :pop, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
describe "Thread::Queue#push" do
it_behaves_like :queue_enq, :push, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::Queue#shift" do
it_behaves_like :queue_deq, :shift, -> { Queue.new }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/length'
describe "Thread::Queue#size" do
it_behaves_like :queue_length, :size, -> { Queue.new }
end

View File

@ -0,0 +1,8 @@
require_relative '../../spec_helper'
describe "Thread::Queue" do
it "is the same class as ::Queue" do
Thread.should have_constant(:Queue)
Thread::Queue.should equal ::Queue
end
end

View File

@ -1,26 +0,0 @@
describe :queue_close, shared: true do
it "closes the queue and returns nil for further #pop" do
q = @object.call
q << 1
q.close
q.pop.should == 1
q.pop.should == nil
q.pop.should == nil
end
it "prevents further #push" do
q = @object.call
q.close
lambda {
q << 1
}.should raise_error(ClosedQueueError)
end
it "may be called multiple times" do
q = @object.call
q.close
q.closed?.should be_true
q.close # no effect
q.closed?.should be_true
end
end

View File

@ -1,37 +0,0 @@
describe :queue_deq, shared: true do
it "removes an item from the Queue" do
q = @object.call
q << Object.new
q.size.should == 1
q.send(@method)
q.size.should == 0
end
it "returns items in the order they were added" do
q = @object.call
q << 1
q << 2
q.send(@method).should == 1
q.send(@method).should == 2
end
it "blocks the thread until there are items in the queue" do
q = @object.call
v = 0
th = Thread.new do
q.send(@method)
v = 1
end
v.should == 0
q << Object.new
th.join
v.should == 1
end
it "raises a ThreadError if Queue is empty" do
q = @object.call
lambda { q.send(@method,true) }.should raise_error(ThreadError)
end
end

View File

@ -1,10 +0,0 @@
describe :queue_enq, shared: true do
it "adds an element to the Queue" do
q = @object.call
q.size.should == 0
q.send(@method, Object.new)
q.size.should == 1
q.send(@method, Object.new)
q.size.should == 2
end
end

View File

@ -1,12 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
require_relative 'shared/enque'
describe "Thread::SizedQueue#<<" do
it_behaves_like :queue_enq, :<<, -> { SizedQueue.new(10) }
end
describe "Thread::SizedQueue#<<" do
it_behaves_like :sizedqueue_enq, :<<
end

View File

@ -1,9 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/clear'
describe "Thread::SizedQueue#clear" do
it_behaves_like :queue_clear, :clear, -> { SizedQueue.new(10) }
# TODO: test for atomicity of Queue#clear
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::SizedQueue#deq" do
it_behaves_like :queue_deq, :deq, -> { SizedQueue.new(10) }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/empty'
describe "Thread::SizedQueue#empty?" do
it_behaves_like :queue_empty?, :empty?, -> { SizedQueue.new(10) }
end

View File

@ -1,12 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
require_relative 'shared/enque'
describe "Thread::SizedQueue#enq" do
it_behaves_like :queue_enq, :enq, -> { SizedQueue.new(10) }
end
describe "Thread::SizedQueue#enq" do
it_behaves_like :sizedqueue_enq, :enq
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/length'
describe "Thread::SizedQueue#length" do
it_behaves_like :queue_length, :length, -> { SizedQueue.new(10) }
end

View File

@ -1,52 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
describe "Thread::SizedQueue#max" do
before :each do
@sized_queue = SizedQueue.new(5)
end
it "returns the size of the queue" do
@sized_queue.max.should == 5
end
end
describe "Thread::SizedQueue#max=" do
before :each do
@sized_queue = SizedQueue.new(5)
end
it "sets the size of the queue" do
@sized_queue.max.should == 5
@sized_queue.max = 10
@sized_queue.max.should == 10
end
it "does not remove items already in the queue beyond the maximum" do
@sized_queue.enq 1
@sized_queue.enq 2
@sized_queue.enq 3
@sized_queue.max = 2
(@sized_queue.size > @sized_queue.max).should be_true
@sized_queue.deq.should == 1
@sized_queue.deq.should == 2
@sized_queue.deq.should == 3
end
it "raises a TypeError when given a non-numeric value" do
lambda { @sized_queue.max = "foo" }.should raise_error(TypeError)
lambda { @sized_queue.max = Object.new }.should raise_error(TypeError)
end
it "raises an argument error when set to zero" do
@sized_queue.max.should == 5
lambda { @sized_queue.max = 0 }.should raise_error(ArgumentError)
@sized_queue.max.should == 5
end
it "raises an argument error when set to a negative number" do
@sized_queue.max.should == 5
lambda { @sized_queue.max = -1 }.should raise_error(ArgumentError)
@sized_queue.max.should == 5
end
end

View File

@ -1,25 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
describe "Thread::SizedQueue#new" do
it "returns a new SizedQueue" do
SizedQueue.new(1).should be_kind_of(SizedQueue)
end
it "raises a TypeError when the given argument is not Numeric" do
lambda { SizedQueue.new("foo") }.should raise_error(TypeError)
lambda { SizedQueue.new(Object.new) }.should raise_error(TypeError)
end
it "raises an argument error when no argument is given" do
lambda { SizedQueue.new }.should raise_error(ArgumentError)
end
it "raises an argument error when the given argument is zero" do
lambda { SizedQueue.new(0) }.should raise_error(ArgumentError)
end
it "raises an argument error when the given argument is negative" do
lambda { SizedQueue.new(-1) }.should raise_error(ArgumentError)
end
end

View File

@ -1,18 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/num_waiting'
describe "Thread::SizedQueue#num_waiting" do
it_behaves_like :queue_num_waiting, :num_waiting, -> { SizedQueue.new(10) }
it "reports the number of threads waiting to push" do
q = SizedQueue.new(1)
q.push(1)
t = Thread.new { q.push(2) }
sleep 0.05 until t.stop?
q.num_waiting.should == 1
q.pop
t.join
end
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::SizedQueue#pop" do
it_behaves_like :queue_deq, :pop, -> { SizedQueue.new(10) }
end

View File

@ -1,12 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/enque'
require_relative 'shared/enque'
describe "Thread::SizedQueue#push" do
it_behaves_like :queue_enq, :push, -> { SizedQueue.new(10) }
end
describe "Thread::SizedQueue#push" do
it_behaves_like :sizedqueue_enq, :push
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/deque'
describe "Thread::SizedQueue#shift" do
it_behaves_like :queue_deq, :shift, -> { SizedQueue.new(10) }
end

View File

@ -1,7 +0,0 @@
require_relative '../../../spec_helper'
require 'thread'
require_relative '../shared/queue/length'
describe "Thread::SizedQueue#size" do
it_behaves_like :queue_length, :size, -> { SizedQueue.new(10) }
end

View File

@ -0,0 +1,8 @@
require_relative '../../spec_helper'
describe "Thread::SizedQueue" do
it "is the same class as ::SizedQueue" do
Thread.should have_constant(:SizedQueue)
Thread::SizedQueue.should equal ::SizedQueue
end
end

View File

@ -17,7 +17,7 @@ platform_is :windows do
end end
it "raises WIN32OLERuntimeError if invalid string is given" do it "raises WIN32OLERuntimeError if invalid string is given" do
lambda { WIN32OLESpecs.new_ole('foo') }.should raise_error( WIN32OLERuntimeError ) lambda { WIN32OLE.new('foo') }.should raise_error( WIN32OLERuntimeError )
end end
end end

View File

@ -44,11 +44,11 @@ describe :kernel_raise, shared: true do
it "re-raises the previously rescued exception if no exception is specified" do it "re-raises the previously rescued exception if no exception is specified" do
lambda do lambda do
begin begin
raise Exception, "outer" @object.raise Exception, "outer"
ScratchPad.record :no_abort ScratchPad.record :no_abort
rescue rescue
begin begin
raise StandardError, "inner" @object.raise StandardError, "inner"
rescue rescue
end end
@ -62,16 +62,17 @@ describe :kernel_raise, shared: true do
it "re-raises a previously rescued exception without overwriting the backtrace" do it "re-raises a previously rescued exception without overwriting the backtrace" do
begin begin
raise 'raised' initial_raise_line = __LINE__; @object.raise 'raised'
rescue => raised rescue => raised
begin begin
raise_again_line = __LINE__; raise raised raise_again_line = __LINE__; @object.raise raised
rescue => raised_again rescue => raised_again
# This spec is written using #backtrace and matching the line number # This spec is written using #backtrace and matching the line number
# from the string, as backtrace_locations is a more advanced # from the string, as backtrace_locations is a more advanced
# method that is not always supported by implementations. # method that is not always supported by implementations.
raised_again.backtrace.first.should_not include(":#{raise_again_line}:") raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:")
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
end end
end end
end end

View File

@ -7,4 +7,6 @@ describe :queue_clear, shared: true do
queue.clear queue.clear
queue.empty?.should be_true queue.empty?.should be_true
end end
# TODO: test for atomicity of Queue#clear
end end

View File

@ -0,0 +1,14 @@
describe :queue_close, shared: true do
it "may be called multiple times" do
q = @object.call
q.close
q.closed?.should be_true
q.close # no effect
q.closed?.should be_true
end
it "returns self" do
q = @object.call
q.close.should == q
end
end

View File

@ -0,0 +1,85 @@
describe :queue_deq, shared: true do
it "removes an item from the queue" do
q = @object.call
q << Object.new
q.size.should == 1
q.send @method
q.size.should == 0
end
it "returns items in the order they were added" do
q = @object.call
q << 1
q << 2
q.send(@method).should == 1
q.send(@method).should == 2
end
it "blocks the thread until there are items in the queue" do
q = @object.call
v = 0
th = Thread.new do
q.send(@method)
v = 1
end
v.should == 0
q << Object.new
th.join
v.should == 1
end
it "removes an item from a closed queue" do
q = @object.call
q << 1
q.close
q.send(@method).should == 1
end
it "returns nil for a closed empty queue" do
q = @object.call
q.close
q.send(@method).should == nil
end
it "returns nil for an empty queue that becomes closed" do
q = @object.call
t = Thread.new {
q.send(@method).should == nil
}
Thread.pass until t.status == "sleep" && q.num_waiting == 1
q.close
t.join
end
describe "in non-blocking mode" do
it "removes an item from the queue" do
q = @object.call
q << Object.new
q.size.should == 1
q.send(@method, true)
q.size.should == 0
end
it "raises a ThreadError if the queue is empty" do
q = @object.call
lambda { q.send(@method, true) }.should raise_error(ThreadError)
end
it "removes an item from a closed queue" do
q = @object.call
q << 1
q.close
q.send(@method, true).should == 1
end
it "raises a ThreadError for a closed empty queue" do
q = @object.call
q.close
lambda { q.send(@method, true) }.should raise_error(ThreadError)
end
end
end

View File

@ -0,0 +1,18 @@
describe :queue_enq, shared: true do
it "adds an element to the Queue" do
q = @object.call
q.size.should == 0
q.send @method, Object.new
q.size.should == 1
q.send @method, Object.new
q.size.should == 2
end
it "is an error for a closed queue" do
q = @object.call
q.close
lambda {
q.send @method, Object.new
}.should raise_error(ClosedQueueError)
end
end

View File

@ -1,6 +1,6 @@
describe :sizedqueue_enq, shared: true do describe :sizedqueue_enq, shared: true do
it "blocks if queued elements exceed size" do it "blocks if queued elements exceed size" do
q = SizedQueue.new(1) q = @object.call(1)
q.size.should == 0 q.size.should == 0
q.send(@method, :first_element) q.send(@method, :first_element)
@ -19,7 +19,7 @@ describe :sizedqueue_enq, shared: true do
end end
it "raises a ThreadError if queued elements exceed size when not blocking" do it "raises a ThreadError if queued elements exceed size when not blocking" do
q = SizedQueue.new(2) q = @object.call(2)
non_blocking = true non_blocking = true
add_to_queue = lambda { q.send(@method, Object.new, non_blocking) } add_to_queue = lambda { q.send(@method, Object.new, non_blocking) }
@ -31,4 +31,20 @@ describe :sizedqueue_enq, shared: true do
q.size.should == 2 q.size.should == 2
add_to_queue.should raise_error(ThreadError) add_to_queue.should raise_error(ThreadError)
end end
it "interrupts enqueuing threads with ClosedQueueError when the queue is closed" do
q = @object.call(1)
q << 1
t = Thread.new {
lambda { q.send(@method, 2) }.should raise_error(ClosedQueueError)
}
Thread.pass until q.num_waiting == 1
q.close
t.join
q.pop.should == 1
end
end end

View File

@ -0,0 +1,47 @@
describe :sizedqueue_max, shared: true do
it "returns the size of the queue" do
q = @object.call(5)
q.max.should == 5
end
end
describe :sizedqueue_max=, shared: true do
it "sets the size of the queue" do
q = @object.call(5)
q.max.should == 5
q.max = 10
q.max.should == 10
end
it "does not remove items already in the queue beyond the maximum" do
q = @object.call(5)
q.enq 1
q.enq 2
q.enq 3
q.max = 2
(q.size > q.max).should be_true
q.deq.should == 1
q.deq.should == 2
q.deq.should == 3
end
it "raises a TypeError when given a non-numeric value" do
q = @object.call(5)
lambda { q.max = "foo" }.should raise_error(TypeError)
lambda { q.max = Object.new }.should raise_error(TypeError)
end
it "raises an argument error when set to zero" do
q = @object.call(5)
q.max.should == 5
lambda { q.max = 0 }.should raise_error(ArgumentError)
q.max.should == 5
end
it "raises an argument error when set to a negative number" do
q = @object.call(5)
q.max.should == 5
lambda { q.max = -1 }.should raise_error(ArgumentError)
q.max.should == 5
end
end

Some files were not shown because too many files have changed in this diff Show More