diff options
author | Benoit Daloze <[email protected]> | 2024-11-06 21:57:34 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2024-11-06 21:58:28 +0100 |
commit | fdc82cca83bbbfe88f90d2888e139a6dde481101 (patch) | |
tree | 99165cce6af5eaca59316c06fed33f958c85e16a /spec/ruby/core | |
parent | 9bc63e7ba066b31314bbd66def4932b398eaf4c9 (diff) |
Update to ruby/spec@54c391e
Diffstat (limited to 'spec/ruby/core')
58 files changed, 1296 insertions, 185 deletions
diff --git a/spec/ruby/core/basicobject/instance_exec_spec.rb b/spec/ruby/core/basicobject/instance_exec_spec.rb index 289fdd889b..370f03d33c 100644 --- a/spec/ruby/core/basicobject/instance_exec_spec.rb +++ b/spec/ruby/core/basicobject/instance_exec_spec.rb @@ -84,17 +84,17 @@ describe "BasicObject#instance_exec" do end.should raise_error(TypeError) end -quarantine! do # Not clean, leaves cvars lying around to break other specs - it "scopes class var accesses in the caller when called on an Integer" do - # Integer can take instance vars - Integer.class_eval "@@__tmp_instance_exec_spec = 1" - (defined? @@__tmp_instance_exec_spec).should == nil - - @@__tmp_instance_exec_spec = 2 - 1.instance_exec { @@__tmp_instance_exec_spec }.should == 2 - Integer.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec) + quarantine! do # Not clean, leaves cvars lying around to break other specs + it "scopes class var accesses in the caller when called on an Integer" do + # Integer can take instance vars + Integer.class_eval "@@__tmp_instance_exec_spec = 1" + (defined? @@__tmp_instance_exec_spec).should == nil + + @@__tmp_instance_exec_spec = 2 + 1.instance_exec { @@__tmp_instance_exec_spec }.should == 2 + Integer.__send__(:remove_class_variable, :@@__tmp_instance_exec_spec) + end end -end it "raises a TypeError when defining methods on numerics" do -> do diff --git a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb index 1960f5721f..eaf311783a 100644 --- a/spec/ruby/core/builtin_constants/builtin_constants_spec.rb +++ b/spec/ruby/core/builtin_constants/builtin_constants_spec.rb @@ -4,6 +4,10 @@ describe "RUBY_VERSION" do it "is a String" do RUBY_VERSION.should be_kind_of(String) end + + it "is frozen" do + RUBY_VERSION.should.frozen? + end end describe "RUBY_PATCHLEVEL" do @@ -16,34 +20,58 @@ describe "RUBY_COPYRIGHT" do it "is a String" do RUBY_COPYRIGHT.should be_kind_of(String) end + + it "is frozen" do + RUBY_COPYRIGHT.should.frozen? + end end describe "RUBY_DESCRIPTION" do it "is a String" do RUBY_DESCRIPTION.should be_kind_of(String) end + + it "is frozen" do + RUBY_DESCRIPTION.should.frozen? + end end describe "RUBY_ENGINE" do it "is a String" do RUBY_ENGINE.should be_kind_of(String) end + + it "is frozen" do + RUBY_ENGINE.should.frozen? + end end describe "RUBY_PLATFORM" do it "is a String" do RUBY_PLATFORM.should be_kind_of(String) end + + it "is frozen" do + RUBY_PLATFORM.should.frozen? + end end describe "RUBY_RELEASE_DATE" do it "is a String" do RUBY_RELEASE_DATE.should be_kind_of(String) end + + it "is frozen" do + RUBY_RELEASE_DATE.should.frozen? + end end describe "RUBY_REVISION" do it "is a String" do RUBY_REVISION.should be_kind_of(String) end + + it "is frozen" do + RUBY_REVISION.should.frozen? + end end diff --git a/spec/ruby/core/complex/equal_value_spec.rb b/spec/ruby/core/complex/equal_value_spec.rb index ad7236b1bd..97c486d820 100644 --- a/spec/ruby/core/complex/equal_value_spec.rb +++ b/spec/ruby/core/complex/equal_value_spec.rb @@ -76,7 +76,7 @@ describe "Complex#==" do (Complex(real, 0) == @other).should be_true end - it "returns false when when the imaginary part is not zero" do + it "returns false when the imaginary part is not zero" do (Complex(3, 1) == @other).should be_false end end diff --git a/spec/ruby/core/data/to_h_spec.rb b/spec/ruby/core/data/to_h_spec.rb new file mode 100644 index 0000000000..41d6960c97 --- /dev/null +++ b/spec/ruby/core/data/to_h_spec.rb @@ -0,0 +1,65 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "3.2" do + describe "Data#to_h" do + it "transforms the data object into a hash" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h.should == { amount: 42, unit: 'km' } + end + + context "with block" do + it "transforms [key, value] pairs returned by the block into a hash" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h { |key, value| [value, key] }.should == { 42 => :amount, 'km' => :unit } + end + + it "passes to a block each pair's key and value as separate arguments" do + ScratchPad.record [] + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + data.to_h { |k, v| ScratchPad << [k, v]; [k, v] } + ScratchPad.recorded.sort.should == [[:amount, 42], [:unit, 'km']] + + ScratchPad.record [] + data.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[:amount, 42], [:unit, 'km']] + end + + it "raises ArgumentError if block returns longer or shorter array" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + -> do + data.to_h { |k, v| [k.to_s, v*v, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) + + -> do + data.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end + + it "raises TypeError if block returns something other than Array" do + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + -> do + data.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + + data.to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + data = DataSpecs::Measure.new(amount: 42, unit: 'km') + + -> do + data.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) + end + end + end +end diff --git a/spec/ruby/core/encoding/compatible_spec.rb b/spec/ruby/core/encoding/compatible_spec.rb index f18d8680a9..d5b958ea0b 100644 --- a/spec/ruby/core/encoding/compatible_spec.rb +++ b/spec/ruby/core/encoding/compatible_spec.rb @@ -161,6 +161,379 @@ describe "Encoding.compatible? String, String" do Encoding.compatible?(@str, "").should == Encoding::UTF_7 end end + + # Encoding negotiation depends on whether encodings are ASCII-compatible, empty + # and contain only ASCII characters (that take 7 bits). Check US-ASCII, UTF-8 and + # BINARY encodings (as most common) as well as an ASCII-compatible, a non-ASCII-compatible and a dummy + # encodings in all possible combinations. + describe "compatibility matrix" do + +# Use the following script to regenerate the matrix: +# +# ``` +# # -*- encoding: binary -*- +# +# ENCODINGS = [ +# "US-ASCII", +# "UTF-8", +# "ASCII-8BIT", +# "ISO-8859-1", # ASCII-compatible +# "UTF-16BE", # non-ASCII-compatible +# "ISO-2022-JP" # dummy +# ] +# +# TYPES = [:empty, :"7bits", :non7bits] +# +# VALUES = { +# empty: "", +# :"7bits" => "\x01", +# non7bits: "\x81" +# } +# +# ENCODINGS.product(TYPES, ENCODINGS, TYPES).each do |encoding1, type1, encoding2, type2| +# value1 = VALUES[type1].dup.force_encoding(encoding1) +# value2 = VALUES[type2].dup.force_encoding(encoding2) +# +# result_encoding = Encoding.compatible?(value1, value2) +# +# puts "[#{encoding1.inspect}, #{value1.inspect}, #{encoding2.inspect}, #{value2.inspect}, #{result_encoding&.name.inspect}]," +# end +# ``` + + matrix = [ + ["US-ASCII", "", "US-ASCII", "", "US-ASCII"], + ["US-ASCII", "", "US-ASCII", "\x01", "US-ASCII"], + ["US-ASCII", "", "US-ASCII", "\x81", "US-ASCII"], + ["US-ASCII", "", "UTF-8", "", "US-ASCII"], + ["US-ASCII", "", "UTF-8", "\u0001", "US-ASCII"], + ["US-ASCII", "", "UTF-8", "\x81", "UTF-8"], + ["US-ASCII", "", "ASCII-8BIT", "", "US-ASCII"], + ["US-ASCII", "", "ASCII-8BIT", "\x01", "US-ASCII"], + ["US-ASCII", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["US-ASCII", "", "ISO-8859-1", "", "US-ASCII"], + ["US-ASCII", "", "ISO-8859-1", "\x01", "US-ASCII"], + ["US-ASCII", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["US-ASCII", "", "UTF-16BE", "", "US-ASCII"], + ["US-ASCII", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["US-ASCII", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["US-ASCII", "", "ISO-2022-JP", "", "US-ASCII"], + ["US-ASCII", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["US-ASCII", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["US-ASCII", "\x01", "US-ASCII", "", "US-ASCII"], + ["US-ASCII", "\x01", "US-ASCII", "\x01", "US-ASCII"], + ["US-ASCII", "\x01", "US-ASCII", "\x81", "US-ASCII"], + ["US-ASCII", "\x01", "UTF-8", "", "US-ASCII"], + ["US-ASCII", "\x01", "UTF-8", "\u0001", "US-ASCII"], + ["US-ASCII", "\x01", "UTF-8", "\x81", "UTF-8"], + ["US-ASCII", "\x01", "ASCII-8BIT", "", "US-ASCII"], + ["US-ASCII", "\x01", "ASCII-8BIT", "\x01", "US-ASCII"], + ["US-ASCII", "\x01", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["US-ASCII", "\x01", "ISO-8859-1", "", "US-ASCII"], + ["US-ASCII", "\x01", "ISO-8859-1", "\x01", "US-ASCII"], + ["US-ASCII", "\x01", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["US-ASCII", "\x01", "UTF-16BE", "", "US-ASCII"], + ["US-ASCII", "\x01", "UTF-16BE", "\x01", nil], + ["US-ASCII", "\x01", "UTF-16BE", "\x81", nil], + ["US-ASCII", "\x01", "ISO-2022-JP", "", "US-ASCII"], + ["US-ASCII", "\x01", "ISO-2022-JP", "\x01", nil], + ["US-ASCII", "\x01", "ISO-2022-JP", "\x81", nil], + ["US-ASCII", "\x81", "US-ASCII", "", "US-ASCII"], + ["US-ASCII", "\x81", "US-ASCII", "\x01", "US-ASCII"], + ["US-ASCII", "\x81", "US-ASCII", "\x81", "US-ASCII"], + ["US-ASCII", "\x81", "UTF-8", "", "US-ASCII"], + ["US-ASCII", "\x81", "UTF-8", "\u0001", "US-ASCII"], + ["US-ASCII", "\x81", "UTF-8", "\x81", nil], + ["US-ASCII", "\x81", "ASCII-8BIT", "", "US-ASCII"], + ["US-ASCII", "\x81", "ASCII-8BIT", "\x01", "US-ASCII"], + ["US-ASCII", "\x81", "ASCII-8BIT", "\x81", nil], + ["US-ASCII", "\x81", "ISO-8859-1", "", "US-ASCII"], + ["US-ASCII", "\x81", "ISO-8859-1", "\x01", "US-ASCII"], + ["US-ASCII", "\x81", "ISO-8859-1", "\x81", nil], + ["US-ASCII", "\x81", "UTF-16BE", "", "US-ASCII"], + ["US-ASCII", "\x81", "UTF-16BE", "\x01", nil], + ["US-ASCII", "\x81", "UTF-16BE", "\x81", nil], + ["US-ASCII", "\x81", "ISO-2022-JP", "", "US-ASCII"], + ["US-ASCII", "\x81", "ISO-2022-JP", "\x01", nil], + ["US-ASCII", "\x81", "ISO-2022-JP", "\x81", nil], + ["UTF-8", "", "US-ASCII", "", "UTF-8"], + ["UTF-8", "", "US-ASCII", "\x01", "UTF-8"], + ["UTF-8", "", "US-ASCII", "\x81", "US-ASCII"], + ["UTF-8", "", "UTF-8", "", "UTF-8"], + ["UTF-8", "", "UTF-8", "\u0001", "UTF-8"], + ["UTF-8", "", "UTF-8", "\x81", "UTF-8"], + ["UTF-8", "", "ASCII-8BIT", "", "UTF-8"], + ["UTF-8", "", "ASCII-8BIT", "\x01", "UTF-8"], + ["UTF-8", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["UTF-8", "", "ISO-8859-1", "", "UTF-8"], + ["UTF-8", "", "ISO-8859-1", "\x01", "UTF-8"], + ["UTF-8", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["UTF-8", "", "UTF-16BE", "", "UTF-8"], + ["UTF-8", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["UTF-8", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["UTF-8", "", "ISO-2022-JP", "", "UTF-8"], + ["UTF-8", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["UTF-8", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["UTF-8", "\u0001", "US-ASCII", "", "UTF-8"], + ["UTF-8", "\u0001", "US-ASCII", "\x01", "UTF-8"], + ["UTF-8", "\u0001", "US-ASCII", "\x81", "US-ASCII"], + ["UTF-8", "\u0001", "UTF-8", "", "UTF-8"], + ["UTF-8", "\u0001", "UTF-8", "\u0001", "UTF-8"], + ["UTF-8", "\u0001", "UTF-8", "\x81", "UTF-8"], + ["UTF-8", "\u0001", "ASCII-8BIT", "", "UTF-8"], + ["UTF-8", "\u0001", "ASCII-8BIT", "\x01", "UTF-8"], + ["UTF-8", "\u0001", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["UTF-8", "\u0001", "ISO-8859-1", "", "UTF-8"], + ["UTF-8", "\u0001", "ISO-8859-1", "\x01", "UTF-8"], + ["UTF-8", "\u0001", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["UTF-8", "\u0001", "UTF-16BE", "", "UTF-8"], + ["UTF-8", "\u0001", "UTF-16BE", "\x01", nil], + ["UTF-8", "\u0001", "UTF-16BE", "\x81", nil], + ["UTF-8", "\u0001", "ISO-2022-JP", "", "UTF-8"], + ["UTF-8", "\u0001", "ISO-2022-JP", "\x01", nil], + ["UTF-8", "\u0001", "ISO-2022-JP", "\x81", nil], + ["UTF-8", "\x81", "US-ASCII", "", "UTF-8"], + ["UTF-8", "\x81", "US-ASCII", "\x01", "UTF-8"], + ["UTF-8", "\x81", "US-ASCII", "\x81", nil], + ["UTF-8", "\x81", "UTF-8", "", "UTF-8"], + ["UTF-8", "\x81", "UTF-8", "\u0001", "UTF-8"], + ["UTF-8", "\x81", "UTF-8", "\x81", "UTF-8"], + ["UTF-8", "\x81", "ASCII-8BIT", "", "UTF-8"], + ["UTF-8", "\x81", "ASCII-8BIT", "\x01", "UTF-8"], + ["UTF-8", "\x81", "ASCII-8BIT", "\x81", nil], + ["UTF-8", "\x81", "ISO-8859-1", "", "UTF-8"], + ["UTF-8", "\x81", "ISO-8859-1", "\x01", "UTF-8"], + ["UTF-8", "\x81", "ISO-8859-1", "\x81", nil], + ["UTF-8", "\x81", "UTF-16BE", "", "UTF-8"], + ["UTF-8", "\x81", "UTF-16BE", "\x01", nil], + ["UTF-8", "\x81", "UTF-16BE", "\x81", nil], + ["UTF-8", "\x81", "ISO-2022-JP", "", "UTF-8"], + ["UTF-8", "\x81", "ISO-2022-JP", "\x01", nil], + ["UTF-8", "\x81", "ISO-2022-JP", "\x81", nil], + ["ASCII-8BIT", "", "US-ASCII", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "US-ASCII", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "", "US-ASCII", "\x81", "US-ASCII"], + ["ASCII-8BIT", "", "UTF-8", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "UTF-8", "\u0001", "ASCII-8BIT"], + ["ASCII-8BIT", "", "UTF-8", "\x81", "UTF-8"], + ["ASCII-8BIT", "", "ASCII-8BIT", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ASCII-8BIT", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ISO-8859-1", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ISO-8859-1", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ASCII-8BIT", "", "UTF-16BE", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["ASCII-8BIT", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["ASCII-8BIT", "", "ISO-2022-JP", "", "ASCII-8BIT"], + ["ASCII-8BIT", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["ASCII-8BIT", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["ASCII-8BIT", "\x01", "US-ASCII", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "US-ASCII", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "US-ASCII", "\x81", "US-ASCII"], + ["ASCII-8BIT", "\x01", "UTF-8", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "UTF-8", "\u0001", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "UTF-8", "\x81", "UTF-8"], + ["ASCII-8BIT", "\x01", "ASCII-8BIT", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ASCII-8BIT", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ISO-8859-1", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ISO-8859-1", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ASCII-8BIT", "\x01", "UTF-16BE", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "UTF-16BE", "\x01", nil], + ["ASCII-8BIT", "\x01", "UTF-16BE", "\x81", nil], + ["ASCII-8BIT", "\x01", "ISO-2022-JP", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x01", "ISO-2022-JP", "\x01", nil], + ["ASCII-8BIT", "\x01", "ISO-2022-JP", "\x81", nil], + ["ASCII-8BIT", "\x81", "US-ASCII", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "US-ASCII", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "US-ASCII", "\x81", nil], + ["ASCII-8BIT", "\x81", "UTF-8", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "UTF-8", "\u0001", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "UTF-8", "\x81", nil], + ["ASCII-8BIT", "\x81", "ASCII-8BIT", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ASCII-8BIT", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ISO-8859-1", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ISO-8859-1", "\x01", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ISO-8859-1", "\x81", nil], + ["ASCII-8BIT", "\x81", "UTF-16BE", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "UTF-16BE", "\x01", nil], + ["ASCII-8BIT", "\x81", "UTF-16BE", "\x81", nil], + ["ASCII-8BIT", "\x81", "ISO-2022-JP", "", "ASCII-8BIT"], + ["ASCII-8BIT", "\x81", "ISO-2022-JP", "\x01", nil], + ["ASCII-8BIT", "\x81", "ISO-2022-JP", "\x81", nil], + ["ISO-8859-1", "", "US-ASCII", "", "ISO-8859-1"], + ["ISO-8859-1", "", "US-ASCII", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "", "US-ASCII", "\x81", "US-ASCII"], + ["ISO-8859-1", "", "UTF-8", "", "ISO-8859-1"], + ["ISO-8859-1", "", "UTF-8", "\u0001", "ISO-8859-1"], + ["ISO-8859-1", "", "UTF-8", "\x81", "UTF-8"], + ["ISO-8859-1", "", "ASCII-8BIT", "", "ISO-8859-1"], + ["ISO-8859-1", "", "ASCII-8BIT", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ISO-8859-1", "", "ISO-8859-1", "", "ISO-8859-1"], + ["ISO-8859-1", "", "ISO-8859-1", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ISO-8859-1", "", "UTF-16BE", "", "ISO-8859-1"], + ["ISO-8859-1", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["ISO-8859-1", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["ISO-8859-1", "", "ISO-2022-JP", "", "ISO-8859-1"], + ["ISO-8859-1", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["ISO-8859-1", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["ISO-8859-1", "\x01", "US-ASCII", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "US-ASCII", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "US-ASCII", "\x81", "US-ASCII"], + ["ISO-8859-1", "\x01", "UTF-8", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "UTF-8", "\u0001", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "UTF-8", "\x81", "UTF-8"], + ["ISO-8859-1", "\x01", "ASCII-8BIT", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "ASCII-8BIT", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ISO-8859-1", "\x01", "ISO-8859-1", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "ISO-8859-1", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "UTF-16BE", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "UTF-16BE", "\x01", nil], + ["ISO-8859-1", "\x01", "UTF-16BE", "\x81", nil], + ["ISO-8859-1", "\x01", "ISO-2022-JP", "", "ISO-8859-1"], + ["ISO-8859-1", "\x01", "ISO-2022-JP", "\x01", nil], + ["ISO-8859-1", "\x01", "ISO-2022-JP", "\x81", nil], + ["ISO-8859-1", "\x81", "US-ASCII", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "US-ASCII", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "US-ASCII", "\x81", nil], + ["ISO-8859-1", "\x81", "UTF-8", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "UTF-8", "\u0001", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "UTF-8", "\x81", nil], + ["ISO-8859-1", "\x81", "ASCII-8BIT", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "ASCII-8BIT", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "ASCII-8BIT", "\x81", nil], + ["ISO-8859-1", "\x81", "ISO-8859-1", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "ISO-8859-1", "\x01", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "UTF-16BE", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "UTF-16BE", "\x01", nil], + ["ISO-8859-1", "\x81", "UTF-16BE", "\x81", nil], + ["ISO-8859-1", "\x81", "ISO-2022-JP", "", "ISO-8859-1"], + ["ISO-8859-1", "\x81", "ISO-2022-JP", "\x01", nil], + ["ISO-8859-1", "\x81", "ISO-2022-JP", "\x81", nil], + ["UTF-16BE", "", "US-ASCII", "", "UTF-16BE"], + ["UTF-16BE", "", "US-ASCII", "\x01", "US-ASCII"], + ["UTF-16BE", "", "US-ASCII", "\x81", "US-ASCII"], + ["UTF-16BE", "", "UTF-8", "", "UTF-16BE"], + ["UTF-16BE", "", "UTF-8", "\u0001", "UTF-8"], + ["UTF-16BE", "", "UTF-8", "\x81", "UTF-8"], + ["UTF-16BE", "", "ASCII-8BIT", "", "UTF-16BE"], + ["UTF-16BE", "", "ASCII-8BIT", "\x01", "ASCII-8BIT"], + ["UTF-16BE", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["UTF-16BE", "", "ISO-8859-1", "", "UTF-16BE"], + ["UTF-16BE", "", "ISO-8859-1", "\x01", "ISO-8859-1"], + ["UTF-16BE", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["UTF-16BE", "", "UTF-16BE", "", "UTF-16BE"], + ["UTF-16BE", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["UTF-16BE", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["UTF-16BE", "", "ISO-2022-JP", "", "UTF-16BE"], + ["UTF-16BE", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["UTF-16BE", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["UTF-16BE", "\x01", "US-ASCII", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "US-ASCII", "\x01", nil], + ["UTF-16BE", "\x01", "US-ASCII", "\x81", nil], + ["UTF-16BE", "\x01", "UTF-8", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "UTF-8", "\u0001", nil], + ["UTF-16BE", "\x01", "UTF-8", "\x81", nil], + ["UTF-16BE", "\x01", "ASCII-8BIT", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "ASCII-8BIT", "\x01", nil], + ["UTF-16BE", "\x01", "ASCII-8BIT", "\x81", nil], + ["UTF-16BE", "\x01", "ISO-8859-1", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "ISO-8859-1", "\x01", nil], + ["UTF-16BE", "\x01", "ISO-8859-1", "\x81", nil], + ["UTF-16BE", "\x01", "UTF-16BE", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "UTF-16BE", "\x01", "UTF-16BE"], + ["UTF-16BE", "\x01", "UTF-16BE", "\x81", "UTF-16BE"], + ["UTF-16BE", "\x01", "ISO-2022-JP", "", "UTF-16BE"], + ["UTF-16BE", "\x01", "ISO-2022-JP", "\x01", nil], + ["UTF-16BE", "\x01", "ISO-2022-JP", "\x81", nil], + ["UTF-16BE", "\x81", "US-ASCII", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "US-ASCII", "\x01", nil], + ["UTF-16BE", "\x81", "US-ASCII", "\x81", nil], + ["UTF-16BE", "\x81", "UTF-8", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "UTF-8", "\u0001", nil], + ["UTF-16BE", "\x81", "UTF-8", "\x81", nil], + ["UTF-16BE", "\x81", "ASCII-8BIT", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "ASCII-8BIT", "\x01", nil], + ["UTF-16BE", "\x81", "ASCII-8BIT", "\x81", nil], + ["UTF-16BE", "\x81", "ISO-8859-1", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "ISO-8859-1", "\x01", nil], + ["UTF-16BE", "\x81", "ISO-8859-1", "\x81", nil], + ["UTF-16BE", "\x81", "UTF-16BE", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "UTF-16BE", "\x01", "UTF-16BE"], + ["UTF-16BE", "\x81", "UTF-16BE", "\x81", "UTF-16BE"], + ["UTF-16BE", "\x81", "ISO-2022-JP", "", "UTF-16BE"], + ["UTF-16BE", "\x81", "ISO-2022-JP", "\x01", nil], + ["UTF-16BE", "\x81", "ISO-2022-JP", "\x81", nil], + ["ISO-2022-JP", "", "US-ASCII", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "US-ASCII", "\x01", "US-ASCII"], + ["ISO-2022-JP", "", "US-ASCII", "\x81", "US-ASCII"], + ["ISO-2022-JP", "", "UTF-8", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "UTF-8", "\u0001", "UTF-8"], + ["ISO-2022-JP", "", "UTF-8", "\x81", "UTF-8"], + ["ISO-2022-JP", "", "ASCII-8BIT", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "ASCII-8BIT", "\x01", "ASCII-8BIT"], + ["ISO-2022-JP", "", "ASCII-8BIT", "\x81", "ASCII-8BIT"], + ["ISO-2022-JP", "", "ISO-8859-1", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "ISO-8859-1", "\x01", "ISO-8859-1"], + ["ISO-2022-JP", "", "ISO-8859-1", "\x81", "ISO-8859-1"], + ["ISO-2022-JP", "", "UTF-16BE", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "UTF-16BE", "\x01", "UTF-16BE"], + ["ISO-2022-JP", "", "UTF-16BE", "\x81", "UTF-16BE"], + ["ISO-2022-JP", "", "ISO-2022-JP", "", "ISO-2022-JP"], + ["ISO-2022-JP", "", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["ISO-2022-JP", "", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "US-ASCII", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "US-ASCII", "\x01", nil], + ["ISO-2022-JP", "\x01", "US-ASCII", "\x81", nil], + ["ISO-2022-JP", "\x01", "UTF-8", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "UTF-8", "\u0001", nil], + ["ISO-2022-JP", "\x01", "UTF-8", "\x81", nil], + ["ISO-2022-JP", "\x01", "ASCII-8BIT", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "ASCII-8BIT", "\x01", nil], + ["ISO-2022-JP", "\x01", "ASCII-8BIT", "\x81", nil], + ["ISO-2022-JP", "\x01", "ISO-8859-1", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "ISO-8859-1", "\x01", nil], + ["ISO-2022-JP", "\x01", "ISO-8859-1", "\x81", nil], + ["ISO-2022-JP", "\x01", "UTF-16BE", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "UTF-16BE", "\x01", nil], + ["ISO-2022-JP", "\x01", "UTF-16BE", "\x81", nil], + ["ISO-2022-JP", "\x01", "ISO-2022-JP", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["ISO-2022-JP", "\x01", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "US-ASCII", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "US-ASCII", "\x01", nil], + ["ISO-2022-JP", "\x81", "US-ASCII", "\x81", nil], + ["ISO-2022-JP", "\x81", "UTF-8", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "UTF-8", "\u0001", nil], + ["ISO-2022-JP", "\x81", "UTF-8", "\x81", nil], + ["ISO-2022-JP", "\x81", "ASCII-8BIT", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "ASCII-8BIT", "\x01", nil], + ["ISO-2022-JP", "\x81", "ASCII-8BIT", "\x81", nil], + ["ISO-2022-JP", "\x81", "ISO-8859-1", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "ISO-8859-1", "\x01", nil], + ["ISO-2022-JP", "\x81", "ISO-8859-1", "\x81", nil], + ["ISO-2022-JP", "\x81", "UTF-16BE", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "UTF-16BE", "\x01", nil], + ["ISO-2022-JP", "\x81", "UTF-16BE", "\x81", nil], + ["ISO-2022-JP", "\x81", "ISO-2022-JP", "", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "ISO-2022-JP", "\x01", "ISO-2022-JP"], + ["ISO-2022-JP", "\x81", "ISO-2022-JP", "\x81", "ISO-2022-JP"], + ] + + matrix.each do |encoding1, value1, encoding2, value2, compatible_encoding| + it "returns #{compatible_encoding} for #{value1.inspect} in #{encoding1} and #{value2.inspect} in #{encoding2}" do + actual_encoding = Encoding.compatible?(value1.dup.force_encoding(encoding1), value2.dup.force_encoding(encoding2)) + actual_encoding&.name.should == compatible_encoding + end + end + end end describe "Encoding.compatible? String, Regexp" do @@ -377,3 +750,9 @@ describe "Encoding.compatible? Object, Object" do Encoding.compatible?(:sym, Object.new).should be_nil end end + +describe "Encoding.compatible? nil, nil" do + it "returns nil" do + Encoding.compatible?(nil, nil).should be_nil + end +end diff --git a/spec/ruby/core/enumerator/each_with_index_spec.rb b/spec/ruby/core/enumerator/each_with_index_spec.rb index 96e53a2804..271e61fec6 100644 --- a/spec/ruby/core/enumerator/each_with_index_spec.rb +++ b/spec/ruby/core/enumerator/each_with_index_spec.rb @@ -21,16 +21,16 @@ describe "Enumerator#each_with_index" do it "passes on the given block's return value" do arr = [1,2,3] - arr.delete_if.with_index { |a,b| false } + arr.delete_if.each_with_index { |a,b| false } arr.should == [1,2,3] end it "returns the iterator's return value" do - [1,2,3].select.with_index { |a,b| false }.should == [] + [1,2,3].select.each_with_index { |a,b| false }.should == [] + [1,2,3].select.each_with_index { |a,b| true }.should == [1,2,3] end it "returns the correct value if chained with itself" do [:a].each_with_index.each_with_index.to_a.should == [[[:a,0],0]] - [:a].each.with_index.with_index.to_a.should == [[[:a,0],0]] end end diff --git a/spec/ruby/core/enumerator/with_index_spec.rb b/spec/ruby/core/enumerator/with_index_spec.rb index ac37cee508..3aeb3fc869 100644 --- a/spec/ruby/core/enumerator/with_index_spec.rb +++ b/spec/ruby/core/enumerator/with_index_spec.rb @@ -69,4 +69,21 @@ describe "Enumerator#with_index" do @enum.with_index(-1) { |*x| res << x} res.should == [[1,-1], [2,0], [3,1], [4,2]] end + + it "passes on the given block's return value" do + arr = [1,2,3] + arr.delete_if.with_index { |a,b| false } + arr.should == [1,2,3] + + arr.delete_if.with_index { |a,b| true } + arr.should == [] + end + + it "returns the iterator's return value" do + @enum.select.with_index { |a,b| false }.should == [] + end + + it "returns the correct value if chained with itself" do + [:a].each.with_index.with_index.to_a.should == [[[:a,0],0]] + end end diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb index 5154354555..d752083db2 100644 --- a/spec/ruby/core/exception/full_message_spec.rb +++ b/spec/ruby/core/exception/full_message_spec.rb @@ -79,6 +79,24 @@ describe "Exception#full_message" do err.full_message(highlight: true).should !~ /unhandled exception/ err.full_message(highlight: false).should !~ /unhandled exception/ end + + it "adds escape sequences to highlight some strings if the message is not specified and :highlight option is specified" do + e = RuntimeError.new("") + + full_message = e.full_message(highlight: true, order: :top).lines + full_message[0].should.end_with? "\e[1;4munhandled exception\e[m\n" + + full_message = e.full_message(highlight: true, order: :bottom).lines + full_message[0].should == "\e[1mTraceback\e[m (most recent call last):\n" + full_message[-1].should.end_with? "\e[1;4munhandled exception\e[m\n" + + full_message = e.full_message(highlight: false, order: :top).lines + full_message[0].should.end_with? "unhandled exception\n" + + full_message = e.full_message(highlight: false, order: :bottom).lines + full_message[0].should == "Traceback (most recent call last):\n" + full_message[-1].should.end_with? "unhandled exception\n" + end end describe "generic Error" do diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb index b3e021e636..2f2baa4a12 100644 --- a/spec/ruby/core/fiber/raise_spec.rb +++ b/spec/ruby/core/fiber/raise_spec.rb @@ -42,7 +42,7 @@ describe "Fiber#raise" do -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error' }.should raise_error(FiberSpecs::CustomError, 'test error') end - it 'accepts error class with with error message and backtrace information' do + it 'accepts error class with error message and backtrace information' do -> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error', ['foo', 'boo'] }.should raise_error(FiberSpecs::CustomError) { |e| diff --git a/spec/ruby/core/file/chown_spec.rb b/spec/ruby/core/file/chown_spec.rb index 8cc8f0d04b..4db0e3712c 100644 --- a/spec/ruby/core/file/chown_spec.rb +++ b/spec/ruby/core/file/chown_spec.rb @@ -78,15 +78,15 @@ describe "File.chown" do end describe "File#chown" do - before :each do - @fname = tmp('file_chown_test') - @file = File.open(@fname, 'w') - end + before :each do + @fname = tmp('file_chown_test') + @file = File.open(@fname, 'w') + end - after :each do - @file.close unless @file.closed? - rm_r @fname - end + after :each do + @file.close unless @file.closed? + rm_r @fname + end as_superuser do platform_is :windows do diff --git a/spec/ruby/core/float/ceil_spec.rb b/spec/ruby/core/float/ceil_spec.rb index 7fc18d304c..75f5610292 100644 --- a/spec/ruby/core/float/ceil_spec.rb +++ b/spec/ruby/core/float/ceil_spec.rb @@ -1,6 +1,11 @@ require_relative '../../spec_helper' +require_relative '../integer/shared/integer_ceil_precision' describe "Float#ceil" do + context "with precision" do + it_behaves_like :integer_ceil_precision, :Float + end + it "returns the smallest Integer greater than or equal to self" do -1.2.ceil.should eql( -1) -1.0.ceil.should eql( -1) diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb index 1373b3a1fb..d2e47937ff 100644 --- a/spec/ruby/core/float/comparison_spec.rb +++ b/spec/ruby/core/float/comparison_spec.rb @@ -72,7 +72,7 @@ describe "Float#<=>" do (-Float::MAX.to_i*2 <=> -infinity_value).should == 1 end - it "returns 0 when self is Infinity and other other is infinite?=1" do + it "returns 0 when self is Infinity and other is infinite?=1" do obj = Object.new def obj.infinite? 1 diff --git a/spec/ruby/core/float/floor_spec.rb b/spec/ruby/core/float/floor_spec.rb index 046216d36d..8b492ef473 100644 --- a/spec/ruby/core/float/floor_spec.rb +++ b/spec/ruby/core/float/floor_spec.rb @@ -1,6 +1,11 @@ require_relative '../../spec_helper' +require_relative '../integer/shared/integer_floor_precision' describe "Float#floor" do + context "with precision" do + it_behaves_like :integer_floor_precision, :Float + end + it "returns the largest Integer less than or equal to self" do -1.2.floor.should eql( -2) -1.0.floor.should eql( -1) diff --git a/spec/ruby/core/hash/element_reference_spec.rb b/spec/ruby/core/hash/element_reference_spec.rb index 94e8237839..d5859cb342 100644 --- a/spec/ruby/core/hash/element_reference_spec.rb +++ b/spec/ruby/core/hash/element_reference_spec.rb @@ -12,7 +12,7 @@ describe "Hash#[]" do h[[]].should == "baz" end - it "returns nil as default default value" do + it "returns nil as default value" do { 0 => 0 }[5].should == nil end diff --git a/spec/ruby/core/hash/hash_spec.rb b/spec/ruby/core/hash/hash_spec.rb index 19eb806dc4..9b47d4b2bf 100644 --- a/spec/ruby/core/hash/hash_spec.rb +++ b/spec/ruby/core/hash/hash_spec.rb @@ -47,7 +47,7 @@ describe "Hash#hash" do a = 1 b = 2 - eval('{a:, b:}.should == { a: 1, b: 2 }') + eval('{a:, b:}.should == { a: 1, b: 2 }') end end end diff --git a/spec/ruby/core/integer/ceil_spec.rb b/spec/ruby/core/integer/ceil_spec.rb index 13bdaf838d..eb633fba78 100644 --- a/spec/ruby/core/integer/ceil_spec.rb +++ b/spec/ruby/core/integer/ceil_spec.rb @@ -1,11 +1,16 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_ceil_precision' describe "Integer#ceil" do it_behaves_like :integer_to_i, :ceil it_behaves_like :integer_rounding_positive_precision, :ceil + context "with precision" do + it_behaves_like :integer_ceil_precision, :Integer + end + context "precision argument specified as part of the ceil method is negative" do it "returns the smallest integer greater than self with at least precision.abs trailing zeros" do 18.ceil(-1).should eql(20) diff --git a/spec/ruby/core/integer/floor_spec.rb b/spec/ruby/core/integer/floor_spec.rb index aaa816fdc5..8fb84d58cb 100644 --- a/spec/ruby/core/integer/floor_spec.rb +++ b/spec/ruby/core/integer/floor_spec.rb @@ -1,19 +1,13 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_floor_precision' describe "Integer#floor" do it_behaves_like :integer_to_i, :floor it_behaves_like :integer_rounding_positive_precision, :floor - context "precision argument specified as part of the floor method is negative" do - it "returns the largest integer less than self with at least precision.abs trailing zeros" do - 1832.floor(-1).should eql(1830) - 1832.floor(-2).should eql(1800) - 1832.floor(-3).should eql(1000) - -1832.floor(-1).should eql(-1840) - -1832.floor(-2).should eql(-1900) - -1832.floor(-3).should eql(-2000) - end + context "with precision" do + it_behaves_like :integer_floor_precision, :Integer end end diff --git a/spec/ruby/core/integer/pow_spec.rb b/spec/ruby/core/integer/pow_spec.rb index 4712911095..ecaca01eff 100644 --- a/spec/ruby/core/integer/pow_spec.rb +++ b/spec/ruby/core/integer/pow_spec.rb @@ -19,13 +19,13 @@ describe "Integer#pow" do 2.pow(61, 5843009213693951).should eql 3697379018277258 2.pow(62, 5843009213693952).should eql 1551748822859776 2.pow(63, 5843009213693953).should eql 3103497645717974 - 2.pow(64, 5843009213693954).should eql 363986077738838 + 2.pow(64, 5843009213693954).should eql 363986077738838 end it "handles sign like #divmod does" do - 2.pow(5, 12).should == 8 - 2.pow(5, -12).should == -4 - -2.pow(5, 12).should == 4 + 2.pow(5, 12).should == 8 + 2.pow(5, -12).should == -4 + -2.pow(5, 12).should == 4 -2.pow(5, -12).should == -8 end diff --git a/spec/ruby/core/integer/remainder_spec.rb b/spec/ruby/core/integer/remainder_spec.rb index 96268b3af5..757e42fbe8 100644 --- a/spec/ruby/core/integer/remainder_spec.rb +++ b/spec/ruby/core/integer/remainder_spec.rb @@ -15,8 +15,8 @@ describe "Integer#remainder" do end it "keeps sign of self" do - 5.remainder( 3).should == 2 - 5.remainder(-3).should == 2 + 5.remainder( 3).should == 2 + 5.remainder(-3).should == 2 -5.remainder( 3).should == -2 -5.remainder(-3).should == -2 end diff --git a/spec/ruby/core/integer/shared/integer_ceil_precision.rb b/spec/ruby/core/integer/shared/integer_ceil_precision.rb new file mode 100644 index 0000000000..9f31c2cf61 --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_ceil_precision.rb @@ -0,0 +1,43 @@ +describe :integer_ceil_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).ceil(0).should.eql?(0) + send(@method, 123).ceil(0).should.eql?(123) + send(@method, -123).ceil(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).ceil(1).should.eql?(send(@method, 0)) + send(@method, 0).ceil(10).should.eql?(send(@method, 0)) + + send(@method, 123).ceil(10).should.eql?(send(@method, 123)) + send(@method, -123).ceil(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).ceil(-1).should.eql?(0) + send(@method, 0).ceil(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).ceil(-1).should.eql?(130) + send(@method, 123).ceil(-2).should.eql?(200) + send(@method, 123).ceil(-3).should.eql?(1000) + + send(@method, -123).ceil(-1).should.eql?(-120) + send(@method, -123).ceil(-2).should.eql?(-100) + send(@method, -123).ceil(-3).should.eql?(0) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns 10**precision.abs when precision.abs is larger than the number digits of self" do + send(@method, 123).ceil(-20).should.eql?(100000000000000000000) + send(@method, 123).ceil(-50).should.eql?(100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/integer/shared/integer_floor_precision.rb b/spec/ruby/core/integer/shared/integer_floor_precision.rb new file mode 100644 index 0000000000..4c5888c6c4 --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_floor_precision.rb @@ -0,0 +1,43 @@ +describe :integer_floor_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).floor(0).should.eql?(0) + send(@method, 123).floor(0).should.eql?(123) + send(@method, -123).floor(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).floor(1).should.eql?(send(@method, 0)) + send(@method, 0).floor(10).should.eql?(send(@method, 0)) + + send(@method, 123).floor(10).should.eql?(send(@method, 123)) + send(@method, -123).floor(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).floor(-1).should.eql?(0) + send(@method, 0).floor(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).floor(-1).should.eql?(120) + send(@method, 123).floor(-2).should.eql?(100) + send(@method, 123).floor(-3).should.eql?(0) + + send(@method, -123).floor(-1).should.eql?(-130) + send(@method, -123).floor(-2).should.eql?(-200) + send(@method, -123).floor(-3).should.eql?(-1000) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns -(10**precision.abs) when self is negative and precision.abs is larger than the number digits of self" do + send(@method, -123).floor(-20).should.eql?(-100000000000000000000) + send(@method, -123).floor(-50).should.eql?(-100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/io/dup_spec.rb b/spec/ruby/core/io/dup_spec.rb index 68d538377f..564e007438 100644 --- a/spec/ruby/core/io/dup_spec.rb +++ b/spec/ruby/core/io/dup_spec.rb @@ -25,27 +25,27 @@ describe "IO#dup" do @i.fileno.should_not == @f.fileno end -quarantine! do # This does not appear to be consistent across platforms - it "shares the original stream between the two IOs" do - start = @f.pos - @i.pos.should == start + quarantine! do # This does not appear to be consistent across platforms + it "shares the original stream between the two IOs" do + start = @f.pos + @i.pos.should == start - s = "Hello, wo.. wait, where am I?\n" - s2 = "<evil voice> Muhahahaa!" + s = "Hello, wo.. wait, where am I?\n" + s2 = "<evil voice> Muhahahaa!" - @f.write s - @i.pos.should == @f.pos + @f.write s + @i.pos.should == @f.pos - @i.rewind - @i.gets.should == s + @i.rewind + @i.gets.should == s - @i.rewind - @i.write s2 + @i.rewind + @i.write s2 - @f.rewind - @f.gets.should == "#{s2}\n" + @f.rewind + @f.gets.should == "#{s2}\n" + end end -end it "allows closing the new IO without affecting the original" do @i.close diff --git a/spec/ruby/core/io/puts_spec.rb b/spec/ruby/core/io/puts_spec.rb index 9ed343c94c..a186ddaa5d 100644 --- a/spec/ruby/core/io/puts_spec.rb +++ b/spec/ruby/core/io/puts_spec.rb @@ -33,7 +33,7 @@ describe "IO#puts" do ScratchPad.recorded.should == "\n" end - it "writes empty string with a newline when when given nil as multiple args" do + it "writes empty string with a newline when given nil as multiple args" do @io.puts(nil, nil).should == nil ScratchPad.recorded.should == "\n\n" end diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb index 8741d9f017..567daa55df 100644 --- a/spec/ruby/core/io/read_spec.rb +++ b/spec/ruby/core/io/read_spec.rb @@ -217,19 +217,19 @@ describe "IO.read from a pipe" do end end -quarantine! do # The process tried to write to a nonexistent pipe. - platform_is :windows do - # TODO: It should raise Errno::ESPIPE on Windows as well - # once https://bugs.ruby-lang.org/issues/12230 is fixed. - it "raises Errno::EINVAL if passed an offset" do - -> { - suppress_warning do # https://bugs.ruby-lang.org/issues/19630 - IO.read("|cmd.exe /C echo hello", 1, 1) - end - }.should raise_error(Errno::EINVAL) + quarantine! do # The process tried to write to a nonexistent pipe. + platform_is :windows do + # TODO: It should raise Errno::ESPIPE on Windows as well + # once https://bugs.ruby-lang.org/issues/12230 is fixed. + it "raises Errno::EINVAL if passed an offset" do + -> { + suppress_warning do # https://bugs.ruby-lang.org/issues/19630 + IO.read("|cmd.exe /C echo hello", 1, 1) + end + }.should raise_error(Errno::EINVAL) + end end end -end ruby_version_is "3.3" do # https://bugs.ruby-lang.org/issues/19630 diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb index 454bc4a58e..5f4cd27da0 100644 --- a/spec/ruby/core/kernel/eval_spec.rb +++ b/spec/ruby/core/kernel/eval_spec.rb @@ -274,6 +274,26 @@ describe "Kernel#eval" do eval("").should == nil end + context "with shebang" do + it "ignores shebang with ruby interpreter" do + pid = eval(<<~CODE.b) + #!/usr/bin/env ruby + Process.pid + CODE + + pid.should == Process.pid + end + + it "ignores shebang with non-ruby interpreter" do + pid = eval(<<~CODE.b) + #!/usr/bin/env puma + Process.pid + CODE + + pid.should == Process.pid + end + end + # See language/magic_comment_spec.rb for more magic comments specs describe "with a magic encoding comment" do it "uses the magic comment encoding for the encoding of literal strings" do diff --git a/spec/ruby/core/kernel/extend_spec.rb b/spec/ruby/core/kernel/extend_spec.rb index 47b22f3a18..6342d8cae1 100644 --- a/spec/ruby/core/kernel/extend_spec.rb +++ b/spec/ruby/core/kernel/extend_spec.rb @@ -76,4 +76,16 @@ describe "Kernel#extend" do -> { @frozen.extend @module }.should raise_error(FrozenError) end end + + it "updated class methods of a module when it extends self and includes another module" do + a = Module.new do + extend self + end + b = Module.new do + def foo; :foo; end + end + + a.include b + a.foo.should == :foo + end end diff --git a/spec/ruby/core/kernel/raise_spec.rb b/spec/ruby/core/kernel/raise_spec.rb index 4f190c120b..a038dcf031 100644 --- a/spec/ruby/core/kernel/raise_spec.rb +++ b/spec/ruby/core/kernel/raise_spec.rb @@ -46,6 +46,22 @@ describe "Kernel#raise" do cause = StandardError.new -> { raise(cause: cause) }.should raise_error(ArgumentError) end + + it "re-raises a rescued exception" do + -> do + begin + raise StandardError, "aaa" + rescue Exception + begin + raise ArgumentError + rescue ArgumentError + end + + # should raise StandardError "aaa" + raise + end + end.should raise_error(StandardError, "aaa") + end end describe "Kernel#raise" do diff --git a/spec/ruby/core/kernel/select_spec.rb b/spec/ruby/core/kernel/select_spec.rb index e0d82f3079..df23414b28 100644 --- a/spec/ruby/core/kernel/select_spec.rb +++ b/spec/ruby/core/kernel/select_spec.rb @@ -10,9 +10,9 @@ end describe "Kernel.select" do it 'does not block when timeout is 0' do IO.pipe do |read, write| - IO.select([read], [], [], 0).should == nil + select([read], [], [], 0).should == nil write.write 'data' - IO.select([read], [], [], 0).should == [[read], [], []] + select([read], [], [], 0).should == [[read], [], []] end end end diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb index d35e313006..1de52a707f 100644 --- a/spec/ruby/core/kernel/sleep_spec.rb +++ b/spec/ruby/core/kernel/sleep_spec.rb @@ -51,6 +51,20 @@ describe "Kernel#sleep" do t.value.should == 5 end + platform_is_not :darwin do + it "sleeps with nanosecond precision" do + start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 100.times do + sleep(0.0001) + end + end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + actual_duration = end_time - start_time + (actual_duration > 0.01).should == true # 100 * 0.0001 => 0.01 + (actual_duration < 0.03).should == true + end + end + ruby_version_is ""..."3.3" do it "raises a TypeError when passed nil" do -> { sleep(nil) }.should raise_error(TypeError) diff --git a/spec/ruby/core/marshal/fixtures/marshal_data.rb b/spec/ruby/core/marshal/fixtures/marshal_data.rb index a508b6bea1..aae3fce0aa 100644 --- a/spec/ruby/core/marshal/fixtures/marshal_data.rb +++ b/spec/ruby/core/marshal/fixtures/marshal_data.rb @@ -1,4 +1,7 @@ # -*- encoding: binary -*- + +require_relative 'marshal_multibyte_data' + class UserDefined class Nested def ==(other) @@ -267,17 +270,6 @@ module MarshalSpec end end - module_eval(<<~ruby.dup.force_encoding(Encoding::UTF_8)) - class MultibyteぁあぃいClass - end - - module MultibyteけげこごModule - end - - class MultibyteぁあぃいTime < Time - end - ruby - class ObjectWithFreezeRaisingException < Object def freeze raise diff --git a/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb b/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb new file mode 100644 index 0000000000..98a0d43392 --- /dev/null +++ b/spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb @@ -0,0 +1,12 @@ +# -*- encoding: utf-8 -*- + +module MarshalSpec + class MultibyteぁあぃいClass + end + + module MultibyteけげこごModule + end + + class MultibyteぁあぃいTime < Time + end +end diff --git a/spec/ruby/core/module/ancestors_spec.rb b/spec/ruby/core/module/ancestors_spec.rb index 5e4c196206..43ebdb864f 100644 --- a/spec/ruby/core/module/ancestors_spec.rb +++ b/spec/ruby/core/module/ancestors_spec.rb @@ -21,6 +21,17 @@ describe "Module#ancestors" do ModuleSpecs::Parent.ancestors.should == ModuleSpecs::Parent.ancestors.uniq end + it "returns a module that is included later into a nested module as well" do + m1 = Module.new + m2 = Module.new + m3 = Module.new do + include m2 + end + m2.include m1 # should be after m3 includes m2 + + m3.ancestors.should == [m3, m2, m1] + end + describe "when called on a singleton class" do it "includes the singleton classes of ancestors" do parent = Class.new diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb index f9edda3a07..4b10dd5963 100644 --- a/spec/ruby/core/module/const_added_spec.rb +++ b/spec/ruby/core/module/const_added_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'fixtures/const_added' describe "Module#const_added" do ruby_version_is "3.2" do @@ -63,6 +64,27 @@ describe "Module#const_added" do ScratchPad.recorded.should == [:SubModule] end + it "is called when a new module is defined under a named module (assigned to a constant)" do + ScratchPad.record [] + + ModuleSpecs::ConstAddedSpecs::NamedModule = Module.new do + def self.const_added(name) + ScratchPad << name + end + + module self::A + def self.const_added(name) + ScratchPad << name + end + + module self::B + end + end + end + + ScratchPad.recorded.should == [:A, :B] + end + it "is called when a new class is defined under self" do ScratchPad.record [] @@ -83,6 +105,27 @@ describe "Module#const_added" do ScratchPad.recorded.should == [:SubClass] end + it "is called when a new class is defined under a named module (assigned to a constant)" do + ScratchPad.record [] + + ModuleSpecs::ConstAddedSpecs::NamedModuleB = Module.new do + def self.const_added(name) + ScratchPad << name + end + + class self::A + def self.const_added(name) + ScratchPad << name + end + + class self::B + end + end + end + + ScratchPad.recorded.should == [:A, :B] + end + it "is called when an autoload is defined" do ScratchPad.record [] diff --git a/spec/ruby/core/module/fixtures/const_added.rb b/spec/ruby/core/module/fixtures/const_added.rb new file mode 100644 index 0000000000..0f5baad65d --- /dev/null +++ b/spec/ruby/core/module/fixtures/const_added.rb @@ -0,0 +1,4 @@ +module ModuleSpecs + module ConstAddedSpecs + end +end diff --git a/spec/ruby/core/module/fixtures/name.rb b/spec/ruby/core/module/fixtures/name.rb index fb9e66c309..25c74d3944 100644 --- a/spec/ruby/core/module/fixtures/name.rb +++ b/spec/ruby/core/module/fixtures/name.rb @@ -7,4 +7,7 @@ module ModuleSpecs Cß.name end end + + module NameSpecs + end end diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb index 78f6b41031..862c6976e1 100644 --- a/spec/ruby/core/module/include_spec.rb +++ b/spec/ruby/core/module/include_spec.rb @@ -581,6 +581,29 @@ describe "Module#include" do c2.include(m) c2.new.foo.should == [:c2, :m1] end + + it "update a module when a nested module is updated and includes a module on its own" do + m1 = Module.new + m2 = Module.new do + def m2; [:m2]; end + end + m3 = Module.new do + def m3; [:m3]; end + end + m4 = Module.new do + def m4; [:m4]; end + end + c = Class.new + + c.include(m1) + m1.include(m2) + m2.include(m3) + m3.include(m4) + + c.new.m2.should == [:m2] + c.new.m3.should == [:m3] + c.new.m4.should == [:m4] + end end describe "Module#include?" do diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb index 0d1f4e24d5..33e8400e88 100644 --- a/spec/ruby/core/module/name_spec.rb +++ b/spec/ruby/core/module/name_spec.rb @@ -140,6 +140,47 @@ describe "Module#name" do valid_names.should include(m::N.name) # You get one of the two, but you don't know which one. end + ruby_version_is "3.2" do + it "is set in #const_added callback when a module defined in the top-level scope" do + ruby_exe(<<~RUBY, args: "2>&1").chomp.should == "TEST1\nTEST2" + class Module + def const_added(name) + puts const_get(name).name + end + end + + # module with name + module TEST1 + end + + # anonymous module + TEST2 = Module.new + RUBY + end + + it "is set in #const_added callback for a nested module when an outer module defined in the top-level scope" do + ScratchPad.record [] + + ModuleSpecs::NameSpecs::NamedModule = Module.new do + def self.const_added(name) + ScratchPad << const_get(name).name + end + + module self::A + def self.const_added(name) + ScratchPad << const_get(name).name + end + + module self::B + end + end + end + + ScratchPad.recorded.should.one?(/#<Module.+>::A$/) + ScratchPad.recorded.should.one?(/#<Module.+>::A::B$/) + end + end + it "returns a frozen String" do ModuleSpecs.name.should.frozen? end diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index 11085c325b..8b9ea5eca8 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -245,7 +245,7 @@ describe "Module#refine" do ruby_version_is ""..."3.2" do it "looks in the included modules for builtin methods" do - result = ruby_exe(<<-RUBY) + result = ruby_exe(<<-RUBY) a = Module.new do def /(other) quo(other) end end diff --git a/spec/ruby/core/objectspace/add_finalizer_spec.rb b/spec/ruby/core/objectspace/add_finalizer_spec.rb deleted file mode 100644 index 3540ac0413..0000000000 --- a/spec/ruby/core/objectspace/add_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.add_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/call_finalizer_spec.rb b/spec/ruby/core/objectspace/call_finalizer_spec.rb deleted file mode 100644 index 6dce92ddd6..0000000000 --- a/spec/ruby/core/objectspace/call_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.call_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb index effecc41d0..4d4cfa9270 100644 --- a/spec/ruby/core/objectspace/define_finalizer_spec.rb +++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb @@ -168,6 +168,31 @@ describe "ObjectSpace.define_finalizer" do ruby_exe(code).lines.sort.should == ["finalized1\n", "finalized2\n"] end + it "defines same finalizer only once" do + code = <<~RUBY + obj = Object.new + p = proc { |id| print "ok" } + ObjectSpace.define_finalizer(obj, p.dup) + ObjectSpace.define_finalizer(obj, p.dup) + RUBY + + ruby_exe(code).should == "ok" + end + + it "returns the defined finalizer" do + obj = Object.new + p = proc { |id| } + p2 = p.dup + + ret = ObjectSpace.define_finalizer(obj, p) + ret.should == [0, p] + ret[1].should.equal?(p) + + ret = ObjectSpace.define_finalizer(obj, p2) + ret.should == [0, p] + ret[1].should.equal?(p) + end + ruby_version_is "3.1" do describe "when $VERBOSE is not nil" do it "warns if an exception is raised in finalizer" do diff --git a/spec/ruby/core/objectspace/finalizers_spec.rb b/spec/ruby/core/objectspace/finalizers_spec.rb deleted file mode 100644 index e7f20fc8a0..0000000000 --- a/spec/ruby/core/objectspace/finalizers_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.finalizers" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/remove_finalizer_spec.rb b/spec/ruby/core/objectspace/remove_finalizer_spec.rb deleted file mode 100644 index 0b2b8cf16b..0000000000 --- a/spec/ruby/core/objectspace/remove_finalizer_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require_relative '../../spec_helper' - -describe "ObjectSpace.remove_finalizer" do - it "needs to be reviewed for spec completeness" -end diff --git a/spec/ruby/core/objectspace/undefine_finalizer_spec.rb b/spec/ruby/core/objectspace/undefine_finalizer_spec.rb index 11d43121f8..f57d5a7845 100644 --- a/spec/ruby/core/objectspace/undefine_finalizer_spec.rb +++ b/spec/ruby/core/objectspace/undefine_finalizer_spec.rb @@ -1,5 +1,33 @@ require_relative '../../spec_helper' describe "ObjectSpace.undefine_finalizer" do - it "needs to be reviewed for spec completeness" + it "removes finalizers for an object" do + code = <<~RUBY + obj = Object.new + ObjectSpace.define_finalizer(obj, proc { |id| puts "hello" }) + ObjectSpace.undefine_finalizer(obj) + RUBY + + ruby_exe(code).should.empty? + end + + it "should not remove finalizers for a frozen object" do + code = <<~RUBY + obj = Object.new + ObjectSpace.define_finalizer(obj, proc { |id| print "ok" }) + obj.freeze + begin + ObjectSpace.undefine_finalizer(obj) + rescue + end + RUBY + + ruby_exe(code).should == "ok" + end + + it "should raise when removing finalizers for a frozen object" do + obj = Object.new + obj.freeze + -> { ObjectSpace.undefine_finalizer(obj) }.should raise_error(FrozenError) + end end diff --git a/spec/ruby/core/proc/curry_spec.rb b/spec/ruby/core/proc/curry_spec.rb index 24df2a8a72..6daabe0ee1 100644 --- a/spec/ruby/core/proc/curry_spec.rb +++ b/spec/ruby/core/proc/curry_spec.rb @@ -159,15 +159,14 @@ describe "Proc#curry with arity argument" do end it "can be passed more than _arity_ arguments if created from a proc" do - -> { @proc_add.curry(3)[1,2,3,4].should == 6 }.should_not - raise_error(ArgumentError) - -> { @proc_add.curry(1)[1,2].curry(3)[3,4,5,6].should == 6 }.should_not - raise_error(ArgumentError) + @proc_add.curry(3)[1,2,3,4].should == 6 + + @proc_add.curry(3)[1,2].curry(3)[3,4,5,6].should == 6 end it "raises an ArgumentError if passed more than _arity_ arguments when created from a lambda" do -> { @lambda_add.curry(3)[1,2,3,4] }.should raise_error(ArgumentError) - -> { @lambda_add.curry(1)[1,2].curry(3)[3,4,5,6] }.should raise_error(ArgumentError) + -> { @lambda_add.curry(3)[1,2].curry(3)[3,4,5,6] }.should raise_error(ArgumentError) end it "returns Procs with arities of -1 regardless of the value of _arity_" do diff --git a/spec/ruby/core/process/constants_spec.rb b/spec/ruby/core/process/constants_spec.rb index 616c54b8e1..57cacadef2 100644 --- a/spec/ruby/core/process/constants_spec.rb +++ b/spec/ruby/core/process/constants_spec.rb @@ -2,69 +2,91 @@ require_relative '../../spec_helper' describe "Process::Constants" do platform_is :darwin, :netbsd, :freebsd do - it "has the correct constant values on BSD-like systems" do - Process::WNOHANG.should == 1 - Process::WUNTRACED.should == 2 - Process::PRIO_PROCESS.should == 0 - Process::PRIO_PGRP.should == 1 - Process::PRIO_USER.should == 2 - Process::RLIM_INFINITY.should == 9223372036854775807 - Process::RLIMIT_CPU.should == 0 - Process::RLIMIT_FSIZE.should == 1 - Process::RLIMIT_DATA.should == 2 - Process::RLIMIT_STACK.should == 3 - Process::RLIMIT_CORE.should == 4 - Process::RLIMIT_RSS.should == 5 - Process::RLIMIT_MEMLOCK.should == 6 - Process::RLIMIT_NPROC.should == 7 - Process::RLIMIT_NOFILE.should == 8 + it "are all present on BSD-like systems" do + %i[ + WNOHANG + WUNTRACED + PRIO_PROCESS + PRIO_PGRP + PRIO_USER + RLIM_INFINITY + RLIMIT_CPU + RLIMIT_FSIZE + RLIMIT_DATA + RLIMIT_STACK + RLIMIT_CORE + RLIMIT_RSS + RLIMIT_MEMLOCK + RLIMIT_NPROC + RLIMIT_NOFILE + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :darwin do - it "has the correct constant values on Darwin" do - Process::RLIM_SAVED_MAX.should == 9223372036854775807 - Process::RLIM_SAVED_CUR.should == 9223372036854775807 - Process::RLIMIT_AS.should == 5 + it "are all present on Darwin" do + %i[ + RLIM_SAVED_MAX + RLIM_SAVED_CUR + RLIMIT_AS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :linux do - it "has the correct constant values on Linux" do - Process::WNOHANG.should == 1 - Process::WUNTRACED.should == 2 - Process::PRIO_PROCESS.should == 0 - Process::PRIO_PGRP.should == 1 - Process::PRIO_USER.should == 2 - Process::RLIMIT_CPU.should == 0 - Process::RLIMIT_FSIZE.should == 1 - Process::RLIMIT_DATA.should == 2 - Process::RLIMIT_STACK.should == 3 - Process::RLIMIT_CORE.should == 4 - Process::RLIMIT_RSS.should == 5 - Process::RLIMIT_NPROC.should == 6 - Process::RLIMIT_NOFILE.should == 7 - Process::RLIMIT_MEMLOCK.should == 8 - Process::RLIMIT_AS.should == 9 - - # These values appear to change according to the platform. - values = [4294967295, 9223372036854775807, 18446744073709551615] - values.include?(Process::RLIM_INFINITY).should be_true - values.include?(Process::RLIM_SAVED_MAX).should be_true - values.include?(Process::RLIM_SAVED_CUR).should be_true + it "are all present on Linux" do + %i[ + WNOHANG + WUNTRACED + PRIO_PROCESS + PRIO_PGRP + PRIO_USER + RLIMIT_CPU + RLIMIT_FSIZE + RLIMIT_DATA + RLIMIT_STACK + RLIMIT_CORE + RLIMIT_RSS + RLIMIT_NPROC + RLIMIT_NOFILE + RLIMIT_MEMLOCK + RLIMIT_AS + RLIM_INFINITY + RLIM_SAVED_MAX + RLIM_SAVED_CUR + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :netbsd, :freebsd do - it "has the correct constant values on NetBSD and FreeBSD" do - Process::RLIMIT_SBSIZE.should == 9 # FIXME: what's it equal? - Process::RLIMIT_AS.should == 10 + it "are all present on NetBSD and FreeBSD" do + %i[ + RLIMIT_SBSIZE + RLIMIT_AS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end platform_is :freebsd do - it "has the correct constant values on FreeBSD" do - Process::RLIMIT_NPTS.should == 11 + it "are all present on FreeBSD" do + %i[ + RLIMIT_NPTS + ].each do |const| + Process.const_defined?(const).should be_true + Process.const_get(const).should be_an_instance_of(Integer) + end end end diff --git a/spec/ruby/core/queue/freeze_spec.rb b/spec/ruby/core/queue/freeze_spec.rb new file mode 100644 index 0000000000..ced2cc52dd --- /dev/null +++ b/spec/ruby/core/queue/freeze_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative '../../shared/queue/freeze' + +describe "Queue#freeze" do + it_behaves_like :queue_freeze, :freeze, -> { Queue.new } +end diff --git a/spec/ruby/core/regexp/shared/new.rb b/spec/ruby/core/regexp/shared/new.rb index 7052bcab63..3ca50d5a47 100644 --- a/spec/ruby/core/regexp/shared/new.rb +++ b/spec/ruby/core/regexp/shared/new.rb @@ -460,6 +460,10 @@ describe :regexp_new_string, shared: true do -> { Regexp.send(@method, "\\" + "u{}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode list: /\\u{}/"))) end + it "raises a RegexpError if the \\u{} escape contains non hexadecimal digits" do + -> { Regexp.send(@method, "\\" + "u{abcX}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode list: /\\u{abcX}/"))) + end + it "raises a RegexpError if more than six hexadecimal digits are given" do -> { Regexp.send(@method, "\\" + "u{0ffffff}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode range: /\\u{0ffffff}/"))) end diff --git a/spec/ruby/core/regexp/shared/quote.rb b/spec/ruby/core/regexp/shared/quote.rb index b5ecc35f04..48179444f0 100644 --- a/spec/ruby/core/regexp/shared/quote.rb +++ b/spec/ruby/core/regexp/shared/quote.rb @@ -2,8 +2,8 @@ describe :regexp_quote, shared: true do it "escapes any characters with special meaning in a regular expression" do - Regexp.send(@method, '\*?{}.+^[]()- ').should == '\\\\\*\?\{\}\.\+\^\[\]\(\)\-\\ ' - Regexp.send(@method, "\*?{}.+^[]()- ").should == '\\*\\?\\{\\}\\.\\+\\^\\[\\]\\(\\)\\-\\ ' + Regexp.send(@method, '\*?{}.+^$[]()- ').should == '\\\\\*\?\{\}\.\+\^\$\[\]\(\)\-\\ ' + Regexp.send(@method, "\*?{}.+^$[]()- ").should == '\\*\\?\\{\\}\\.\\+\\^\\$\\[\\]\\(\\)\\-\\ ' Regexp.send(@method, '\n\r\f\t').should == '\\\\n\\\\r\\\\f\\\\t' Regexp.send(@method, "\n\r\f\t").should == '\\n\\r\\f\\t' end diff --git a/spec/ruby/core/sizedqueue/freeze_spec.rb b/spec/ruby/core/sizedqueue/freeze_spec.rb new file mode 100644 index 0000000000..98f01cae2f --- /dev/null +++ b/spec/ruby/core/sizedqueue/freeze_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative '../../shared/queue/freeze' + +describe "SizedQueue#freeze" do + it_behaves_like :queue_freeze, :freeze, -> { SizedQueue.new(1) } +end diff --git a/spec/ruby/core/string/byteslice_spec.rb b/spec/ruby/core/string/byteslice_spec.rb index 5b1027f4a5..9fe504aeb1 100644 --- a/spec/ruby/core/string/byteslice_spec.rb +++ b/spec/ruby/core/string/byteslice_spec.rb @@ -17,7 +17,7 @@ describe "String#byteslice with Range" do it_behaves_like :string_slice_range, :byteslice end -describe "String#byteslice on on non ASCII strings" do +describe "String#byteslice on non ASCII strings" do it "returns byteslice of unicode strings" do "\u3042".byteslice(1).should == "\x81".dup.force_encoding("UTF-8") "\u3042".byteslice(1, 2).should == "\x81\x82".dup.force_encoding("UTF-8") diff --git a/spec/ruby/core/string/bytesplice_spec.rb b/spec/ruby/core/string/bytesplice_spec.rb index 967edcba29..5cb3b2c158 100644 --- a/spec/ruby/core/string/bytesplice_spec.rb +++ b/spec/ruby/core/string/bytesplice_spec.rb @@ -58,6 +58,79 @@ describe "String#bytesplice" do -> { s.bytesplice(2, 1, "xxx") }.should raise_error(FrozenError, "can't modify frozen String: \"hello\"") end end + + ruby_version_is "3.3" do + it "raises IndexError when str_index is less than -bytesize" do + -> { "hello".bytesplice(2, 1, "HELLO", -6, 0) }.should raise_error(IndexError, "index -6 out of string") + end + + it "raises IndexError when str_index is greater than bytesize" do + -> { "hello".bytesplice(2, 1, "HELLO", 6, 0) }.should raise_error(IndexError, "index 6 out of string") + end + + it "raises IndexError for negative str length" do + -> { "abc".bytesplice(0, 1, "", 0, -2) }.should raise_error(IndexError, "negative length -2") + end + + it "replaces with integer str indices" do + "hello".bytesplice(1, 2, "HELLO", -5, 0).should == "hlo" + "hello".bytesplice(1, 2, "HELLO", 0, 0).should == "hlo" + "hello".bytesplice(1, 2, "HELLO", 0, 1).should == "hHlo" + "hello".bytesplice(1, 2, "HELLO", 0, 5).should == "hHELLOlo" + "hello".bytesplice(1, 2, "HELLO", 0, 6).should == "hHELLOlo" + end + + it "raises RangeError when str range left boundary is less than -bytesize" do + -> { "hello".bytesplice(0..1, "HELLO", -6...-6) }.should raise_error(RangeError, "-6...-6 out of range") + end + + it "replaces with str ranges" do + "hello".bytesplice(1..2, "HELLO", -5...-5).should == "hlo" + "hello".bytesplice(1..2, "HELLO", 0...0).should == "hlo" + "hello".bytesplice(1..2, "HELLO", 0..0).should == "hHlo" + "hello".bytesplice(1..2, "HELLO", 0...1).should == "hHlo" + "hello".bytesplice(1..2, "HELLO", 0..1).should == "hHElo" + "hello".bytesplice(1..2, "HELLO", 0..-1).should == "hHELLOlo" + "hello".bytesplice(1..2, "HELLO", 0...5).should == "hHELLOlo" + "hello".bytesplice(1..2, "HELLO", 0...6).should == "hHELLOlo" + end + + it "raises ArgumentError when integer str index is provided without str length argument" do + -> { "hello".bytesplice(0, 1, "xxx", 0) }.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 2, 3, or 5)") + end + + it "replaces on an empty string with str index/length" do + "".bytesplice(0, 0, "", 0, 0).should == "" + "".bytesplice(0, 0, "xxx", 0, 1).should == "x" + end + + it "mutates self with substring and str index/length" do + s = "hello" + s.bytesplice(2, 1, "xxx", 1, 2).should.equal?(s) + s.should.eql?("hexxlo") + end + + it "raises when string is frozen and str index/length" do + s = "hello".freeze + -> { s.bytesplice(2, 1, "xxx", 0, 1) }.should raise_error(FrozenError, "can't modify frozen String: \"hello\"") + end + + it "replaces on an empty string with str range" do + "".bytesplice(0..0, "", 0..0).should == "" + "".bytesplice(0..0, "xyz", 0..1).should == "xy" + end + + it "mutates self with substring and str range" do + s = "hello" + s.bytesplice(2..2, "xyz", 1..2).should.equal?(s) + s.should.eql?("heyzlo") + end + + it "raises when string is frozen and str range" do + s = "hello".freeze + -> { s.bytesplice(2..2, "yzx", 0..1) }.should raise_error(FrozenError, "can't modify frozen String: \"hello\"") + end + end end describe "String#bytesplice with multibyte characters" do @@ -131,4 +204,95 @@ describe "String#bytesplice with multibyte characters" do result.encoding.should == Encoding::UTF_8 end end + + ruby_version_is "3.3" do + it "raises IndexError when str_index is out of byte size boundary" do + -> { "こんにちは".bytesplice(3, 3, "こんにちは", -16, 0) }.should raise_error(IndexError, "index -16 out of string") + end + + it "raises IndexError when str_index is not on a codepoint boundary" do + -> { "こんにちは".bytesplice(3, 3, "こんにちは", 1, 0) }.should raise_error(IndexError, "offset 1 does not land on character boundary") + end + + it "raises IndexError when str_length is not matching the codepoint boundary" do + -> { "こんにちは".bytesplice(3, 3, "こんにちは", 0, 1) }.should raise_error(IndexError, "offset 1 does not land on character boundary") + -> { "こんにちは".bytesplice(3, 3, "こんにちは", 0, 2) }.should raise_error(IndexError, "offset 2 does not land on character boundary") + end + + it "replaces with integer str indices" do + "こんにちは".bytesplice(3, 3, "こんにちは", -15, 0).should == "こにちは" + "こんにちは".bytesplice(3, 3, "こんにちは", 0, 0).should == "こにちは" + "こんにちは".bytesplice(3, 3, "こんにちは", 0, 3).should == "ここにちは" + "こんにちは".bytesplice(3, 3, "はは", 3, 3).should == "こはにちは" + "こんにちは".bytesplice(3, 3, "こんにちは", 15, 0).should == "こにちは" + end + + it "replaces with str range" do + "こんにちは".bytesplice(0..2, "こんにちは", -15...-16).should == "んにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 0...0).should == "んにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 3..5).should == "んんにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 3...6).should == "んんにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 3..8).should == "んにんにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 0..-1).should == "こんにちはんにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 0...15).should == "こんにちはんにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 0...18).should == "こんにちはんにちは" + end + + it "treats negative length for str range as 0" do + "こんにちは".bytesplice(0..2, "こんにちは", 0...-100).should == "んにちは" + "こんにちは".bytesplice(0..2, "こんにちは", 3...-100).should == "んにちは" + "こんにちは".bytesplice(0..2, "こんにちは", -15...-100).should == "んにちは" + end + + it "raises when ranges not match codepoint boundaries in str" do + -> { "こんにちは".bytesplice(3...3, "こ", 0..0) }.should raise_error(IndexError, "offset 1 does not land on character boundary") + -> { "こんにちは".bytesplice(3...3, "こ", 0..1) }.should raise_error(IndexError, "offset 2 does not land on character boundary") + # Begin is incorrect + -> { "こんにちは".bytesplice(3...3, "こんにちは", -4..-1) }.should raise_error(IndexError, "offset 11 does not land on character boundary") + -> { "こんにちは".bytesplice(3...3, "こんにちは", -5..-1) }.should raise_error(IndexError, "offset 10 does not land on character boundary") + # End is incorrect + -> { "こんにちは".bytesplice(3...3, "こんにちは", -3..-2) }.should raise_error(IndexError, "offset 14 does not land on character boundary") + -> { "こんにちは".bytesplice(3...3, "こんにちは", -3..-3) }.should raise_error(IndexError, "offset 13 does not land on character boundary") + end + + it "deals with a different encoded argument with str index/length" do + s = "こんにちは" + s.encoding.should == Encoding::UTF_8 + sub = "goodbye" + sub.force_encoding(Encoding::US_ASCII) + + result = s.bytesplice(3, 3, sub, 0, 3) + result.should == "こgooにちは" + result.encoding.should == Encoding::UTF_8 + + s = "hello" + s.force_encoding(Encoding::US_ASCII) + sub = "こんにちは" + sub.encoding.should == Encoding::UTF_8 + + result = s.bytesplice(1, 2, sub, 3, 3) + result.should == "hんlo" + result.encoding.should == Encoding::UTF_8 + end + + it "deals with a different encoded argument with str range" do + s = "こんにちは" + s.encoding.should == Encoding::UTF_8 + sub = "goodbye" + sub.force_encoding(Encoding::US_ASCII) + + result = s.bytesplice(3..5, sub, 0..2) + result.should == "こgooにちは" + result.encoding.should == Encoding::UTF_8 + + s = "hello" + s.force_encoding(Encoding::US_ASCII) + sub = "こんにちは" + sub.encoding.should == Encoding::UTF_8 + + result = s.bytesplice(1..2, sub, 3..5) + result.should == "hんlo" + result.encoding.should == Encoding::UTF_8 + end + end end diff --git a/spec/ruby/core/thread/element_reference_spec.rb b/spec/ruby/core/thread/element_reference_spec.rb index 85280cb287..fde9d1f440 100644 --- a/spec/ruby/core/thread/element_reference_spec.rb +++ b/spec/ruby/core/thread/element_reference_spec.rb @@ -37,6 +37,17 @@ describe "Thread#[]" do t2["value"].should == 2 end + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('value') + key.should_receive(:to_str).and_return('value') + + th = Thread.new do + Thread.current[:value] = 1 + end.join + + th[key].should == 1 + end + it "raises exceptions on the wrong type of keys" do -> { Thread.current[nil] }.should raise_error(TypeError) -> { Thread.current[5] }.should raise_error(TypeError) diff --git a/spec/ruby/core/thread/element_set_spec.rb b/spec/ruby/core/thread/element_set_spec.rb index c7498f7ac9..f205177304 100644 --- a/spec/ruby/core/thread/element_set_spec.rb +++ b/spec/ruby/core/thread/element_set_spec.rb @@ -12,10 +12,33 @@ describe "Thread#[]=" do th.freeze -> { th[:foo] = "bar" - }.should raise_error(FrozenError, /frozen/) + }.should raise_error(FrozenError, "can't modify frozen thread locals") end.join end + it "accepts Strings and Symbols" do + t1 = Thread.new do + Thread.current[:value] = 1 + end.join + t2 = Thread.new do + Thread.current["value"] = 2 + end.join + + t1[:value].should == 1 + t2[:value].should == 2 + end + + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('value') + key.should_receive(:to_str).and_return('value') + + th = Thread.new do + Thread.current[key] = 1 + end.join + + th[:value].should == 1 + end + it "raises exceptions on the wrong type of keys" do -> { Thread.current[nil] = true }.should raise_error(TypeError) -> { Thread.current[5] = true }.should raise_error(TypeError) diff --git a/spec/ruby/core/thread/group_spec.rb b/spec/ruby/core/thread/group_spec.rb index 59f5ac37c8..d0d4704b66 100644 --- a/spec/ruby/core/thread/group_spec.rb +++ b/spec/ruby/core/thread/group_spec.rb @@ -1,5 +1,16 @@ require_relative '../../spec_helper' -require_relative 'fixtures/classes' + describe "Thread#group" do - it "needs to be reviewed for spec completeness" + it "returns the default thread group for the main thread" do + Thread.main.group.should == ThreadGroup::Default + end + + it "returns the thread group explicitly set for this thread" do + thread = Thread.new { nil } + thread_group = ThreadGroup.new + thread_group.add(thread) + thread.group.should == thread_group + ensure + thread.join if thread + end end diff --git a/spec/ruby/core/thread/key_spec.rb b/spec/ruby/core/thread/key_spec.rb index 6940cf5f28..339fa98f53 100644 --- a/spec/ruby/core/thread/key_spec.rb +++ b/spec/ruby/core/thread/key_spec.rb @@ -16,6 +16,13 @@ describe "Thread#key?" do @th.key?(:stanley.to_s).should == false end + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('key') + key.should_receive(:to_str).and_return('oliver') + + @th.key?(key).should == true + end + it "raises exceptions on the wrong type of keys" do -> { Thread.current.key? nil }.should raise_error(TypeError) -> { Thread.current.key? 5 }.should raise_error(TypeError) diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb index fa5b5c56d6..c310a8631e 100644 --- a/spec/ruby/core/time/new_spec.rb +++ b/spec/ruby/core/time/new_spec.rb @@ -485,6 +485,8 @@ describe "Time.new with a timezone argument" do Time.new("2020-12-25 00:56:17 +0900").should == t Time.new("2020-12-25 00:57:47 +090130").should == t Time.new("2020-12-25T00:56:17+09:00").should == t + + Time.new("2020-12-25T00:56:17.123456+09:00").should == Time.utc(2020, 12, 24, 15, 56, 17, 123456) end it "accepts precision keyword argument and truncates specified digits of sub-second part" do @@ -511,6 +513,16 @@ describe "Time.new with a timezone argument" do Time.new("2021-12-25 00:00:00", in: "-01:00").to_s.should == "2021-12-25 00:00:00 -0100" end + it "returns Time of Jan 1 for string with just year" do + Time.new("2021").should == Time.new(2021, 1, 1) + Time.new("2021").zone.should == Time.new(2021, 1, 1).zone + Time.new("2021").utc_offset.should == Time.new(2021, 1, 1).utc_offset + end + + it "returns Time of Jan 1 for string with just year in timezone specified with in keyword argument" do + Time.new("2021", in: "+17:00").to_s.should == "2021-01-01 00:00:00 +1700" + end + it "converts precision keyword argument into Integer if is not nil" do obj = Object.new def obj.to_int; 3; end @@ -539,101 +551,109 @@ describe "Time.new with a timezone argument" do it "raises ArgumentError if part of time string is missing" do -> { Time.new("2020-12-25 00:56 +09:00") - }.should raise_error(ArgumentError, "missing sec part: 00:56 ") + }.should raise_error(ArgumentError, /missing sec part: 00:56 |can't parse:/) -> { Time.new("2020-12-25 00 +09:00") - }.should raise_error(ArgumentError, "missing min part: 00 ") + }.should raise_error(ArgumentError, /missing min part: 00 |can't parse:/) + end + + ruby_version_is "3.2.3" do + it "raises ArgumentError if the time part is missing" do + -> { + Time.new("2020-12-25") + }.should raise_error(ArgumentError, /no time information|can't parse:/) + end end it "raises ArgumentError if subsecond is missing after dot" do -> { Time.new("2020-12-25 00:56:17. +0900") - }.should raise_error(ArgumentError, "subsecond expected after dot: 00:56:17. ") + }.should raise_error(ArgumentError, /subsecond expected after dot: 00:56:17. |can't parse:/) end it "raises ArgumentError if String argument is not in the supported format" do -> { Time.new("021-12-25 00:00:00.123456 +09:00") - }.should raise_error(ArgumentError, "year must be 4 or more digits: 021") + }.should raise_error(ArgumentError, /year must be 4 or more digits: 021|can't parse:/) -> { Time.new("2020-012-25 00:56:17 +0900") - }.should raise_error(ArgumentError, /\Atwo digits mon is expected after [`']-': -012-25 00:\z/) + }.should raise_error(ArgumentError, /\Atwo digits mon is expected after [`']-': -012-25 00:\z|can't parse:/) -> { Time.new("2020-2-25 00:56:17 +0900") - }.should raise_error(ArgumentError, /\Atwo digits mon is expected after [`']-': -2-25 00:56\z/) + }.should raise_error(ArgumentError, /\Atwo digits mon is expected after [`']-': -2-25 00:56\z|can't parse:/) -> { Time.new("2020-12-215 00:56:17 +0900") - }.should raise_error(ArgumentError, /\Atwo digits mday is expected after [`']-': -215 00:56:\z/) + }.should raise_error(ArgumentError, /\Atwo digits mday is expected after [`']-': -215 00:56:\z|can't parse:/) -> { Time.new("2020-12-25 000:56:17 +0900") - }.should raise_error(ArgumentError, "two digits hour is expected: 000:56:17 ") + }.should raise_error(ArgumentError, /two digits hour is expected: 000:56:17 |can't parse:/) -> { Time.new("2020-12-25 0:56:17 +0900") - }.should raise_error(ArgumentError, "two digits hour is expected: 0:56:17 +0") + }.should raise_error(ArgumentError, /two digits hour is expected: 0:56:17 \+0|can't parse:/) -> { Time.new("2020-12-25 00:516:17 +0900") - }.should raise_error(ArgumentError, /\Atwo digits min is expected after [`']:': :516:17 \+09\z/) + }.should raise_error(ArgumentError, /\Atwo digits min is expected after [`']:': :516:17 \+09\z|can't parse:/) -> { Time.new("2020-12-25 00:6:17 +0900") - }.should raise_error(ArgumentError, /\Atwo digits min is expected after [`']:': :6:17 \+0900\z/) + }.should raise_error(ArgumentError, /\Atwo digits min is expected after [`']:': :6:17 \+0900\z|can't parse:/) -> { Time.new("2020-12-25 00:56:137 +0900") - }.should raise_error(ArgumentError, /\Atwo digits sec is expected after [`']:': :137 \+0900\z/) + }.should raise_error(ArgumentError, /\Atwo digits sec is expected after [`']:': :137 \+0900\z|can't parse:/) -> { Time.new("2020-12-25 00:56:7 +0900") - }.should raise_error(ArgumentError, /\Atwo digits sec is expected after [`']:': :7 \+0900\z/) + }.should raise_error(ArgumentError, /\Atwo digits sec is expected after [`']:': :7 \+0900\z|can't parse:/) -> { Time.new("2020-12-25 00:56. +0900") - }.should raise_error(ArgumentError, "fraction min is not supported: 00:56.") + }.should raise_error(ArgumentError, /fraction min is not supported: 00:56\.|can't parse:/) -> { Time.new("2020-12-25 00. +0900") - }.should raise_error(ArgumentError, "fraction hour is not supported: 00.") + }.should raise_error(ArgumentError, /fraction hour is not supported: 00\.|can't parse:/) end it "raises ArgumentError if date/time parts values are not valid" do -> { Time.new("2020-13-25 00:56:17 +09:00") - }.should raise_error(ArgumentError, "mon out of range") + }.should raise_error(ArgumentError, /(mon|argument) out of range/) -> { Time.new("2020-12-32 00:56:17 +09:00") - }.should raise_error(ArgumentError, "mday out of range") + }.should raise_error(ArgumentError, /(mday|argument) out of range/) -> { Time.new("2020-12-25 25:56:17 +09:00") - }.should raise_error(ArgumentError, "hour out of range") + }.should raise_error(ArgumentError, /(hour|argument) out of range/) -> { Time.new("2020-12-25 00:61:17 +09:00") - }.should raise_error(ArgumentError, "min out of range") + }.should raise_error(ArgumentError, /(min|argument) out of range/) -> { Time.new("2020-12-25 00:56:61 +09:00") - }.should raise_error(ArgumentError, "sec out of range") + }.should raise_error(ArgumentError, /(sec|argument) out of range/) -> { Time.new("2020-12-25 00:56:17 +23:59:60") - }.should raise_error(ArgumentError, /utc_offset/) + }.should raise_error(ArgumentError, /utc_offset|argument out of range/) -> { Time.new("2020-12-25 00:56:17 +24:00") - }.should raise_error(ArgumentError, /utc_offset/) + }.should raise_error(ArgumentError, /(utc_offset|argument) out of range/) -> { Time.new("2020-12-25 00:56:17 +23:61") - }.should raise_error(ArgumentError, /utc_offset/) + }.should raise_error(ArgumentError, /utc_offset|can't parse:/) ruby_bug '#20797', ''...'3.4' do -> { @@ -647,6 +667,18 @@ describe "Time.new with a timezone argument" do Time.new("2021-11-31 00:00:60 +09:00".encode("utf-32le")) }.should raise_error(ArgumentError, "time string should have ASCII compatible encoding") end + + it "raises ArgumentError if string doesn't start with year" do + -> { + Time.new("a\nb") + }.should raise_error(ArgumentError, "can't parse: \"a\\nb\"") + end + + it "raises ArgumentError if string has extra characters after offset" do + -> { + Time.new("2021-11-31 00:00:59 +09:00 abc") + }.should raise_error(ArgumentError, /can't parse.+ abc/) + end end end end diff --git a/spec/ruby/core/warning/warn_spec.rb b/spec/ruby/core/warning/warn_spec.rb index 1c21fe29e0..572885c2b4 100644 --- a/spec/ruby/core/warning/warn_spec.rb +++ b/spec/ruby/core/warning/warn_spec.rb @@ -121,7 +121,7 @@ describe "Warning.warn" do end end - ruby_bug '#19530', ''...'3.4' do + ruby_bug '#20573', ''...'3.4' do it "isn't called by Kernel.warn when category is :deprecated but Warning[:deprecated] is false" do warn_deprecated = Warning[:deprecated] begin |