2018-03-04 10:09:32 -05:00
|
|
|
require_relative 'spec_helper'
|
2017-05-07 08:04:49 -04:00
|
|
|
|
|
|
|
load_extension("struct")
|
|
|
|
|
|
|
|
describe "C-API Struct function" do
|
|
|
|
before :each do
|
|
|
|
@s = CApiStructSpecs.new
|
|
|
|
@struct = @s.rb_struct_define("CAPIStruct", "a", "b", "c")
|
|
|
|
end
|
|
|
|
|
|
|
|
after :each do
|
|
|
|
Struct.send(:remove_const, :CAPIStruct)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_define" do
|
|
|
|
it "creates accessors for the struct members" do
|
|
|
|
instance = @struct.new
|
|
|
|
instance.a = 1
|
|
|
|
instance.b = 2
|
|
|
|
instance.c = 3
|
|
|
|
instance.a.should == 1
|
|
|
|
instance.b.should == 2
|
|
|
|
instance.c.should == 3
|
|
|
|
end
|
|
|
|
|
|
|
|
it "has a value of nil for the member of a newly created instance" do
|
|
|
|
# Verify that attributes are on an instance basis
|
|
|
|
Struct::CAPIStruct.new.b.should be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "creates a constant scoped under Struct for the named Struct" do
|
|
|
|
Struct.should have_constant(:CAPIStruct)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the member names as Symbols" do
|
|
|
|
@struct.members.should == [:a, :b, :c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "C-API Struct function" do
|
|
|
|
before :each do
|
|
|
|
@s = CApiStructSpecs.new
|
|
|
|
@struct = @s.rb_struct_define(nil, "a", "b", "c")
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_define for an anonymous struct" do
|
|
|
|
it "creates accessors for the struct members" do
|
|
|
|
instance = @struct.new
|
|
|
|
instance.a = 1
|
|
|
|
instance.b = 2
|
|
|
|
instance.c = 3
|
|
|
|
instance.a.should == 1
|
|
|
|
instance.b.should == 2
|
|
|
|
instance.c.should == 3
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the member names as Symbols" do
|
|
|
|
@struct.members.should == [:a, :b, :c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "C-API Struct function" do
|
|
|
|
before :each do
|
|
|
|
@s = CApiStructSpecs.new
|
2018-08-27 10:25:00 -04:00
|
|
|
@struct = @s.rb_struct_define_under(CApiStructSpecs, "CAPIStructUnder", "a", "b", "c")
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_define_under" do
|
|
|
|
it "creates accessors for the struct members" do
|
|
|
|
instance = @struct.new
|
|
|
|
instance.a = 1
|
|
|
|
instance.b = 2
|
|
|
|
instance.c = 3
|
|
|
|
instance.a.should == 1
|
|
|
|
instance.b.should == 2
|
|
|
|
instance.c.should == 3
|
|
|
|
end
|
|
|
|
|
|
|
|
it "has a value of nil for the member of a newly created instance" do
|
|
|
|
# Verify that attributes are on an instance basis
|
2018-08-27 10:25:00 -04:00
|
|
|
CApiStructSpecs::CAPIStructUnder.new.b.should be_nil
|
|
|
|
end
|
|
|
|
|
|
|
|
it "does not create a constant scoped under Struct for the named Struct" do
|
|
|
|
Struct.should_not have_constant(:CAPIStructUnder)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "creates a constant scoped under the namespace of the given class" do
|
2018-08-27 10:25:00 -04:00
|
|
|
CApiStructSpecs.should have_constant(:CAPIStructUnder)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the member names as Symbols" do
|
|
|
|
@struct.members.should == [:a, :b, :c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "C-API Struct function" do
|
|
|
|
before :each do
|
|
|
|
@s = CApiStructSpecs.new
|
|
|
|
@klass = Struct.new(:a, :b, :c)
|
|
|
|
@struct = @klass.new
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_define" do
|
|
|
|
it "raises an ArgumentError if arguments contain duplicate member name" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_define(nil, "a", "b", "a") }.should raise_error(ArgumentError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "raises a NameError if an invalid constant name is given" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_define("foo", "a", "b", "c") }.should raise_error(NameError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_aref" do
|
|
|
|
it "returns the value of a struct member with a symbol key" do
|
|
|
|
@struct[:a] = 2
|
|
|
|
@s.rb_struct_aref(@struct, :a).should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the value of a struct member with a string key" do
|
|
|
|
@struct[:b] = 2
|
|
|
|
@s.rb_struct_aref(@struct, "b").should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns the value of a struct member by index" do
|
|
|
|
@struct[:c] = 3
|
|
|
|
@s.rb_struct_aref(@struct, 2).should == 3
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises a NameError if the struct member does not exist" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_aref(@struct, :d) }.should raise_error(NameError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "raises an IndexError if the given index is out of range" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_aref(@struct, -4) }.should raise_error(IndexError)
|
|
|
|
-> { @s.rb_struct_aref(@struct, 3) }.should raise_error(IndexError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_getmember" do
|
|
|
|
it "returns the value of a struct member" do
|
|
|
|
@struct[:a] = 2
|
|
|
|
@s.rb_struct_getmember(@struct, :a).should == 2
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises a NameError if the struct member does not exist" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_getmember(@struct, :d) }.should raise_error(NameError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_s_members" do
|
|
|
|
it "returns the struct members as an array of symbols" do
|
|
|
|
@s.rb_struct_s_members(@klass).should == [:a, :b, :c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_members" do
|
|
|
|
it "returns the struct members as an array of symbols" do
|
|
|
|
@s.rb_struct_members(@struct).should == [:a, :b, :c]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_aset" do
|
|
|
|
it "sets the value of a struct member with a symbol key" do
|
|
|
|
@s.rb_struct_aset(@struct, :a, 1)
|
|
|
|
@struct[:a].should == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets the value of a struct member with a string key" do
|
|
|
|
@s.rb_struct_aset(@struct, "b", 1)
|
|
|
|
@struct[:b].should == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
it "sets the value of a struct member by index" do
|
|
|
|
@s.rb_struct_aset(@struct, 2, 1)
|
|
|
|
@struct[:c].should == 1
|
|
|
|
end
|
|
|
|
|
|
|
|
it "raises a NameError if the struct member does not exist" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_aset(@struct, :d, 1) }.should raise_error(NameError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
it "raises an IndexError if the given index is out of range" do
|
2019-07-27 06:40:09 -04:00
|
|
|
-> { @s.rb_struct_aset(@struct, -4, 1) }.should raise_error(IndexError)
|
|
|
|
-> { @s.rb_struct_aset(@struct, 3, 1) }.should raise_error(IndexError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
|
2020-02-08 21:07:01 -05:00
|
|
|
it "raises a FrozenError if the struct is frozen" do
|
2017-05-07 08:04:49 -04:00
|
|
|
@struct.freeze
|
2020-02-08 21:07:01 -05:00
|
|
|
-> { @s.rb_struct_aset(@struct, :a, 1) }.should raise_error(FrozenError)
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe "rb_struct_new" do
|
|
|
|
it "creates a new instance of a struct" do
|
|
|
|
i = @s.rb_struct_new(@klass, 1, 2, 3)
|
|
|
|
i.a.should == 1
|
|
|
|
i.b.should == 2
|
|
|
|
i.c.should == 3
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-04-27 12:53:23 -04:00
|
|
|
describe "rb_struct_size" do
|
|
|
|
it "returns the number of struct members" do
|
|
|
|
@s.rb_struct_size(@struct).should == 3
|
2017-05-07 08:04:49 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|