summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <[email protected]>2024-11-06 21:57:34 +0100
committerBenoit Daloze <[email protected]>2024-11-06 21:58:28 +0100
commitfdc82cca83bbbfe88f90d2888e139a6dde481101 (patch)
tree99165cce6af5eaca59316c06fed33f958c85e16a /spec/ruby/core
parent9bc63e7ba066b31314bbd66def4932b398eaf4c9 (diff)
Update to ruby/spec@54c391e
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/basicobject/instance_exec_spec.rb20
-rw-r--r--spec/ruby/core/builtin_constants/builtin_constants_spec.rb28
-rw-r--r--spec/ruby/core/complex/equal_value_spec.rb2
-rw-r--r--spec/ruby/core/data/to_h_spec.rb65
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb379
-rw-r--r--spec/ruby/core/enumerator/each_with_index_spec.rb6
-rw-r--r--spec/ruby/core/enumerator/with_index_spec.rb17
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb18
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb2
-rw-r--r--spec/ruby/core/file/chown_spec.rb16
-rw-r--r--spec/ruby/core/float/ceil_spec.rb5
-rw-r--r--spec/ruby/core/float/comparison_spec.rb2
-rw-r--r--spec/ruby/core/float/floor_spec.rb5
-rw-r--r--spec/ruby/core/hash/element_reference_spec.rb2
-rw-r--r--spec/ruby/core/hash/hash_spec.rb2
-rw-r--r--spec/ruby/core/integer/ceil_spec.rb5
-rw-r--r--spec/ruby/core/integer/floor_spec.rb12
-rw-r--r--spec/ruby/core/integer/pow_spec.rb8
-rw-r--r--spec/ruby/core/integer/remainder_spec.rb4
-rw-r--r--spec/ruby/core/integer/shared/integer_ceil_precision.rb43
-rw-r--r--spec/ruby/core/integer/shared/integer_floor_precision.rb43
-rw-r--r--spec/ruby/core/io/dup_spec.rb30
-rw-r--r--spec/ruby/core/io/puts_spec.rb2
-rw-r--r--spec/ruby/core/io/read_spec.rb22
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb20
-rw-r--r--spec/ruby/core/kernel/extend_spec.rb12
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb16
-rw-r--r--spec/ruby/core/kernel/select_spec.rb4
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb14
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_data.rb14
-rw-r--r--spec/ruby/core/marshal/fixtures/marshal_multibyte_data.rb12
-rw-r--r--spec/ruby/core/module/ancestors_spec.rb11
-rw-r--r--spec/ruby/core/module/const_added_spec.rb43
-rw-r--r--spec/ruby/core/module/fixtures/const_added.rb4
-rw-r--r--spec/ruby/core/module/fixtures/name.rb3
-rw-r--r--spec/ruby/core/module/include_spec.rb23
-rw-r--r--spec/ruby/core/module/name_spec.rb41
-rw-r--r--spec/ruby/core/module/refine_spec.rb2
-rw-r--r--spec/ruby/core/objectspace/add_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/call_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb25
-rw-r--r--spec/ruby/core/objectspace/finalizers_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/remove_finalizer_spec.rb5
-rw-r--r--spec/ruby/core/objectspace/undefine_finalizer_spec.rb30
-rw-r--r--spec/ruby/core/proc/curry_spec.rb9
-rw-r--r--spec/ruby/core/process/constants_spec.rb116
-rw-r--r--spec/ruby/core/queue/freeze_spec.rb6
-rw-r--r--spec/ruby/core/regexp/shared/new.rb4
-rw-r--r--spec/ruby/core/regexp/shared/quote.rb4
-rw-r--r--spec/ruby/core/sizedqueue/freeze_spec.rb6
-rw-r--r--spec/ruby/core/string/byteslice_spec.rb2
-rw-r--r--spec/ruby/core/string/bytesplice_spec.rb164
-rw-r--r--spec/ruby/core/thread/element_reference_spec.rb11
-rw-r--r--spec/ruby/core/thread/element_set_spec.rb25
-rw-r--r--spec/ruby/core/thread/group_spec.rb15
-rw-r--r--spec/ruby/core/thread/key_spec.rb7
-rw-r--r--spec/ruby/core/time/new_spec.rb78
-rw-r--r--spec/ruby/core/warning/warn_spec.rb2
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