mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@d394dfd
This commit is contained in:
parent
a68ddf4287
commit
c9213aa864
44 changed files with 904 additions and 20 deletions
|
@ -24,4 +24,15 @@ describe "Enumerator#next" do
|
||||||
@enum.rewind
|
@enum.rewind
|
||||||
@enum.next.should == 1
|
@enum.next.should == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "restarts the enumerator if an exception terminated a previous iteration" do
|
||||||
|
exception = StandardError.new
|
||||||
|
enum = Enumerator.new do
|
||||||
|
raise exception
|
||||||
|
end
|
||||||
|
|
||||||
|
result = 2.times.map { enum.next rescue $! }
|
||||||
|
|
||||||
|
result.should == [exception, exception]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,12 @@ describe "KeyError" do
|
||||||
|
|
||||||
error.receiver.should == receiver
|
error.receiver.should == receiver
|
||||||
error.key.should == key
|
error.key.should == key
|
||||||
|
|
||||||
|
error = KeyError.new("message", receiver: receiver, key: key)
|
||||||
|
|
||||||
|
error.message.should == "message"
|
||||||
|
error.receiver.should == receiver
|
||||||
|
error.key.should == key
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -136,4 +136,13 @@ describe "File.join" do
|
||||||
File.join(bin).should == "bin"
|
File.join(bin).should == "bin"
|
||||||
File.join("usr", bin).should == "usr/bin"
|
File.join("usr", bin).should == "usr/bin"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "raises errors for null bytes" do
|
||||||
|
-> { File.join("\x00x", "metadata.gz") }.should raise_error(ArgumentError) { |e|
|
||||||
|
e.message.should == 'string contains null byte'
|
||||||
|
}
|
||||||
|
-> { File.join("metadata.gz", "\x00x") }.should raise_error(ArgumentError) { |e|
|
||||||
|
e.message.should == 'string contains null byte'
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -43,10 +43,11 @@ platform_is_not :windows do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns an error when given missing non-ASCII path" do
|
it "returns an error when given missing non-ASCII path" do
|
||||||
missing_path = "/missingfilepath\xE3E4".force_encoding("ASCII-8BIT")
|
missing_path = "/missingfilepath\xE3E4".b
|
||||||
-> {
|
-> {
|
||||||
File.stat(missing_path)
|
File.stat(missing_path)
|
||||||
}.should raise_error(Errno::ENOENT) { |e|
|
}.should raise_error(SystemCallError) { |e|
|
||||||
|
[Errno::ENOENT, Errno::EILSEQ].should include(e.class)
|
||||||
e.message.should include(missing_path)
|
e.message.should include(missing_path)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -279,4 +279,44 @@ describe "IO.copy_stream" do
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
describe "with a destination that does partial reads" do
|
||||||
|
before do
|
||||||
|
@from_out, @from_in = IO.pipe
|
||||||
|
@to_out, @to_in = IO.pipe
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
[@from_out, @from_in, @to_out, @to_in].each {|io| io.close rescue nil}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "calls #write repeatedly on the destination Object" do
|
||||||
|
@from_in.write "1234"
|
||||||
|
@from_in.close
|
||||||
|
|
||||||
|
th = Thread.new do
|
||||||
|
IO.copy_stream(@from_out, @to_in)
|
||||||
|
end
|
||||||
|
|
||||||
|
copied = ""
|
||||||
|
4.times do
|
||||||
|
copied += @to_out.read(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
th.join
|
||||||
|
|
||||||
|
copied.should == "1234"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "IO.copy_stream" do
|
||||||
|
it "does not use buffering when writing to STDOUT" do
|
||||||
|
IO.popen([*ruby_exe, fixture(__FILE__ , "copy_in_out.rb")], "r+") do |io|
|
||||||
|
io.write("bar")
|
||||||
|
io.read(3).should == "bar"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -164,7 +164,7 @@ module IOSpecs
|
||||||
@io = io
|
@io = io
|
||||||
end
|
end
|
||||||
|
|
||||||
def read(size, buf=nil)
|
def read(size, buf)
|
||||||
@io.read size, buf
|
@io.read size, buf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ module IOSpecs
|
||||||
@io = io
|
@io = io
|
||||||
end
|
end
|
||||||
|
|
||||||
def readpartial(size, buf=nil)
|
def readpartial(size, buf)
|
||||||
@io.readpartial size, buf
|
@io.readpartial size, buf
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
2
spec/ruby/core/io/fixtures/copy_in_out.rb
Normal file
2
spec/ruby/core/io/fixtures/copy_in_out.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
STDOUT.sync = false
|
||||||
|
IO.copy_stream(STDIN, STDOUT)
|
|
@ -90,6 +90,16 @@ describe "Kernel#require_relative with a relative path" do
|
||||||
ScratchPad.recorded.should == []
|
ScratchPad.recorded.should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "raises a LoadError that includes the missing path" do
|
||||||
|
missing_path = "#{@dir}/nonexistent.rb"
|
||||||
|
expanded_missing_path = File.expand_path(missing_path, File.dirname(__FILE__))
|
||||||
|
-> { require_relative(missing_path) }.should raise_error(LoadError) { |e|
|
||||||
|
e.message.should include(expanded_missing_path)
|
||||||
|
e.path.should == expanded_missing_path
|
||||||
|
}
|
||||||
|
ScratchPad.recorded.should == []
|
||||||
|
end
|
||||||
|
|
||||||
it "raises a LoadError if basepath does not exist" do
|
it "raises a LoadError if basepath does not exist" do
|
||||||
-> { eval("require_relative('#{@dir}/nonexistent.rb')") }.should raise_error(LoadError)
|
-> { eval("require_relative('#{@dir}/nonexistent.rb')") }.should raise_error(LoadError)
|
||||||
end
|
end
|
||||||
|
|
|
@ -243,6 +243,96 @@ describe "Module#using" do
|
||||||
mod.call_foo(c).should == "foo from refinement"
|
mod.call_foo(c).should == "foo from refinement"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "is active for module defined via Module.new {}" do
|
||||||
|
refinement = Module.new do
|
||||||
|
refine Integer do
|
||||||
|
def foo; "foo from refinement"; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
|
||||||
|
Module.new do
|
||||||
|
using refinement
|
||||||
|
|
||||||
|
Module.new do
|
||||||
|
result = 1.foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.should == "foo from refinement"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is active for class defined via Class.new {}" do
|
||||||
|
refinement = Module.new do
|
||||||
|
refine Integer do
|
||||||
|
def foo; "foo from refinement"; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result = nil
|
||||||
|
|
||||||
|
Module.new do
|
||||||
|
using refinement
|
||||||
|
|
||||||
|
Class.new do
|
||||||
|
result = 1.foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result.should == "foo from refinement"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is active for block called via instance_exec" do
|
||||||
|
refinement = Module.new do
|
||||||
|
refine Integer do
|
||||||
|
def foo; "foo from refinement"; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
c = Class.new do
|
||||||
|
using refinement
|
||||||
|
|
||||||
|
def abc
|
||||||
|
block = -> {
|
||||||
|
1.foo
|
||||||
|
}
|
||||||
|
|
||||||
|
self.instance_exec(&block)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
c.new.abc.should == "foo from refinement"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is active for block called via instance_eval" do
|
||||||
|
refinement = Module.new do
|
||||||
|
refine String do
|
||||||
|
def foo; "foo from refinement"; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
c = Class.new do
|
||||||
|
using refinement
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@a = "1703"
|
||||||
|
|
||||||
|
@a.instance_eval do
|
||||||
|
def abc
|
||||||
|
"#{self}: #{self.foo}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def abc
|
||||||
|
@a.abc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
c.new.abc.should == "1703: foo from refinement"
|
||||||
|
end
|
||||||
|
|
||||||
it "is not active if `using` call is not evaluated" do
|
it "is not active if `using` call is not evaluated" do
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
|
|
11
spec/ruby/core/objectspace/weakmap/each_key_spec.rb
Normal file
11
spec/ruby/core/objectspace/weakmap/each_key_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
require_relative 'shared/each'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_key" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { a = []; map.each_key{ |k| a << k }; a }, %w[A B]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_key" do
|
||||||
|
it_behaves_like :weakmap_each, :each_key
|
||||||
|
end
|
11
spec/ruby/core/objectspace/weakmap/each_pair_spec.rb
Normal file
11
spec/ruby/core/objectspace/weakmap/each_pair_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
require_relative 'shared/each'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_pair" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { a = []; map.each_pair{ |k,v| a << "#{k}#{v}" }; a }, %w[Ax By]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_key" do
|
||||||
|
it_behaves_like :weakmap_each, :each_pair
|
||||||
|
end
|
11
spec/ruby/core/objectspace/weakmap/each_spec.rb
Normal file
11
spec/ruby/core/objectspace/weakmap/each_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
require_relative 'shared/each'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { a = []; map.each{ |k,v| a << "#{k}#{v}" }; a }, %w[Ax By]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_key" do
|
||||||
|
it_behaves_like :weakmap_each, :each
|
||||||
|
end
|
11
spec/ruby/core/objectspace/weakmap/each_value_spec.rb
Normal file
11
spec/ruby/core/objectspace/weakmap/each_value_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
require_relative 'shared/each'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_value" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { a = []; map.each_value{ |k| a << k }; a }, %w[x y]
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#each_key" do
|
||||||
|
it_behaves_like :weakmap_each, :each_value
|
||||||
|
end
|
24
spec/ruby/core/objectspace/weakmap/element_reference_spec.rb
Normal file
24
spec/ruby/core/objectspace/weakmap/element_reference_spec.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#[]" do
|
||||||
|
it "is faithful to the map's content" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a b].map(&:upcase)
|
||||||
|
ref1, ref2 = %w[x y]
|
||||||
|
map[key1] = ref1
|
||||||
|
map[key1].should == ref1
|
||||||
|
map[key1] = ref1
|
||||||
|
map[key1].should == ref1
|
||||||
|
map[key2] = ref2
|
||||||
|
map[key1].should == ref1
|
||||||
|
map[key2].should == ref2
|
||||||
|
end
|
||||||
|
|
||||||
|
it "matches using identity semantics" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a a].map(&:upcase)
|
||||||
|
ref = "x"
|
||||||
|
map[key1] = ref
|
||||||
|
map[key2].should == nil
|
||||||
|
end
|
||||||
|
end
|
61
spec/ruby/core/objectspace/weakmap/element_set_spec.rb
Normal file
61
spec/ruby/core/objectspace/weakmap/element_set_spec.rb
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#[]=" do
|
||||||
|
def should_accept(map, key, value)
|
||||||
|
(map[key] = value).should == value
|
||||||
|
map.should.key?(key)
|
||||||
|
map[key].should == value
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is correct" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a b].map(&:upcase)
|
||||||
|
ref1, ref2 = %w[x y]
|
||||||
|
should_accept(map, key1, ref1)
|
||||||
|
should_accept(map, key1, ref1)
|
||||||
|
should_accept(map, key2, ref2)
|
||||||
|
map[key1].should == ref1
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is ""..."2.7" do
|
||||||
|
it "does not accept primitive or frozen keys or values" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
x = Object.new
|
||||||
|
-> { map[true] = x }.should raise_error(ArgumentError)
|
||||||
|
-> { map[false] = x }.should raise_error(ArgumentError)
|
||||||
|
-> { map[nil] = x }.should raise_error(ArgumentError)
|
||||||
|
-> { map[42] = x }.should raise_error(ArgumentError)
|
||||||
|
-> { map[:foo] = x }.should raise_error(ArgumentError)
|
||||||
|
-> { map[x] = true }.should raise_error(ArgumentError)
|
||||||
|
-> { map[x] = false }.should raise_error(ArgumentError)
|
||||||
|
-> { map[x] = nil }.should raise_error(ArgumentError)
|
||||||
|
-> { map[x] = 42 }.should raise_error(ArgumentError)
|
||||||
|
-> { map[x] = :foo }.should raise_error(ArgumentError)
|
||||||
|
|
||||||
|
y = Object.new.freeze
|
||||||
|
-> { map[x] = y}.should raise_error(FrozenError)
|
||||||
|
-> { map[y] = x}.should raise_error(FrozenError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is "2.7" do
|
||||||
|
it "accepts primitive or frozen keys or values" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
x = Object.new
|
||||||
|
should_accept(map, true, x)
|
||||||
|
should_accept(map, false, x)
|
||||||
|
should_accept(map, nil, x)
|
||||||
|
should_accept(map, 42, x)
|
||||||
|
should_accept(map, :foo, x)
|
||||||
|
|
||||||
|
should_accept(map, x, true)
|
||||||
|
should_accept(map, x, false)
|
||||||
|
should_accept(map, x, 42)
|
||||||
|
should_accept(map, x, :foo)
|
||||||
|
|
||||||
|
y = Object.new.freeze
|
||||||
|
should_accept(map, x, y)
|
||||||
|
should_accept(map, y, x)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/include_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/include_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/include'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#include?" do
|
||||||
|
it_behaves_like :weakmap_include?, :include?
|
||||||
|
end
|
25
spec/ruby/core/objectspace/weakmap/inspect_spec.rb
Normal file
25
spec/ruby/core/objectspace/weakmap/inspect_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#inspect" do
|
||||||
|
it "displays object pointers in output" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
# important to test with BasicObject (without Kernel) here to test edge cases
|
||||||
|
key1, key2 = [BasicObject.new, Object.new]
|
||||||
|
ref1, ref2 = [BasicObject.new, Object.new]
|
||||||
|
map.inspect.should =~ /\A\#<ObjectSpace::WeakMap:0x\h+>\z/
|
||||||
|
map[key1] = ref1
|
||||||
|
map.inspect.should =~ /\A\#<ObjectSpace::WeakMap:0x\h+: \#<BasicObject:0x\h+> => \#<BasicObject:0x\h+>>\z/
|
||||||
|
map[key1] = ref1
|
||||||
|
map.inspect.should =~ /\A\#<ObjectSpace::WeakMap:0x\h+: \#<BasicObject:0x\h+> => \#<BasicObject:0x\h+>>\z/
|
||||||
|
map[key2] = ref2
|
||||||
|
|
||||||
|
regexp1 = /\A\#<ObjectSpace::WeakMap:0x\h+: \#<BasicObject:0x\h+> => \#<BasicObject:0x\h+>, \#<Object:0x\h+> => \#<Object:0x\h+>>\z/
|
||||||
|
regexp2 = /\A\#<ObjectSpace::WeakMap:0x\h+: \#<Object:0x\h+> => \#<Object:0x\h+>, \#<BasicObject:0x\h+> => \#<BasicObject:0x\h+>>\z/
|
||||||
|
str = map.inspect
|
||||||
|
if str =~ regexp1
|
||||||
|
str.should =~ regexp1
|
||||||
|
else
|
||||||
|
str.should =~ regexp2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/key_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/key_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/include'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#key?" do
|
||||||
|
it_behaves_like :weakmap_include?, :key?
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/keys_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/keys_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#keys" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { map.keys }, %w[A B]
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/length_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/length_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/size'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#length" do
|
||||||
|
it_behaves_like :weakmap_size, :length
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/member_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/member_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/include'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#member?" do
|
||||||
|
it_behaves_like :weakmap_include?, :member?
|
||||||
|
end
|
10
spec/ruby/core/objectspace/weakmap/shared/each.rb
Normal file
10
spec/ruby/core/objectspace/weakmap/shared/each.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
describe :weakmap_each, shared: true do
|
||||||
|
it "must take a block, except when empty" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key = "a".upcase
|
||||||
|
ref = "x"
|
||||||
|
map.send(@method).should == map
|
||||||
|
map[key] = ref
|
||||||
|
-> { map.send(@method) }.should raise_error(LocalJumpError)
|
||||||
|
end
|
||||||
|
end
|
34
spec/ruby/core/objectspace/weakmap/shared/include.rb
Normal file
34
spec/ruby/core/objectspace/weakmap/shared/include.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
describe :weakmap_include?, shared: true do
|
||||||
|
it "recognizes keys in use" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a b].map(&:upcase)
|
||||||
|
ref1, ref2 = %w[x y]
|
||||||
|
|
||||||
|
map[key1] = ref1
|
||||||
|
map.send(@method, key1).should == true
|
||||||
|
map[key1] = ref1
|
||||||
|
map.send(@method, key1).should == true
|
||||||
|
map[key2] = ref2
|
||||||
|
map.send(@method, key2).should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "matches using identity semantics" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a a].map(&:upcase)
|
||||||
|
ref = "x"
|
||||||
|
map[key1] = ref
|
||||||
|
map.send(@method, key2).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is "2.7" do
|
||||||
|
ruby_bug "#16826", "2.7.0"..."2.8.1" do
|
||||||
|
it "reports true if the pair exists and the value is nil" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key = Object.new
|
||||||
|
map[key] = nil
|
||||||
|
map.size.should == 1
|
||||||
|
map.send(@method, key).should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
spec/ruby/core/objectspace/weakmap/shared/members.rb
Normal file
14
spec/ruby/core/objectspace/weakmap/shared/members.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
describe :weakmap_members, shared: true do
|
||||||
|
it "is correct" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a b].map(&:upcase)
|
||||||
|
ref1, ref2 = %w[x y]
|
||||||
|
@method.call(map).should == []
|
||||||
|
map[key1] = ref1
|
||||||
|
@method.call(map).should == @object[0..0]
|
||||||
|
map[key1] = ref1
|
||||||
|
@method.call(map).should == @object[0..0]
|
||||||
|
map[key2] = ref2
|
||||||
|
@method.call(map).sort.should == @object
|
||||||
|
end
|
||||||
|
end
|
14
spec/ruby/core/objectspace/weakmap/shared/size.rb
Normal file
14
spec/ruby/core/objectspace/weakmap/shared/size.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
describe :weakmap_size, shared: true do
|
||||||
|
it "is correct" do
|
||||||
|
map = ObjectSpace::WeakMap.new
|
||||||
|
key1, key2 = %w[a b].map(&:upcase)
|
||||||
|
ref1, ref2 = %w[x y]
|
||||||
|
map.send(@method).should == 0
|
||||||
|
map[key1] = ref1
|
||||||
|
map.send(@method).should == 1
|
||||||
|
map[key1] = ref1
|
||||||
|
map.send(@method).should == 1
|
||||||
|
map[key2] = ref2
|
||||||
|
map.send(@method).should == 2
|
||||||
|
end
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/size_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/size_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/size'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#size" do
|
||||||
|
it_behaves_like :weakmap_size, :size
|
||||||
|
end
|
6
spec/ruby/core/objectspace/weakmap/values_spec.rb
Normal file
6
spec/ruby/core/objectspace/weakmap/values_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
require_relative '../../../spec_helper'
|
||||||
|
require_relative 'shared/members'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap#values" do
|
||||||
|
it_behaves_like :weakmap_members, -> map { map.values }, %w[x y]
|
||||||
|
end
|
12
spec/ruby/core/objectspace/weakmap_spec.rb
Normal file
12
spec/ruby/core/objectspace/weakmap_spec.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
require_relative '../../spec_helper'
|
||||||
|
|
||||||
|
describe "ObjectSpace::WeakMap" do
|
||||||
|
|
||||||
|
# Note that we can't really spec the most important aspect of this class: that entries get removed when the values
|
||||||
|
# become unreachable. This is because Ruby does not offer a way to reliable invoke GC (GC.start is not enough, neither
|
||||||
|
# on MRI or on alternative implementations).
|
||||||
|
|
||||||
|
it "includes Enumerable" do
|
||||||
|
ObjectSpace::WeakMap.include?(Enumerable).should == true
|
||||||
|
end
|
||||||
|
end
|
|
@ -19,13 +19,13 @@ describe "Process.clock_getres" do
|
||||||
|
|
||||||
# These are observed
|
# These are observed
|
||||||
|
|
||||||
platform_is_not :solaris, :aix, :openbsd, :android do
|
platform_is :linux, :darwin, :windows do
|
||||||
it "with Process::CLOCK_REALTIME reports at least 1 microsecond" do
|
it "with Process::CLOCK_REALTIME reports at least 1 microsecond" do
|
||||||
Process.clock_getres(Process::CLOCK_REALTIME, :nanosecond).should <= 1_000
|
Process.clock_getres(Process::CLOCK_REALTIME, :nanosecond).should <= 1_000
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
platform_is_not :aix, :openbsd, :android do
|
platform_is :linux, :darwin, :windows do
|
||||||
it "with Process::CLOCK_MONOTONIC reports at least 1 microsecond" do
|
it "with Process::CLOCK_MONOTONIC reports at least 1 microsecond" do
|
||||||
Process.clock_getres(Process::CLOCK_MONOTONIC, :nanosecond).should <= 1_000
|
Process.clock_getres(Process::CLOCK_MONOTONIC, :nanosecond).should <= 1_000
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,4 +6,11 @@ describe :time_to_i, shared: true do
|
||||||
it "doesn't return an actual number of seconds in time" do
|
it "doesn't return an actual number of seconds in time" do
|
||||||
Time.at(65.5).send(@method).should == 65
|
Time.at(65.5).send(@method).should == 65
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "rounds fractional seconds toward zero" do
|
||||||
|
t = Time.utc(1960, 1, 1, 0, 0, 0, 999_999)
|
||||||
|
|
||||||
|
t.to_f.to_i.should == -315619199
|
||||||
|
t.to_i.should == -315619200
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,26 +3,32 @@ require_relative 'fixtures/classes'
|
||||||
|
|
||||||
describe 'TracePoint#inspect' do
|
describe 'TracePoint#inspect' do
|
||||||
it 'returns a string containing a human-readable TracePoint status' do
|
it 'returns a string containing a human-readable TracePoint status' do
|
||||||
TracePoint.new(:line) {}.inspect.should ==
|
TracePoint.new(:line) {}.inspect.should == '#<TracePoint:disabled>'
|
||||||
'#<TracePoint:disabled>'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a String showing the event, path and line' do
|
it 'returns a String showing the event, path and line' do
|
||||||
inspect = nil
|
inspect = nil
|
||||||
|
line = nil
|
||||||
|
TracePoint.new(:line) { |tp|
|
||||||
|
inspect ||= tp.inspect
|
||||||
|
}.enable do
|
||||||
line = __LINE__
|
line = __LINE__
|
||||||
TracePoint.new(:line) { |tp| inspect = tp.inspect }.enable do
|
|
||||||
inspect.should == "#<TracePoint:line@#{__FILE__}:#{line+2}>"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
inspect.should == "#<TracePoint:line@#{__FILE__}:#{line}>"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns a String showing the event, path and line for a :class event' do
|
it 'returns a String showing the event, path and line for a :class event' do
|
||||||
inspect = nil
|
inspect = nil
|
||||||
line = __LINE__
|
line = nil
|
||||||
TracePoint.new(:class) { |tp| inspect = tp.inspect }.enable do
|
TracePoint.new(:class) { |tp|
|
||||||
|
inspect ||= tp.inspect
|
||||||
|
}.enable do
|
||||||
|
line = __LINE__ + 1
|
||||||
class TracePointSpec::C
|
class TracePointSpec::C
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
inspect.should == "#<TracePoint:class@#{__FILE__}:#{line+2}>"
|
inspect.should == "#<TracePoint:class@#{__FILE__}:#{line}>"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,11 @@ describe "Ruby character strings" do
|
||||||
"#@my_ip".should == 'xxx'
|
"#@my_ip".should == 'xxx'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "does not interpolate invalid variable names" do
|
||||||
|
"#@".should == '#@'
|
||||||
|
"#$%".should == '#$%'
|
||||||
|
end
|
||||||
|
|
||||||
it "has characters [.(=?!# end simple # interpolation" do
|
it "has characters [.(=?!# end simple # interpolation" do
|
||||||
"#@ip[".should == 'xxx['
|
"#@ip[".should == 'xxx['
|
||||||
"#@ip.".should == 'xxx.'
|
"#@ip.".should == 'xxx.'
|
||||||
|
@ -260,6 +265,12 @@ describe "Ruby String literals" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "Ruby String interpolation" do
|
describe "Ruby String interpolation" do
|
||||||
|
it "permits an empty expression" do
|
||||||
|
s = "#{}" # rubocop:disable Lint/EmptyInterpolation
|
||||||
|
s.should.empty?
|
||||||
|
s.should_not.frozen?
|
||||||
|
end
|
||||||
|
|
||||||
it "returns a string with the source encoding by default" do
|
it "returns a string with the source encoding by default" do
|
||||||
"a#{"b"}c".encoding.should == Encoding::BINARY
|
"a#{"b"}c".encoding.should == Encoding::BINARY
|
||||||
eval('"a#{"b"}c"'.force_encoding("us-ascii")).encoding.should == Encoding::US_ASCII
|
eval('"a#{"b"}c"'.force_encoding("us-ascii")).encoding.should == Encoding::US_ASCII
|
||||||
|
|
|
@ -10,7 +10,10 @@ describe "Matrix.unitary?" do
|
||||||
|
|
||||||
it "returns true for unitary matrices" do
|
it "returns true for unitary matrices" do
|
||||||
Matrix[[0, Complex(0, 1)], [Complex(0, 1), 0]].unitary?.should == true
|
Matrix[[0, Complex(0, 1)], [Complex(0, 1), 0]].unitary?.should == true
|
||||||
|
end
|
||||||
|
|
||||||
version_is((Matrix::const_defined?(:VERSION) ? Matrix::VERSION : "0.1.0"), "0.3.0") do
|
version_is((Matrix::const_defined?(:VERSION) ? Matrix::VERSION : "0.1.0"), "0.3.0") do
|
||||||
|
it "returns true for unitary matrices with a Complex and a negative #imag" do
|
||||||
Matrix[[0, Complex(0, 1)], [Complex(0, -1), 0]].unitary?.should == true
|
Matrix[[0, Complex(0, 1)], [Complex(0, -1), 0]].unitary?.should == true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,10 +53,10 @@ module NetHTTPSpecs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
|
||||||
@server = nil
|
@server = nil
|
||||||
@server_thread = nil
|
@server_thread = nil
|
||||||
|
|
||||||
|
class << self
|
||||||
def port
|
def port
|
||||||
raise "server not started" unless @server
|
raise "server not started" unless @server
|
||||||
@server.config[:Port]
|
@server.config[:Port]
|
||||||
|
@ -89,8 +89,12 @@ module NetHTTPSpecs
|
||||||
if @server
|
if @server
|
||||||
begin
|
begin
|
||||||
@server.shutdown
|
@server.shutdown
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE, Errno::EBADF
|
||||||
# Because WEBrick is not thread-safe and only catches IOError
|
# Because WEBrick is not thread-safe and only catches IOError
|
||||||
|
|
||||||
|
# EBADF can happen because WEBrick @server_thread concurrently closes the shutdown pipe
|
||||||
|
# once @status = :Shutdown, while the current thread does write_nonblock("\0").
|
||||||
|
# On MRI this EBADF is replaced by IOError due to the GIL around both #close and #write_nonblock.
|
||||||
end
|
end
|
||||||
@server = nil
|
@server = nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -51,6 +51,22 @@ describe 'RbConfig::CONFIG' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
platform_is :linux do
|
||||||
|
it "['AR'] exists and can be executed" do
|
||||||
|
ar = RbConfig::CONFIG.fetch('AR')
|
||||||
|
out = `#{ar} --version`
|
||||||
|
$?.should.success?
|
||||||
|
out.should_not be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "['STRIP'] exists and can be executed" do
|
||||||
|
strip = RbConfig::CONFIG.fetch('STRIP')
|
||||||
|
out = `#{strip} --version`
|
||||||
|
$?.should.success?
|
||||||
|
out.should_not be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "RbConfig::TOPDIR" do
|
describe "RbConfig::TOPDIR" do
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require_relative 'spec_helper'
|
require_relative 'spec_helper'
|
||||||
require_relative 'fixtures/class'
|
require_relative 'fixtures/class'
|
||||||
|
require_relative '../../core/module/fixtures/classes'
|
||||||
|
|
||||||
load_extension("class")
|
load_extension("class")
|
||||||
compile_extension("class_under_autoload")
|
compile_extension("class_under_autoload")
|
||||||
|
@ -39,6 +40,69 @@ describe "C-API Class function" do
|
||||||
@s = CApiClassSpecs.new
|
@s = CApiClassSpecs.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "rb_class_instance_methods" do
|
||||||
|
it "returns the public and protected methods of self and its ancestors" do
|
||||||
|
methods = @s.rb_class_instance_methods(ModuleSpecs::Basic)
|
||||||
|
methods.should include(:protected_module, :public_module)
|
||||||
|
|
||||||
|
methods = @s.rb_class_instance_methods(ModuleSpecs::Basic, true)
|
||||||
|
methods.should include(:protected_module, :public_module)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when passed false as a parameter, returns the instance methods of the class" do
|
||||||
|
methods = @s.rb_class_instance_methods(ModuleSpecs::Child, false)
|
||||||
|
methods.should include(:protected_child, :public_child)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_class_public_instance_methods" do
|
||||||
|
it "returns a list of public methods in module and its ancestors" do
|
||||||
|
methods = @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild)
|
||||||
|
methods.should include(:public_3)
|
||||||
|
methods.should include(:public_2)
|
||||||
|
methods.should include(:public_1)
|
||||||
|
|
||||||
|
methods = @s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, true)
|
||||||
|
methods.should include(:public_3)
|
||||||
|
methods.should include(:public_2)
|
||||||
|
methods.should include(:public_1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when passed false as a parameter, should return only methods defined in that module" do
|
||||||
|
@s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, false).should == [:public_1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_class_protected_instance_methods" do
|
||||||
|
it "returns a list of protected methods in module and its ancestors" do
|
||||||
|
methods = @s.rb_class_protected_instance_methods(ModuleSpecs::CountsChild)
|
||||||
|
methods.should include(:protected_3)
|
||||||
|
methods.should include(:protected_2)
|
||||||
|
methods.should include(:protected_1)
|
||||||
|
|
||||||
|
methods = @s.rb_class_protected_instance_methods(ModuleSpecs::CountsChild, true)
|
||||||
|
methods.should include(:protected_3)
|
||||||
|
methods.should include(:protected_2)
|
||||||
|
methods.should include(:protected_1)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when passed false as a parameter, should return only methods defined in that module" do
|
||||||
|
@s.rb_class_public_instance_methods(ModuleSpecs::CountsChild, false).should == [:public_1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_class_private_instance_methods" do
|
||||||
|
it "returns a list of private methods in module and its ancestors" do
|
||||||
|
@s.rb_class_private_instance_methods(ModuleSpecs::CountsChild).should == ModuleSpecs::CountsChild.private_instance_methods
|
||||||
|
@s.rb_class_private_instance_methods(ModuleSpecs::CountsChild, true).should == ModuleSpecs::CountsChild.private_instance_methods
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when passed false as a parameter, should return only methods defined in that module" do
|
||||||
|
methods = @s.rb_class_private_instance_methods(ModuleSpecs::CountsChild, false)
|
||||||
|
methods.should == [:private_1]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "rb_class_new_instance" do
|
describe "rb_class_new_instance" do
|
||||||
it "allocates and initializes a new object" do
|
it "allocates and initializes a new object" do
|
||||||
o = @s.rb_class_new_instance(0, nil, CApiClassSpecs::Alloc)
|
o = @s.rb_class_new_instance(0, nil, CApiClassSpecs::Alloc)
|
||||||
|
@ -338,7 +402,7 @@ describe "C-API Class function" do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "rb_class_new" do
|
describe "rb_class_new" do
|
||||||
it "returns an new subclass of the superclass" do
|
it "returns a new subclass of the superclass" do
|
||||||
subclass = @s.rb_class_new(CApiClassSpecs::NewClass)
|
subclass = @s.rb_class_new(CApiClassSpecs::NewClass)
|
||||||
CApiClassSpecs::NewClass.should be_ancestor_of(subclass)
|
CApiClassSpecs::NewClass.should be_ancestor_of(subclass)
|
||||||
end
|
end
|
||||||
|
|
|
@ -37,6 +37,26 @@ static VALUE class_spec_rb_path_to_class(VALUE self, VALUE path) {
|
||||||
return rb_path_to_class(path);
|
return rb_path_to_class(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE class_spec_rb_class_instance_methods(int argc, VALUE* argv, VALUE self) {
|
||||||
|
VALUE mod = argv[0];
|
||||||
|
return rb_class_instance_methods(--argc, ++argv, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE class_spec_rb_class_public_instance_methods(int argc, VALUE* argv, VALUE self) {
|
||||||
|
VALUE mod = argv[0];
|
||||||
|
return rb_class_public_instance_methods(--argc, ++argv, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE class_spec_rb_class_protected_instance_methods(int argc, VALUE* argv, VALUE self) {
|
||||||
|
VALUE mod = argv[0];
|
||||||
|
return rb_class_protected_instance_methods(--argc, ++argv, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE class_spec_rb_class_private_instance_methods(int argc, VALUE* argv, VALUE self) {
|
||||||
|
VALUE mod = argv[0];
|
||||||
|
return rb_class_private_instance_methods(--argc, ++argv, mod);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE class_spec_rb_class_new(VALUE self, VALUE super) {
|
static VALUE class_spec_rb_class_new(VALUE self, VALUE super) {
|
||||||
return rb_class_new(super);
|
return rb_class_new(super);
|
||||||
}
|
}
|
||||||
|
@ -146,6 +166,10 @@ void Init_class_spec(void) {
|
||||||
rb_define_method(cls, "rb_class2name", class_spec_rb_class2name, 1);
|
rb_define_method(cls, "rb_class2name", class_spec_rb_class2name, 1);
|
||||||
rb_define_method(cls, "rb_path2class", class_spec_rb_path2class, 1);
|
rb_define_method(cls, "rb_path2class", class_spec_rb_path2class, 1);
|
||||||
rb_define_method(cls, "rb_path_to_class", class_spec_rb_path_to_class, 1);
|
rb_define_method(cls, "rb_path_to_class", class_spec_rb_path_to_class, 1);
|
||||||
|
rb_define_method(cls, "rb_class_instance_methods", class_spec_rb_class_instance_methods, -1);
|
||||||
|
rb_define_method(cls, "rb_class_public_instance_methods", class_spec_rb_class_public_instance_methods, -1);
|
||||||
|
rb_define_method(cls, "rb_class_protected_instance_methods", class_spec_rb_class_protected_instance_methods, -1);
|
||||||
|
rb_define_method(cls, "rb_class_private_instance_methods", class_spec_rb_class_private_instance_methods, -1);
|
||||||
rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1);
|
rb_define_method(cls, "rb_class_new", class_spec_rb_class_new, 1);
|
||||||
rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3);
|
rb_define_method(cls, "rb_class_new_instance", class_spec_rb_class_new_instance, 3);
|
||||||
rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1);
|
rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1);
|
||||||
|
|
71
spec/ruby/optional/capi/ext/rbasic_spec.c
Normal file
71
spec/ruby/optional/capi/ext/rbasic_spec.c
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "rubyspec.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
VALUE rbasic_spec_taint_flag(VALUE self) {
|
||||||
|
return INT2FIX(RUBY_FL_TAINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_spec_freeze_flag(VALUE self) {
|
||||||
|
return INT2FIX(RUBY_FL_FREEZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_spec_get_flags(VALUE self, VALUE val) {
|
||||||
|
return INT2FIX(RBASIC(val)->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_spec_set_flags(VALUE self, VALUE val, VALUE flags) {
|
||||||
|
RBASIC(val)->flags = FIX2INT(flags);
|
||||||
|
return INT2FIX(RBASIC(val)->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
|
||||||
|
RBASIC(to)->flags = RBASIC(from)->flags;
|
||||||
|
return INT2FIX(RBASIC(to)->flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_spec_get_klass(VALUE self, VALUE val) {
|
||||||
|
return RBASIC(val)->klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_rdata_spec_get_flags(VALUE self, VALUE structure) {
|
||||||
|
return INT2FIX(RDATA(structure)->basic.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_rdata_spec_set_flags(VALUE self, VALUE structure, VALUE flags) {
|
||||||
|
RDATA(structure)->basic.flags = FIX2INT(flags);
|
||||||
|
return INT2FIX(RDATA(structure)->basic.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_rdata_spec_copy_flags(VALUE self, VALUE to, VALUE from) {
|
||||||
|
RDATA(to)->basic.flags = RDATA(from)->basic.flags;
|
||||||
|
return INT2FIX(RDATA(to)->basic.flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE rbasic_rdata_spec_get_klass(VALUE self, VALUE structure) {
|
||||||
|
return RDATA(structure)->basic.klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init_rbasic_spec(void) {
|
||||||
|
VALUE cls = rb_define_class("CApiRBasicSpecs", rb_cObject);
|
||||||
|
rb_define_method(cls, "taint_flag", rbasic_spec_taint_flag, 0);
|
||||||
|
rb_define_method(cls, "freeze_flag", rbasic_spec_freeze_flag, 0);
|
||||||
|
rb_define_method(cls, "get_flags", rbasic_spec_get_flags, 1);
|
||||||
|
rb_define_method(cls, "set_flags", rbasic_spec_set_flags, 2);
|
||||||
|
rb_define_method(cls, "copy_flags", rbasic_spec_copy_flags, 2);
|
||||||
|
rb_define_method(cls, "get_klass", rbasic_spec_get_klass, 1);
|
||||||
|
|
||||||
|
cls = rb_define_class("CApiRBasicRDataSpecs", rb_cObject);
|
||||||
|
rb_define_method(cls, "get_flags", rbasic_rdata_spec_get_flags, 1);
|
||||||
|
rb_define_method(cls, "set_flags", rbasic_rdata_spec_set_flags, 2);
|
||||||
|
rb_define_method(cls, "copy_flags", rbasic_rdata_spec_copy_flags, 2);
|
||||||
|
rb_define_method(cls, "get_klass", rbasic_rdata_spec_get_klass, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -75,6 +75,10 @@ VALUE symbol_spec_rb_sym2str(VALUE self, VALUE sym) {
|
||||||
return rb_sym2str(sym);
|
return rb_sym2str(sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE symbol_spec_rb_to_symbol(VALUE self, VALUE val) {
|
||||||
|
return rb_to_symbol(val);
|
||||||
|
}
|
||||||
|
|
||||||
void Init_symbol_spec(void) {
|
void Init_symbol_spec(void) {
|
||||||
VALUE cls = rb_define_class("CApiSymbolSpecs", rb_cObject);
|
VALUE cls = rb_define_class("CApiSymbolSpecs", rb_cObject);
|
||||||
rb_define_method(cls, "SYMBOL_P", symbol_spec_SYMBOL_P, 1);
|
rb_define_method(cls, "SYMBOL_P", symbol_spec_SYMBOL_P, 1);
|
||||||
|
@ -93,6 +97,7 @@ void Init_symbol_spec(void) {
|
||||||
rb_define_method(cls, "rb_is_const_id", symbol_spec_rb_is_const_id, 1);
|
rb_define_method(cls, "rb_is_const_id", symbol_spec_rb_is_const_id, 1);
|
||||||
rb_define_method(cls, "rb_is_instance_id", symbol_spec_rb_is_instance_id, 1);
|
rb_define_method(cls, "rb_is_instance_id", symbol_spec_rb_is_instance_id, 1);
|
||||||
rb_define_method(cls, "rb_sym2str", symbol_spec_rb_sym2str, 1);
|
rb_define_method(cls, "rb_sym2str", symbol_spec_rb_sym2str, 1);
|
||||||
|
rb_define_method(cls, "rb_to_symbol", symbol_spec_rb_to_symbol, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
49
spec/ruby/optional/capi/ext/tracepoint_spec.c
Normal file
49
spec/ruby/optional/capi/ext/tracepoint_spec.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "rubyspec.h"
|
||||||
|
|
||||||
|
#include <ruby/debug.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static VALUE callback_called = Qnil;
|
||||||
|
|
||||||
|
static void callback(VALUE tpval, void *data) {
|
||||||
|
callback_called = (VALUE) data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE tracepoint_spec_rb_tracepoint_new(VALUE self, VALUE data) {
|
||||||
|
return rb_tracepoint_new(Qnil, RUBY_EVENT_LINE, callback, (void*) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE tracepoint_spec_callback_called(VALUE self){
|
||||||
|
return callback_called;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE tracepoint_spec_rb_tracepoint_disable(VALUE self, VALUE trace) {
|
||||||
|
rb_tracepoint_disable(trace);
|
||||||
|
return rb_tracepoint_enabled_p(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE tracepoint_spec_rb_tracepoint_enable(VALUE self, VALUE trace) {
|
||||||
|
rb_tracepoint_enable(trace);
|
||||||
|
return rb_tracepoint_enabled_p(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE tracepoint_spec_rb_tracepoint_enabled_p(VALUE self, VALUE trace) {
|
||||||
|
return rb_tracepoint_enabled_p(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init_tracepoint_spec(void) {
|
||||||
|
VALUE cls = rb_define_class("CApiTracePointSpecs", rb_cObject);
|
||||||
|
rb_define_method(cls, "rb_tracepoint_new", tracepoint_spec_rb_tracepoint_new, 1);
|
||||||
|
rb_define_method(cls, "rb_tracepoint_disable", tracepoint_spec_rb_tracepoint_disable, 1);
|
||||||
|
rb_define_method(cls, "rb_tracepoint_enable", tracepoint_spec_rb_tracepoint_enable, 1);
|
||||||
|
rb_define_method(cls, "rb_tracepoint_enabled_p", tracepoint_spec_rb_tracepoint_enabled_p, 1);
|
||||||
|
rb_define_method(cls, "callback_called?", tracepoint_spec_callback_called, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
22
spec/ruby/optional/capi/rbasic_spec.rb
Normal file
22
spec/ruby/optional/capi/rbasic_spec.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
require_relative 'spec_helper'
|
||||||
|
require_relative 'shared/rbasic'
|
||||||
|
load_extension("rbasic")
|
||||||
|
load_extension("data")
|
||||||
|
load_extension("array")
|
||||||
|
|
||||||
|
describe "RBasic support for regular objects" do
|
||||||
|
before :all do
|
||||||
|
@specs = CApiRBasicSpecs.new
|
||||||
|
@data = -> { [Object.new, Object.new] }
|
||||||
|
end
|
||||||
|
it_should_behave_like :rbasic
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "RBasic support for RData" do
|
||||||
|
before :all do
|
||||||
|
@specs = CApiRBasicRDataSpecs.new
|
||||||
|
@wrapping = CApiWrappedStructSpecs.new
|
||||||
|
@data = -> { [@wrapping.wrap_struct(1024), @wrapping.wrap_struct(1025)] }
|
||||||
|
end
|
||||||
|
it_should_behave_like :rbasic
|
||||||
|
end
|
81
spec/ruby/optional/capi/shared/rbasic.rb
Normal file
81
spec/ruby/optional/capi/shared/rbasic.rb
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
describe :rbasic, shared: true do
|
||||||
|
|
||||||
|
before :all do
|
||||||
|
specs = CApiRBasicSpecs.new
|
||||||
|
@taint = specs.taint_flag
|
||||||
|
@freeze = specs.freeze_flag
|
||||||
|
end
|
||||||
|
|
||||||
|
it "reports the appropriate FREEZE flag for the object when reading" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
initial = @specs.get_flags(obj)
|
||||||
|
obj.freeze
|
||||||
|
@specs.get_flags(obj).should == @freeze | initial
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports setting the FREEZE flag" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
initial = @specs.get_flags(obj)
|
||||||
|
@specs.set_flags(obj, @freeze | initial).should == @freeze | initial
|
||||||
|
obj.frozen?.should == true
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is ""..."2.7" do
|
||||||
|
it "reports the appropriate FREEZE and TAINT flags for the object when reading" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
initial = @specs.get_flags(obj)
|
||||||
|
obj.taint
|
||||||
|
@specs.get_flags(obj).should == @taint | initial
|
||||||
|
obj.untaint
|
||||||
|
@specs.get_flags(obj).should == initial
|
||||||
|
obj.freeze
|
||||||
|
@specs.get_flags(obj).should == @freeze | initial
|
||||||
|
|
||||||
|
obj, _ = @data.call
|
||||||
|
obj.taint
|
||||||
|
obj.freeze
|
||||||
|
@specs.get_flags(obj).should == @freeze | @taint | initial
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports setting the FREEZE and TAINT flags" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
initial = @specs.get_flags(obj)
|
||||||
|
@specs.set_flags(obj, @taint | initial).should == @taint | initial
|
||||||
|
obj.tainted?.should == true
|
||||||
|
@specs.set_flags(obj, initial).should == initial
|
||||||
|
obj.tainted?.should == false
|
||||||
|
@specs.set_flags(obj, @freeze | initial).should == @freeze | initial
|
||||||
|
obj.frozen?.should == true
|
||||||
|
|
||||||
|
obj, _ = @data.call
|
||||||
|
@specs.set_flags(obj, @freeze | @taint | initial).should == @freeze | @taint | initial
|
||||||
|
obj.tainted?.should == true
|
||||||
|
obj.frozen?.should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports user flags" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
@specs.get_flags(obj) == 0
|
||||||
|
@specs.set_flags(obj, 1 << 14 | 1 << 16).should == 1 << 14 | 1 << 16
|
||||||
|
@specs.get_flags(obj).should == 1 << 14 | 1 << 16
|
||||||
|
@specs.set_flags(obj, 0).should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports copying the flags from one object over to the other" do
|
||||||
|
obj1, obj2 = @data.call
|
||||||
|
@specs.set_flags(obj1, @taint | 1 << 14 | 1 << 16)
|
||||||
|
@specs.copy_flags(obj2, obj1)
|
||||||
|
@specs.get_flags(obj2).should == @taint | 1 << 14 | 1 << 16
|
||||||
|
@specs.set_flags(obj1, 0)
|
||||||
|
@specs.copy_flags(obj2, obj1)
|
||||||
|
@specs.get_flags(obj2).should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it "supports retrieving the (meta)class" do
|
||||||
|
obj, _ = @data.call
|
||||||
|
@specs.get_klass(obj).should == obj.class
|
||||||
|
obj.singleton_class # ensure the singleton class exists
|
||||||
|
@specs.get_klass(obj).should == obj.singleton_class
|
||||||
|
end
|
||||||
|
end
|
|
@ -153,4 +153,20 @@ describe "C-API Symbol function" do
|
||||||
@s.rb_sym2str(:bacon).should == "bacon"
|
@s.rb_sym2str(:bacon).should == "bacon"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "rb_to_symbol" do
|
||||||
|
it "returns a Symbol for a Symbol" do
|
||||||
|
@s.rb_to_symbol(:foo).should == :foo
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a Symbol for a String" do
|
||||||
|
@s.rb_to_symbol("foo").should == :foo
|
||||||
|
end
|
||||||
|
|
||||||
|
it "coerces to Symbol using to_str" do
|
||||||
|
o = mock('o')
|
||||||
|
o.should_receive(:to_str).and_return("foo")
|
||||||
|
@s.rb_to_symbol(o).should == :foo
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
56
spec/ruby/optional/capi/tracepoint_spec.rb
Normal file
56
spec/ruby/optional/capi/tracepoint_spec.rb
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
require_relative 'spec_helper'
|
||||||
|
|
||||||
|
load_extension("tracepoint")
|
||||||
|
|
||||||
|
describe "CApiTracePointSpecs" do
|
||||||
|
before :each do
|
||||||
|
@s = CApiTracePointSpecs.new
|
||||||
|
end
|
||||||
|
|
||||||
|
after :each do
|
||||||
|
@trace.disable if @trace and @trace.enabled?
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_tracepoint_new" do
|
||||||
|
it "returns a tracepoint object" do
|
||||||
|
@trace = @s.rb_tracepoint_new(7)
|
||||||
|
@trace.should be_an_instance_of(TracePoint)
|
||||||
|
@trace.enabled?.should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "traces lines when given RUBY_EVENT_LINE" do
|
||||||
|
@trace = @s.rb_tracepoint_new(8)
|
||||||
|
@trace.enable
|
||||||
|
@s.callback_called?.should == 8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_tracepoint_disable" do
|
||||||
|
it "disables an enabled TracePoint" do
|
||||||
|
@trace = @s.rb_tracepoint_new(9)
|
||||||
|
@trace.enabled?.should == false
|
||||||
|
@trace.enable
|
||||||
|
@trace.enabled?.should == true
|
||||||
|
@s.rb_tracepoint_disable(@trace).should == false
|
||||||
|
@trace.enabled?.should == false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_tracepoint_enable" do
|
||||||
|
it "enables a disabled TracePoint" do
|
||||||
|
@trace = @s.rb_tracepoint_new(10)
|
||||||
|
@trace.enabled?.should == false
|
||||||
|
@s.rb_tracepoint_enable(@trace).should == true
|
||||||
|
@trace.enabled?.should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "rb_tracepoint_enabled_p" do
|
||||||
|
it "returns correct enabled status" do
|
||||||
|
@trace = @s.rb_tracepoint_new(11)
|
||||||
|
@s.rb_tracepoint_enabled_p(@trace).should == false
|
||||||
|
@trace.enable
|
||||||
|
@s.rb_tracepoint_enabled_p(@trace).should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue