Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ruby/spec #10753

Merged
merged 1 commit into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions spec/ruby/core/binding/dup_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,21 @@
bind.frozen?.should == true
bind.dup.frozen?.should == false
end

it "retains original binding variables but the list is distinct" do
bind1 = binding
eval "a = 1", bind1

bind2 = bind1.dup
eval("a = 2", bind2)
eval("a", bind1).should == 2
eval("a", bind2).should == 2

eval("b = 2", bind2)
-> { eval("b", bind1) }.should raise_error(NameError)
eval("b", bind2).should == 2

bind1.local_variables.sort.should == [:a, :bind1, :bind2]
bind2.local_variables.sort.should == [:a, :b, :bind1, :bind2]
end
end
8 changes: 7 additions & 1 deletion spec/ruby/core/enumerator/next_values_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def o.each
yield :e1, :e2, :e3
yield nil
yield
yield [:f1, :f2]
end

@e = o.to_enum
Expand Down Expand Up @@ -48,8 +49,13 @@ def o.each
@e.next_values.should == []
end

it "raises StopIteration if called on a finished enumerator" do
it "returns an array of array if yield is called with an array" do
7.times { @e.next }
@e.next_values.should == [[:f1, :f2]]
end

it "raises StopIteration if called on a finished enumerator" do
8.times { @e.next }
-> { @e.next_values }.should raise_error(StopIteration)
end
end
8 changes: 7 additions & 1 deletion spec/ruby/core/enumerator/peek_values_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def o.each
yield :e1, :e2, :e3
yield nil
yield
yield [:f1, :f2]
end

@e = o.to_enum
Expand Down Expand Up @@ -50,8 +51,13 @@ def o.each
@e.peek_values.should == []
end

it "raises StopIteration if called on a finished enumerator" do
it "returns an array of array if yield is called with an array" do
7.times { @e.next }
@e.peek_values.should == [[:f1, :f2]]
end

it "raises StopIteration if called on a finished enumerator" do
8.times { @e.next }
-> { @e.peek_values }.should raise_error(StopIteration)
end
end
9 changes: 8 additions & 1 deletion spec/ruby/core/io/pread_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

it "accepts a length, an offset, and an output buffer" do
buffer = +"foo"
@file.pread(3, 4, buffer)
@file.pread(3, 4, buffer).should.equal?(buffer)
buffer.should == "567"
end

Expand All @@ -38,6 +38,13 @@
buffer.should == "12345"
end

it "preserves the encoding of the given buffer" do
buffer = ''.encode(Encoding::ISO_8859_1)
@file.pread(10, 0, buffer)

buffer.encoding.should == Encoding::ISO_8859_1
end

it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
Expand Down
15 changes: 15 additions & 0 deletions spec/ruby/core/io/read_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,21 @@
buf.should == @contents[0..4]
end

it "preserves the encoding of the given buffer" do
buffer = ''.encode(Encoding::ISO_8859_1)
@io.read(10, buffer)

buffer.encoding.should == Encoding::ISO_8859_1
end

# https://bugs.ruby-lang.org/issues/20416
it "does not preserve the encoding of the given buffer when max length is not provided" do
buffer = ''.encode(Encoding::ISO_8859_1)
@io.read(nil, buffer)

buffer.encoding.should_not == Encoding::ISO_8859_1
end

it "returns the given buffer" do
buf = +""

Expand Down
3 changes: 2 additions & 1 deletion spec/ruby/core/io/readpartial_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
buffer = +"existing content"
@wr.write("hello world")
@wr.close
@rd.readpartial(11, buffer)
@rd.readpartial(11, buffer).should.equal?(buffer)
buffer.should == "hello world"
end

Expand Down Expand Up @@ -106,6 +106,7 @@
@wr.write("abc")
@wr.close
@rd.readpartial(10, buffer)

buffer.encoding.should == Encoding::ISO_8859_1
end
end
9 changes: 8 additions & 1 deletion spec/ruby/core/io/sysread_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@

it "discards the existing buffer content upon successful read" do
buffer = +"existing content"
@file.sysread(11, buffer)
@file.sysread(11, buffer).should.equal?(buffer)
buffer.should == "01234567890"
end

Expand All @@ -107,6 +107,13 @@
-> { @file.sysread(1, buffer) }.should raise_error(EOFError)
buffer.should be_empty
end

it "preserves the encoding of the given buffer" do
buffer = ''.encode(Encoding::ISO_8859_1)
string = @file.sysread(10, buffer)

buffer.encoding.should == Encoding::ISO_8859_1
end
end

describe "IO#sysread" do
Expand Down
28 changes: 28 additions & 0 deletions spec/ruby/core/module/include_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,34 @@ def self.append_features(mod)
-> { ModuleSpecs::SubclassSpec.include(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
end

ruby_version_is ""..."3.2" do
it "raises ArgumentError when the argument is a refinement" do
refinement = nil

Module.new do
refine String do
refinement = self
end
end

-> { ModuleSpecs::Basic.include(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed")
end
end

ruby_version_is "3.2" do
it "raises a TypeError when the argument is a refinement" do
refinement = nil

Module.new do
refine String do
refinement = self
end
end

-> { ModuleSpecs::Basic.include(refinement) }.should raise_error(TypeError, "Cannot include refinement")
end
end

it "imports constants to modules and classes" do
ModuleSpecs::A.constants.should include(:CONSTANT_A)
ModuleSpecs::B.constants.should include(:CONSTANT_A, :CONSTANT_B)
Expand Down
48 changes: 48 additions & 0 deletions spec/ruby/core/module/prepend_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,26 @@ def foo
foo.call.should == 'm'
end

it "updates the optimized method when a prepended module is updated" do
out = ruby_exe(<<~RUBY)
module M; end
class Integer
prepend M
end
l = -> { 1 + 2 }
p l.call
M.module_eval do
def +(o)
$called = true
super(o)
end
end
p l.call
p $called
RUBY
out.should == "3\n3\ntrue\n"
end

it "updates the method when there is a base included method and the prepended module overrides it" do
base_module = Module.new do
def foo
Expand Down Expand Up @@ -415,6 +435,34 @@ module M
-> { ModuleSpecs::SubclassSpec.prepend(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
end

ruby_version_is ""..."3.2" do
it "raises ArgumentError when the argument is a refinement" do
refinement = nil

Module.new do
refine String do
refinement = self
end
end

-> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed")
end
end

ruby_version_is "3.2" do
it "raises a TypeError when the argument is a refinement" do
refinement = nil

Module.new do
refine String do
refinement = self
end
end

-> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(TypeError, "Cannot prepend refinement")
end
end

it "imports constants" do
m1 = Module.new
m1::MY_CONSTANT = 1
Expand Down
28 changes: 28 additions & 0 deletions spec/ruby/core/warning/performance_warning_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require_relative '../../spec_helper'


describe "Performance warnings" do
guard -> { ruby_version_is("3.4") || RUBY_ENGINE == "truffleruby" } do
# Optimising Integer, Float or Symbol methods is kind of implementation detail
# but multiple implementations do so. So it seems reasonable to have a test case
# for at least one such common method.
# See https://bugs.ruby-lang.org/issues/20429
context "when redefined optimised methods" do
it "emits performance warning for redefining Integer#+" do
code = <<~CODE
Warning[:performance] = true

class Integer
ORIG_METHOD = instance_method(:+)

def +(...)
ORIG_METHOD.bind(self).call(...)
end
end
CODE

ruby_exe(code, args: "2>&1").should.include?("warning: Redefining 'Integer#+' disables interpreter and JIT optimizations")
end
end
end
end
19 changes: 19 additions & 0 deletions spec/ruby/language/break_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,25 @@ def mid(&b)
end
end

describe "The break statement in a method" do
it "is invalid and raises a SyntaxError" do
-> {
eval("def m; break; end")
}.should raise_error(SyntaxError)
end
end

describe "The break statement in a module literal" do
it "is invalid and raises a SyntaxError" do
code = <<~RUBY
module BreakSpecs:ModuleWithBreak
break
end
RUBY

-> { eval(code) }.should raise_error(SyntaxError)
end
end

# TODO: Rewrite all the specs from here to the end of the file in the style
# above.
Expand Down
4 changes: 2 additions & 2 deletions spec/ruby/language/execution_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

2.times do
runner.instance_exec do
`test #{:command}`
`test #{:command}` # rubocop:disable Lint/LiteralInInterpolation
end
end

Expand Down Expand Up @@ -84,7 +84,7 @@

2.times do
runner.instance_exec do
%x{test #{:command}}
%x{test #{:command}} # rubocop:disable Lint/LiteralInInterpolation
end
end

Expand Down
32 changes: 32 additions & 0 deletions spec/ruby/language/hash_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@
-> { eval("{:a ==> 1}") }.should raise_error(SyntaxError)
end

it "recognizes '!' at the end of the key" do
eval("{:a! =>1}").should == {:"a!" => 1}
eval("{:a! => 1}").should == {:"a!" => 1}

eval("{a!:1}").should == {:"a!" => 1}
eval("{a!: 1}").should == {:"a!" => 1}
end

it "raises a SyntaxError if there is no space between `!` and `=>`" do
-> { eval("{:a!=> 1}") }.should raise_error(SyntaxError)
end

it "recognizes '?' at the end of the key" do
eval("{:a? =>1}").should == {:"a?" => 1}
eval("{:a? => 1}").should == {:"a?" => 1}

eval("{a?:1}").should == {:"a?" => 1}
eval("{a?: 1}").should == {:"a?" => 1}
end

it "raises a SyntaxError if there is no space between `?` and `=>`" do
-> { eval("{:a?=> 1}") }.should raise_error(SyntaxError)
end

it "constructs a new hash with the given elements" do
{foo: 123}.should == {foo: 123}
h = {rbx: :cool, specs: 'fail_sometimes'}
Expand Down Expand Up @@ -271,6 +295,14 @@ def foo(val)

a.new.foo(1).should == {bar: "baz", val: 1}
end

it "raises a SyntaxError when the hash key ends with `!`" do
-> { eval("{a!:}") }.should raise_error(SyntaxError, /identifier a! is not valid to get/)
end

it "raises a SyntaxError when the hash key ends with `?`" do
-> { eval("{a?:}") }.should raise_error(SyntaxError, /identifier a\? is not valid to get/)
end
end
end
end