diff options
author | Benoit Daloze <[email protected]> | 2021-01-28 17:08:57 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2021-01-28 17:08:57 +0100 |
commit | 2e32b919b4f2f5b7f2e1509d6fa985526ef1f61c (patch) | |
tree | aedadac3c99ca0097c2bbeaa95830332d6fb9971 /spec/ruby/core | |
parent | 1b377b32c8616f85c0a97e68758c5c2db83f2169 (diff) |
Update to ruby/spec@8cafaa5
Diffstat (limited to 'spec/ruby/core')
21 files changed, 572 insertions, 6 deletions
diff --git a/spec/ruby/core/integer/digits_spec.rb b/spec/ruby/core/integer/digits_spec.rb index 4a8e33980c..3d0a64c25f 100644 --- a/spec/ruby/core/integer/digits_spec.rb +++ b/spec/ruby/core/integer/digits_spec.rb @@ -29,4 +29,13 @@ describe "Integer#digits" do it "raises Math::DomainError when calling digits on a negative number" do -> { -12345.digits(7) }.should raise_error(Math::DomainError) end + + it "returns integer values > 9 when base is above 10" do + 1234.digits(16).should == [2, 13, 4] + end + + it "can be used with base > 37" do + 1234.digits(100).should == [34, 12] + 980099.digits(100).should == [99, 0, 98] + end end diff --git a/spec/ruby/core/kernel/caller_locations_spec.rb b/spec/ruby/core/kernel/caller_locations_spec.rb index 8050b5b3ab..bbb7e7b737 100644 --- a/spec/ruby/core/kernel/caller_locations_spec.rb +++ b/spec/ruby/core/kernel/caller_locations_spec.rb @@ -36,6 +36,14 @@ describe 'Kernel#caller_locations' do end end + ruby_version_is "2.7" do + it "works with beginless ranges" do + locations1 = caller_locations(0) + locations2 = caller_locations(eval("(...5)")) + locations2.map(&:to_s)[eval("(2..)")].should == locations1[eval("(...5)")].map(&:to_s)[eval("(2..)")] + end + end + it "can be called with a range whose end is negative" do locations1 = caller_locations(0) locations2 = caller_locations(2..-1) diff --git a/spec/ruby/core/kernel/caller_spec.rb b/spec/ruby/core/kernel/caller_spec.rb index 06e9ea6fc8..6c175868cb 100644 --- a/spec/ruby/core/kernel/caller_spec.rb +++ b/spec/ruby/core/kernel/caller_spec.rb @@ -52,6 +52,14 @@ describe 'Kernel#caller' do end end + ruby_version_is "2.7" do + it "works with beginless ranges" do + locations1 = KernelSpecs::CallerTest.locations(0) + locations2 = KernelSpecs::CallerTest.locations(eval("(..5)")) + locations2.map(&:to_s)[eval("(2..)")].should == locations1[eval("(..5)")].map(&:to_s)[eval("(2..)")] + end + end + guard -> { Kernel.instance_method(:tap).source_location } do it "includes core library methods defined in Ruby" do file, line = Kernel.instance_method(:tap).source_location diff --git a/spec/ruby/core/kernel/lambda_spec.rb b/spec/ruby/core/kernel/lambda_spec.rb index 4dd34c6ca9..9a960f3589 100644 --- a/spec/ruby/core/kernel/lambda_spec.rb +++ b/spec/ruby/core/kernel/lambda_spec.rb @@ -123,4 +123,16 @@ describe "Kernel.lambda" do it "allows long returns to flow through it" do KernelSpecs::Lambda.new.outer.should == :good end + + it "treats the block as a Proc when lambda is re-defined" do + klass = Class.new do + def lambda (&block); block; end + def ret + lambda { return 1 }.call + 2 + end + end + klass.new.lambda { 42 }.should be_an_instance_of Proc + klass.new.ret.should == 1 + end end diff --git a/spec/ruby/core/kernel/rand_spec.rb b/spec/ruby/core/kernel/rand_spec.rb index a82b4fba74..481189d969 100644 --- a/spec/ruby/core/kernel/rand_spec.rb +++ b/spec/ruby/core/kernel/rand_spec.rb @@ -117,6 +117,48 @@ describe "Kernel.rand" do end end + context "given an inclusive range between 0 and 1" do + it "returns an Integer between the two Integers" do + x = rand(0..1) + x.should be_kind_of(Integer) + (0..1).should include(x) + end + + it "returns a Float if at least one side is Float" do + seed = 42 + x1 = Random.new(seed).rand(0..1.0) + x2 = Random.new(seed).rand(0.0..1.0) + x3 = Random.new(seed).rand(0.0..1) + + x3.should be_kind_of(Float) + x1.should equal(x3) + x2.should equal(x3) + + (0.0..1.0).should include(x3) + end + end + + context "given an exclusive range between 0 and 1" do + it "returns zero as an Integer" do + x = rand(0...1) + x.should be_kind_of(Integer) + x.should eql(0) + end + + it "returns a Float if at least one side is Float" do + seed = 42 + x1 = Random.new(seed).rand(0...1.0) + x2 = Random.new(seed).rand(0.0...1.0) + x3 = Random.new(seed).rand(0.0...1) + + x3.should be_kind_of(Float) + x1.should equal(x3) + x2.should equal(x3) + + (0.0...1.0).should include(x3) + end + end + it "returns a numeric for an range argument where max is < 1" do rand(0.25..0.75).should be_kind_of(Numeric) end diff --git a/spec/ruby/core/module/ruby2_keywords_spec.rb b/spec/ruby/core/module/ruby2_keywords_spec.rb new file mode 100644 index 0000000000..34c45cb1bc --- /dev/null +++ b/spec/ruby/core/module/ruby2_keywords_spec.rb @@ -0,0 +1,112 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "2.7" do + describe "Module#ruby2_keywords" do + it "marks the final hash argument as keyword hash" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) a.last end + ruby2_keywords :foo + end + + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + + ruby_version_is "2.7" ... "3.0" do + it "fixes delegation warnings when calling a method accepting keywords" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) bar(*a) end + def bar(*a, **b) end + end + + -> { obj.foo(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + + -> { obj.foo(1, 2, {a: "a"}) }.should_not complain + end + end + + it "returns nil" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) end + + ruby2_keywords(:foo).should == nil + end + end + + it "raises NameError when passed not existing method name" do + obj = Object.new + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :not_existing + end + }.should raise_error(NameError, /undefined method `not_existing'/) + end + + it "acceps String as well" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) a.last end + ruby2_keywords "foo" + end + + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + + it "raises TypeError when passed not Symbol or String" do + obj = Object.new + + -> { + obj.singleton_class.class_exec do + ruby2_keywords Object.new + end + }.should raise_error(TypeError, /is not a symbol nor a string/) + end + + it "prints warning when a method does not accept argument splat" do + obj = Object.new + def obj.foo(a, b, c) end + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + + it "prints warning when a method accepts keywords" do + obj = Object.new + def obj.foo(a:, b:) end + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + + it "prints warning when a method accepts keyword splat" do + obj = Object.new + def obj.foo(**a) end + + -> { + obj.singleton_class.class_exec do + ruby2_keywords :foo + end + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + end +end diff --git a/spec/ruby/core/module/to_s_spec.rb b/spec/ruby/core/module/to_s_spec.rb index 29f6ecf726..6b1a615ef9 100644 --- a/spec/ruby/core/module/to_s_spec.rb +++ b/spec/ruby/core/module/to_s_spec.rb @@ -42,4 +42,27 @@ describe "Module#to_s" do obj = ModuleSpecs::NamedClass.new obj.singleton_class.to_s.should =~ /\A#<Class:#<ModuleSpecs::NamedClass:0x\h+>>\z/ end + + it "always show the refinement name, even if the module is named" do + module ModuleSpecs::RefinementInspect + R = refine String do + end + end + + ModuleSpecs::RefinementInspect::R.name.should == 'ModuleSpecs::RefinementInspect::R' + ModuleSpecs::RefinementInspect::R.to_s.should == '#<refinement:String@ModuleSpecs::RefinementInspect>' + end + + it 'does not call #inspect or #to_s for singleton classes' do + klass = Class.new + obj = klass.new + def obj.to_s + "to_s" + end + def obj.inspect + "inspect" + end + sclass = obj.singleton_class + sclass.to_s.should =~ /\A#<Class:#<#{Regexp.escape klass.to_s}:0x\h+>>\z/ + end end diff --git a/spec/ruby/core/proc/ruby2_keywords_spec.rb b/spec/ruby/core/proc/ruby2_keywords_spec.rb new file mode 100644 index 0000000000..4f6bc151b6 --- /dev/null +++ b/spec/ruby/core/proc/ruby2_keywords_spec.rb @@ -0,0 +1,64 @@ +require_relative '../../spec_helper' + +ruby_version_is "2.7" do + describe "Proc#ruby2_keywords" do + it "marks the final hash argument as keyword hash" do + f = -> *a { a.last } + f.ruby2_keywords + + last = f.call(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + + ruby_version_is "2.7" ... "3.0" do + it "fixes delegation warnings when calling a method accepting keywords" do + obj = Object.new + def obj.foo(*a, **b) end + + f = -> *a { obj.foo(*a) } + + -> { f.call(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + f.ruby2_keywords + -> { f.call(1, 2, {a: "a"}) }.should_not complain + end + + it "fixes delegation warnings when calling a proc accepting keywords" do + g = -> *a, **b { } + f = -> *a { g.call(*a) } + + -> { f.call(1, 2, {a: "a"}) }.should complain(/Using the last argument as keyword parameters is deprecated/) + f.ruby2_keywords + -> { f.call(1, 2, {a: "a"}) }.should_not complain + end + end + + it "returns self" do + f = -> *a { } + f.ruby2_keywords.should equal f + end + + it "prints warning when a proc does not accept argument splat" do + f = -> a, b, c { } + + -> { + f.ruby2_keywords + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + + it "prints warning when a proc accepts keywords" do + f = -> a:, b: { } + + -> { + f.ruby2_keywords + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + + it "prints warning when a proc accepts keyword splat" do + f = -> **a { } + + -> { + f.ruby2_keywords + }.should complain(/Skipping set of ruby2_keywords flag for/) + end + end +end diff --git a/spec/ruby/core/range/shared/cover.rb b/spec/ruby/core/range/shared/cover.rb index 5b09cea4e0..e04682ba71 100644 --- a/spec/ruby/core/range/shared/cover.rb +++ b/spec/ruby/core/range/shared/cover.rb @@ -152,4 +152,46 @@ describe :range_cover_subrange, shared: true do end end end + + ruby_version_is "2.7" do + it "allows self to be a beginless range" do + eval("(...10)").send(@method, (3..7)).should be_true + eval("(...10)").send(@method, (3..15)).should be_false + + eval("(..7.9)").send(@method, (2.5..6.5)).should be_true + eval("(..7.9)").send(@method, (2.5..8.5)).should be_false + + eval("(..'i')").send(@method, ('d'..'f')).should be_true + eval("(..'i')").send(@method, ('d'..'z')).should be_false + end + + it "allows self to be a endless range" do + eval("(0...)").send(@method, (3..7)).should be_true + eval("(5...)").send(@method, (3..15)).should be_false + + eval("(1.1..)").send(@method, (2.5..6.5)).should be_true + eval("(3.3..)").send(@method, (2.5..8.5)).should be_false + + eval("('a'..)").send(@method, ('d'..'f')).should be_true + eval("('p'..)").send(@method, ('d'..'z')).should be_false + end + + it "accepts beginless range argument" do + eval("(..10)").send(@method, eval("(...10)")).should be_true + (0..10).send(@method, eval("(...10)")).should be_false + + (1.1..7.9).send(@method, eval("(...10.5)")).should be_false + + ('c'..'i').send(@method, eval("(..'i')")).should be_false + end + + it "accepts endless range argument" do + eval("(0..)").send(@method, eval("(0...)")).should be_true + (0..10).send(@method, eval("(0...)")).should be_false + + (1.1..7.9).send(@method, eval("(0.8...)")).should be_false + + ('c'..'i').send(@method, eval("('a'..)")).should be_false + end + end end diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb index b308524310..0267e3ccb0 100644 --- a/spec/ruby/core/range/shared/cover_and_include.rb +++ b/spec/ruby/core/range/shared/cover_and_include.rb @@ -26,6 +26,13 @@ describe :range_cover_and_include, shared: true do end end + ruby_version_is "2.7" do + it "returns true if other is an element of self for beginless ranges" do + eval("(..10)").send(@method, 2.4).should == true + eval("(...10.5)").send(@method, 2.4).should == true + end + end + it "compares values using <=>" do rng = (1..5) m = mock("int") diff --git a/spec/ruby/core/range/to_a_spec.rb b/spec/ruby/core/range/to_a_spec.rb index 08f50e4d9e..9a1352b7b0 100644 --- a/spec/ruby/core/range/to_a_spec.rb +++ b/spec/ruby/core/range/to_a_spec.rb @@ -16,6 +16,11 @@ describe "Range#to_a" do (0xffff...0xfffd).to_a.should == [] end + it "works with Ranges of 64-bit integers" do + large = 1 << 40 + (large..large+1).to_a.should == [1099511627776, 1099511627777] + end + it "works with Ranges of Symbols" do (:A..:z).to_a.size.should == 58 end diff --git a/spec/ruby/core/range/to_s_spec.rb b/spec/ruby/core/range/to_s_spec.rb index ccbc5d8e7e..59672da822 100644 --- a/spec/ruby/core/range/to_s_spec.rb +++ b/spec/ruby/core/range/to_s_spec.rb @@ -18,6 +18,13 @@ describe "Range#to_s" do end end + ruby_version_is "2.7" do + it "can show beginless ranges" do + eval("(..1)").to_s.should == "..1" + eval("(...1.0)").to_s.should == "...1.0" + end + end + ruby_version_is ''...'2.7' do it "returns a tainted string if either end is tainted" do (("a".taint)..."c").to_s.tainted?.should be_true diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb index 390035ef30..86fd4e85ba 100644 --- a/spec/ruby/core/string/scrub_spec.rb +++ b/spec/ruby/core/string/scrub_spec.rb @@ -39,6 +39,13 @@ describe "String#scrub with a custom replacement" do "abc\u3042#{x81}".scrub("*").should == "abc\u3042*" end + it "replaces invalid byte sequences in frozen strings" do + x81 = [0x81].pack('C').force_encoding('utf-8') + (-"abc\u3042#{x81}").scrub("*").should == "abc\u3042*" + utf16_str = ("abc".encode('UTF-16LE').bytes + [0x81]).pack('c*').force_encoding('UTF-16LE') + (-(utf16_str)).scrub("*".encode('UTF-16LE')).should == "abc*".encode('UTF-16LE') + end + it "replaces an incomplete character at the end with a single replacement" do xE3x80 = [0xE3, 0x80].pack('CC').force_encoding 'utf-8' xE3x80.scrub("*").should == "*" diff --git a/spec/ruby/core/string/shared/slice.rb b/spec/ruby/core/string/shared/slice.rb index 69997b7c1d..a674e0b6ef 100644 --- a/spec/ruby/core/string/shared/slice.rb +++ b/spec/ruby/core/string/shared/slice.rb @@ -335,6 +335,16 @@ describe :string_slice_range, shared: true do "hello there".send(@method, eval("(-4...)")).should == "here" end end + + ruby_version_is "2.7" do + it "works with beginless ranges" do + "hello there".send(@method, eval("(..5)")).should == "hello " + "hello there".send(@method, eval("(...5)")).should == "hello" + "hello there".send(@method, eval("(..-4)")).should == "hello th" + "hello there".send(@method, eval("(...-4)")).should == "hello t" + "hello there".send(@method, eval("(...nil)")).should == "hello there" + end + end end describe :string_slice_regexp, shared: true do diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb index c5441e3a49..2ebfe1e353 100644 --- a/spec/ruby/core/string/split_spec.rb +++ b/spec/ruby/core/string/split_spec.rb @@ -471,6 +471,14 @@ describe "String#split with Regexp" do a.should == ["Chunky", "Bacon"] end + it "yields each split substring with default pattern for a non-ASCII string" do + a = [] + returned_object = "l'été arrive bientôt".split { |str| a << str } + + returned_object.should == "l'été arrive bientôt" + a.should == ["l'été", "arrive", "bientôt"] + end + it "yields the string when limit is 1" do a = [] returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize } diff --git a/spec/ruby/core/struct/hash_spec.rb b/spec/ruby/core/struct/hash_spec.rb index d3c95fbe56..53361eb7a9 100644 --- a/spec/ruby/core/struct/hash_spec.rb +++ b/spec/ruby/core/struct/hash_spec.rb @@ -56,5 +56,9 @@ describe "Struct#hash" do # See the Struct#eql? specs end + it "returns different hashes for different struct classes" do + Struct.new(:x).new(1).hash.should != Struct.new(:y).new(1).hash + end + it_behaves_like :struct_accessor, :hash end diff --git a/spec/ruby/core/symbol/name_spec.rb b/spec/ruby/core/symbol/name_spec.rb new file mode 100644 index 0000000000..15b9aa75e9 --- /dev/null +++ b/spec/ruby/core/symbol/name_spec.rb @@ -0,0 +1,19 @@ +require_relative '../../spec_helper' + +ruby_version_is "3.0" do + describe "Symbol#name" do + it "returns string" do + :ruby.name.should == "ruby" + :ルビー.name.should == "ルビー" + end + + it "returns same string instance" do + :"ruby_3".name.should.equal?(:ruby_3.name) + :"ruby_#{1+2}".name.should.equal?(:ruby_3.name) + end + + it "returns frozen string" do + :symbol.name.should.frozen? + end + end +end diff --git a/spec/ruby/core/thread/backtrace_locations_spec.rb b/spec/ruby/core/thread/backtrace_locations_spec.rb index ead4be2d8c..1f77e13378 100644 --- a/spec/ruby/core/thread/backtrace_locations_spec.rb +++ b/spec/ruby/core/thread/backtrace_locations_spec.rb @@ -51,6 +51,14 @@ describe "Thread#backtrace_locations" do end end + ruby_version_is "2.7" do + it "can be called with an beginless range" do + locations1 = Thread.current.backtrace_locations(0) + locations2 = Thread.current.backtrace_locations(eval("(..5)")) + locations2.map(&:to_s)[eval("(2..)")].should == locations1[eval("(..5)")].map(&:to_s)[eval("(2..)")] + end + end + it "returns nil if omitting more locations than available" do Thread.current.backtrace_locations(100).should == nil Thread.current.backtrace_locations(100..-1).should == nil diff --git a/spec/ruby/core/thread/handle_interrupt_spec.rb b/spec/ruby/core/thread/handle_interrupt_spec.rb new file mode 100644 index 0000000000..ea7e81cb98 --- /dev/null +++ b/spec/ruby/core/thread/handle_interrupt_spec.rb @@ -0,0 +1,125 @@ +require_relative '../../spec_helper' + +describe "Thread.handle_interrupt" do + def make_handle_interrupt_thread(interrupt_config, blocking = true) + interrupt_class = Class.new(RuntimeError) + + ScratchPad.record [] + + in_handle_interrupt = Queue.new + can_continue = Queue.new + + thread = Thread.new do + begin + Thread.handle_interrupt(interrupt_config) do + begin + in_handle_interrupt << true + if blocking + Thread.pass # Make it clearer the other thread needs to wait for this one to be in #pop + can_continue.pop + else + begin + can_continue.pop(true) + rescue ThreadError + Thread.pass + retry + end + end + rescue interrupt_class + ScratchPad << :interrupted + end + end + rescue interrupt_class + ScratchPad << :deferred + end + end + + in_handle_interrupt.pop + if blocking + # Ensure the thread is inside Thread#pop, as if thread.raise is done before it would be deferred + Thread.pass until thread.stop? + end + thread.raise interrupt_class, "interrupt" + can_continue << true + thread.join + + ScratchPad.recorded + end + + before :each do + Thread.pending_interrupt?.should == false # sanity check + end + + it "with :never defers interrupts until exiting the handle_interrupt block" do + make_handle_interrupt_thread(RuntimeError => :never).should == [:deferred] + end + + it "with :on_blocking defers interrupts until the next blocking call" do + make_handle_interrupt_thread(RuntimeError => :on_blocking).should == [:interrupted] + make_handle_interrupt_thread({ RuntimeError => :on_blocking }, false).should == [:deferred] + end + + it "with :immediate handles interrupts immediately" do + make_handle_interrupt_thread(RuntimeError => :immediate).should == [:interrupted] + end + + it "with :immediate immediately runs pending interrupts, before the block" do + Thread.handle_interrupt(RuntimeError => :never) do + current = Thread.current + Thread.new { + current.raise "interrupt immediate" + }.join + + Thread.pending_interrupt?.should == true + -> { + Thread.handle_interrupt(RuntimeError => :immediate) { + flunk "not reached" + } + }.should raise_error(RuntimeError, "interrupt immediate") + Thread.pending_interrupt?.should == false + end + end + + it "also works with suspended Fibers and does not duplicate interrupts" do + fiber = Fiber.new { Fiber.yield } + fiber.resume + + Thread.handle_interrupt(RuntimeError => :never) do + current = Thread.current + Thread.new { + current.raise "interrupt with fibers" + }.join + + Thread.pending_interrupt?.should == true + -> { + Thread.handle_interrupt(RuntimeError => :immediate) { + flunk "not reached" + } + }.should raise_error(RuntimeError, "interrupt with fibers") + Thread.pending_interrupt?.should == false + end + + fiber.resume + end + + it "runs pending interrupts at the end of the block, even if there was an exception raised in the block" do + executed = false + -> { + Thread.handle_interrupt(RuntimeError => :never) do + current = Thread.current + Thread.new { + current.raise "interrupt exception" + }.join + + Thread.pending_interrupt?.should == true + executed = true + raise "regular exception" + end + }.should raise_error(RuntimeError, "interrupt exception") + executed.should == true + end + + it "supports multiple pairs in the Hash" do + make_handle_interrupt_thread(ArgumentError => :never, RuntimeError => :never).should == [:deferred] + end +end diff --git a/spec/ruby/core/thread/pending_interrupt_spec.rb b/spec/ruby/core/thread/pending_interrupt_spec.rb new file mode 100644 index 0000000000..cd565d92a4 --- /dev/null +++ b/spec/ruby/core/thread/pending_interrupt_spec.rb @@ -0,0 +1,32 @@ +require_relative '../../spec_helper' + +describe "Thread.pending_interrupt?" do + it "returns false if there are no pending interrupts, e.g., outside any Thread.handle_interrupt block" do + Thread.pending_interrupt?.should == false + end + + it "returns true if there are pending interrupts, e.g., Thread#raise inside Thread.handle_interrupt" do + executed = false + -> { + Thread.handle_interrupt(RuntimeError => :never) do + Thread.pending_interrupt?.should == false + + current = Thread.current + Thread.new { + current.raise "interrupt" + }.join + + Thread.pending_interrupt?.should == true + executed = true + end + }.should raise_error(RuntimeError, "interrupt") + executed.should == true + Thread.pending_interrupt?.should == false + end +end + +describe "Thread#pending_interrupt?" do + it "returns whether the given threads has pending interrupts" do + Thread.current.pending_interrupt?.should == false + end +end diff --git a/spec/ruby/core/time/inspect_spec.rb b/spec/ruby/core/time/inspect_spec.rb index 85133838e2..6f1b2e3ef1 100644 --- a/spec/ruby/core/time/inspect_spec.rb +++ b/spec/ruby/core/time/inspect_spec.rb @@ -5,17 +5,31 @@ describe "Time#inspect" do it_behaves_like :inspect, :inspect ruby_version_is "2.7" do - it "preserves milliseconds" do + it "preserves microseconds" do t = Time.utc(2007, 11, 1, 15, 25, 0, 123456) t.inspect.should == "2007-11-01 15:25:00.123456 UTC" end - it "formats nanoseconds as a Rational" do - t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789) - t.nsec.should == 123456789 - t.strftime("%N").should == "123456789" + it "omits trailing zeros from microseconds" do + t = Time.utc(2007, 11, 1, 15, 25, 0, 100000) + t.inspect.should == "2007-11-01 15:25:00.1 UTC" + end + + it "uses the correct time zone without microseconds" do + t = Time.utc(2000, 1, 1) + t = t.localtime(9*3600) + t.inspect.should == "2000-01-01 09:00:00 +0900" + end + + it "uses the correct time zone with microseconds" do + t = Time.utc(2000, 1, 1, 0, 0, 0, 123456) + t = t.localtime(9*3600) + t.inspect.should == "2000-01-01 09:00:00.123456 +0900" + end - t.inspect.should == "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC" + it "preserves nanoseconds" do + t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r) + t.inspect.should == "2007-11-01 15:25:00.123456789 UTC" end end end |