diff options
Diffstat (limited to 'spec/ruby/optional')
| -rw-r--r-- | spec/ruby/optional/capi/encoding_spec.rb | 30 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/ext/encoding_spec.c | 5 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/ext/kernel_spec.c | 11 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/ext/string_spec.c | 10 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/io_spec.rb | 240 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/kernel_spec.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/object_spec.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/spec_helper.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/string_spec.rb | 125 | ||||
| -rw-r--r-- | spec/ruby/optional/capi/struct_spec.rb | 142 |
10 files changed, 381 insertions, 196 deletions
diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb index c14983c7ea..734b5f1253 100644 --- a/spec/ruby/optional/capi/encoding_spec.rb +++ b/spec/ruby/optional/capi/encoding_spec.rb @@ -745,4 +745,34 @@ describe "C-API Encoding function" do ruby_exe(code, args: "2>&1", exit_status: 1).should.include?('too many encoding (> 256) (EncodingError)') end end + + describe "ONIGENC_IS_UNICODE" do + it "is true only for select UTF-related encodings" do + unicode = [ + Encoding::UTF_8, + Encoding::UTF8_DOCOMO, + Encoding::UTF8_KDDI, + Encoding::UTF8_MAC, + Encoding::UTF8_SOFTBANK, + Encoding::CESU_8, + Encoding::UTF_16LE, + Encoding::UTF_16BE, + Encoding::UTF_32LE, + Encoding::UTF_32BE + ] + unicode.each do |enc| + @s.should.ONIGENC_IS_UNICODE(enc) + end + + (Encoding.list - unicode).each { |enc| + @s.should_not.ONIGENC_IS_UNICODE(enc) + } + end + + # Redundant with the above but more explicit + it "is false for the dummy UTF-16 and UTF-32 encodings" do + @s.should_not.ONIGENC_IS_UNICODE(Encoding::UTF_16) + @s.should_not.ONIGENC_IS_UNICODE(Encoding::UTF_32) + end + end end diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c index aa8662cfbd..98d4e2e3b7 100644 --- a/spec/ruby/optional/capi/ext/encoding_spec.c +++ b/spec/ruby/optional/capi/ext/encoding_spec.c @@ -324,6 +324,10 @@ static VALUE encoding_spec_rb_define_dummy_encoding(VALUE self, VALUE name) { return INT2NUM(rb_define_dummy_encoding(RSTRING_PTR(name))); } +static VALUE encoding_spec_ONIGENC_IS_UNICODE(VALUE self, VALUE encoding) { + return ONIGENC_IS_UNICODE(rb_to_encoding(encoding)) ? Qtrue : Qfalse; +} + void Init_encoding_spec(void) { VALUE cls; native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*)); @@ -384,6 +388,7 @@ void Init_encoding_spec(void) { rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1); rb_define_method(cls, "rb_enc_left_char_head", encoding_spec_rb_enc_left_char_head, 2); rb_define_method(cls, "rb_define_dummy_encoding", encoding_spec_rb_define_dummy_encoding, 1); + rb_define_method(cls, "ONIGENC_IS_UNICODE", encoding_spec_ONIGENC_IS_UNICODE, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c index a8fed21b59..eee324052d 100644 --- a/spec/ruby/optional/capi/ext/kernel_spec.c +++ b/spec/ruby/optional/capi/ext/kernel_spec.c @@ -1,4 +1,5 @@ #include "ruby.h" +#include "ruby/vm.h" #include "rubyspec.h" #include <errno.h> @@ -337,6 +338,15 @@ static VALUE kernel_spec_rb_set_end_proc(VALUE self, VALUE io) { return Qnil; } +static void at_exit_hook(ruby_vm_t *vm) { + puts("ruby_vm_at_exit hook ran"); +} + +static VALUE kernel_spec_ruby_vm_at_exit(VALUE self) { + ruby_vm_at_exit(at_exit_hook); + return self; +} + static VALUE kernel_spec_rb_f_sprintf(VALUE self, VALUE ary) { return rb_f_sprintf((int)RARRAY_LEN(ary), RARRAY_PTR(ary)); } @@ -434,6 +444,7 @@ void Init_kernel_spec(void) { rb_define_method(cls, "rb_yield_splat", kernel_spec_rb_yield_splat, 1); rb_define_method(cls, "rb_exec_recursive", kernel_spec_rb_exec_recursive, 1); rb_define_method(cls, "rb_set_end_proc", kernel_spec_rb_set_end_proc, 1); + rb_define_method(cls, "ruby_vm_at_exit", kernel_spec_ruby_vm_at_exit, 0); rb_define_method(cls, "rb_f_sprintf", kernel_spec_rb_f_sprintf, 1); rb_define_method(cls, "rb_str_format", kernel_spec_rb_str_format, 3); rb_define_method(cls, "rb_make_backtrace", kernel_spec_rb_make_backtrace, 0); diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c index 094013e049..74aa9e56e8 100644 --- a/spec/ruby/optional/capi/ext/string_spec.c +++ b/spec/ruby/optional/capi/ext/string_spec.c @@ -581,6 +581,14 @@ static VALUE string_spec_rb_str_to_interned_str(VALUE self, VALUE str) { return rb_str_to_interned_str(str); } +static VALUE string_spec_rb_interned_str(VALUE self, VALUE str, VALUE len) { + return rb_interned_str(RSTRING_PTR(str), FIX2LONG(len)); +} + +static VALUE string_spec_rb_interned_str_cstr(VALUE self, VALUE str) { + return rb_interned_str_cstr(RSTRING_PTR(str)); +} + void Init_string_spec(void) { VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject); rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2); @@ -681,6 +689,8 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_enc_interned_str_cstr", string_spec_rb_enc_interned_str_cstr, 2); rb_define_method(cls, "rb_enc_interned_str", string_spec_rb_enc_interned_str, 3); rb_define_method(cls, "rb_str_to_interned_str", string_spec_rb_str_to_interned_str, 1); + rb_define_method(cls, "rb_interned_str", string_spec_rb_interned_str, 2); + rb_define_method(cls, "rb_interned_str_cstr", string_spec_rb_interned_str_cstr, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index ab7a7fc8f6..dc4ac3e374 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -494,166 +494,164 @@ describe "C-API IO function" do end end - ruby_version_is "3.3" do - describe "rb_io_mode" do - it "returns the mode" do - (@o.rb_io_mode(@r_io) & 0b11).should == 0b01 - (@o.rb_io_mode(@w_io) & 0b11).should == 0b10 - (@o.rb_io_mode(@rw_io) & 0b11).should == 0b11 - end + describe "rb_io_mode" do + it "returns the mode" do + (@o.rb_io_mode(@r_io) & 0b11).should == 0b01 + (@o.rb_io_mode(@w_io) & 0b11).should == 0b10 + (@o.rb_io_mode(@rw_io) & 0b11).should == 0b11 end + end - describe "rb_io_path" do - it "returns the IO#path" do - @o.rb_io_path(@r_io).should == @r_io.path - @o.rb_io_path(@rw_io).should == @rw_io.path - @o.rb_io_path(@rw_io).should == @name - end + describe "rb_io_path" do + it "returns the IO#path" do + @o.rb_io_path(@r_io).should == @r_io.path + @o.rb_io_path(@rw_io).should == @rw_io.path + @o.rb_io_path(@rw_io).should == @name end + end - describe "rb_io_closed_p" do - it "returns false when io is not closed" do - @o.rb_io_closed_p(@r_io).should == false - @r_io.closed?.should == false - end + describe "rb_io_closed_p" do + it "returns false when io is not closed" do + @o.rb_io_closed_p(@r_io).should == false + @r_io.closed?.should == false + end - it "returns true when io is closed" do - @r_io.close + it "returns true when io is closed" do + @r_io.close - @o.rb_io_closed_p(@r_io).should == true - @r_io.closed?.should == true - end + @o.rb_io_closed_p(@r_io).should == true + @r_io.closed?.should == true end + end - quarantine! do # "Errno::EBADF: Bad file descriptor" at closing @r_io, @rw_io etc in the after :each hook - describe "rb_io_open_descriptor" do - it "creates a new IO instance" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.should.is_a?(IO) - end - - it "return an instance of the specified class" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.class.should == File + quarantine! do # "Errno::EBADF: Bad file descriptor" at closing @r_io, @rw_io etc in the after :each hook + describe "rb_io_open_descriptor" do + it "creates a new IO instance" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.should.is_a?(IO) + end - io = @o.rb_io_open_descriptor(IO, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.class.should == IO - end + it "return an instance of the specified class" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.class.should == File - it "sets the specified file descriptor" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.fileno.should == @r_io.fileno - end + io = @o.rb_io_open_descriptor(IO, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.class.should == IO + end - it "sets the specified path" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.path.should == "a.txt" - end + it "sets the specified file descriptor" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.fileno.should == @r_io.fileno + end - it "sets the specified mode" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, CApiIOSpecs::FMODE_BINMODE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.should.binmode? + it "sets the specified path" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.path.should == "a.txt" + end - io = @o.rb_io_open_descriptor(File, @r_io.fileno, CApiIOSpecs::FMODE_TEXTMODE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.should_not.binmode? - end + it "sets the specified mode" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, CApiIOSpecs::FMODE_BINMODE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.should.binmode? - it "sets the specified timeout" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.timeout.should == 60 - end + io = @o.rb_io_open_descriptor(File, @r_io.fileno, CApiIOSpecs::FMODE_TEXTMODE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.should_not.binmode? + end - it "sets the specified internal encoding" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.internal_encoding.should == Encoding::US_ASCII - end + it "sets the specified timeout" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.timeout.should == 60 + end - it "sets the specified external encoding" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.external_encoding.should == Encoding::UTF_8 - end + it "sets the specified internal encoding" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.internal_encoding.should == Encoding::US_ASCII + end - it "does not apply the specified encoding flags" do - name = tmp("rb_io_open_descriptor_specs") - File.write(name, "123\r\n456\n89") - file = File.open(name, "r") + it "sets the specified external encoding" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.external_encoding.should == Encoding::UTF_8 + end - io = @o.rb_io_open_descriptor(File, file.fileno, CApiIOSpecs::FMODE_READABLE, "a.txt", 60, "US-ASCII", "UTF-8", CApiIOSpecs::ECONV_UNIVERSAL_NEWLINE_DECORATOR, {}) - io.read_nonblock(20).should == "123\r\n456\n89" - ensure - file.close - rm_r name - end + it "does not apply the specified encoding flags" do + name = tmp("rb_io_open_descriptor_specs") + File.write(name, "123\r\n456\n89") + file = File.open(name, "r") - it "ignores the IO open options" do - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {external_encoding: "windows-1251"}) - io.external_encoding.should == Encoding::UTF_8 + io = @o.rb_io_open_descriptor(File, file.fileno, CApiIOSpecs::FMODE_READABLE, "a.txt", 60, "US-ASCII", "UTF-8", CApiIOSpecs::ECONV_UNIVERSAL_NEWLINE_DECORATOR, {}) + io.read_nonblock(20).should == "123\r\n456\n89" + ensure + file.close + rm_r name + end - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {internal_encoding: "windows-1251"}) - io.internal_encoding.should == Encoding::US_ASCII + it "ignores the IO open options" do + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {external_encoding: "windows-1251"}) + io.external_encoding.should == Encoding::UTF_8 - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {encoding: "windows-1251:binary"}) - io.external_encoding.should == Encoding::UTF_8 - io.internal_encoding.should == Encoding::US_ASCII + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {internal_encoding: "windows-1251"}) + io.internal_encoding.should == Encoding::US_ASCII - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {textmode: false}) - io.should_not.binmode? + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {encoding: "windows-1251:binary"}) + io.external_encoding.should == Encoding::UTF_8 + io.internal_encoding.should == Encoding::US_ASCII - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {binmode: true}) - io.should_not.binmode? + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {textmode: false}) + io.should_not.binmode? - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {autoclose: false}) - io.should.autoclose? + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {binmode: true}) + io.should_not.binmode? - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {path: "a.txt"}) - io.path.should == "a.txt" - end + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {autoclose: false}) + io.should.autoclose? - it "ignores the IO encoding options" do - io = @o.rb_io_open_descriptor(File, @w_io.fileno, CApiIOSpecs::FMODE_WRITABLE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {crlf_newline: true}) + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, "a.txt", 60, "US-ASCII", "UTF-8", 0, {path: "a.txt"}) + io.path.should == "a.txt" + end - io.write("123\r\n456\n89") - io.flush + it "ignores the IO encoding options" do + io = @o.rb_io_open_descriptor(File, @w_io.fileno, CApiIOSpecs::FMODE_WRITABLE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {crlf_newline: true}) - @r_io.read_nonblock(20).should == "123\r\n456\n89" - end + io.write("123\r\n456\n89") + io.flush - it "allows wrong mode" do - io = @o.rb_io_open_descriptor(File, @w_io.fileno, CApiIOSpecs::FMODE_READABLE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) - io.should.is_a?(File) + @r_io.read_nonblock(20).should == "123\r\n456\n89" + end - platform_is_not :windows do - -> { io.read_nonblock(1) }.should raise_error(Errno::EBADF) - end + it "allows wrong mode" do + io = @o.rb_io_open_descriptor(File, @w_io.fileno, CApiIOSpecs::FMODE_READABLE, "a.txt", 60, "US-ASCII", "UTF-8", 0, {}) + io.should.is_a?(File) - platform_is :windows do - -> { io.read_nonblock(1) }.should raise_error(IO::EWOULDBLOCKWaitReadable) - end + platform_is_not :windows do + -> { io.read_nonblock(1) }.should raise_error(Errno::EBADF) end - it "tolerates NULL as rb_io_encoding *encoding parameter" do - io = @o.rb_io_open_descriptor_without_encoding(File, @r_io.fileno, 0, "a.txt", 60) - io.should.is_a?(File) + platform_is :windows do + -> { io.read_nonblock(1) }.should raise_error(IO::EWOULDBLOCKWaitReadable) end + end - it "deduplicates path String" do - path = "a.txt".dup - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) - io.path.should_not equal(path) + it "tolerates NULL as rb_io_encoding *encoding parameter" do + io = @o.rb_io_open_descriptor_without_encoding(File, @r_io.fileno, 0, "a.txt", 60) + io.should.is_a?(File) + end - path = "a.txt".freeze - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) - io.path.should_not equal(path) - end + it "deduplicates path String" do + path = "a.txt".dup + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) + io.path.should_not equal(path) + + path = "a.txt".freeze + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) + io.path.should_not equal(path) + end - it "calls #to_str to convert a path to a String" do - path = Object.new - def path.to_str; "a.txt"; end + it "calls #to_str to convert a path to a String" do + path = Object.new + def path.to_str; "a.txt"; end - io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) + io = @o.rb_io_open_descriptor(File, @r_io.fileno, 0, path, 60, "US-ASCII", "UTF-8", 0, {}) - io.path.should == "a.txt" - end + io.path.should == "a.txt" end end end diff --git a/spec/ruby/optional/capi/kernel_spec.rb b/spec/ruby/optional/capi/kernel_spec.rb index 6633ee50c1..0a2362fb30 100644 --- a/spec/ruby/optional/capi/kernel_spec.rb +++ b/spec/ruby/optional/capi/kernel_spec.rb @@ -703,6 +703,12 @@ describe "C-API Kernel function" do end end + describe "ruby_vm_at_exit" do + it "runs a C function after the VM is terminated" do + ruby_exe("require #{kernel_path.inspect}; CApiKernelSpecs.new.ruby_vm_at_exit").should == "ruby_vm_at_exit hook ran\n" + end + end + describe "rb_f_sprintf" do it "returns a string according to format and arguments" do @s.rb_f_sprintf(["%d %f %s", 10, 2.5, "test"]).should == "10 2.500000 test" diff --git a/spec/ruby/optional/capi/object_spec.rb b/spec/ruby/optional/capi/object_spec.rb index 8b4d8a9bba..6716fd9e33 100644 --- a/spec/ruby/optional/capi/object_spec.rb +++ b/spec/ruby/optional/capi/object_spec.rb @@ -1004,7 +1004,6 @@ describe "CApiObject" do it "calls the callback function for each cvar and ivar on a class" do exp = [:@@cvar, :foo, :@@cvar2, :bar, :@ivar, :baz] - exp.unshift(:__classpath__, 'CApiObjectSpecs::CVars') if RUBY_VERSION < "3.3" ary = @o.rb_ivar_foreach(CApiObjectSpecs::CVars) ary.should == exp @@ -1012,7 +1011,6 @@ describe "CApiObject" do it "calls the callback function for each cvar and ivar on a module" do exp = [:@@mvar, :foo, :@@mvar2, :bar, :@ivar, :baz] - exp.unshift(:__classpath__, 'CApiObjectSpecs::MVars') if RUBY_VERSION < "3.3" ary = @o.rb_ivar_foreach(CApiObjectSpecs::MVars) ary.should == exp diff --git a/spec/ruby/optional/capi/spec_helper.rb b/spec/ruby/optional/capi/spec_helper.rb index e7abf46e6c..d937c967d0 100644 --- a/spec/ruby/optional/capi/spec_helper.rb +++ b/spec/ruby/optional/capi/spec_helper.rb @@ -59,7 +59,11 @@ def compile_extension(name) tmpdir = tmp("cext_#{name}") Dir.mkdir(tmpdir) begin - ["#{core_ext_dir}/rubyspec.h", "#{spec_ext_dir}/#{ext}.c"].each do |file| + files = ["#{core_ext_dir}/rubyspec.h", "#{spec_ext_dir}/#{ext}.c"] + if spec_ext_dir != core_ext_dir + files += Dir.glob("#{spec_ext_dir}/*.h") + end + files.each do |file| if cxx and file.end_with?('.c') cp file, "#{tmpdir}/#{File.basename(file, '.c')}.cpp" else diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index 72f20ee6a5..889f0a6cfe 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -1369,8 +1369,133 @@ describe "C-API String function" do result1.should_not.equal?(result2) end + it "preserves the encoding of the original string" do + result1 = @s.rb_str_to_interned_str("hello".dup.force_encoding(Encoding::US_ASCII)) + result2 = @s.rb_str_to_interned_str("hello".dup.force_encoding(Encoding::UTF_8)) + result1.encoding.should == Encoding::US_ASCII + result2.encoding.should == Encoding::UTF_8 + end + it "returns the same string as String#-@" do @s.rb_str_to_interned_str("hello").should.equal?(-"hello") end end + + describe "rb_interned_str" do + it "returns a frozen string" do + str = "hello" + result = @s.rb_interned_str(str, str.bytesize) + result.should.is_a?(String) + result.should.frozen? + result.encoding.should == Encoding::US_ASCII + end + + it "returns the same frozen string" do + str = "hello" + result1 = @s.rb_interned_str(str, str.bytesize) + result2 = @s.rb_interned_str(str, str.bytesize) + result1.should.equal?(result2) + end + + it "supports strings with embedded null bytes" do + str = "foo\x00bar\x00baz".b + result = @s.rb_interned_str(str, str.bytesize) + result.should == str + end + + it "return US_ASCII encoding for an empty string" do + result = @s.rb_interned_str("", 0) + result.should == "" + result.encoding.should == Encoding::US_ASCII + end + + it "returns US_ASCII encoding for strings of only 7 bit ASCII" do + 0x00.upto(0x7f).each do |char| + result = @s.rb_interned_str(char.chr, 1) + result.encoding.should == Encoding::US_ASCII + end + end + + ruby_bug "21842", ""..."4.1" do + it "returns BINARY encoding for strings that use the 8th bit" do + 0x80.upto(0xff) do |char| + result = @s.rb_interned_str(char.chr, 1) + result.encoding.should == Encoding::BINARY + end + end + end + + it 'returns the same string when using non-ascii characters' do + str = 'こんにちは' + result1 = @s.rb_interned_str(str, str.bytesize) + result2 = @s.rb_interned_str(str, str.bytesize) + result1.should.equal?(result2) + end + + ruby_bug "21842", ""..."4.1" do + it "returns the same string as String#-@" do + str = "hello".dup.force_encoding(Encoding::US_ASCII) + @s.rb_interned_str(str, str.bytesize).should.equal?(-str) + end + end + end + + describe "rb_interned_str_cstr" do + it "returns a frozen string" do + str = "hello" + result = @s.rb_interned_str_cstr(str) + result.should.is_a?(String) + result.should.frozen? + result.encoding.should == Encoding::US_ASCII + end + + it "returns the same frozen string" do + str = "hello" + result1 = @s.rb_interned_str_cstr(str) + result2 = @s.rb_interned_str_cstr(str) + result1.should.equal?(result2) + end + + it "does not support strings with embedded null bytes" do + str = "foo\x00bar\x00baz".b + result = @s.rb_interned_str_cstr(str) + result.should == "foo" + end + + it "return US_ASCII encoding for an empty string" do + result = @s.rb_interned_str_cstr("") + result.should == "" + result.encoding.should == Encoding::US_ASCII + end + + it "returns US_ASCII encoding for strings of only 7 bit ASCII" do + 0x01.upto(0x7f).each do |char| + result = @s.rb_interned_str_cstr(char.chr) + result.encoding.should == Encoding::US_ASCII + end + end + + ruby_bug "21842", ""..."4.1" do + it "returns BINARY encoding for strings that use the 8th bit" do + 0x80.upto(0xff) do |char| + result = @s.rb_interned_str_cstr(char.chr) + result.encoding.should == Encoding::BINARY + end + end + end + + it 'returns the same string when using non-ascii characters' do + str = 'こんにちは' + result1 = @s.rb_interned_str_cstr(str) + result2 = @s.rb_interned_str_cstr(str) + result1.should.equal?(result2) + end + + ruby_bug "21842", ""..."4.1" do + it "returns the same string as String#-@" do + str = "hello".dup.force_encoding(Encoding::US_ASCII) + @s.rb_interned_str_cstr(str).should.equal?(-str) + end + end + end end diff --git a/spec/ruby/optional/capi/struct_spec.rb b/spec/ruby/optional/capi/struct_spec.rb index cc8d7f932e..3f9eff52bc 100644 --- a/spec/ruby/optional/capi/struct_spec.rb +++ b/spec/ruby/optional/capi/struct_spec.rb @@ -239,78 +239,76 @@ describe "C-API Struct function" do end end -ruby_version_is "3.3" do - describe "C-API Data function" do - before :all do - @s = CApiStructSpecs.new - @klass = @s.rb_data_define(nil, "a", "b", "c") - end - - describe "rb_data_define" do - it "returns a subclass of Data class when passed nil as the first argument" do - @klass.should.is_a? Class - @klass.superclass.should == Data - end - - it "returns a subclass of a class when passed as the first argument" do - superclass = Class.new(Data) - klass = @s.rb_data_define(superclass, "a", "b", "c") - - klass.should.is_a? Class - klass.superclass.should == superclass - end - - it "creates readers for the members" do - obj = @klass.new(1, 2, 3) - - obj.a.should == 1 - obj.b.should == 2 - obj.c.should == 3 - end - - it "returns the member names as Symbols" do - obj = @klass.new(0, 0, 0) - - obj.members.should == [:a, :b, :c] - end - - it "raises an ArgumentError if arguments contain duplicate member name" do - -> { @s.rb_data_define(nil, "a", "b", "a") }.should raise_error(ArgumentError) - end - - it "raises when first argument is not a class" do - -> { @s.rb_data_define([], "a", "b", "c") }.should raise_error(TypeError, "wrong argument type Array (expected Class)") - end - end - - describe "rb_struct_initialize" do - it "sets all members for a Data instance" do - data = @klass.allocate - @s.rb_struct_initialize(data, [1, 2, 3]).should == nil - data.a.should == 1 - data.b.should == 2 - data.c.should == 3 - end - - it "freezes the Data instance" do - data = @klass.allocate - @s.rb_struct_initialize(data, [1, 2, 3]).should == nil - data.should.frozen? - -> { @s.rb_struct_initialize(data, [1, 2, 3]) }.should raise_error(FrozenError) - end - - it "raises ArgumentError if too many values" do - data = @klass.allocate - -> { @s.rb_struct_initialize(data, [1, 2, 3, 4]) }.should raise_error(ArgumentError, "struct size differs") - end - - it "treats missing values as nil" do - data = @klass.allocate - @s.rb_struct_initialize(data, [1, 2]).should == nil - data.a.should == 1 - data.b.should == 2 - data.c.should == nil - end +describe "C-API Data function" do + before :all do + @s = CApiStructSpecs.new + @klass = @s.rb_data_define(nil, "a", "b", "c") + end + + describe "rb_data_define" do + it "returns a subclass of Data class when passed nil as the first argument" do + @klass.should.is_a? Class + @klass.superclass.should == Data + end + + it "returns a subclass of a class when passed as the first argument" do + superclass = Class.new(Data) + klass = @s.rb_data_define(superclass, "a", "b", "c") + + klass.should.is_a? Class + klass.superclass.should == superclass + end + + it "creates readers for the members" do + obj = @klass.new(1, 2, 3) + + obj.a.should == 1 + obj.b.should == 2 + obj.c.should == 3 + end + + it "returns the member names as Symbols" do + obj = @klass.new(0, 0, 0) + + obj.members.should == [:a, :b, :c] + end + + it "raises an ArgumentError if arguments contain duplicate member name" do + -> { @s.rb_data_define(nil, "a", "b", "a") }.should raise_error(ArgumentError) + end + + it "raises when first argument is not a class" do + -> { @s.rb_data_define([], "a", "b", "c") }.should raise_error(TypeError, "wrong argument type Array (expected Class)") + end + end + + describe "rb_struct_initialize" do + it "sets all members for a Data instance" do + data = @klass.allocate + @s.rb_struct_initialize(data, [1, 2, 3]).should == nil + data.a.should == 1 + data.b.should == 2 + data.c.should == 3 + end + + it "freezes the Data instance" do + data = @klass.allocate + @s.rb_struct_initialize(data, [1, 2, 3]).should == nil + data.should.frozen? + -> { @s.rb_struct_initialize(data, [1, 2, 3]) }.should raise_error(FrozenError) + end + + it "raises ArgumentError if too many values" do + data = @klass.allocate + -> { @s.rb_struct_initialize(data, [1, 2, 3, 4]) }.should raise_error(ArgumentError, "struct size differs") + end + + it "treats missing values as nil" do + data = @klass.allocate + @s.rb_struct_initialize(data, [1, 2]).should == nil + data.a.should == 1 + data.b.should == 2 + data.c.should == nil end end end |
