Update to ruby/spec@573cf97
This commit is contained in:
parent
8b55aaa85c
commit
1e5949bd60
@ -28,6 +28,15 @@ describe "The --disable-frozen-string-literal flag causes string literals to" do
|
||||
end
|
||||
|
||||
describe "With neither --enable-frozen-string-literal nor --disable-frozen-string-literal flag set" do
|
||||
before do
|
||||
# disable --enable-frozen-string-literal and --disable-frozen-string-literal passed in $RUBYOPT
|
||||
@rubyopt = ENV["RUBYOPT"]
|
||||
ENV["RUBYOPT"] = ""
|
||||
end
|
||||
|
||||
after do
|
||||
ENV["RUBYOPT"] = @rubyopt
|
||||
end
|
||||
|
||||
it "produce a different object each time" do
|
||||
ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb")).chomp.should == "false"
|
||||
|
@ -7,7 +7,7 @@ ruby_version_is '3.1' do
|
||||
assert_subclasses(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2])
|
||||
end
|
||||
|
||||
it "does not return included modules" do
|
||||
it "does not return included modules from the parent" do
|
||||
parent = Class.new
|
||||
child = Class.new(parent)
|
||||
mod = Module.new
|
||||
@ -16,6 +16,33 @@ ruby_version_is '3.1' do
|
||||
assert_subclasses(parent, [child])
|
||||
end
|
||||
|
||||
it "does not return included modules from the child" do
|
||||
parent = Class.new
|
||||
child = Class.new(parent)
|
||||
mod = Module.new
|
||||
parent.include(mod)
|
||||
|
||||
assert_subclasses(parent, [child])
|
||||
end
|
||||
|
||||
it "does not return prepended modules from the parent" do
|
||||
parent = Class.new
|
||||
child = Class.new(parent)
|
||||
mod = Module.new
|
||||
parent.prepend(mod)
|
||||
|
||||
assert_subclasses(parent, [child])
|
||||
end
|
||||
|
||||
it "does not return prepended modules from the child" do
|
||||
parent = Class.new
|
||||
child = Class.new(parent)
|
||||
mod = Module.new
|
||||
child.prepend(mod)
|
||||
|
||||
assert_subclasses(parent, [child])
|
||||
end
|
||||
|
||||
it "does not return singleton classes" do
|
||||
a = Class.new
|
||||
|
||||
|
@ -131,4 +131,17 @@ describe "Dir#children" do
|
||||
children = @dir.children.sort
|
||||
children.first.encoding.should equal(Encoding::EUC_KR)
|
||||
end
|
||||
|
||||
it "returns the same result when called repeatedly" do
|
||||
@dir = Dir.open DirSpecs.mock_dir
|
||||
|
||||
a = []
|
||||
@dir.each {|dir| a << dir}
|
||||
|
||||
b = []
|
||||
@dir.each {|dir| b << dir}
|
||||
|
||||
a.sort.should == b.sort
|
||||
a.sort.should == DirSpecs.expected_paths
|
||||
end
|
||||
end
|
||||
|
@ -86,6 +86,19 @@ describe "Dir#each_child" do
|
||||
@dir.each_child { |f| f }.should == @dir
|
||||
end
|
||||
|
||||
it "returns the same result when called repeatedly" do
|
||||
@dir = Dir.open DirSpecs.mock_dir
|
||||
|
||||
a = []
|
||||
@dir.each {|dir| a << dir}
|
||||
|
||||
b = []
|
||||
@dir.each {|dir| b << dir}
|
||||
|
||||
a.sort.should == b.sort
|
||||
a.sort.should == DirSpecs.expected_paths
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
it "returns an Enumerator" do
|
||||
@dir = Dir.new(DirSpecs.mock_dir)
|
||||
|
@ -35,6 +35,17 @@ describe "Dir#each" do
|
||||
ls.should include(@dir.read)
|
||||
end
|
||||
|
||||
it "returns the same result when called repeatedly" do
|
||||
a = []
|
||||
@dir.each {|dir| a << dir}
|
||||
|
||||
b = []
|
||||
@dir.each {|dir| b << dir}
|
||||
|
||||
a.sort.should == b.sort
|
||||
a.sort.should == DirSpecs.expected_paths
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
it "returns an Enumerator" do
|
||||
@dir.each.should be_an_instance_of(Enumerator)
|
||||
|
3
spec/ruby/core/exception/fixtures/syntax_error.rb
Normal file
3
spec/ruby/core/exception/fixtures/syntax_error.rb
Normal file
@ -0,0 +1,3 @@
|
||||
# rubocop:disable Lint/Syntax
|
||||
1+1=2
|
||||
# rubocop:enable Lint/Syntax
|
27
spec/ruby/core/exception/syntax_error_spec.rb
Normal file
27
spec/ruby/core/exception/syntax_error_spec.rb
Normal file
@ -0,0 +1,27 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.2" do
|
||||
describe "SyntaxError#path" do
|
||||
it "returns the file path provided to eval" do
|
||||
filename = "speccing.rb"
|
||||
|
||||
-> {
|
||||
eval("if true", TOPLEVEL_BINDING, filename)
|
||||
}.should raise_error(SyntaxError) { |e|
|
||||
e.path.should == filename
|
||||
}
|
||||
end
|
||||
|
||||
it "returns the file path that raised an exception" do
|
||||
expected_path = fixture(__FILE__, "syntax_error.rb")
|
||||
|
||||
-> {
|
||||
require_relative "fixtures/syntax_error"
|
||||
}.should raise_error(SyntaxError) { |e| e.path.should == expected_path }
|
||||
end
|
||||
|
||||
it "returns nil when constructed directly" do
|
||||
SyntaxError.new.path.should == nil
|
||||
end
|
||||
end
|
||||
end
|
@ -110,6 +110,10 @@ describe "Hash#compare_by_identity" do
|
||||
@idh.keys.first.should equal foo
|
||||
end
|
||||
|
||||
# Check `#[]=` call with a String literal.
|
||||
# Don't use `#+` because with `#+` it's no longer a String literal.
|
||||
#
|
||||
# See https://bugs.ruby-lang.org/issues/12855
|
||||
it "gives different identity for string literals" do
|
||||
eval <<~RUBY
|
||||
# frozen_string_literal: false
|
||||
|
@ -135,7 +135,7 @@ describe "Kernel#eval" do
|
||||
it "includes file and line information in syntax error" do
|
||||
expected = 'speccing.rb'
|
||||
-> {
|
||||
eval('if true',TOPLEVEL_BINDING, expected)
|
||||
eval('if true', TOPLEVEL_BINDING, expected)
|
||||
}.should raise_error(SyntaxError) { |e|
|
||||
e.message.should =~ /#{expected}:1:.+/
|
||||
}
|
||||
@ -144,7 +144,7 @@ describe "Kernel#eval" do
|
||||
it "evaluates string with given filename and negative linenumber" do
|
||||
expected_file = 'speccing.rb'
|
||||
-> {
|
||||
eval('if true',TOPLEVEL_BINDING, expected_file, -100)
|
||||
eval('if true', TOPLEVEL_BINDING, expected_file, -100)
|
||||
}.should raise_error(SyntaxError) { |e|
|
||||
e.message.should =~ /#{expected_file}:-100:.+/
|
||||
}
|
||||
|
@ -647,7 +647,7 @@ describe :marshal_load, shared: true do
|
||||
end
|
||||
|
||||
it "sets binmode if it is loading through StringIO stream" do
|
||||
io = StringIO.new(+"\004\b:\vsymbol")
|
||||
io = StringIO.new("\004\b:\vsymbol")
|
||||
def io.binmode; raise "binmode"; end
|
||||
-> { Marshal.load(io) }.should raise_error(RuntimeError, "binmode")
|
||||
end
|
||||
|
@ -1,7 +1,61 @@
|
||||
require_relative '../spec_helper'
|
||||
|
||||
# Should be synchronized with spec/ruby/language/optional_assignments_spec.rb
|
||||
# Some specs for assignments are located in language/variables_spec.rb
|
||||
describe 'Assignments' do
|
||||
describe 'using =' do
|
||||
describe 'evaluation order' do
|
||||
it 'evaluates expressions left to right when assignment with an accessor' do
|
||||
object = Object.new
|
||||
def object.a=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :receiver; object).a = (ScratchPad << :rhs; :value)
|
||||
ScratchPad.recorded.should == [:receiver, :rhs]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a #[]=' do
|
||||
object = Object.new
|
||||
def object.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :receiver; object)[(ScratchPad << :argument; :a)] = (ScratchPad << :rhs; :value)
|
||||
ScratchPad.recorded.should == [:receiver, :argument, :rhs]
|
||||
end
|
||||
|
||||
# similar tests for evaluation order are located in language/constants_spec.rb
|
||||
ruby_version_is ''...'3.2' do
|
||||
it 'evaluates expressions right to left when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :module; m)::A = (ScratchPad << :rhs; :value)
|
||||
ScratchPad.recorded.should == [:rhs, :module]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.2' do
|
||||
it 'evaluates expressions left to right when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :module; m)::A = (ScratchPad << :rhs; :value)
|
||||
ScratchPad.recorded.should == [:module, :rhs]
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises TypeError after evaluation of right-hand-side when compounded constant module is not a module' do
|
||||
ScratchPad.record []
|
||||
|
||||
-> {
|
||||
(:not_a_module)::A = (ScratchPad << :rhs; :value)
|
||||
}.should raise_error(TypeError)
|
||||
|
||||
ScratchPad.recorded.should == [:rhs]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'using +=' do
|
||||
describe 'using an accessor' do
|
||||
before do
|
||||
@ -148,3 +202,328 @@ describe 'Assignments' do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# generic cases
|
||||
describe 'Multiple assignments' do
|
||||
it 'assigns multiple targets when assignment with an accessor' do
|
||||
object = Object.new
|
||||
class << object
|
||||
attr_accessor :a, :b
|
||||
end
|
||||
|
||||
object.a, object.b = :a, :b
|
||||
|
||||
object.a.should == :a
|
||||
object.b.should == :b
|
||||
end
|
||||
|
||||
it 'assigns multiple targets when assignment with a nested accessor' do
|
||||
object = Object.new
|
||||
class << object
|
||||
attr_accessor :a, :b
|
||||
end
|
||||
|
||||
(object.a, object.b), c = [:a, :b], nil
|
||||
|
||||
object.a.should == :a
|
||||
object.b.should == :b
|
||||
end
|
||||
|
||||
it 'assigns multiple targets when assignment with a #[]=' do
|
||||
object = Object.new
|
||||
class << object
|
||||
def []=(k, v) (@h ||= {})[k] = v; end
|
||||
def [](k) (@h ||= {})[k]; end
|
||||
end
|
||||
|
||||
object[:a], object[:b] = :a, :b
|
||||
|
||||
object[:a].should == :a
|
||||
object[:b].should == :b
|
||||
end
|
||||
|
||||
it 'assigns multiple targets when assignment with a nested #[]=' do
|
||||
object = Object.new
|
||||
class << object
|
||||
def []=(k, v) (@h ||= {})[k] = v; end
|
||||
def [](k) (@h ||= {})[k]; end
|
||||
end
|
||||
|
||||
(object[:a], object[:b]), c = [:v1, :v2], nil
|
||||
|
||||
object[:a].should == :v1
|
||||
object[:b].should == :v2
|
||||
end
|
||||
|
||||
it 'assigns multiple targets when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
|
||||
m::A, m::B = :a, :b
|
||||
|
||||
m::A.should == :a
|
||||
m::B.should == :b
|
||||
end
|
||||
|
||||
it 'assigns multiple targets when assignment with a nested compounded constant' do
|
||||
m = Module.new
|
||||
|
||||
(m::A, m::B), c = [:a, :b], nil
|
||||
|
||||
m::A.should == :a
|
||||
m::B.should == :b
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Multiple assignments' do
|
||||
describe 'evaluation order' do
|
||||
ruby_version_is ''...'3.1' do
|
||||
it 'evaluates expressions right to left when assignment with an accessor' do
|
||||
object = Object.new
|
||||
def object.a=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; object).a, (ScratchPad << :b; object).a = (ScratchPad << :c; :c), (ScratchPad << :d; :d)
|
||||
ScratchPad.recorded.should == [:c, :d, :a, :b]
|
||||
end
|
||||
|
||||
it 'evaluates expressions right to left when assignment with a nested accessor' do
|
||||
object = Object.new
|
||||
def object.a=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
((ScratchPad << :a; object).a, foo), bar = [(ScratchPad << :b; :b)]
|
||||
ScratchPad.recorded.should == [:b, :a]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
it 'evaluates expressions left to right when assignment with an accessor' do
|
||||
object = Object.new
|
||||
def object.a=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; object).a, (ScratchPad << :b; object).a = (ScratchPad << :c; :c), (ScratchPad << :d; :d)
|
||||
ScratchPad.recorded.should == [:a, :b, :c, :d]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a nested accessor' do
|
||||
object = Object.new
|
||||
def object.a=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
((ScratchPad << :a; object).a, foo), bar = [(ScratchPad << :b; :b)]
|
||||
ScratchPad.recorded.should == [:a, :b]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a deeply nested accessor' do
|
||||
o = Object.new
|
||||
def o.a=(value) end
|
||||
def o.b=(value) end
|
||||
def o.c=(value) end
|
||||
def o.d=(value) end
|
||||
def o.e=(value) end
|
||||
def o.f=(value) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; o).a,
|
||||
((ScratchPad << :b; o).b,
|
||||
((ScratchPad << :c; o).c, (ScratchPad << :d; o).d),
|
||||
(ScratchPad << :e; o).e),
|
||||
(ScratchPad << :f; o).f = (ScratchPad << :value; :value)
|
||||
|
||||
ScratchPad.recorded.should == [:a, :b, :c, :d, :e, :f, :value]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'3.1' do
|
||||
it 'evaluates expressions right to left when assignment with a #[]=' do
|
||||
object = Object.new
|
||||
def object.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; object)[(ScratchPad << :b; :b)], (ScratchPad << :c; object)[(ScratchPad << :d; :d)] = (ScratchPad << :e; :e), (ScratchPad << :f; :f)
|
||||
ScratchPad.recorded.should == [:e, :f, :a, :b, :c, :d]
|
||||
end
|
||||
|
||||
it 'evaluates expressions right to left when assignment with a nested #[]=' do
|
||||
object = Object.new
|
||||
def object.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
((ScratchPad << :a; object)[(ScratchPad << :b; :b)], foo), bar = [(ScratchPad << :c; :c)]
|
||||
ScratchPad.recorded.should == [:c, :a, :b]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
it 'evaluates expressions left to right when assignment with a #[]=' do
|
||||
object = Object.new
|
||||
def object.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; object)[(ScratchPad << :b; :b)], (ScratchPad << :c; object)[(ScratchPad << :d; :d)] = (ScratchPad << :e; :e), (ScratchPad << :f; :f)
|
||||
ScratchPad.recorded.should == [:a, :b, :c, :d, :e, :f]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a nested #[]=' do
|
||||
object = Object.new
|
||||
def object.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
((ScratchPad << :a; object)[(ScratchPad << :b; :b)], foo), bar = [(ScratchPad << :c; :c)]
|
||||
ScratchPad.recorded.should == [:a, :b, :c]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a deeply nested #[]=' do
|
||||
o = Object.new
|
||||
def o.[]=(_, _) end
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :ra; o)[(ScratchPad << :aa; :aa)],
|
||||
((ScratchPad << :rb; o)[(ScratchPad << :ab; :ab)],
|
||||
((ScratchPad << :rc; o)[(ScratchPad << :ac; :ac)], (ScratchPad << :rd; o)[(ScratchPad << :ad; :ad)]),
|
||||
(ScratchPad << :re; o)[(ScratchPad << :ae; :ae)]),
|
||||
(ScratchPad << :rf; o)[(ScratchPad << :af; :af)] = (ScratchPad << :value; :value)
|
||||
|
||||
ScratchPad.recorded.should == [:ra, :aa, :rb, :ab, :rc, :ac, :rd, :ad, :re, :ae, :rf, :af, :value]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is ''...'3.2' do
|
||||
it 'evaluates expressions right to left when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; m)::A, (ScratchPad << :b; m)::B = (ScratchPad << :c; :c), (ScratchPad << :d; :d)
|
||||
ScratchPad.recorded.should == [:c, :d, :a, :b]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.2' do
|
||||
it 'evaluates expressions left to right when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; m)::A, (ScratchPad << :b; m)::B = (ScratchPad << :c; :c), (ScratchPad << :d; :d)
|
||||
ScratchPad.recorded.should == [:a, :b, :c, :d]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with a nested compounded constant' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
((ScratchPad << :a; m)::A, foo), bar = [(ScratchPad << :b; :b)]
|
||||
ScratchPad.recorded.should == [:a, :b]
|
||||
end
|
||||
|
||||
it 'evaluates expressions left to right when assignment with deeply nested compounded constants' do
|
||||
m = Module.new
|
||||
ScratchPad.record []
|
||||
|
||||
(ScratchPad << :a; m)::A,
|
||||
((ScratchPad << :b; m)::B,
|
||||
((ScratchPad << :c; m)::C, (ScratchPad << :d; m)::D),
|
||||
(ScratchPad << :e; m)::E),
|
||||
(ScratchPad << :f; m)::F = (ScratchPad << :value; :value)
|
||||
|
||||
ScratchPad.recorded.should == [:a, :b, :c, :d, :e, :f, :value]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when assignment with method call and receiver is self' do
|
||||
it 'assigns values correctly when assignment with accessor' do
|
||||
object = Object.new
|
||||
class << object
|
||||
attr_accessor :a, :b
|
||||
|
||||
def assign(v1, v2)
|
||||
self.a, self.b = v1, v2
|
||||
end
|
||||
end
|
||||
|
||||
object.assign :v1, :v2
|
||||
object.a.should == :v1
|
||||
object.b.should == :v2
|
||||
end
|
||||
|
||||
it 'evaluates expressions right to left when assignment with a nested accessor' do
|
||||
object = Object.new
|
||||
class << object
|
||||
attr_accessor :a, :b
|
||||
|
||||
def assign(v1, v2)
|
||||
(self.a, self.b), c = [v1, v2], nil
|
||||
end
|
||||
end
|
||||
|
||||
object.assign :v1, :v2
|
||||
object.a.should == :v1
|
||||
object.b.should == :v2
|
||||
end
|
||||
|
||||
it 'assigns values correctly when assignment with a #[]=' do
|
||||
object = Object.new
|
||||
class << object
|
||||
def []=(key, v)
|
||||
@h ||= {}
|
||||
@h[key] = v
|
||||
end
|
||||
|
||||
def [](key)
|
||||
(@h || {})[key]
|
||||
end
|
||||
|
||||
def assign(k1, v1, k2, v2)
|
||||
self[k1], self[k2] = v1, v2
|
||||
end
|
||||
end
|
||||
|
||||
object.assign :k1, :v1, :k2, :v2
|
||||
object[:k1].should == :v1
|
||||
object[:k2].should == :v2
|
||||
end
|
||||
|
||||
it 'assigns values correctly when assignment with a nested #[]=' do
|
||||
object = Object.new
|
||||
class << object
|
||||
def []=(key, v)
|
||||
@h ||= {}
|
||||
@h[key] = v
|
||||
end
|
||||
|
||||
def [](key)
|
||||
(@h || {})[key]
|
||||
end
|
||||
|
||||
def assign(k1, v1, k2, v2)
|
||||
(self[k1], self[k2]), c = [v1, v2], nil
|
||||
end
|
||||
end
|
||||
|
||||
object.assign :k1, :v1, :k2, :v2
|
||||
object[:k1].should == :v1
|
||||
object[:k2].should == :v2
|
||||
end
|
||||
|
||||
it 'assigns values correctly when assignment with compounded constant' do
|
||||
m = Module.new
|
||||
m.module_exec do
|
||||
self::A, self::B = :v1, :v2
|
||||
end
|
||||
|
||||
m::A.should == :v1
|
||||
m::B.should == :v2
|
||||
end
|
||||
|
||||
it 'assigns values correctly when assignment with a nested compounded constant' do
|
||||
m = Module.new
|
||||
m.module_exec do
|
||||
(self::A, self::B), c = [:v1, :v2], nil
|
||||
end
|
||||
|
||||
m::A.should == :v1
|
||||
m::B.should == :v2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -415,6 +415,19 @@ describe "The 'case'-construct" do
|
||||
self.test("bar").should == false
|
||||
self.test(true).should == true
|
||||
end
|
||||
|
||||
it "warns if there are identical when clauses" do
|
||||
-> {
|
||||
eval <<~RUBY
|
||||
case 1
|
||||
when 2
|
||||
:foo
|
||||
when 2
|
||||
:bar
|
||||
end
|
||||
RUBY
|
||||
}.should complain(/warning: duplicated .when' clause with line \d+ is ignored/, verbose: true)
|
||||
end
|
||||
end
|
||||
|
||||
describe "The 'case'-construct with no target expression" do
|
||||
|
@ -335,7 +335,7 @@ describe "An ensure block inside 'do end' block" do
|
||||
begin
|
||||
raise "oops"
|
||||
ensure
|
||||
return caller(0, 2)
|
||||
return caller(0, 2) # rubocop:disable Lint/EnsureReturn
|
||||
end
|
||||
end
|
||||
line = __LINE__
|
||||
|
@ -305,6 +305,15 @@ describe "The if expression" do
|
||||
6.times(&b)
|
||||
ScratchPad.recorded.should == [4, 5, 4, 5]
|
||||
end
|
||||
|
||||
it "warns when Integer literals are used instead of predicates" do
|
||||
-> {
|
||||
eval <<~RUBY
|
||||
10.times { |i| ScratchPad << i if 4..5 }
|
||||
RUBY
|
||||
}.should complain(/warning: integer literal in flip-flop/, verbose: true)
|
||||
ScratchPad.recorded.should == []
|
||||
end
|
||||
end
|
||||
|
||||
describe "when a branch syntactically does not return a value" do
|
||||
|
@ -231,9 +231,16 @@ describe "Ruby String literals" do
|
||||
ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files.rb")).chomp.should == "true"
|
||||
end
|
||||
|
||||
it "produce different objects for literals with the same content in different files if the other file doesn't have the comment" do
|
||||
frozen_string_literal = "test".frozen? && "test".equal?("test")
|
||||
ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files_no_comment.rb")).chomp.should == (!frozen_string_literal).to_s
|
||||
guard -> { !(eval("'test'").frozen? && "test".equal?("test")) } do
|
||||
it "produces different objects for literals with the same content in different files if the other file doesn't have the comment and String literals aren't frozen by default" do
|
||||
ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files_no_comment.rb")).chomp.should == "true"
|
||||
end
|
||||
end
|
||||
|
||||
guard -> { eval("'test'").frozen? && "test".equal?("test") } do
|
||||
it "produces the same objects for literals with the same content in different files if the other file doesn't have the comment and String literals are frozen by default" do
|
||||
ruby_exe(fixture(__FILE__, "freeze_magic_comment_across_files_no_comment.rb")).chomp.should == "false"
|
||||
end
|
||||
end
|
||||
|
||||
it "produce different objects for literals with the same content in different files if they have different encodings" do
|
||||
|
@ -48,25 +48,18 @@ describe "IO#wait" do
|
||||
end
|
||||
|
||||
it "waits for the READABLE event to be ready" do
|
||||
queue = Queue.new
|
||||
thread = Thread.new { queue.pop; sleep 1; @w.write('data to read') };
|
||||
@r.wait(IO::READABLE, 0).should == nil
|
||||
|
||||
queue.push('signal');
|
||||
@r.wait(IO::READABLE, 2).should_not == nil
|
||||
|
||||
thread.join
|
||||
@w.write('data to read')
|
||||
@r.wait(IO::READABLE, 0).should_not == nil
|
||||
end
|
||||
|
||||
it "waits for the WRITABLE event to be ready" do
|
||||
written_bytes = IOWaitSpec.exhaust_write_buffer(@w)
|
||||
@w.wait(IO::WRITABLE, 0).should == nil
|
||||
|
||||
queue = Queue.new
|
||||
thread = Thread.new { queue.pop; sleep 1; @r.read(written_bytes) };
|
||||
|
||||
queue.push('signal');
|
||||
@w.wait(IO::WRITABLE, 2).should_not == nil
|
||||
|
||||
thread.join
|
||||
@r.read(written_bytes)
|
||||
@w.wait(IO::WRITABLE, 0).should_not == nil
|
||||
end
|
||||
|
||||
it "returns nil when the READABLE event is not ready during the timeout" do
|
||||
@ -89,6 +82,24 @@ describe "IO#wait" do
|
||||
-> { @w.wait(-1, 0) }.should raise_error(ArgumentError, "Events must be positive integer!")
|
||||
end
|
||||
end
|
||||
|
||||
it "changes thread status to 'sleep' when waits for READABLE event" do
|
||||
t = Thread.new { @r.wait(IO::READABLE, 10) }
|
||||
sleep 1
|
||||
t.status.should == 'sleep'
|
||||
t.kill
|
||||
t.join # Thread#kill doesn't wait for the thread to end
|
||||
end
|
||||
|
||||
it "changes thread status to 'sleep' when waits for WRITABLE event" do
|
||||
written_bytes = IOWaitSpec.exhaust_write_buffer(@w)
|
||||
|
||||
t = Thread.new { @w.wait(IO::WRITABLE, 10) }
|
||||
sleep 1
|
||||
t.status.should == 'sleep'
|
||||
t.kill
|
||||
t.join # Thread#kill doesn't wait for the thread to end
|
||||
end
|
||||
end
|
||||
|
||||
context "[timeout, mode] passed" do
|
||||
|
@ -8,7 +8,7 @@ describe "Net::HTTPResponse#inspect" do
|
||||
res.inspect.should == "#<Net::HTTPUnknownResponse ??? test response readbody=false>"
|
||||
|
||||
res = Net::HTTPUnknownResponse.new("1.0", "???", "test response")
|
||||
socket = Net::BufferedIO.new(StringIO.new(+"test body"))
|
||||
socket = Net::BufferedIO.new(StringIO.new("test body"))
|
||||
res.reading_body(socket, true) {}
|
||||
res.inspect.should == "#<Net::HTTPUnknownResponse ??? test response readbody=true>"
|
||||
end
|
||||
|
@ -5,7 +5,7 @@ require 'stringio'
|
||||
describe "Net::HTTPResponse#read_body" do
|
||||
before :each do
|
||||
@res = Net::HTTPUnknownResponse.new("1.0", "???", "test response")
|
||||
@socket = Net::BufferedIO.new(StringIO.new(+"test body"))
|
||||
@socket = Net::BufferedIO.new(StringIO.new("test body"))
|
||||
end
|
||||
|
||||
describe "when passed no arguments" do
|
||||
|
@ -5,7 +5,7 @@ require "stringio"
|
||||
describe "Net::HTTPResponse#reading_body" do
|
||||
before :each do
|
||||
@res = Net::HTTPUnknownResponse.new("1.0", "???", "test response")
|
||||
@socket = Net::BufferedIO.new(StringIO.new(+"test body"))
|
||||
@socket = Net::BufferedIO.new(StringIO.new("test body"))
|
||||
end
|
||||
|
||||
describe "when body_allowed is true" do
|
||||
|
@ -3,7 +3,7 @@ require 'stringio'
|
||||
describe :net_httpresponse_body, shared: true do
|
||||
before :each do
|
||||
@res = Net::HTTPUnknownResponse.new("1.0", "???", "test response")
|
||||
@socket = Net::BufferedIO.new(StringIO.new(+"test body"))
|
||||
@socket = Net::BufferedIO.new(StringIO.new("test body"))
|
||||
end
|
||||
|
||||
it "returns the read body" do
|
||||
|
@ -18,7 +18,37 @@ describe "BasicSocket#read_nonblock" do
|
||||
|
||||
it "receives data after it's ready" do
|
||||
IO.select([@r], nil, nil, 2)
|
||||
@r.recv_nonblock(5).should == "aaa"
|
||||
@r.read_nonblock(5).should == "aaa"
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it 'returned data is binary encoded regardless of the external encoding' do
|
||||
IO.select([@r], nil, nil, 2)
|
||||
@r.read_nonblock(1).encoding.should == Encoding::BINARY
|
||||
|
||||
@w.send("bbb", 0, @r.getsockname)
|
||||
@r.set_encoding(Encoding::ISO_8859_1)
|
||||
IO.select([@r], nil, nil, 2)
|
||||
buffer = @r.read_nonblock(3)
|
||||
buffer.should == "bbb"
|
||||
buffer.encoding.should == Encoding::BINARY
|
||||
end
|
||||
end
|
||||
|
||||
it 'replaces the content of the provided buffer without changing its encoding' do
|
||||
buffer = "initial data".dup.force_encoding(Encoding::UTF_8)
|
||||
|
||||
IO.select([@r], nil, nil, 2)
|
||||
@r.read_nonblock(3, buffer)
|
||||
buffer.should == "aaa"
|
||||
buffer.encoding.should == Encoding::UTF_8
|
||||
|
||||
@w.send("bbb", 0, @r.getsockname)
|
||||
@r.set_encoding(Encoding::ISO_8859_1)
|
||||
IO.select([@r], nil, nil, 2)
|
||||
@r.read_nonblock(3, buffer)
|
||||
buffer.should == "bbb"
|
||||
buffer.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
platform_is :linux do
|
||||
|
47
spec/ruby/library/socket/basicsocket/read_spec.rb
Normal file
47
spec/ruby/library/socket/basicsocket/read_spec.rb
Normal file
@ -0,0 +1,47 @@
|
||||
require_relative '../spec_helper'
|
||||
require_relative '../fixtures/classes'
|
||||
|
||||
describe "BasicSocket#read" do
|
||||
SocketSpecs.each_ip_protocol do |family, ip_address|
|
||||
before :each do
|
||||
@r = Socket.new(family, :DGRAM)
|
||||
@w = Socket.new(family, :DGRAM)
|
||||
|
||||
@r.bind(Socket.pack_sockaddr_in(0, ip_address))
|
||||
@w.send("aaa", 0, @r.getsockname)
|
||||
end
|
||||
|
||||
after :each do
|
||||
@r.close unless @r.closed?
|
||||
@w.close unless @w.closed?
|
||||
end
|
||||
|
||||
it "receives data after it's ready" do
|
||||
@r.read(3).should == "aaa"
|
||||
end
|
||||
|
||||
it 'returned data is binary encoded regardless of the external encoding' do
|
||||
@r.read(3).encoding.should == Encoding::BINARY
|
||||
|
||||
@w.send("bbb", 0, @r.getsockname)
|
||||
@r.set_encoding(Encoding::UTF_8)
|
||||
buffer = @r.read(3)
|
||||
buffer.should == "bbb"
|
||||
buffer.encoding.should == Encoding::BINARY
|
||||
end
|
||||
|
||||
it 'replaces the content of the provided buffer without changing its encoding' do
|
||||
buffer = "initial data".dup.force_encoding(Encoding::UTF_8)
|
||||
|
||||
@r.read(3, buffer)
|
||||
buffer.should == "aaa"
|
||||
buffer.encoding.should == Encoding::UTF_8
|
||||
|
||||
@w.send("bbb", 0, @r.getsockname)
|
||||
@r.set_encoding(Encoding::ISO_8859_1)
|
||||
@r.read(3, buffer)
|
||||
buffer.should == "bbb"
|
||||
buffer.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
end
|
||||
end
|
@ -3,6 +3,6 @@ require_relative 'fixtures/classes'
|
||||
|
||||
describe "StringIO#fcntl" do
|
||||
it "raises a NotImplementedError" do
|
||||
-> { StringIO.new(+"boom").fcntl }.should raise_error(NotImplementedError)
|
||||
-> { StringIO.new("boom").fcntl }.should raise_error(NotImplementedError)
|
||||
end
|
||||
end
|
||||
|
@ -172,7 +172,7 @@ end
|
||||
# NOTE: Synchronise with core/io/new_spec.rb (core/io/shared/new.rb)
|
||||
describe "StringIO#initialize when passed keyword arguments" do
|
||||
it "sets the mode based on the passed :mode option" do
|
||||
io = StringIO.new(+"example", "r")
|
||||
io = StringIO.new("example", "r")
|
||||
io.closed_read?.should be_false
|
||||
io.closed_write?.should be_true
|
||||
end
|
||||
|
@ -33,7 +33,7 @@ end
|
||||
describe "StringIO#read_nonblock" do
|
||||
|
||||
it "accepts an exception option" do
|
||||
stringio = StringIO.new(+'foo')
|
||||
stringio = StringIO.new('foo')
|
||||
stringio.read_nonblock(3, exception: false).should == 'foo'
|
||||
end
|
||||
|
||||
|
@ -3,11 +3,11 @@ require_relative 'fixtures/classes'
|
||||
|
||||
describe "StringIO#reopen when passed [Object, Integer]" do
|
||||
before :each do
|
||||
@io = StringIO.new(+"example")
|
||||
@io = StringIO.new("example")
|
||||
end
|
||||
|
||||
it "reopens self with the passed Object in the passed mode" do
|
||||
@io.reopen(+"reopened", IO::RDONLY)
|
||||
@io.reopen("reopened", IO::RDONLY)
|
||||
@io.closed_read?.should be_false
|
||||
@io.closed_write?.should be_true
|
||||
@io.string.should == "reopened"
|
||||
@ -51,11 +51,11 @@ end
|
||||
|
||||
describe "StringIO#reopen when passed [Object, Object]" do
|
||||
before :each do
|
||||
@io = StringIO.new(+"example")
|
||||
@io = StringIO.new("example")
|
||||
end
|
||||
|
||||
it "reopens self with the passed Object in the passed mode" do
|
||||
@io.reopen(+"reopened", "r")
|
||||
@io.reopen("reopened", "r")
|
||||
@io.closed_read?.should be_false
|
||||
@io.closed_write?.should be_true
|
||||
@io.string.should == "reopened"
|
||||
@ -83,7 +83,7 @@ describe "StringIO#reopen when passed [Object, Object]" do
|
||||
|
||||
it "tries to convert the passed Object to a String using #to_str" do
|
||||
obj = mock("to_str")
|
||||
obj.should_receive(:to_str).and_return(+"to_str")
|
||||
obj.should_receive(:to_str).and_return("to_str")
|
||||
@io.reopen(obj, "r")
|
||||
@io.string.should == "to_str"
|
||||
end
|
||||
@ -107,7 +107,7 @@ describe "StringIO#reopen when passed [Object, Object]" do
|
||||
it "tries to convert the passed mode Object to an Integer using #to_str" do
|
||||
obj = mock("to_str")
|
||||
obj.should_receive(:to_str).and_return("r")
|
||||
@io.reopen(+"reopened", obj)
|
||||
@io.reopen("reopened", obj)
|
||||
@io.closed_read?.should be_false
|
||||
@io.closed_write?.should be_true
|
||||
@io.string.should == "reopened"
|
||||
@ -128,7 +128,7 @@ end
|
||||
|
||||
describe "StringIO#reopen when passed [String]" do
|
||||
before :each do
|
||||
@io = StringIO.new(+"example")
|
||||
@io = StringIO.new("example")
|
||||
end
|
||||
|
||||
it "reopens self with the passed String in read-write mode" do
|
||||
@ -157,7 +157,7 @@ end
|
||||
|
||||
describe "StringIO#reopen when passed [Object]" do
|
||||
before :each do
|
||||
@io = StringIO.new(+"example")
|
||||
@io = StringIO.new("example")
|
||||
end
|
||||
|
||||
it "raises a TypeError when passed an Object that can't be converted to a StringIO" do
|
||||
@ -180,7 +180,7 @@ end
|
||||
|
||||
describe "StringIO#reopen when passed no arguments" do
|
||||
before :each do
|
||||
@io = StringIO.new(+"example\nsecond line")
|
||||
@io = StringIO.new("example\nsecond line")
|
||||
end
|
||||
|
||||
it "resets self's mode to read-write" do
|
||||
@ -208,7 +208,7 @@ end
|
||||
# for details.
|
||||
describe "StringIO#reopen" do
|
||||
before :each do
|
||||
@io = StringIO.new(+'hello','a')
|
||||
@io = StringIO.new(+'hello', 'a')
|
||||
end
|
||||
|
||||
# TODO: find out if this is really a bug
|
||||
|
@ -8,7 +8,12 @@ extern "C" {
|
||||
VALUE registered_tagged_value;
|
||||
VALUE registered_reference_value;
|
||||
VALUE registered_before_rb_gc_register_address;
|
||||
VALUE registered_before_rb_global_variable;
|
||||
VALUE registered_before_rb_global_variable_string;
|
||||
VALUE registered_before_rb_global_variable_bignum;
|
||||
VALUE registered_before_rb_global_variable_float;
|
||||
VALUE registered_after_rb_global_variable_string;
|
||||
VALUE registered_after_rb_global_variable_bignum;
|
||||
VALUE registered_after_rb_global_variable_float;
|
||||
VALUE rb_gc_register_address_outside_init;
|
||||
|
||||
static VALUE registered_tagged_address(VALUE self) {
|
||||
@ -23,8 +28,28 @@ static VALUE get_registered_before_rb_gc_register_address(VALUE self) {
|
||||
return registered_before_rb_gc_register_address;
|
||||
}
|
||||
|
||||
static VALUE get_registered_before_rb_global_variable(VALUE self) {
|
||||
return registered_before_rb_global_variable;
|
||||
static VALUE get_registered_before_rb_global_variable_string(VALUE self) {
|
||||
return registered_before_rb_global_variable_string;
|
||||
}
|
||||
|
||||
static VALUE get_registered_before_rb_global_variable_bignum(VALUE self) {
|
||||
return registered_before_rb_global_variable_bignum;
|
||||
}
|
||||
|
||||
static VALUE get_registered_before_rb_global_variable_float(VALUE self) {
|
||||
return registered_before_rb_global_variable_float;
|
||||
}
|
||||
|
||||
static VALUE get_registered_after_rb_global_variable_string(VALUE self) {
|
||||
return registered_after_rb_global_variable_string;
|
||||
}
|
||||
|
||||
static VALUE get_registered_after_rb_global_variable_bignum(VALUE self) {
|
||||
return registered_after_rb_global_variable_bignum;
|
||||
}
|
||||
|
||||
static VALUE get_registered_after_rb_global_variable_float(VALUE self) {
|
||||
return registered_after_rb_global_variable_float;
|
||||
}
|
||||
|
||||
static VALUE gc_spec_rb_gc_register_address(VALUE self) {
|
||||
@ -71,17 +96,34 @@ void Init_gc_spec(void) {
|
||||
rb_gc_register_address(®istered_tagged_value);
|
||||
rb_gc_register_address(®istered_reference_value);
|
||||
rb_gc_register_address(®istered_before_rb_gc_register_address);
|
||||
rb_global_variable(®istered_before_rb_global_variable);
|
||||
rb_global_variable(®istered_before_rb_global_variable_string);
|
||||
rb_global_variable(®istered_before_rb_global_variable_bignum);
|
||||
rb_global_variable(®istered_before_rb_global_variable_float);
|
||||
|
||||
registered_tagged_value = INT2NUM(10);
|
||||
registered_reference_value = rb_str_new2("Globally registered data");
|
||||
registered_before_rb_gc_register_address = rb_str_new_cstr("registered before rb_gc_register_address()");
|
||||
registered_before_rb_global_variable = rb_str_new_cstr("registered before rb_global_variable()");
|
||||
|
||||
registered_before_rb_global_variable_string = rb_str_new_cstr("registered before rb_global_variable()");
|
||||
registered_before_rb_global_variable_bignum = LL2NUM(INT64_MAX);
|
||||
registered_before_rb_global_variable_float = DBL2NUM(3.14);
|
||||
|
||||
registered_after_rb_global_variable_string = rb_str_new_cstr("registered after rb_global_variable()");
|
||||
rb_global_variable(®istered_after_rb_global_variable_string);
|
||||
registered_after_rb_global_variable_bignum = LL2NUM(INT64_MAX);
|
||||
rb_global_variable(®istered_after_rb_global_variable_bignum);
|
||||
registered_after_rb_global_variable_float = DBL2NUM(6.28);
|
||||
rb_global_variable(®istered_after_rb_global_variable_float);
|
||||
|
||||
rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0);
|
||||
rb_define_method(cls, "registered_reference_address", registered_reference_address, 0);
|
||||
rb_define_method(cls, "registered_before_rb_gc_register_address", get_registered_before_rb_gc_register_address, 0);
|
||||
rb_define_method(cls, "registered_before_rb_global_variable", get_registered_before_rb_global_variable, 0);
|
||||
rb_define_method(cls, "registered_before_rb_global_variable_string", get_registered_before_rb_global_variable_string, 0);
|
||||
rb_define_method(cls, "registered_before_rb_global_variable_bignum", get_registered_before_rb_global_variable_bignum, 0);
|
||||
rb_define_method(cls, "registered_before_rb_global_variable_float", get_registered_before_rb_global_variable_float, 0);
|
||||
rb_define_method(cls, "registered_after_rb_global_variable_string", get_registered_after_rb_global_variable_string, 0);
|
||||
rb_define_method(cls, "registered_after_rb_global_variable_bignum", get_registered_after_rb_global_variable_bignum, 0);
|
||||
rb_define_method(cls, "registered_after_rb_global_variable_float", get_registered_after_rb_global_variable_float, 0);
|
||||
rb_define_method(cls, "rb_gc_register_address", gc_spec_rb_gc_register_address, 0);
|
||||
rb_define_method(cls, "rb_gc_unregister_address", gc_spec_rb_gc_unregister_address, 0);
|
||||
rb_define_method(cls, "rb_gc_enable", gc_spec_rb_gc_enable, 0);
|
||||
|
@ -27,9 +27,36 @@ describe "CApiGCSpecs" do
|
||||
end
|
||||
|
||||
describe "rb_global_variable" do
|
||||
it "keeps the value alive even if the value is assigned after rb_global_variable() is called" do
|
||||
before :all do
|
||||
GC.start
|
||||
@f.registered_before_rb_global_variable.should == "registered before rb_global_variable()"
|
||||
end
|
||||
|
||||
describe "keeps the value alive even if the value is assigned after rb_global_variable() is called" do
|
||||
it "for a string" do
|
||||
@f.registered_before_rb_global_variable_string.should == "registered before rb_global_variable()"
|
||||
end
|
||||
|
||||
it "for a bignum" do
|
||||
@f.registered_before_rb_global_variable_bignum.should == 2**63 - 1
|
||||
end
|
||||
|
||||
it "for a Float" do
|
||||
@f.registered_before_rb_global_variable_float.should == 3.14
|
||||
end
|
||||
end
|
||||
|
||||
describe "keeps the value alive when the value is assigned before rb_global_variable() is called" do
|
||||
it "for a string" do
|
||||
@f.registered_after_rb_global_variable_string.should == "registered after rb_global_variable()"
|
||||
end
|
||||
|
||||
it "for a bignum" do
|
||||
@f.registered_after_rb_global_variable_bignum.should == 2**63 - 1
|
||||
end
|
||||
|
||||
it "for a Float" do
|
||||
@f.registered_after_rb_global_variable_float.should == 6.28
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user