From 36dde35e029c7a6607e6c674062ce6fc7a51c0bd Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Sat, 27 Feb 2021 13:00:26 +0100 Subject: Update to ruby/spec@37e52e5 --- spec/ruby/core/array/drop_spec.rb | 13 +++++ spec/ruby/core/array/drop_while_spec.rb | 13 +++++ spec/ruby/core/array/slice_spec.rb | 58 +++++++++++++++++++++ spec/ruby/core/array/take_spec.rb | 13 +++++ spec/ruby/core/array/take_while_spec.rb | 13 +++++ .../basicobject/singleton_method_added_spec.rb | 59 ++++++++++++++++++++++ spec/ruby/core/dir/children_spec.rb | 14 +++-- spec/ruby/core/dir/each_child_spec.rb | 12 +++++ spec/ruby/core/dir/entries_spec.rb | 13 +++-- spec/ruby/core/dir/foreach_spec.rb | 12 +++++ spec/ruby/core/enumerator/lazy/chunk_while_spec.rb | 5 ++ spec/ruby/core/enumerator/lazy/slice_after_spec.rb | 5 ++ .../ruby/core/enumerator/lazy/slice_before_spec.rb | 5 ++ spec/ruby/core/enumerator/lazy/slice_when_spec.rb | 5 ++ spec/ruby/core/env/except_spec.rb | 36 +++++++++++++ spec/ruby/core/io/close_spec.rb | 43 +++++++++++----- spec/ruby/core/io/fixtures/classes.rb | 3 ++ spec/ruby/core/kernel/fixtures/classes.rb | 17 ++++--- spec/ruby/core/kernel/public_send_spec.rb | 8 +++ spec/ruby/core/kernel/shared/method.rb | 8 ++- spec/ruby/core/kernel/shared/require.rb | 8 ++- spec/ruby/core/main/ruby2_keywords_spec.rb | 11 ++++ spec/ruby/core/module/attr_accessor_spec.rb | 15 +++++- spec/ruby/core/module/attr_writer_spec.rb | 12 ++++- spec/ruby/core/module/const_defined_spec.rb | 5 ++ spec/ruby/core/module/const_get_spec.rb | 8 +++ spec/ruby/core/module/refine_spec.rb | 39 +++++++++++++- spec/ruby/core/proc/shared/call.rb | 3 ++ spec/ruby/core/regexp/case_compare_spec.rb | 10 ++++ spec/ruby/core/signal/trap_spec.rb | 14 +++++ spec/ruby/core/string/scrub_spec.rb | 14 +++++ spec/ruby/core/time/shared/now.rb | 12 ++--- 32 files changed, 467 insertions(+), 39 deletions(-) create mode 100644 spec/ruby/core/env/except_spec.rb create mode 100644 spec/ruby/core/main/ruby2_keywords_spec.rb (limited to 'spec/ruby/core') diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb index 84ea86b04c..f911fd9018 100644 --- a/spec/ruby/core/array/drop_spec.rb +++ b/spec/ruby/core/array/drop_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "Array#drop" do it "removes the specified number of elements from the start of the array" do @@ -48,4 +49,16 @@ describe "Array#drop" do -> { [1, 2].drop(obj) }.should raise_error(TypeError) end + + ruby_version_is ''...'3.0' do + it 'returns a subclass instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(ArraySpecs::MyArray) + end + end + + ruby_version_is '3.0' do + it 'returns a Array instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(Array) + end + end end diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb index cfb6b1e267..bb783d22a5 100644 --- a/spec/ruby/core/array/drop_while_spec.rb +++ b/spec/ruby/core/array/drop_while_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "Array#drop_while" do it "removes elements from the start of the array while the block evaluates to true" do @@ -12,4 +13,16 @@ describe "Array#drop_while" do it "removes elements from the start of the array until the block returns false" do [1, 2, 3, false, 5].drop_while { |n| n }.should == [false, 5] end + + ruby_version_is ''...'3.0' do + it 'returns a subclass instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray) + end + end + + ruby_version_is '3.0' do + it 'returns a Array instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(Array) + end + end end diff --git a/spec/ruby/core/array/slice_spec.rb b/spec/ruby/core/array/slice_spec.rb index f416d8d0ce..2f98df9488 100644 --- a/spec/ruby/core/array/slice_spec.rb +++ b/spec/ruby/core/array/slice_spec.rb @@ -185,6 +185,64 @@ describe "Array#slice!" do a.should == [3, 4] end end + + describe "with a subclass of Array" do + before :each do + @array = ArraySpecs::MyArray[1, 2, 3, 4, 5] + end + + ruby_version_is ''...'3.0' do + it "returns a subclass instance with [n, m]" do + @array.slice!(0, 2).should be_an_instance_of(ArraySpecs::MyArray) + end + + it "returns a subclass instance with [-n, m]" do + @array.slice!(-3, 2).should be_an_instance_of(ArraySpecs::MyArray) + end + + it "returns a subclass instance with [n..m]" do + @array.slice!(1..3).should be_an_instance_of(ArraySpecs::MyArray) + end + + it "returns a subclass instance with [n...m]" do + @array.slice!(1...3).should be_an_instance_of(ArraySpecs::MyArray) + end + + it "returns a subclass instance with [-n..-m]" do + @array.slice!(-3..-1).should be_an_instance_of(ArraySpecs::MyArray) + end + + it "returns a subclass instance with [-n...-m]" do + @array.slice!(-3...-1).should be_an_instance_of(ArraySpecs::MyArray) + end + end + + ruby_version_is '3.0' do + it "returns a Array instance with [n, m]" do + @array.slice!(0, 2).should be_an_instance_of(Array) + end + + it "returns a Array instance with [-n, m]" do + @array.slice!(-3, 2).should be_an_instance_of(Array) + end + + it "returns a Array instance with [n..m]" do + @array.slice!(1..3).should be_an_instance_of(Array) + end + + it "returns a Array instance with [n...m]" do + @array.slice!(1...3).should be_an_instance_of(Array) + end + + it "returns a Array instance with [-n..-m]" do + @array.slice!(-3..-1).should be_an_instance_of(Array) + end + + it "returns a Array instance with [-n...-m]" do + @array.slice!(-3...-1).should be_an_instance_of(Array) + end + end + end end describe "Array#slice" do diff --git a/spec/ruby/core/array/take_spec.rb b/spec/ruby/core/array/take_spec.rb index 0de99b0a7e..4fb6f0ce75 100644 --- a/spec/ruby/core/array/take_spec.rb +++ b/spec/ruby/core/array/take_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "Array#take" do it "returns the first specified number of elements" do @@ -24,4 +25,16 @@ describe "Array#take" do it "raises an ArgumentError when the argument is negative" do ->{ [1].take(-3) }.should raise_error(ArgumentError) end + + ruby_version_is ''...'3.0' do + it 'returns a subclass instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(ArraySpecs::MyArray) + end + end + + ruby_version_is '3.0' do + it 'returns a Array instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(Array) + end + end end diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb index f159e6f251..363419b265 100644 --- a/spec/ruby/core/array/take_while_spec.rb +++ b/spec/ruby/core/array/take_while_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative 'fixtures/classes' describe "Array#take_while" do it "returns all elements until the block returns false" do @@ -12,4 +13,16 @@ describe "Array#take_while" do it "returns all elements until the block returns false" do [1, 2, false, 4].take_while{ |element| element }.should == [1, 2] end + + ruby_version_is ''...'3.0' do + it 'returns a subclass instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray) + end + end + + ruby_version_is '3.0' do + it 'returns a Array instance for Array subclasses' do + ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(Array) + end + end end diff --git a/spec/ruby/core/basicobject/singleton_method_added_spec.rb b/spec/ruby/core/basicobject/singleton_method_added_spec.rb index 8d256e22db..ab6b2a2d10 100644 --- a/spec/ruby/core/basicobject/singleton_method_added_spec.rb +++ b/spec/ruby/core/basicobject/singleton_method_added_spec.rb @@ -83,4 +83,63 @@ describe "BasicObject#singleton_method_added" do end ScratchPad.recorded.should == [:singleton_method_added, :new_method_with_define_method] end + + describe "when singleton_method_added is undefined" do + it "raises NoMethodError for a metaclass" do + class BasicObjectSpecs::NoSingletonMethodAdded + class << self + undef_method :singleton_method_added + end + + -> { + def self.foo + end + }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for/) + end + end + + it "raises NoMethodError for a singleton instance" do + object = Object.new + class << object + undef_method :singleton_method_added + + -> { + def foo + end + }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for # { + define_method(:bar) {} + }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for # { + object.define_singleton_method(:baz) {} + }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for # '2' } + end + + it "ignores keys not present in the original hash" do + ENV.clear + + ENV['one'] = '1' + ENV['two'] = '2' + + ENV.except('one', 'three').should == { 'two' => '2' } + end + end +end diff --git a/spec/ruby/core/io/close_spec.rb b/spec/ruby/core/io/close_spec.rb index dda82b34de..eb560eaf67 100644 --- a/spec/ruby/core/io/close_spec.rb +++ b/spec/ruby/core/io/close_spec.rb @@ -45,19 +45,36 @@ describe "IO#close" do end it 'raises an IOError with a clear message' do - read_io, write_io = IO.pipe - going_to_read = false - thread = Thread.new do - -> do - going_to_read = true - read_io.read - end.should raise_error(IOError, 'stream closed in another thread') - end - - Thread.pass until going_to_read && thread.stop? - read_io.close - thread.join - write_io.close + matching_exception = nil + + -> do + IOSpecs::THREAD_CLOSE_RETRIES.times do + read_io, write_io = IO.pipe + going_to_read = false + + thread = Thread.new do + begin + going_to_read = true + read_io.read + rescue IOError => ioe + if ioe.message == IOSpecs::THREAD_CLOSE_ERROR_MESSAGE + matching_exception = ioe + end + # try again + end + end + + # best attempt to ensure the thread is actually blocked on read + Thread.pass until going_to_read && thread.stop? + sleep(0.001) + + read_io.close + thread.join + write_io.close + + matching_exception&.tap {|ex| raise ex} + end + end.should raise_error(IOError, IOSpecs::THREAD_CLOSE_ERROR_MESSAGE) end end diff --git a/spec/ruby/core/io/fixtures/classes.rb b/spec/ruby/core/io/fixtures/classes.rb index 5cc42c9b44..5d81d5fcd9 100644 --- a/spec/ruby/core/io/fixtures/classes.rb +++ b/spec/ruby/core/io/fixtures/classes.rb @@ -1,6 +1,9 @@ # -*- encoding: utf-8 -*- module IOSpecs + THREAD_CLOSE_RETRIES = 10 + THREAD_CLOSE_ERROR_MESSAGE = 'stream closed in another thread' + class SubIO < IO end diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb index 8702c925c8..1bf5715c50 100644 --- a/spec/ruby/core/kernel/fixtures/classes.rb +++ b/spec/ruby/core/kernel/fixtures/classes.rb @@ -362,18 +362,19 @@ module KernelSpecs class RespondViaMissing def respond_to_missing?(method, priv=false) case method - when :handled_publicly - true - when :handled_privately - priv - when :not_handled - false - else - raise "Typo in method name" + when :handled_publicly + true + when :handled_privately + priv + when :not_handled + false + else + raise "Typo in method name: #{method.inspect}" end end def method_missing(method, *args) + raise "the method name should be a Symbol" unless Symbol === method "Done #{method}(#{args})" end end diff --git a/spec/ruby/core/kernel/public_send_spec.rb b/spec/ruby/core/kernel/public_send_spec.rb index 6b942a2e4b..4dae419ff9 100644 --- a/spec/ruby/core/kernel/public_send_spec.rb +++ b/spec/ruby/core/kernel/public_send_spec.rb @@ -104,5 +104,13 @@ describe "Kernel#public_send" do }.should raise_error(NoMethodError) end + it "includes `public_send` in the backtrace when passed not enough arguments" do + -> { public_send() }.should raise_error(ArgumentError) { |e| e.backtrace[0].should.include?("`public_send'") } + end + + it "includes `public_send` in the backtrace when passed a single incorrect argument" do + -> { public_send(Object.new) }.should raise_error(TypeError) { |e| e.backtrace[0].should.include?("`public_send'") } + end + it_behaves_like :basicobject_send, :public_send end diff --git a/spec/ruby/core/kernel/shared/method.rb b/spec/ruby/core/kernel/shared/method.rb index 3418966b1b..8b6ab23fd3 100644 --- a/spec/ruby/core/kernel/shared/method.rb +++ b/spec/ruby/core/kernel/shared/method.rb @@ -15,12 +15,18 @@ describe :kernel_method, shared: true do m.call.should == 'class done' end - it "returns a method object if we repond_to_missing? method" do + it "returns a method object if respond_to_missing?(method) is true" do m = KernelSpecs::RespondViaMissing.new.send(@method, :handled_publicly) m.should be_an_instance_of Method m.call(42).should == "Done handled_publicly([42])" end + it "the returned method object if respond_to_missing?(method) calls #method_missing with a Symbol name" do + m = KernelSpecs::RespondViaMissing.new.send(@method, "handled_publicly") + m.should be_an_instance_of Method + m.call(42).should == "Done handled_publicly([42])" + end + it "raises a NameError for an invalid method name" do class KernelSpecs::Foo; def bar; 'done'; end; end -> { diff --git a/spec/ruby/core/kernel/shared/require.rb b/spec/ruby/core/kernel/shared/require.rb index d656b3b2f2..9a2c38be1a 100644 --- a/spec/ruby/core/kernel/shared/require.rb +++ b/spec/ruby/core/kernel/shared/require.rb @@ -546,8 +546,12 @@ describe :kernel_require, shared: true do ScratchPad.recorded.should == [] end - it "complex, enumerator, rational and thread are already required" do - provided = %w[complex enumerator rational thread] + provided = %w[complex enumerator rational thread] + ruby_version_is "2.7" do + provided << 'ruby2_keywords' + end + + it "#{provided.join(', ')} are already required" do features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems') provided.each { |feature| features.should =~ /\b#{feature}\.(rb|so|jar)$/ diff --git a/spec/ruby/core/main/ruby2_keywords_spec.rb b/spec/ruby/core/main/ruby2_keywords_spec.rb new file mode 100644 index 0000000000..0999cddeed --- /dev/null +++ b/spec/ruby/core/main/ruby2_keywords_spec.rb @@ -0,0 +1,11 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "2.7" do + describe "main.ruby2_keywords" do + it "is the same as Object.ruby2_keywords" do + main = TOPLEVEL_BINDING.receiver + main.should have_private_method(:ruby2_keywords) + end + end +end diff --git a/spec/ruby/core/module/attr_accessor_spec.rb b/spec/ruby/core/module/attr_accessor_spec.rb index e6a6ac7b66..ba5289cbea 100644 --- a/spec/ruby/core/module/attr_accessor_spec.rb +++ b/spec/ruby/core/module/attr_accessor_spec.rb @@ -33,7 +33,20 @@ describe "Module#attr_accessor" do attr_accessor :spec_attr_accessor end - -> { true.spec_attr_accessor = "a" }.should raise_error(RuntimeError) + -> { true.spec_attr_accessor = "a" }.should raise_error(FrozenError) + end + + it "raises FrozenError if the receiver if frozen" do + c = Class.new do + attr_accessor :foo + end + obj = c.new + obj.foo = 1 + obj.foo.should == 1 + + obj.freeze + -> { obj.foo = 42 }.should raise_error(FrozenError) + obj.foo.should == 1 end it "converts non string/symbol names to strings using to_str" do diff --git a/spec/ruby/core/module/attr_writer_spec.rb b/spec/ruby/core/module/attr_writer_spec.rb index dbf30c8144..0e9d201317 100644 --- a/spec/ruby/core/module/attr_writer_spec.rb +++ b/spec/ruby/core/module/attr_writer_spec.rb @@ -29,7 +29,17 @@ describe "Module#attr_writer" do attr_writer :spec_attr_writer end - -> { true.spec_attr_writer = "a" }.should raise_error(RuntimeError) + -> { true.spec_attr_writer = "a" }.should raise_error(FrozenError) + end + + it "raises FrozenError if the receiver if frozen" do + c = Class.new do + attr_writer :foo + end + obj = c.new + obj.freeze + + -> { obj.foo = 42 }.should raise_error(FrozenError) end it "converts non string/symbol names to strings using to_str" do diff --git a/spec/ruby/core/module/const_defined_spec.rb b/spec/ruby/core/module/const_defined_spec.rb index 0673adca3d..75730395e8 100644 --- a/spec/ruby/core/module/const_defined_spec.rb +++ b/spec/ruby/core/module/const_defined_spec.rb @@ -40,6 +40,11 @@ describe "Module#const_defined?" do ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, true).should be_true end + it "coerces the inherit flag to a boolean" do + ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, nil).should be_false + ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, :true).should be_true + end + it "returns true if the given String names a constant defined in the receiver" do ConstantSpecs.const_defined?("CS_CONST2").should == true ConstantSpecs.const_defined?("ModuleA").should == true diff --git a/spec/ruby/core/module/const_get_spec.rb b/spec/ruby/core/module/const_get_spec.rb index 0a6702903f..9f9fafe5bb 100644 --- a/spec/ruby/core/module/const_get_spec.rb +++ b/spec/ruby/core/module/const_get_spec.rb @@ -88,6 +88,14 @@ describe "Module#const_get" do end.should raise_error(NameError) end + it "coerces the inherit flag to a boolean" do + ConstantSpecs::ContainerA::ChildA.const_get(:CS_CONST4, :true).should == :const4 + + -> do + ConstantSpecs::ContainerA::ChildA.const_get(:CS_CONST1, nil) + end.should raise_error(NameError) + end + it "accepts a toplevel scope qualifier" do ConstantSpecs.const_get("::CS_CONST1").should == :const1 end diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index 54217a9326..e5f65f5f96 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -573,6 +573,43 @@ describe "Module#refine" do end end + ruby_version_is "" ... "2.7" do + it "is not honored by Kernel#public_method" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end + end + end + + -> { + Module.new do + using refinement + klass.new.public_method(:foo) + end + }.should raise_error(NameError, /undefined method `foo'/) + end + end + + ruby_version_is "2.7" do + it "is honored by Kernel#public_method" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end + end + end + + result = nil + Module.new do + using refinement + result = klass.new.public_method(:foo).class + end + + result.should == Method + end + end + ruby_version_is "" ... "2.7" do it "is not honored by Kernel#instance_method" do klass = Class.new @@ -592,7 +629,7 @@ describe "Module#refine" do end ruby_version_is "2.7" do - it "is honored by Kernel#method" do + it "is honored by Kernel#instance_method" do klass = Class.new refinement = Module.new do refine klass do diff --git a/spec/ruby/core/proc/shared/call.rb b/spec/ruby/core/proc/shared/call.rb index c30ea84b23..dbec34df4b 100644 --- a/spec/ruby/core/proc/shared/call.rb +++ b/spec/ruby/core/proc/shared/call.rb @@ -49,6 +49,9 @@ describe :proc_call_on_proc_or_lambda, shared: true do a = proc {|x| x}.send(@method, 1, 2, 3) a.should == 1 + + a = proc {|x:| x}.send(@method, 2, x: 1) + a.should == 1 end it "will call #to_ary on argument and return self if return is nil" do diff --git a/spec/ruby/core/regexp/case_compare_spec.rb b/spec/ruby/core/regexp/case_compare_spec.rb index a621713f6f..5ae8b56c6a 100644 --- a/spec/ruby/core/regexp/case_compare_spec.rb +++ b/spec/ruby/core/regexp/case_compare_spec.rb @@ -22,4 +22,14 @@ describe "Regexp#===" do (/abc/ === nil).should be_false (/abc/ === /abc/).should be_false end + + it "uses #to_str on string-like objects" do + stringlike = Class.new do + def to_str + "abc" + end + end.new + + (/abc/ === stringlike).should be_true + end end diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb index 831a5ee23e..45879b7147 100644 --- a/spec/ruby/core/signal/trap_spec.rb +++ b/spec/ruby/core/signal/trap_spec.rb @@ -49,7 +49,21 @@ platform_is_not :windows do it "registers an handler doing nothing with :IGNORE" do Signal.trap :HUP, :IGNORE + Signal.trap(:HUP, @saved_trap).should == "IGNORE" + end + + it "can register a new handler after :IGNORE" do + Signal.trap :HUP, :IGNORE + + done = false + Signal.trap(:HUP) do + ScratchPad.record :block_trap + done = true + end + Process.kill(:HUP, Process.pid).should == 1 + Thread.pass until done + ScratchPad.recorded.should == :block_trap end it "ignores the signal when passed nil" do diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb index 86fd4e85ba..b513acfb70 100644 --- a/spec/ruby/core/string/scrub_spec.rb +++ b/spec/ruby/core/string/scrub_spec.rb @@ -105,4 +105,18 @@ describe "String#scrub!" do input.scrub! { |b| "" } input.should == "a" end + + it "maintains the state of frozen strings that are already valid" do + input = "a" + input.freeze + input.scrub! + input.frozen?.should be_true + end + + it "preserves the instance variables of already valid strings" do + input = "a" + input.instance_variable_set(:@a, 'b') + input.scrub! + input.instance_variable_get(:@a).should == 'b' + end end diff --git a/spec/ruby/core/time/shared/now.rb b/spec/ruby/core/time/shared/now.rb index 80f66a1134..f4018d72f4 100644 --- a/spec/ruby/core/time/shared/now.rb +++ b/spec/ruby/core/time/shared/now.rb @@ -19,15 +19,15 @@ describe :time_now, shared: true do end it "has at least microsecond precision" do - times = [] - 10_000.times do - times << Time.now.nsec - end - # The clock should not be less accurate than expected (times should # not all be a multiple of the next precision up, assuming precisions # are multiples of ten.) expected = 1_000 - times.select { |t| t % (expected * 10) == 0 }.size.should_not == times.size + t = 0 + 10_000.times.find do + t = Time.now.nsec + t % (expected * 10) != 0 + end + (t % (expected * 10)).should != 0 end end -- cgit v1.2.3