Skip to content

Commit 0c6439c

Browse files
eregonheadius
authored andcommitted
Implement and add specs for rb_struct_initialize() for both Struct and Data
* Fixes truffleruby/truffleruby#3997
1 parent 1b8e211 commit 0c6439c

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed

optional/capi/ext/struct_spec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ static VALUE struct_spec_rb_struct_size(VALUE self, VALUE st) {
6262
return rb_struct_size(st);
6363
}
6464

65+
static VALUE struct_spec_rb_struct_initialize(VALUE self, VALUE st, VALUE values) {
66+
return rb_struct_initialize(st, values);
67+
}
68+
6569
#if defined(RUBY_VERSION_IS_3_3)
6670
/* Only allow setting three attributes, should be sufficient for testing. */
6771
static VALUE struct_spec_rb_data_define(VALUE self, VALUE superclass,
@@ -90,6 +94,7 @@ void Init_struct_spec(void) {
9094
rb_define_method(cls, "rb_struct_define_under", struct_spec_rb_struct_define_under, 5);
9195
rb_define_method(cls, "rb_struct_new", struct_spec_rb_struct_new, 4);
9296
rb_define_method(cls, "rb_struct_size", struct_spec_rb_struct_size, 1);
97+
rb_define_method(cls, "rb_struct_initialize", struct_spec_rb_struct_initialize, 2);
9398
#if defined(RUBY_VERSION_IS_3_3)
9499
rb_define_method(cls, "rb_data_define", struct_spec_rb_data_define, 4);
95100
#endif

optional/capi/struct_spec.rb

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,48 @@
208208
@s.rb_struct_size(@struct).should == 3
209209
end
210210
end
211+
212+
describe "rb_struct_initialize" do
213+
it "sets all members" do
214+
@s.rb_struct_initialize(@struct, [1, 2, 3]).should == nil
215+
@struct.a.should == 1
216+
@struct.b.should == 2
217+
@struct.c.should == 3
218+
end
219+
220+
it "does not freeze the Struct instance" do
221+
@s.rb_struct_initialize(@struct, [1, 2, 3]).should == nil
222+
@struct.should_not.frozen?
223+
@s.rb_struct_initialize(@struct, [4, 5, 6]).should == nil
224+
@struct.a.should == 4
225+
@struct.b.should == 5
226+
@struct.c.should == 6
227+
end
228+
229+
it "raises ArgumentError if too many values" do
230+
-> { @s.rb_struct_initialize(@struct, [1, 2, 3, 4]) }.should raise_error(ArgumentError, "struct size differs")
231+
end
232+
233+
it "treats missing values as nil" do
234+
@s.rb_struct_initialize(@struct, [1, 2]).should == nil
235+
@struct.a.should == 1
236+
@struct.b.should == 2
237+
@struct.c.should == nil
238+
end
239+
end
211240
end
212241

213242
ruby_version_is "3.3" do
214243
describe "C-API Data function" do
215-
before :each do
244+
before :all do
216245
@s = CApiStructSpecs.new
246+
@klass = @s.rb_data_define(nil, "a", "b", "c")
217247
end
218248

219249
describe "rb_data_define" do
220250
it "returns a subclass of Data class when passed nil as the first argument" do
221-
klass = @s.rb_data_define(nil, "a", "b", "c")
222-
223-
klass.should.is_a? Class
224-
klass.superclass.should == Data
251+
@klass.should.is_a? Class
252+
@klass.superclass.should == Data
225253
end
226254

227255
it "returns a subclass of a class when passed as the first argument" do
@@ -233,17 +261,15 @@
233261
end
234262

235263
it "creates readers for the members" do
236-
klass = @s.rb_data_define(nil, "a", "b", "c")
237-
obj = klass.new(1, 2, 3)
264+
obj = @klass.new(1, 2, 3)
238265

239266
obj.a.should == 1
240267
obj.b.should == 2
241268
obj.c.should == 3
242269
end
243270

244271
it "returns the member names as Symbols" do
245-
klass = @s.rb_data_define(nil, "a", "b", "c")
246-
obj = klass.new(0, 0, 0)
272+
obj = @klass.new(0, 0, 0)
247273

248274
obj.members.should == [:a, :b, :c]
249275
end
@@ -256,5 +282,35 @@
256282
-> { @s.rb_data_define([], "a", "b", "c") }.should raise_error(TypeError, "wrong argument type Array (expected Class)")
257283
end
258284
end
285+
286+
describe "rb_struct_initialize" do
287+
it "sets all members for a Data instance" do
288+
data = @klass.allocate
289+
@s.rb_struct_initialize(data, [1, 2, 3]).should == nil
290+
data.a.should == 1
291+
data.b.should == 2
292+
data.c.should == 3
293+
end
294+
295+
it "freezes the Data instance" do
296+
data = @klass.allocate
297+
@s.rb_struct_initialize(data, [1, 2, 3]).should == nil
298+
data.should.frozen?
299+
-> { @s.rb_struct_initialize(data, [1, 2, 3]) }.should raise_error(FrozenError)
300+
end
301+
302+
it "raises ArgumentError if too many values" do
303+
data = @klass.allocate
304+
-> { @s.rb_struct_initialize(data, [1, 2, 3, 4]) }.should raise_error(ArgumentError, "struct size differs")
305+
end
306+
307+
it "treats missing values as nil" do
308+
data = @klass.allocate
309+
@s.rb_struct_initialize(data, [1, 2]).should == nil
310+
data.a.should == 1
311+
data.b.should == 2
312+
data.c.should == nil
313+
end
314+
end
259315
end
260316
end

0 commit comments

Comments
 (0)