aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/optional/capi
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2019-05-28 22:41:48 +0200
committerBenoit Daloze <eregontp@gmail.com>2019-05-28 22:41:48 +0200
commita66bc2c01194a9c017c874a30db5b3b6bd95e966 (patch)
tree598d6375b44fd86f90c3477c73086f6fcf08d76c /spec/ruby/optional/capi
parentd070523e7be4b95914adeef9a10401fba7718c5a (diff)
downloadruby-a66bc2c01194a9c017c874a30db5b3b6bd95e966.tar.gz
Update to ruby/spec@9a501a8
Diffstat (limited to 'spec/ruby/optional/capi')
-rw-r--r--spec/ruby/optional/capi/ext/hash_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/kernel_spec.c12
-rw-r--r--spec/ruby/optional/capi/ext/util_spec.c25
-rw-r--r--spec/ruby/optional/capi/hash_spec.rb5
-rw-r--r--spec/ruby/optional/capi/kernel_spec.rb16
-rw-r--r--spec/ruby/optional/capi/util_spec.rb44
6 files changed, 108 insertions, 0 deletions
diff --git a/spec/ruby/optional/capi/ext/hash_spec.c b/spec/ruby/optional/capi/ext/hash_spec.c
index 4e9312a1d1..c8735cec2c 100644
--- a/spec/ruby/optional/capi/ext/hash_spec.c
+++ b/spec/ruby/optional/capi/ext/hash_spec.c
@@ -96,6 +96,11 @@ VALUE hash_spec_rb_hash_lookup2(VALUE self, VALUE hash, VALUE key, VALUE def) {
return rb_hash_lookup2(hash, key, def);
}
+VALUE hash_spec_rb_hash_lookup2_default_undef(VALUE self, VALUE hash, VALUE key) {
+ VALUE ret = rb_hash_lookup2(hash, key, Qundef);
+ return ret == Qundef ? Qtrue : Qfalse;
+}
+
VALUE hash_spec_rb_hash_new(VALUE self) {
return rb_hash_new();
}
@@ -127,6 +132,7 @@ void Init_hash_spec(void) {
rb_define_method(cls, "rb_hash_lookup_nil", hash_spec_rb_hash_lookup_nil, 2);
rb_define_method(cls, "rb_hash_lookup", hash_spec_rb_hash_lookup, 2);
rb_define_method(cls, "rb_hash_lookup2", hash_spec_rb_hash_lookup2, 3);
+ rb_define_method(cls, "rb_hash_lookup2_default_undef", hash_spec_rb_hash_lookup2_default_undef, 2);
rb_define_method(cls, "rb_hash_new", hash_spec_rb_hash_new, 0);
rb_define_method(cls, "rb_hash_size", hash_spec_rb_hash_size, 1);
rb_define_method(cls, "rb_hash_set_ifnone", hash_spec_rb_hash_set_ifnone, 2);
diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c
index 48e2b1ca95..ed6e08a880 100644
--- a/spec/ruby/optional/capi/ext/kernel_spec.c
+++ b/spec/ruby/optional/capi/ext/kernel_spec.c
@@ -175,6 +175,17 @@ static VALUE kernel_spec_rb_protect_yield(VALUE self, VALUE obj, VALUE ary) {
return res;
}
+static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary) {
+ int status = 0;
+ VALUE res = rb_eval_string_protect(RSTRING_PTR(str), &status);
+ rb_ary_store(ary, 0, INT2NUM(23));
+ rb_ary_store(ary, 1, res);
+ if (status) {
+ rb_jump_tag(status);
+ }
+ return res;
+}
+
VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) {
errno = 1;
if(msg == Qnil) {
@@ -301,6 +312,7 @@ void Init_kernel_spec(void) {
rb_define_method(cls, "rb_rescue", kernel_spec_rb_rescue, 4);
rb_define_method(cls, "rb_rescue2", kernel_spec_rb_rescue2, -1);
rb_define_method(cls, "rb_protect_yield", kernel_spec_rb_protect_yield, 2);
+ rb_define_method(cls, "rb_eval_string_protect", kernel_spec_rb_eval_string_protect, 2);
rb_define_method(cls, "rb_catch", kernel_spec_rb_catch, 2);
rb_define_method(cls, "rb_catch_obj", kernel_spec_rb_catch_obj, 2);
rb_define_method(cls, "rb_sys_fail", kernel_spec_rb_sys_fail, 1);
diff --git a/spec/ruby/optional/capi/ext/util_spec.c b/spec/ruby/optional/capi/ext/util_spec.c
index d99ed12e14..181949ee4b 100644
--- a/spec/ruby/optional/capi/ext/util_spec.c
+++ b/spec/ruby/optional/capi/ext/util_spec.c
@@ -44,6 +44,30 @@ VALUE util_spec_rb_scan_args(VALUE self, VALUE argv, VALUE fmt, VALUE expected,
return INT2NUM(result);
}
+static VALUE util_spec_rb_get_kwargs(VALUE self, VALUE keyword_hash, VALUE keys, VALUE required, VALUE optional) {
+ int req = FIX2INT(required);
+ int opt = FIX2INT(optional);
+ int len = RARRAY_LEN(keys);
+
+ int values_len = req + (opt < 0 ? -1 - opt : opt);
+ int i = 0;
+
+ ID *ids = malloc(sizeof(VALUE) * len);
+ VALUE *results = malloc(sizeof(VALUE) * values_len);
+ int extracted = 0;
+ VALUE ary = Qundef;
+
+ for (i = 0; i < len; i++) {
+ ids[i] = SYM2ID(rb_ary_entry(keys, i));
+ }
+
+ extracted = rb_get_kwargs(keyword_hash, ids, req, opt, results);
+ ary = rb_ary_new_from_values(extracted, results);
+ free(results);
+ free(ids);
+ return ary;
+}
+
static VALUE util_spec_rb_long2int(VALUE self, VALUE n) {
return INT2NUM(rb_long2int(NUM2LONG(n)));
}
@@ -64,6 +88,7 @@ static VALUE util_spec_rb_sourceline(VALUE self) {
void Init_util_spec(void) {
VALUE cls = rb_define_class("CApiUtilSpecs", rb_cObject);
rb_define_method(cls, "rb_scan_args", util_spec_rb_scan_args, 4);
+ rb_define_method(cls, "rb_get_kwargs", util_spec_rb_get_kwargs, 4);
rb_define_method(cls, "rb_long2int", util_spec_rb_long2int, 1);
rb_define_method(cls, "rb_iter_break", util_spec_rb_iter_break, 0);
rb_define_method(cls, "rb_sourcefile", util_spec_rb_sourcefile, 0);
diff --git a/spec/ruby/optional/capi/hash_spec.rb b/spec/ruby/optional/capi/hash_spec.rb
index f584e73006..92dc62d55b 100644
--- a/spec/ruby/optional/capi/hash_spec.rb
+++ b/spec/ruby/optional/capi/hash_spec.rb
@@ -211,6 +211,11 @@ describe "C-API Hash function" do
@s.rb_hash_lookup2(hash, :chunky, 10).should == 10
end
+
+ it "returns undefined if that is the default value specified" do
+ hsh = Hash.new(0)
+ @s.rb_hash_lookup2_default_undef(hsh, :chunky).should be_true
+ end
end
end
diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb
index ab6c2bceef..3fb2c8ed2d 100644
--- a/spec/ruby/optional/capi/kernel_spec.rb
+++ b/spec/ruby/optional/capi/kernel_spec.rb
@@ -292,6 +292,22 @@ describe "C-API Kernel function" do
end
end
+ describe "rb_eval_string_protect" do
+ it "will evaluate the given string" do
+ proof = []
+ res = @s.rb_eval_string_protect('1 + 7', proof)
+ proof.should == [23, 8]
+ end
+
+ it "will allow cleanup code to be run when an exception is raised" do
+ proof = []
+ lambda do
+ @s.rb_eval_string_protect('raise RuntimeError', proof)
+ end.should raise_error(RuntimeError)
+ proof.should == [23, nil]
+ end
+ end
+
describe "rb_rescue" do
before :each do
@proc = lambda { |x| x }
diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb
index 33dc30df85..5f8f9c6e3b 100644
--- a/spec/ruby/optional/capi/util_spec.rb
+++ b/spec/ruby/optional/capi/util_spec.rb
@@ -154,6 +154,50 @@ describe "C-API Util function" do
end
end
+ describe "rb_get_kwargs" do
+ it "extracts required arguments in the order requested" do
+ h = { :a => 7, :b => 5 }
+ @o.rb_get_kwargs(h, [:b, :a], 2, 0).should == [5, 7]
+ h.should == {}
+ end
+
+ it "extracts required and optional arguments in the order requested" do
+ h = { :a => 7, :c => 12, :b => 5 }
+ @o.rb_get_kwargs(h, [:b, :a, :c], 2, 1).should == [5, 7, 12]
+ h.should == {}
+ end
+
+ it "accepts nil instead of a hash when only optional arguments are requested" do
+ h = nil
+ @o.rb_get_kwargs(h, [:b, :a, :c], 0, 3).should == []
+ h.should == nil
+ end
+
+ it "raises an error if a required argument is not in the hash" do
+ h = { :a => 7, :c => 12, :b => 5 }
+ lambda { @o.rb_get_kwargs(h, [:b, :d], 2, 0) }.should raise_error(ArgumentError, /missing keyword: d/)
+ h.should == {:a => 7, :c => 12}
+ end
+
+ it "does not raise an error for an optional argument not in the hash" do
+ h = { :a => 7, :b => 5 }
+ @o.rb_get_kwargs(h, [:b, :a, :c], 2, 1).should == [5, 7]
+ h.should == {}
+ end
+
+ it "raises an error if there are additional arguments and optional is positive" do
+ h = { :a => 7, :c => 12, :b => 5 }
+ lambda { @o.rb_get_kwargs(h, [:b, :a], 2, 0) }.should raise_error(ArgumentError, /unknown keyword: c/)
+ h.should == {:c => 12}
+ end
+
+ it "leaves additional arguments in the hash if optional is negative" do
+ h = { :a => 7, :c => 12, :b => 5 }
+ @o.rb_get_kwargs(h, [:b, :a], 2, -1).should == [5, 7]
+ h.should == {:c => 12}
+ end
+ end
+
platform_is wordsize: 64 do
describe "rb_long2int" do
it "raises a RangeError if the value is outside the range of a C int" do