From ed488e6a04eb924fc19ea7659bdc28013a07ed67 Mon Sep 17 00:00:00 2001 From: eregon Date: Thu, 14 Sep 2017 15:56:33 +0000 Subject: Update to ruby/spec@a4bc1d8 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- spec/rubyspec/Gemfile | 3 - spec/rubyspec/README.md | 8 ++ spec/rubyspec/command_line/dash_e_spec.rb | 6 +- spec/rubyspec/command_line/dash_v_spec.rb | 7 ++ spec/rubyspec/core/kernel/exit_spec.rb | 2 +- spec/rubyspec/core/module/prepend_spec.rb | 16 +++ spec/rubyspec/core/random/default_spec.rb | 7 ++ spec/rubyspec/core/rational/to_r_spec.rb | 10 ++ spec/rubyspec/core/struct/inspect_spec.rb | 9 +- spec/rubyspec/core/thread/status_spec.rb | 16 +++ spec/rubyspec/core/thread/terminate_spec.rb | 4 - spec/rubyspec/core/time/shared/time_params.rb | 5 + spec/rubyspec/language/for_spec.rb | 6 ++ spec/rubyspec/library/getoptlong/shared/get.rb | 9 +- .../library/net/http/http/send_request_spec.rb | 109 +++++---------------- spec/rubyspec/optional/capi/ext/fixnum_spec.c | 20 +++- spec/rubyspec/optional/capi/ext/gc_spec.c | 11 +++ spec/rubyspec/optional/capi/ext/hash_spec.c | 10 ++ spec/rubyspec/optional/capi/ext/proc_spec.c | 20 ++++ spec/rubyspec/optional/capi/ext/range_spec.c | 19 ++++ spec/rubyspec/optional/capi/ext/rubyspec.h | 10 ++ spec/rubyspec/optional/capi/ext/st_spec.c | 82 ++++++++++++++++ spec/rubyspec/optional/capi/ext/string_spec.c | 20 ++++ spec/rubyspec/optional/capi/fixnum_spec.rb | 52 +++++++++- spec/rubyspec/optional/capi/gc_spec.rb | 10 ++ spec/rubyspec/optional/capi/hash_spec.rb | 19 ++++ spec/rubyspec/optional/capi/proc_spec.rb | 14 +++ spec/rubyspec/optional/capi/range_spec.rb | 27 +++++ spec/rubyspec/optional/capi/st_spec.rb | 41 ++++++++ spec/rubyspec/optional/capi/string_spec.rb | 16 +++ spec/rubyspec/shared/process/exit.rb | 30 +++--- 31 files changed, 496 insertions(+), 122 deletions(-) delete mode 100644 spec/rubyspec/Gemfile create mode 100644 spec/rubyspec/core/random/default_spec.rb create mode 100644 spec/rubyspec/optional/capi/ext/st_spec.c create mode 100644 spec/rubyspec/optional/capi/st_spec.rb (limited to 'spec') diff --git a/spec/rubyspec/Gemfile b/spec/rubyspec/Gemfile deleted file mode 100644 index 28793d427f..0000000000 --- a/spec/rubyspec/Gemfile +++ /dev/null @@ -1,3 +0,0 @@ -source 'https://rubygems.org' - -gem 'mspec', :git => 'https://github.com/ruby/mspec' diff --git a/spec/rubyspec/README.md b/spec/rubyspec/README.md index d1657c568b..970688a623 100644 --- a/spec/rubyspec/README.md +++ b/spec/rubyspec/README.md @@ -27,6 +27,14 @@ ruby/spec is known to be tested in these implementations for every commit: * [TruffleRuby](https://github.com/graalvm/truffleruby) on Travis * [Opal](https://github.com/opal/opal/tree/master/spec) on Travis +ruby/spec describes the behavior of Ruby 2.2 and more recent Ruby versions. +More precisely, every latest stable MRI release [passes](https://rubyci.org/) all specs of ruby/spec +(latest 2.2.x, 2.3.x, 2.4.x, etc). + +For older specs try these commits: +* Ruby 2.0.0-p647 - [Suite](https://github.com/ruby/spec/commit/245862558761d5abc676843ef74f86c9bcc8ea8d) using [MSpec](https://github.com/ruby/mspec/commit/f90efa068791064f955de7a843e96e2d7d3041c2) (may encounter 2 failures) +* Ruby 2.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed) + ### Running the specs First, clone this repository: diff --git a/spec/rubyspec/command_line/dash_e_spec.rb b/spec/rubyspec/command_line/dash_e_spec.rb index 86c6990058..3435e78e29 100644 --- a/spec/rubyspec/command_line/dash_e_spec.rb +++ b/spec/rubyspec/command_line/dash_e_spec.rb @@ -17,9 +17,12 @@ describe "The -e command line option" do ruby_exe("puts __FILE__", escape: false).chomp.should == "-e" end + it "uses '-e' in $0" do + system(*ruby_exe, '-e', 'exit $0 == "-e"').should == true + end + #needs to test return => LocalJumpError -quarantine! do # For some unknown reason, running these under `bundle exec` or with -rbundler/setup fails describe "with -n and a Fixnum range" do before :each do @script = "-ne 'print if %s' #{fixture(__FILE__, "conditional_range.txt")}" @@ -36,4 +39,3 @@ quarantine! do # For some unknown reason, running these under `bundle exec` or w end end end -end diff --git a/spec/rubyspec/command_line/dash_v_spec.rb b/spec/rubyspec/command_line/dash_v_spec.rb index f690d7baf1..a7abd9de82 100644 --- a/spec/rubyspec/command_line/dash_v_spec.rb +++ b/spec/rubyspec/command_line/dash_v_spec.rb @@ -3,4 +3,11 @@ require File.expand_path('../shared/verbose', __FILE__) describe "The -v command line option" do it_behaves_like :command_line_verbose, "-v" + + describe "when used alone" do + it "prints version and ends" do + version = ruby_exe(nil, args: '--version') + ruby_exe(nil, args: '-v').should == version + end + end end diff --git a/spec/rubyspec/core/kernel/exit_spec.rb b/spec/rubyspec/core/kernel/exit_spec.rb index 5e175d5036..61a6670cfd 100644 --- a/spec/rubyspec/core/kernel/exit_spec.rb +++ b/spec/rubyspec/core/kernel/exit_spec.rb @@ -15,7 +15,7 @@ describe "Kernel#exit!" do Kernel.should have_private_instance_method(:exit!) end - it_behaves_like :process_exit!, :exit!, KernelSpecs::Method.new + it_behaves_like :process_exit!, :exit!, "self" end describe "Kernel.exit" do diff --git a/spec/rubyspec/core/module/prepend_spec.rb b/spec/rubyspec/core/module/prepend_spec.rb index 7d162bd5c5..c0cce616a2 100644 --- a/spec/rubyspec/core/module/prepend_spec.rb +++ b/spec/rubyspec/core/module/prepend_spec.rb @@ -342,4 +342,20 @@ describe "Module#prepend" do child_class.new.foo(ary) ary.should == [3, 2, 1] end + + describe "called on a module" do + describe "included into a class" + it "does not obscure the module's methods from reflective access" do + mod = Module.new do + def foo; end + end + cls = Class.new do + include mod + end + pre = Module.new + mod.prepend pre + + cls.instance_methods.should include(:foo) + end + end end diff --git a/spec/rubyspec/core/random/default_spec.rb b/spec/rubyspec/core/random/default_spec.rb new file mode 100644 index 0000000000..51a76c01ce --- /dev/null +++ b/spec/rubyspec/core/random/default_spec.rb @@ -0,0 +1,7 @@ +require File.expand_path('../../../spec_helper', __FILE__) + +describe "Random::DEFAULT" do + it "returns a Random instance" do + Random::DEFAULT.should be_an_instance_of(Random) + end +end diff --git a/spec/rubyspec/core/rational/to_r_spec.rb b/spec/rubyspec/core/rational/to_r_spec.rb index 22c8b4532c..6e44cf1b23 100644 --- a/spec/rubyspec/core/rational/to_r_spec.rb +++ b/spec/rubyspec/core/rational/to_r_spec.rb @@ -7,4 +7,14 @@ describe "Rational#to_r" do obj = BasicObject.new lambda { Rational(obj) }.should raise_error(TypeError) end + + it "works when a BasicObject has to_r" do + obj = BasicObject.new; def obj.to_r; 1 / 2.to_r end + Rational(obj).should == Rational('1/2') + end + + it "fails when a BasicObject's to_r does not return a Rational" do + obj = BasicObject.new; def obj.to_r; 1 end + lambda { Rational(obj) }.should raise_error(TypeError) + end end diff --git a/spec/rubyspec/core/struct/inspect_spec.rb b/spec/rubyspec/core/struct/inspect_spec.rb index a85466e1a2..94fb71a5f1 100644 --- a/spec/rubyspec/core/struct/inspect_spec.rb +++ b/spec/rubyspec/core/struct/inspect_spec.rb @@ -6,12 +6,9 @@ describe "Struct#inspect" do it "returns a string representation of some kind" do car = StructClasses::Car.new('Ford', 'Ranger') car.inspect.should == '#' - # ujihisa reported in http://rubyspec.org/issues/show/130 that the - # following example failed under mspec. Prefixing 'Whiskey' with a double - # colon causes it to work. Given that this is an mspec bug, as opposed to - # a problem with a spec, I've used the workaround below. - ::Whiskey = Struct.new(:name, :ounces) - ::Whiskey.new('Jack', 100).inspect.should == '#' + + Whiskey = Struct.new(:name, :ounces) + Whiskey.new('Jack', 100).inspect.should == '#' end it_behaves_like(:struct_inspect, :inspect) diff --git a/spec/rubyspec/core/thread/status_spec.rb b/spec/rubyspec/core/thread/status_spec.rb index 3fbc4f888a..6cfdf0be40 100644 --- a/spec/rubyspec/core/thread/status_spec.rb +++ b/spec/rubyspec/core/thread/status_spec.rb @@ -41,4 +41,20 @@ describe "Thread#status" do it "reports aborting on a killed thread after sleep" do ThreadSpecs.status_of_dying_thread_after_sleep.status.should == 'aborting' end + + it "reports aborting on an externally killed thread that sleeps" do + q = Queue.new + t = Thread.new do + begin + q.push nil + sleep + ensure + q.push Thread.current.status + end + end + q.pop + t.kill + t.join + q.pop.should == 'aborting' + end end diff --git a/spec/rubyspec/core/thread/terminate_spec.rb b/spec/rubyspec/core/thread/terminate_spec.rb index 9ac4a5b6f8..bb89d87762 100644 --- a/spec/rubyspec/core/thread/terminate_spec.rb +++ b/spec/rubyspec/core/thread/terminate_spec.rb @@ -5,7 +5,3 @@ require File.expand_path('../shared/exit', __FILE__) describe "Thread#terminate" do it_behaves_like :thread_exit, :terminate end - -describe "Thread#terminate!" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/rubyspec/core/time/shared/time_params.rb b/spec/rubyspec/core/time/shared/time_params.rb index b60699dfb3..87b52d9f8d 100644 --- a/spec/rubyspec/core/time/shared/time_params.rb +++ b/spec/rubyspec/core/time/shared/time_params.rb @@ -24,6 +24,11 @@ describe :time_params, shared: true do Time.send(@method, 2000, 2, 3, 4, 5, 0) end + it "accepts a too big day of the month by going to the next month" do + Time.send(@method, 1999, 2, 31).should == + Time.send(@method, 1999, 3, 3) + end + it "raises a TypeError if the year is nil" do lambda { Time.send(@method, nil) }.should raise_error(TypeError) end diff --git a/spec/rubyspec/language/for_spec.rb b/spec/rubyspec/language/for_spec.rb index a043da5476..c9d043fa25 100644 --- a/spec/rubyspec/language/for_spec.rb +++ b/spec/rubyspec/language/for_spec.rb @@ -12,6 +12,12 @@ describe "The for expression" do j.should == 6 end + it "iterates over a list of arrays and destructures with empty comma" do + for i, in [[1,2]] + i.should == 1 + end + end + it "iterates over an Hash passing each key-value pair to the block" do k = 0 l = 0 diff --git a/spec/rubyspec/library/getoptlong/shared/get.rb b/spec/rubyspec/library/getoptlong/shared/get.rb index c6e5b44368..91a0fbaacc 100644 --- a/spec/rubyspec/library/getoptlong/shared/get.rb +++ b/spec/rubyspec/library/getoptlong/shared/get.rb @@ -53,9 +53,12 @@ describe :getoptlong_get, shared: true do end end - it "returns multiline argument" do - argv [ "--size=\n10k\n" ] do - @opts.send(@method).should == [ "--size", "\n10k\n" ] + ruby_version_is "2.5" do + # https://bugs.ruby-lang.org/issues/13858 + it "returns multiline argument" do + argv [ "--size=\n10k\n" ] do + @opts.send(@method).should == [ "--size", "\n10k\n" ] + end end end end diff --git a/spec/rubyspec/library/net/http/http/send_request_spec.rb b/spec/rubyspec/library/net/http/http/send_request_spec.rb index 8d21b6aa3b..5a704496ec 100644 --- a/spec/rubyspec/library/net/http/http/send_request_spec.rb +++ b/spec/rubyspec/library/net/http/http/send_request_spec.rb @@ -6,6 +6,13 @@ describe "Net::HTTP#send_request" do before :each do NetHTTPSpecs.start_server @http = Net::HTTP.start("localhost", NetHTTPSpecs.port) + + # HEAD is special so handled separately + @methods = %w[ + GET POST PUT DELETE + OPTIONS + PROPFIND PROPPATCH LOCK UNLOCK + ] end after :each do @@ -16,103 +23,39 @@ describe "Net::HTTP#send_request" do # TODO: Does only work with GET and POST requests describe "when passed type, path" do it "sends a HTTP Request of the passed type to the passed path" do - response = @http.send_request("GET", "/request") - response.body.should == "Request type: GET" - - # response = @http.send_request("HEAD", "/request") - # response.body.should be_nil - - response = @http.send_request("POST", "/request") - response.body.should == "Request type: POST" - - # response = @http.send_request("PUT", "/request") - # response.body.should == "Request type: PUT" - - # response = @http.send_request("DELETE", "/request") - # response.body.should == "Request type: DELETE" - - # response = @http.send_request("PROPGET", "/request") - # response.body.should == "Request type: DELETE" + response = @http.send_request("HEAD", "/request") + response.body.should be_nil - # response = @http.send_request("PROPSET", "/request") - # response.body.should == "Request type: DELETE" - - # response = @http.send_request("OPTIONS", "/request") - # response.body.should be_nil - - # response = @http.send_request("LOCK", "/request") - # response.body.should == "Request type: LOCK - - # response = @http.send_request("UNLOCK", "/request") - # response.body.should == "Request type: UNLOCK + @methods.each do |method| + response = @http.send_request(method, "/request") + response.body.should == "Request type: #{method}" + end end end describe "when passed type, path, body" do it "sends a HTTP Request with the passed body" do - response = @http.send_request("GET", "/request/body", "test=test") - response.body.should == "test=test" - - # response = @http.send_request("HEAD", "/request/body", "test=test") - # response.body.should be_nil - - response = @http.send_request("POST", "/request/body", "test=test") - response.body.should == "test=test" - - # response = @http.send_request("PUT", "/request/body", "test=test") - # response.body.should == "test=test" + response = @http.send_request("HEAD", "/request/body", "test=test") + response.body.should be_nil - # response = @http.send_request("DELETE", "/request/body", "test=test") - # response.body.should == "test=test" - - # response = @http.send_request("PROPGET", "/request/body", "test=test") - # response.body.should == "test=test" - - # response = @http.send_request("PROPSET", "/request/body", "test=test") - # response.body.should == "test=test" - - # response = @http.send_request("OPTIONS", "/request/body", "test=test") - # response.body.should be_nil - - # response = @http.send_request("LOCK", "/request/body", "test=test") - # response.body.should == "test=test" - - # response = @http.send_request("UNLOCK", "/request/body", "test=test") - # response.body.should == "test=test" + @methods.each do |method| + response = @http.send_request(method, "/request/body", "test=test") + response.body.should == "test=test" + end end end describe "when passed type, path, body, headers" do it "sends a HTTP Request with the passed headers" do - response = @http.send_request("GET", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("HEAD", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should be_nil - - response = @http.send_request("POST", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("PUT", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("DELETE", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("PROPGET", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("PROPSET", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') - - # response = @http.send_request("OPTIONS", "/request/body", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should be_nil + referer = 'https://www.ruby-lang.org/'.freeze - # response = @http.send_request("LOCK", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') + response = @http.send_request("HEAD", "/request/header", "test=test", "referer" => referer) + response.body.should be_nil - # response = @http.send_request("UNLOCK", "/request/header", "test=test", "referer" => "http://www.rubyspec.org") - # response.body.should include('"referer"=>["http://www.rubyspec.org"]') + @methods.each do |method| + response = @http.send_request(method, "/request/header", "test=test", "referer" => referer) + response.body.should include('"referer"=>["' + referer + '"]') + end end end end diff --git a/spec/rubyspec/optional/capi/ext/fixnum_spec.c b/spec/rubyspec/optional/capi/ext/fixnum_spec.c index 49dd039c52..78d452f936 100644 --- a/spec/rubyspec/optional/capi/ext/fixnum_spec.c +++ b/spec/rubyspec/optional/capi/ext/fixnum_spec.c @@ -5,23 +5,37 @@ extern "C" { #endif +static VALUE fixnum_spec_FIX2INT(VALUE self, VALUE value) { + int i = FIX2INT(value); + return INT2NUM(i); +} + +static VALUE fixnum_spec_FIX2UINT(VALUE self, VALUE value) { + unsigned int i = FIX2UINT(value); + return UINT2NUM(i); +} + #ifdef HAVE_RB_FIX2UINT static VALUE fixnum_spec_rb_fix2uint(VALUE self, VALUE value) { - return INT2FIX(rb_fix2uint(value)); + unsigned int i = rb_fix2uint(value); + return UINT2NUM(i); } #endif #ifdef HAVE_RB_FIX2INT static VALUE fixnum_spec_rb_fix2int(VALUE self, VALUE value) { - return INT2FIX(rb_fix2int(value)); + int i = rb_fix2int(value); + return INT2NUM(i); } #endif - void Init_fixnum_spec(void) { VALUE cls; cls = rb_define_class("CApiFixnumSpecs", rb_cObject); + rb_define_method(cls, "FIX2INT", fixnum_spec_FIX2INT, 1); + rb_define_method(cls, "FIX2UINT", fixnum_spec_FIX2UINT, 1); + #ifdef HAVE_RB_FIX2UINT rb_define_method(cls, "rb_fix2uint", fixnum_spec_rb_fix2uint, 1); #endif diff --git a/spec/rubyspec/optional/capi/ext/gc_spec.c b/spec/rubyspec/optional/capi/ext/gc_spec.c index c5895eb0aa..05341bb01d 100644 --- a/spec/rubyspec/optional/capi/ext/gc_spec.c +++ b/spec/rubyspec/optional/capi/ext/gc_spec.c @@ -30,6 +30,13 @@ static VALUE gc_spec_rb_gc_disable() { } #endif +#ifdef HAVE_RB_GC +static VALUE gc_spec_rb_gc() { + rb_gc(); + return Qnil; +} +#endif + void Init_gc_spec(void) { VALUE cls; @@ -54,6 +61,10 @@ void Init_gc_spec(void) { rb_define_method(cls, "rb_gc_disable", gc_spec_rb_gc_disable, 0); #endif +#ifdef HAVE_RB_GC + rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0); +#endif + } #ifdef __cplusplus diff --git a/spec/rubyspec/optional/capi/ext/hash_spec.c b/spec/rubyspec/optional/capi/ext/hash_spec.c index ac45003844..73e7ef5c13 100644 --- a/spec/rubyspec/optional/capi/ext/hash_spec.c +++ b/spec/rubyspec/optional/capi/ext/hash_spec.c @@ -23,6 +23,12 @@ VALUE hash_spec_rb_hash_dup(VALUE self, VALUE hash) { } #endif +#ifdef HAVE_RB_HASH_FETCH +VALUE hash_spec_rb_hash_fetch(VALUE self, VALUE hash, VALUE key) { + return rb_hash_fetch(hash, key); +} +#endif + #ifdef HAVE_RB_HASH_FREEZE VALUE hash_spec_rb_hash_freeze(VALUE self, VALUE hash) { return rb_hash_freeze(hash); @@ -175,6 +181,10 @@ void Init_hash_spec(void) { rb_define_method(cls, "rb_hash_delete_if", hash_spec_rb_hash_delete_if, 1); #endif +#ifdef HAVE_RB_HASH_FETCH + rb_define_method(cls, "rb_hash_fetch", hash_spec_rb_hash_fetch, 2); +#endif + #ifdef HAVE_RB_HASH_FOREACH rb_define_method(cls, "rb_hash_foreach", hash_spec_rb_hash_foreach, 1); rb_define_method(cls, "rb_hash_foreach_stop", hash_spec_rb_hash_foreach_stop, 1); diff --git a/spec/rubyspec/optional/capi/ext/proc_spec.c b/spec/rubyspec/optional/capi/ext/proc_spec.c index b7a47536d9..f9c0f6b1b9 100644 --- a/spec/rubyspec/optional/capi/ext/proc_spec.c +++ b/spec/rubyspec/optional/capi/ext/proc_spec.c @@ -17,6 +17,18 @@ VALUE proc_spec_rb_proc_new(VALUE self) { } #endif +#ifdef HAVE_RB_PROC_ARITY +VALUE proc_spec_rb_proc_arity(VALUE self, VALUE prc) { + return INT2FIX(rb_proc_arity(prc)); +} +#endif + +#ifdef HAVE_RB_PROC_CALL +VALUE proc_spec_rb_proc_call(VALUE self, VALUE prc, VALUE args) { + return rb_proc_call(prc, args); +} +#endif + /* This helper is not strictly necessary but reflects the code in wxRuby that * originally exposed issues with this Proc.new behavior. */ @@ -57,6 +69,14 @@ void Init_proc_spec(void) { rb_define_method(cls, "rb_proc_new", proc_spec_rb_proc_new, 0); #endif +#ifdef HAVE_RB_PROC_ARITY + rb_define_method(cls, "rb_proc_arity", proc_spec_rb_proc_arity, 1); +#endif + +#ifdef HAVE_RB_PROC_CALL + rb_define_method(cls, "rb_proc_call", proc_spec_rb_proc_call, 2); +#endif + rb_define_method(cls, "rb_Proc_new", proc_spec_rb_Proc_new, 1); } diff --git a/spec/rubyspec/optional/capi/ext/range_spec.c b/spec/rubyspec/optional/capi/ext/range_spec.c index 02aff5a5c2..46ee88a85d 100644 --- a/spec/rubyspec/optional/capi/ext/range_spec.c +++ b/spec/rubyspec/optional/capi/ext/range_spec.c @@ -29,6 +29,21 @@ VALUE range_spec_rb_range_values(VALUE self, VALUE range) { } #endif +#ifdef HAVE_RB_RANGE_BEG_LEN +VALUE range_spec_rb_range_beg_len(VALUE self, VALUE range, VALUE begpv, VALUE lenpv, VALUE lenv, VALUE errv) { + long begp = FIX2LONG(begpv); + long lenp = FIX2LONG(lenpv); + long len = FIX2LONG(lenv); + long err = FIX2LONG(errv); + VALUE ary = rb_ary_new(); + VALUE res = rb_range_beg_len(range, &begp, &lenp, len, err); + rb_ary_store(ary, 0, LONG2FIX(begp)); + rb_ary_store(ary, 1, LONG2FIX(lenp)); + rb_ary_store(ary, 2, res); + return ary; +} +#endif + void Init_range_spec(void) { VALUE cls; cls = rb_define_class("CApiRangeSpecs", rb_cObject); @@ -40,6 +55,10 @@ void Init_range_spec(void) { #ifdef HAVE_RB_RANGE_VALUES rb_define_method(cls, "rb_range_values", range_spec_rb_range_values, 1); #endif + +#ifdef HAVE_RB_RANGE_BEG_LEN + rb_define_method(cls, "rb_range_beg_len", range_spec_rb_range_beg_len, 5); +#endif } #ifdef __cplusplus diff --git a/spec/rubyspec/optional/capi/ext/rubyspec.h b/spec/rubyspec/optional/capi/ext/rubyspec.h index 9cba34b888..8866e39af4 100644 --- a/spec/rubyspec/optional/capi/ext/rubyspec.h +++ b/spec/rubyspec/optional/capi/ext/rubyspec.h @@ -299,6 +299,7 @@ #define HAVE_RB_HASH_CLEAR 1 #define HAVE_RB_HASH_DELETE 1 #define HAVE_RB_HASH_DELETE_IF 1 +#define HAVE_RB_HASH_FETCH 1 #define HAVE_RB_HASH_FOREACH 1 #define HAVE_RB_HASH_LOOKUP 1 #define HAVE_RB_HASH_LOOKUP2 1 @@ -372,6 +373,7 @@ #define HAVE_RB_GC_REGISTER_ADDRESS 1 #define HAVE_RB_GC_ENABLE 1 #define HAVE_RB_GC_DISABLE 1 +#define HAVE_RB_GC 1 /* Marshal */ #define HAVE_RB_MARSHAL_DUMP 1 @@ -476,10 +478,13 @@ /* Proc */ #define HAVE_RB_PROC_NEW 1 +#define HAVE_RB_PROC_ARITY 1 +#define HAVE_RB_PROC_CALL 1 /* Range */ #define HAVE_RB_RANGE_NEW 1 #define HAVE_RB_RANGE_VALUES 1 +#define HAVE_RB_RANGE_BEG_LEN 1 /* Rational */ #define HAVE_RB_RATIONAL 1 @@ -499,6 +504,9 @@ #define HAVE_RB_REG_OPTIONS 1 #define HAVE_RB_REG_REGCOMP 1 +/* st */ +#define HAVE_RB_ST 1 + /* String */ #define HAVE_RB_CSTR2INUM 1 #define HAVE_RB_CSTR_TO_INUM 1 @@ -522,6 +530,8 @@ #define HAVE_RB_STR_NEW3 1 #define HAVE_RB_STR_NEW4 1 #define HAVE_RB_STR_NEW5 1 +#define HAVE_RB_TAINTED_STR_NEW 1 +#define HAVE_RB_TAINTED_STR_NEW2 1 #define HAVE_RB_STR_PLUS 1 #define HAVE_RB_STR_TIMES 1 #define HAVE_RB_STR_RESIZE 1 diff --git a/spec/rubyspec/optional/capi/ext/st_spec.c b/spec/rubyspec/optional/capi/ext/st_spec.c new file mode 100644 index 0000000000..ea2d81964d --- /dev/null +++ b/spec/rubyspec/optional/capi/ext/st_spec.c @@ -0,0 +1,82 @@ +#include "ruby.h" +#include "rubyspec.h" + +#include +#include + +#ifdef HAVE_RB_ST +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_RB_ST +VALUE st_spec_st_init_numtable(VALUE self) { + st_table *tbl = st_init_numtable(); + int entries = tbl->num_entries; + st_free_table(tbl); + return INT2FIX(entries); +} + +VALUE st_spec_st_init_numtable_with_size(VALUE self) { + st_table *tbl = st_init_numtable_with_size(128); + int entries = tbl->num_entries; + st_free_table(tbl); + return INT2FIX(entries); +} + +VALUE st_spec_st_insert(VALUE self) { + int entries; + st_table *tbl = st_init_numtable_with_size(128); + st_insert(tbl, 1, 1); + entries = tbl->num_entries; + st_free_table(tbl); + return INT2FIX(entries); +} + +static int sum(st_data_t key, st_data_t value, st_data_t arg) { + *(int*)arg += value; + return ST_CONTINUE; +} + +VALUE st_spec_st_foreach(VALUE self) { + int total = 0; + st_table *tbl = st_init_numtable_with_size(128); + st_insert(tbl, 1, 3); + st_insert(tbl, 2, 4); + st_foreach(tbl, sum, (st_data_t)&total); + st_free_table(tbl); + return INT2FIX(total); +} + +VALUE st_spec_st_lookup(VALUE self) { + st_data_t result = (st_data_t)0; + st_table *tbl = st_init_numtable_with_size(128); + st_insert(tbl, 7, 42); + st_insert(tbl, 2, 4); + st_lookup(tbl, (st_data_t)7, &result); + st_free_table(tbl); + return INT2FIX(result); +} + +#endif + +void Init_st_spec(void) { + VALUE cls; + cls = rb_define_class("CApiStSpecs", rb_cObject); + +#ifdef HAVE_RB_ST + rb_define_method(cls, "st_init_numtable", st_spec_st_init_numtable, 0); + rb_define_method(cls, "st_init_numtable_with_size", st_spec_st_init_numtable_with_size, 0); + rb_define_method(cls, "st_insert", st_spec_st_insert, 0); + rb_define_method(cls, "st_foreach", st_spec_st_foreach, 0); + rb_define_method(cls, "st_lookup", st_spec_st_lookup, 0); +#endif + +} + +#ifdef __cplusplus +} +#endif diff --git a/spec/rubyspec/optional/capi/ext/string_spec.c b/spec/rubyspec/optional/capi/ext/string_spec.c index 69e66fbde1..0568b42212 100644 --- a/spec/rubyspec/optional/capi/ext/string_spec.c +++ b/spec/rubyspec/optional/capi/ext/string_spec.c @@ -257,6 +257,18 @@ VALUE string_spec_rb_str_new5(VALUE self, VALUE str, VALUE ptr, VALUE len) { } #endif +#ifdef HAVE_RB_TAINTED_STR_NEW +VALUE string_spec_rb_tainted_str_new(VALUE self, VALUE str, VALUE len) { + return rb_tainted_str_new(RSTRING_PTR(str), FIX2INT(len)); +} +#endif + +#ifdef HAVE_RB_TAINTED_STR_NEW2 +VALUE string_spec_rb_tainted_str_new2(VALUE self, VALUE str) { + return rb_tainted_str_new2(RSTRING_PTR(str)); +} +#endif + #ifdef HAVE_RB_STR_PLUS VALUE string_spec_rb_str_plus(VALUE self, VALUE str1, VALUE str2) { return rb_str_plus(str1, str2); @@ -564,6 +576,14 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_str_new5", string_spec_rb_str_new5, 3); #endif +#ifdef HAVE_RB_TAINTED_STR_NEW + rb_define_method(cls, "rb_tainted_str_new", string_spec_rb_tainted_str_new, 2); +#endif + +#ifdef HAVE_RB_TAINTED_STR_NEW2 + rb_define_method(cls, "rb_tainted_str_new2", string_spec_rb_tainted_str_new2, 1); +#endif + #ifdef HAVE_RB_STR_PLUS rb_define_method(cls, "rb_str_plus", string_spec_rb_str_plus, 2); #endif diff --git a/spec/rubyspec/optional/capi/fixnum_spec.rb b/spec/rubyspec/optional/capi/fixnum_spec.rb index 87f257fec7..d9e9d1946d 100644 --- a/spec/rubyspec/optional/capi/fixnum_spec.rb +++ b/spec/rubyspec/optional/capi/fixnum_spec.rb @@ -7,6 +7,40 @@ describe "CApiFixnumSpecs" do @s = CApiFixnumSpecs.new end + describe "FIX2INT" do + it "converts a Fixnum to a native int" do + @s.FIX2INT(42).should == 42 + @s.FIX2INT(-14).should == -14 + end + + max_int = (1 << 31) - 1 + min_int = -(1 << 31) + + guard -> { fixnum_min <= min_int and max_int <= fixnum_max } do + it "converts a Fixnum representing the minimum and maximum native int" do + @s.FIX2INT(max_int).should == max_int + @s.FIX2INT(min_int).should == min_int + end + end + + end + + describe "FIX2UINT" do + it "converts a Fixnum to a native int" do + @s.FIX2UINT(42).should == 42 + @s.FIX2UINT(0).should == 0 + end + + max_uint = (1 << 32) - 1 + + guard -> { max_uint <= fixnum_max } do + it "converts a Fixnum representing the maximum native uint" do + @s.FIX2UINT(max_uint).should == max_uint + end + end + + end + platform_is wordsize: 64 do describe "rb_fix2uint" do it "raises a TypeError if passed nil" do @@ -14,6 +48,7 @@ describe "CApiFixnumSpecs" do end it "converts a Fixnum" do + @s.rb_fix2uint(0).should == 0 @s.rb_fix2uint(1).should == 1 end @@ -25,6 +60,12 @@ describe "CApiFixnumSpecs" do @s.rb_fix2uint(25.4567).should == 25 end + it "raises a RangeError if the value does not fit a native uint" do + # Interestingly, on MRI rb_fix2uint(-1) is allowed + lambda { @s.rb_fix2uint(0xffff_ffff+1) }.should raise_error(RangeError) + lambda { @s.rb_fix2uint(-(1 << 31) - 1) }.should raise_error(RangeError) + end + it "raises a RangeError if the value is more than 32bits" do lambda { @s.rb_fix2uint(0xffff_ffff+1) }.should raise_error(RangeError) end @@ -44,7 +85,11 @@ describe "CApiFixnumSpecs" do @s.rb_fix2int(1).should == 1 end - it "converts the maximum uint value" do + it "converts the minimum int value" do + @s.rb_fix2int(-(1 << 31)).should == -(1 << 31) + end + + it "converts the maximum int value" do @s.rb_fix2int(0x7fff_ffff).should == 0x7fff_ffff end @@ -56,6 +101,11 @@ describe "CApiFixnumSpecs" do @s.rb_fix2int(-2147442171).should == -2147442171 end + it "raises a RangeError if the value does not fit a native int" do + lambda { @s.rb_fix2int(0x7fff_ffff+1) }.should raise_error(RangeError) + lambda { @s.rb_fix2int(-(1 << 31) - 1) }.should raise_error(RangeError) + end + it "raises a RangeError if the value is more than 32bits" do lambda { @s.rb_fix2int(0xffff_ffff+1) }.should raise_error(RangeError) end diff --git a/spec/rubyspec/optional/capi/gc_spec.rb b/spec/rubyspec/optional/capi/gc_spec.rb index 71efef3fad..ee9e11d11c 100644 --- a/spec/rubyspec/optional/capi/gc_spec.rb +++ b/spec/rubyspec/optional/capi/gc_spec.rb @@ -41,4 +41,14 @@ describe "CApiGCSpecs" do end end + describe "rb_gc" do + + it "increases gc count" do + gc_count = GC.count + @f.rb_gc + GC.count.should > gc_count + end + + end + end diff --git a/spec/rubyspec/optional/capi/hash_spec.rb b/spec/rubyspec/optional/capi/hash_spec.rb index 15284566f1..1c406f0394 100644 --- a/spec/rubyspec/optional/capi/hash_spec.rb +++ b/spec/rubyspec/optional/capi/hash_spec.rb @@ -119,6 +119,25 @@ describe "C-API Hash function" do end end + describe "rb_hash_fetch" do + before :each do + @hsh = {:a => 1, :b => 2} + end + + it "returns the value associated with the key" do + @s.rb_hash_fetch(@hsh, :b).should == 2 + end + + it "raises a KeyError if the key is not found and default is set" do + @hsh.default = :d + lambda { @s.rb_hash_fetch(@hsh, :c) }.should raise_error(KeyError) + end + + it "raises a KeyError if the key is not found and no default is set" do + lambda { @s.rb_hash_fetch(@hsh, :c) }.should raise_error(KeyError) + end + end + describe "rb_hash_foreach" do it "iterates over the hash" do hsh = {name: "Evan", sign: :libra} diff --git a/spec/rubyspec/optional/capi/proc_spec.rb b/spec/rubyspec/optional/capi/proc_spec.rb index c325e0fdfc..1cd8de9a86 100644 --- a/spec/rubyspec/optional/capi/proc_spec.rb +++ b/spec/rubyspec/optional/capi/proc_spec.rb @@ -40,6 +40,20 @@ describe "C-API Proc function" do @prc.source_location.should == nil end end + + describe "rb_proc_arity" do + it "returns the correct arity" do + prc = Proc.new {|a,b,c|} + @p.rb_proc_arity(prc).should == 3 + end + end + + describe "rb_proc_call" do + it "calls the Proc" do + prc = Proc.new {|a,b| a * b } + @p.rb_proc_call(prc, [6, 7]).should == 42 + end + end end describe "C-API when calling Proc.new from a C function" do diff --git a/spec/rubyspec/optional/capi/range_spec.rb b/spec/rubyspec/optional/capi/range_spec.rb index b145079f39..aa16f9773e 100644 --- a/spec/rubyspec/optional/capi/range_spec.rb +++ b/spec/rubyspec/optional/capi/range_spec.rb @@ -65,4 +65,31 @@ describe "C-API Range function" do excl.should be_false end end + + describe "rb_range_beg_len" do + it "returns correct begin, length and result" do + r = 2..5 + begp, lenp, result = @s.rb_range_beg_len(r, 0, 0, 10, 0) + result.should be_true + begp.should == 2 + lenp.should == 4 + end + + it "returns nil when not in range" do + r = 2..5 + begp, lenp, result = @s.rb_range_beg_len(r, 0, 0, 1, 0) + result.should be_nil + end + + it "raises a RangeError when not in range and err is 1" do + r = -5..-1 + lambda { @s.rb_range_beg_len(r, 0, 0, 1, 1) }.should raise_error(RangeError) + end + + it "returns nil when not in range and err is 0" do + r = -5..-1 + begp, lenp, result = @s.rb_range_beg_len(r, 0, 0, 1, 0) + result.should be_nil + end + end end diff --git a/spec/rubyspec/optional/capi/st_spec.rb b/spec/rubyspec/optional/capi/st_spec.rb new file mode 100644 index 0000000000..7f2bc08c62 --- /dev/null +++ b/spec/rubyspec/optional/capi/st_spec.rb @@ -0,0 +1,41 @@ +# encoding: utf-8 +require File.expand_path('../spec_helper', __FILE__) + +load_extension('st') + +describe "st hash table function" do + before :each do + @s = CApiStSpecs.new + end + + describe "st_init_numtable" do + it "initializes without error" do + @s.st_init_numtable.should == 0 + end + end + + describe "st_init_numtable_with_size" do + it "initializes without error" do + @s.st_init_numtable_with_size.should == 0 + end + end + + describe "st_insert" do + it "returns size 1 after insert" do + @s.st_insert.should == 1 + end + end + + describe "st_foreach" do + it "iterates over each pair of key and value" do + @s.st_foreach.should == 7 + end + end + + describe "st_lookup" do + it "returns the expected value" do + @s.st_lookup.should == 42 + end + end + +end diff --git a/spec/rubyspec/optional/capi/string_spec.rb b/spec/rubyspec/optional/capi/string_spec.rb index 7528a71682..25ef10b6f6 100644 --- a/spec/rubyspec/optional/capi/string_spec.rb +++ b/spec/rubyspec/optional/capi/string_spec.rb @@ -228,6 +228,22 @@ describe "C-API String function" do end end + describe "rb_tainted_str_new" do + it "creates a new tainted String" do + newstring = @s.rb_tainted_str_new("test", 4) + newstring.should == "test" + newstring.tainted?.should be_true + end + end + + describe "rb_tainted_str_new2" do + it "creates a new tainted String" do + newstring = @s.rb_tainted_str_new2("test") + newstring.should == "test" + newstring.tainted?.should be_true + end + end + describe "rb_str_append" do it "appends a string to another string" do @s.rb_str_append("Hello", " Goodbye").should == "Hello Goodbye" diff --git a/spec/rubyspec/shared/process/exit.rb b/spec/rubyspec/shared/process/exit.rb index a5c9eca665..7d567c8195 100644 --- a/spec/rubyspec/shared/process/exit.rb +++ b/spec/rubyspec/shared/process/exit.rb @@ -74,23 +74,21 @@ describe :process_exit, shared: true do end describe :process_exit!, shared: true do - with_feature :fork do - it "exits with the given status" do - pid = Process.fork { @object.exit!(1) } - pid, status = Process.waitpid2(pid) - status.exitstatus.should == 1 - end - - it "exits when called from a thread" do - pid = Process.fork do - Thread.new { @object.exit!(1) }.join + it "exits with the given status" do + out = ruby_exe("#{@object}.send(:exit!, 21)", args: '2>&1') + out.should == "" + $?.exitstatus.should == 21 + end - # Do not let the main thread complete - sleep - end + it "exits when called from a thread" do + out = ruby_exe("Thread.new { #{@object}.send(:exit!, 21) }.join; sleep", args: '2>&1') + out.should == "" + $?.exitstatus.should == 21 + end - pid, status = Process.waitpid2(pid) - status.exitstatus.should == 1 - end + it "exits when called from a fiber" do + out = ruby_exe("Fiber.new { #{@object}.send(:exit!, 21) }.resume", args: '2>&1') + out.should == "" + $?.exitstatus.should == 21 end end -- cgit v1.2.3