diff --git a/lib/bundler/templates/newgem/Gemfile.tt b/lib/bundler/templates/newgem/Gemfile.tt index ea7a33ee28f8e2..691814b5379f51 100644 --- a/lib/bundler/templates/newgem/Gemfile.tt +++ b/lib/bundler/templates/newgem/Gemfile.tt @@ -6,19 +6,19 @@ source "https://rubygems.org" gemspec gem "irb" -gem "rake", "~> 13.0" +gem "rake", ">= 13.0" <%- if config[:ext] -%> gem "rake-compiler" <%- end -%> <%- if config[:test] -%> -gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>" +gem "<%= config[:test] %>", ">= <%= config[:test_framework_version] %>" <%- end -%> <%- if config[:linter] == "rubocop" -%> -gem "rubocop", "~> <%= config[:linter_version] %>" +gem "rubocop", ">= <%= config[:linter_version] %>" <%- elsif config[:linter] == "standard" -%> -gem "standard", "~> <%= config[:linter_version] %>" +gem "standard", ">= <%= config[:linter_version] %>" <%- end -%> diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt index 7d0fc565e21cd8..2729530e8d9748 100644 --- a/lib/bundler/templates/newgem/newgem.gemspec.tt +++ b/lib/bundler/templates/newgem/newgem.gemspec.tt @@ -45,12 +45,12 @@ Gem::Specification.new do |spec| <%- end -%> # Uncomment to register a new dependency of your gem - # spec.add_dependency "example-gem", "~> 1.0" + # spec.add_dependency "example-gem", ">= 1.0" <%- if config[:ext] == 'rust' -%> - spec.add_dependency "rb_sys", "~> 0.9.127" + spec.add_dependency "rb_sys", ">= 0.9.127" <%- end -%> <%- if config[:ext] == 'go' -%> - spec.add_dependency "go_gem", "~> 0.2" + spec.add_dependency "go_gem", ">= 0.2" <%- end -%> # For more information and examples about making a new gem, check out our diff --git a/pack.c b/pack.c index 94bb510e0db182..24221bc3d6429c 100644 --- a/pack.c +++ b/pack.c @@ -1024,9 +1024,10 @@ pack_unpack_internal(VALUE str, VALUE fmt, enum unpack_mode mode, long offset) StringValue(fmt); rb_must_asciicompat(fmt); - if (offset < 0) rb_raise(rb_eArgError, "offset can't be negative"); len = RSTRING_LEN(str); - if (offset > len) rb_raise(rb_eArgError, "offset outside of string"); + if (offset < 0 ? (offset += len) < 0 : offset > len) { + rb_raise(rb_eArgError, "offset outside of string"); + } s = RSTRING_PTR(str); send = s + len; diff --git a/rational.c b/rational.c index 329a06845ac254..d6214451b483db 100644 --- a/rational.c +++ b/rational.c @@ -2304,6 +2304,12 @@ islettere(int c) return (c == 'e' || c == 'E'); } +inline static int +isletterr(int c) +{ + return (c == 'r' || c == 'R'); +} + static VALUE negate_num(VALUE num) { @@ -2353,7 +2359,13 @@ read_num(const char **s, const char *const end, VALUE *num, VALUE *nexp) ok = 1; } - if (ok && *s + 1 < end && islettere(**s)) { + if (!ok || *s >= end) { + /* failed or finish */ + } + else if (isletterr(**s)) { + (*s)++; + } + else if (*s + 1 < end && islettere(**s)) { (*s)++; expsign = read_sign(s, end); exp = rb_int_parse_cstr(*s, end-*s, &e, NULL, diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index f00aa276c463d2..3024a2486f79de 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -752,7 +752,7 @@ def create_temporary_dir(dir) builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile")) builder.dependencies rspec_dep = builder.dependencies.find {|d| d.name == "rspec" } - expect(rspec_dep).to be_specific + expect(rspec_dep).not_to be_specific end end @@ -837,7 +837,7 @@ def create_temporary_dir(dir) builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile")) builder.dependencies minitest_dep = builder.dependencies.find {|d| d.name == "minitest" } - expect(minitest_dep).to be_specific + expect(minitest_dep).not_to be_specific end it "builds spec skeleton" do @@ -898,7 +898,7 @@ def create_temporary_dir(dir) builder.eval_gemfile(bundled_app("#{gem_name}/Gemfile")) builder.dependencies test_unit_dep = builder.dependencies.find {|d| d.name == "test-unit" } - expect(test_unit_dep).to be_specific + expect(test_unit_dep).not_to be_specific end it "builds spec skeleton" do @@ -1829,7 +1829,7 @@ def setup_rust_env end it "includes go_gem in gem_name.gemspec" do - expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include('spec.add_dependency "go_gem", "~> 0.2"') + expect(bundled_app("#{gem_name}/#{gem_name}.gemspec").read).to include('spec.add_dependency "go_gem", ">= 0.2"') end it "includes go_gem extension in extconf.rb" do diff --git a/spec/ruby/core/string/unpack1_spec.rb b/spec/ruby/core/string/unpack1_spec.rb index 3b0fa90900abcf..ee10042eb8f43b 100644 --- a/spec/ruby/core/string/unpack1_spec.rb +++ b/spec/ruby/core/string/unpack1_spec.rb @@ -20,8 +20,22 @@ "؈".unpack1("C", offset: 1).should == 136 end - it "raises an ArgumentError when the offset is negative" do - -> { "a".unpack1("C", offset: -1) }.should.raise(ArgumentError, "offset can't be negative") + describe "when the offset is negative" do + ruby_version_is "4.1" do + it "starts unpacking from the end" do + "abc".unpack1("C", offset: -2).should == 98 + end + + it "raises an ArgumentError if it is less than -length" do + -> { "a".unpack1("C", offset: -2) }.should.raise(ArgumentError, "offset outside of string") + end + end + + ruby_version_is ""..."4.1" do + it "raises an ArgumentError" do + -> { "a".unpack1("C", offset: -1) }.should.raise(ArgumentError, "offset can't be negative") + end + end end it "returns nil if the offset is at the end of the string" do diff --git a/spec/ruby/core/string/unpack_spec.rb b/spec/ruby/core/string/unpack_spec.rb index 28dbbc14c411c6..eb4710ce140232 100644 --- a/spec/ruby/core/string/unpack_spec.rb +++ b/spec/ruby/core/string/unpack_spec.rb @@ -18,8 +18,22 @@ "؈".unpack("CC", offset: 1).should == [136, nil] end - it "raises an ArgumentError when the offset is negative" do - -> { "a".unpack("C", offset: -1) }.should.raise(ArgumentError, "offset can't be negative") + describe "when the offset is negative" do + ruby_version_is "4.1" do + it "starts unpacking from the end" do + "abc".unpack("CC", offset: -2).should == [98, 99] + end + + it "raises an ArgumentError if it is less than -length" do + -> { "a".unpack("C", offset: -2) }.should.raise(ArgumentError, "offset outside of string") + end + end + + ruby_version_is ""..."4.1" do + it "raises an ArgumentError" do + -> { "a".unpack("C", offset: -1) }.should.raise(ArgumentError, "offset can't be negative") + end + end end it "returns nil if the offset is at the end of the string" do diff --git a/test/ruby/test_pack.rb b/test/ruby/test_pack.rb index 3020e02761574a..6e5f0fe7ff948f 100644 --- a/test/ruby/test_pack.rb +++ b/test/ruby/test_pack.rb @@ -913,27 +913,29 @@ def test_unpack1 def test_unpack1_offset assert_equal 65, "ZA".unpack1("C", offset: 1) + assert_equal 65, "ZA".unpack1("C", offset: -1) assert_equal "01000001", "YZA".unpack1("B*", offset: 2) assert_nil "abc".unpack1("C", offset: 3) - assert_raise_with_message(ArgumentError, /offset can't be negative/) { - "a".unpack1("C", offset: -1) - } assert_raise_with_message(ArgumentError, /offset outside of string/) { "a".unpack1("C", offset: 2) } + assert_raise_with_message(ArgumentError, /offset outside of string/) { + "a".unpack1("C", offset: -2) + } assert_nil "a".unpack1("C", offset: 1) end def test_unpack_offset assert_equal [65], "ZA".unpack("C", offset: 1) + assert_equal [65], "ZA".unpack("C", offset: -1) assert_equal ["01000001"], "YZA".unpack("B*", offset: 2) assert_equal [nil, nil, nil], "abc".unpack("CCC", offset: 3) - assert_raise_with_message(ArgumentError, /offset can't be negative/) { - "a".unpack("C", offset: -1) - } assert_raise_with_message(ArgumentError, /offset outside of string/) { "a".unpack("C", offset: 2) } + assert_raise_with_message(ArgumentError, /offset outside of string/) { + "a".unpack("C", offset: -2) + } assert_equal [nil], "a".unpack("C", offset: 1) end diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index e0edbde4637c44..a02e11acc5b636 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -65,7 +65,7 @@ def test_freeze assert_instance_of(String, c.to_s) end - def test_conv + def test_conv_integer c = Rational(0,1) assert_equal(Rational(0,1), c) @@ -94,6 +94,11 @@ def test_conv c = Rational(Rational(1,2),Rational(1,2)) assert_equal(Rational(1), c) + assert_equal(Rational(3),Rational(3)) + assert_equal(Rational(1),Rational(3,3)) + end + + def test_conv_complex c = Rational(Complex(1,2),2) assert_equal(Complex(Rational(1,2),1), c) @@ -102,11 +107,21 @@ def test_conv c = Rational(Complex(1,2),Complex(1,2)) assert_equal(Rational(1), c) + end - assert_equal(Rational(3),Rational(3)) - assert_equal(Rational(1),Rational(3,3)) + def test_conv_float assert_equal(3.3.to_r,Rational(3.3)) assert_equal(1,Rational(3.3,3.3)) + + if (0.0/0).nan? + assert_raise(FloatDomainError){Rational(0.0/0)} + end + if (1.0/0).infinite? + assert_raise(FloatDomainError){Rational(1.0/0)} + end + end + + def test_conv_string assert_equal(Rational(3),Rational('3')) assert_equal(Rational(1),Rational('3.0','3.0')) assert_equal(Rational(1),Rational('3/3','3/3')) @@ -115,6 +130,10 @@ def test_conv assert_equal(Rational(111, 10), Rational('1.11e1')) assert_equal(Rational(111, 100), Rational('1.11e0')) assert_equal(Rational(111, 1000), Rational('1.11e-1')) + assert_equal(Rational(5, 4), Rational('3.0r','2.4R')) + end + + def test_conv_error assert_raise(TypeError){Rational(nil)} assert_raise(ArgumentError){Rational('')} @@ -131,7 +150,9 @@ def test_conv assert_raise(TypeError){Rational(Object.new)} assert_raise(TypeError){Rational(Object.new, Object.new)} assert_raise(TypeError){Rational(1, Object.new)} + end + def test_conv_coerce bug12485 = '[ruby-core:75995] [Bug #12485]' o = Object.new def o.to_int; 1; end @@ -163,13 +184,6 @@ def o.to_r; raise; end assert_raise(ArgumentError){Rational()} assert_raise(ArgumentError){Rational(1,2,3)} - if (0.0/0).nan? - assert_raise(FloatDomainError){Rational(0.0/0)} - end - if (1.0/0).infinite? - assert_raise(FloatDomainError){Rational(1.0/0)} - end - bug16518 = "[ruby-core:96942] [Bug #16518]" cls = Class.new(Numeric) do def /(y); 42; end @@ -829,6 +843,10 @@ def test_parse ng[5, 3, '5/3x'] ng[5, 1, '5/-3'] + + ok[30, 24, '3.0r/2.4R'] + ng[30, 24, '3.0r/2.4re1'] + ng[30, 240, '3.0r/2.4e1r'] end def test_parse_zero_denominator