summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/ruby/core/array/shared/slice.rb24
-rw-r--r--spec/ruby/core/dir/shared/glob.rb22
-rw-r--r--spec/ruby/core/encoding/compatible_spec.rb2
-rw-r--r--spec/ruby/core/encoding/converter/putback_spec.rb13
-rw-r--r--spec/ruby/core/enumerable/grep_spec.rb12
-rw-r--r--spec/ruby/core/enumerable/grep_v_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb9
-rw-r--r--spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb7
-rw-r--r--spec/ruby/core/exception/errno_spec.rb9
-rw-r--r--spec/ruby/core/gc/auto_compact_spec.rb5
-rw-r--r--spec/ruby/core/gc/measure_total_time_spec.rb19
-rw-r--r--spec/ruby/core/gc/stat_spec.rb18
-rw-r--r--spec/ruby/core/gc/total_time_spec.rb15
-rw-r--r--spec/ruby/core/integer/plus_spec.rb15
-rw-r--r--spec/ruby/core/kernel/clone_spec.rb36
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb7
-rw-r--r--spec/ruby/core/kernel/initialize_clone_spec.rb28
-rw-r--r--spec/ruby/core/kernel/initialize_dup_spec.rb20
-rw-r--r--spec/ruby/core/kernel/instance_variables_spec.rb11
-rw-r--r--spec/ruby/core/kernel/print_spec.rb12
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb64
-rw-r--r--spec/ruby/core/matchdata/captures_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/element_reference_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/fixtures/classes.rb3
-rw-r--r--spec/ruby/core/matchdata/post_match_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/pre_match_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/to_a_spec.rb8
-rw-r--r--spec/ruby/core/matchdata/to_s_spec.rb8
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb7
-rw-r--r--spec/ruby/core/numeric/quo_spec.rb9
-rw-r--r--spec/ruby/core/range/step_spec.rb26
-rw-r--r--spec/ruby/core/string/each_grapheme_cluster_spec.rb8
-rw-r--r--spec/ruby/core/string/force_encoding_spec.rb2
-rw-r--r--spec/ruby/core/string/scan_spec.rb8
-rw-r--r--spec/ruby/core/string/scrub_spec.rb4
-rw-r--r--spec/ruby/core/string/shared/eql.rb2
-rw-r--r--spec/ruby/core/string/shared/length.rb16
-rw-r--r--spec/ruby/core/string/valid_encoding_spec.rb8
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb6
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb6
-rw-r--r--spec/ruby/core/warning/warn_spec.rb3
-rw-r--r--spec/ruby/language/class_variable_spec.rb6
-rw-r--r--spec/ruby/language/regexp/encoding_spec.rb17
-rw-r--r--spec/ruby/library/fiber/resume_spec.rb12
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb18
-rw-r--r--spec/ruby/library/rexml/element/each_element_with_text_spec.rb4
-rw-r--r--spec/ruby/library/rexml/element/has_text_spec.rb2
-rw-r--r--spec/ruby/library/rexml/node/parent_spec.rb2
-rw-r--r--spec/ruby/library/rexml/shared/elements_to_a.rb2
-rw-r--r--spec/ruby/library/stringio/ungetbyte_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/check_until_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/exist_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/matched_size_spec.rb21
-rw-r--r--spec/ruby/library/stringscanner/scan_until_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/search_full_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/shared/matched_size.rb21
-rw-r--r--spec/ruby/library/stringscanner/size_spec.rb17
-rw-r--r--spec/ruby/library/stringscanner/skip_until_spec.rb6
-rw-r--r--spec/ruby/optional/capi/class_spec.rb5
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c10
-rw-r--r--spec/ruby/optional/capi/fixtures/class.rb3
-rw-r--r--spec/ruby/optional/capi/string_spec.rb27
62 files changed, 656 insertions, 59 deletions
diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb
index cf195ad7a4..540a050130 100644
--- a/spec/ruby/core/array/shared/slice.rb
+++ b/spec/ruby/core/array/shared/slice.rb
@@ -743,6 +743,30 @@ describe :array_slice, shared: true do
@array.send(@method, eval("(-2..-4).step(10)")).should == []
@array.send(@method, eval("(-2...-4).step(10)")).should == []
end
+
+ it "has range with bounds outside of array" do
+ # end is equal to array's length
+ @array.send(@method, (0..6).step(1)).should == [0, 1, 2, 3, 4, 5]
+ -> { @array.send(@method, (0..6).step(2)) }.should raise_error(RangeError)
+
+ # end is greater than length with positive steps
+ @array.send(@method, (1..6).step(2)).should == [1, 3, 5]
+ @array.send(@method, (2..7).step(2)).should == [2, 4]
+ -> { @array.send(@method, (2..8).step(2)) }.should raise_error(RangeError)
+
+ # begin is greater than length with negative steps
+ @array.send(@method, (6..1).step(-2)).should == [5, 3, 1]
+ @array.send(@method, (7..2).step(-2)).should == [5, 3]
+ -> { @array.send(@method, (8..2).step(-2)) }.should raise_error(RangeError)
+ end
+
+ it "has endless range with start outside of array's bounds" do
+ @array.send(@method, eval("(6..).step(1)")).should == []
+ @array.send(@method, eval("(7..).step(1)")).should == nil
+
+ @array.send(@method, eval("(6..).step(2)")).should == []
+ -> { @array.send(@method, eval("(7..).step(2)")) }.should raise_error(RangeError)
+ end
end
end
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index 69fb0f0a01..a38ff8aa68 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -55,12 +55,24 @@ describe :dir_glob, shared: true do
end
end
+ ruby_version_is "3.0"..."3.1" do
+ it "result is sorted with any non false value of sort:" do
+ result = Dir.send(@method, '*', sort: 0)
+ result.should == result.sort
+
+ result = Dir.send(@method, '*', sort: nil)
+ result.should == result.sort
+
+ result = Dir.send(@method, '*', sort: 'false')
+ result.should == result.sort
+ end
+ end
+
ruby_version_is "3.1" do
- it "true or false is expected as sort:" do
- -> {Dir.send(@method, '*', sort: nil)}.should raise_error ArgumentError, /true or false/
- -> {Dir.send(@method, '*', sort: 0)}.should raise_error ArgumentError, /true or false/
- -> {Dir.send(@method, '*', sort: "")}.should raise_error ArgumentError, /true or false/
- -> {Dir.send(@method, '*', sort: Object.new)}.should raise_error ArgumentError, /true or false/
+ it "raises an ArgumentError if sort: is not true or false" do
+ -> { Dir.send(@method, '*', sort: 0) }.should raise_error ArgumentError, /expected true or false/
+ -> { Dir.send(@method, '*', sort: nil) }.should raise_error ArgumentError, /expected true or false/
+ -> { Dir.send(@method, '*', sort: 'false') }.should raise_error ArgumentError, /expected true or false/
end
end
diff --git a/spec/ruby/core/encoding/compatible_spec.rb b/spec/ruby/core/encoding/compatible_spec.rb
index dc47a6553a..80ecab6155 100644
--- a/spec/ruby/core/encoding/compatible_spec.rb
+++ b/spec/ruby/core/encoding/compatible_spec.rb
@@ -54,7 +54,7 @@ describe "Encoding.compatible? String, String" do
it "returns nil if the second's Encoding is not ASCII compatible" do
a = "abc".force_encoding("UTF-8")
- b = "123".force_encoding("UTF-16LE")
+ b = "1234".force_encoding("UTF-16LE")
Encoding.compatible?(a, b).should be_nil
end
end
diff --git a/spec/ruby/core/encoding/converter/putback_spec.rb b/spec/ruby/core/encoding/converter/putback_spec.rb
index 87495eaf3f..c4e0a5da21 100644
--- a/spec/ruby/core/encoding/converter/putback_spec.rb
+++ b/spec/ruby/core/encoding/converter/putback_spec.rb
@@ -34,14 +34,23 @@ describe "Encoding::Converter#putback" do
@ec.putback.should == ""
end
+ it "returns the problematic bytes for UTF-16LE" do
+ ec = Encoding::Converter.new("utf-16le", "iso-8859-1")
+ src = "\x00\xd8\x61\x00"
+ dst = ""
+ ec.primitive_convert(src, dst).should == :invalid_byte_sequence
+ ec.primitive_errinfo.should == [:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "a\x00"]
+ ec.putback.should == "a\x00".force_encoding("utf-16le")
+ ec.putback.should == ""
+ end
+
it "accepts an integer argument corresponding to the number of bytes to be put back" do
ec = Encoding::Converter.new("utf-16le", "iso-8859-1")
src = "\x00\xd8\x61\x00"
dst = ""
ec.primitive_convert(src, dst).should == :invalid_byte_sequence
ec.primitive_errinfo.should == [:invalid_byte_sequence, "UTF-16LE", "UTF-8", "\x00\xD8", "a\x00"]
- ec.putback(1).should == "\x00".force_encoding("utf-16le")
- ec.putback.should == "a".force_encoding("utf-16le")
+ ec.putback(2).should == "a\x00".force_encoding("utf-16le")
ec.putback.should == ""
end
end
diff --git a/spec/ruby/core/enumerable/grep_spec.rb b/spec/ruby/core/enumerable/grep_spec.rb
index ac3d3db641..b81075291f 100644
--- a/spec/ruby/core/enumerable/grep_spec.rb
+++ b/spec/ruby/core/enumerable/grep_spec.rb
@@ -65,6 +65,18 @@ describe "Enumerable#grep" do
["abc", "def"].grep(/b/).should == ["abc"]
Regexp.last_match[0].should == "z"
end
+
+ it "correctly handles non-string elements" do
+ 'set last match' =~ /set last (.*)/
+ [:a, 'b', 'z', :c, 42, nil].grep(/[a-d]/).should == [:a, 'b', :c]
+ $1.should == 'match'
+
+ o = Object.new
+ def o.to_str
+ 'hello'
+ end
+ [o].grep(/ll/).first.should.equal?(o)
+ end
end
describe "with a block" do
diff --git a/spec/ruby/core/enumerable/grep_v_spec.rb b/spec/ruby/core/enumerable/grep_v_spec.rb
index 892640efa4..35fde27eb6 100644
--- a/spec/ruby/core/enumerable/grep_v_spec.rb
+++ b/spec/ruby/core/enumerable/grep_v_spec.rb
@@ -45,6 +45,18 @@ describe "Enumerable#grep_v" do
["abc", "def"].grep_v(/e/).should == ["abc"]
Regexp.last_match[0].should == "z"
end
+
+ it "correctly handles non-string elements" do
+ 'set last match' =~ /set last (.*)/
+ [:a, 'b', 'z', :c, 42, nil].grep_v(/[a-d]/).should == ['z', 42, nil]
+ $1.should == 'match'
+
+ o = Object.new
+ def o.to_str
+ 'hello'
+ end
+ [o].grep_v(/mm/).first.should.equal?(o)
+ end
end
describe "without block" do
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb
index bed30c546d..1837a4f246 100644
--- a/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb
@@ -6,4 +6,13 @@ describe "Enumerator::ArithmeticSequence#begin" do
(1..10).step.begin.should == 1
(1...10).step.begin.should == 1
end
+
+ ruby_version_is "2.7" do
+ context "with beginless" do
+ it "returns nil as begin of the sequence" do
+ eval("(..10).step(1)").begin.should == nil
+ eval("(...10).step(1)").begin.should == nil
+ end
+ end
+ end
end
diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb
index 29e6e105cf..05429cac3e 100644
--- a/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb
+++ b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb
@@ -6,4 +6,11 @@ describe "Enumerator::ArithmeticSequence#end" do
(1..10).step.end.should == 10
(1...10).step(17).end.should == 10
end
+
+ context "with endless" do
+ it "returns nil as end of the sequence" do
+ (1..).step(1).end.should == nil
+ (1...).step(1).end.should == nil
+ end
+ end
end
diff --git a/spec/ruby/core/exception/errno_spec.rb b/spec/ruby/core/exception/errno_spec.rb
index 095a926e09..a063e522ea 100644
--- a/spec/ruby/core/exception/errno_spec.rb
+++ b/spec/ruby/core/exception/errno_spec.rb
@@ -56,3 +56,12 @@ describe "Errno::ENOTSUP" do
end
end
end
+
+describe "Errno::ENOENT" do
+ it "lets subclasses inherit the default error message" do
+ c = Class.new(Errno::ENOENT)
+ raise c, "custom message"
+ rescue => e
+ e.message.should == "No such file or directory - custom message"
+ end
+end
diff --git a/spec/ruby/core/gc/auto_compact_spec.rb b/spec/ruby/core/gc/auto_compact_spec.rb
index 386725996d..4f9d043171 100644
--- a/spec/ruby/core/gc/auto_compact_spec.rb
+++ b/spec/ruby/core/gc/auto_compact_spec.rb
@@ -12,6 +12,11 @@ ruby_version_is "3.0" do
original = GC.auto_compact
begin
GC.auto_compact = !original
+ rescue NotImplementedError # platform does not support autocompact
+ skip
+ end
+
+ begin
GC.auto_compact.should == !original
ensure
GC.auto_compact = original
diff --git a/spec/ruby/core/gc/measure_total_time_spec.rb b/spec/ruby/core/gc/measure_total_time_spec.rb
new file mode 100644
index 0000000000..05d4598ebc
--- /dev/null
+++ b/spec/ruby/core/gc/measure_total_time_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "3.1" do
+ describe "GC.measure_total_time" do
+ before :each do
+ @default = GC.measure_total_time
+ end
+
+ after :each do
+ GC.measure_total_time = @default
+ end
+
+ it "can set and get a boolean value" do
+ original = GC.measure_total_time
+ GC.measure_total_time = !original
+ GC.measure_total_time.should == !original
+ end
+ end
+end
diff --git a/spec/ruby/core/gc/stat_spec.rb b/spec/ruby/core/gc/stat_spec.rb
index eb71fd9691..3b43b28a92 100644
--- a/spec/ruby/core/gc/stat_spec.rb
+++ b/spec/ruby/core/gc/stat_spec.rb
@@ -7,6 +7,16 @@ describe "GC.stat" do
stat.keys.should.include?(:count)
end
+ it "updates the given hash values" do
+ hash = { count: "hello", __other__: "world" }
+ stat = GC.stat(hash)
+
+ stat.should be_kind_of(Hash)
+ stat.should equal hash
+ stat[:count].should be_kind_of(Integer)
+ stat[:__other__].should == "world"
+ end
+
it "the values are all Integer since rb_gc_stat() returns size_t" do
GC.stat.values.each { |value| value.should be_kind_of(Integer) }
end
@@ -41,4 +51,12 @@ describe "GC.stat" do
GC.stat(:total_allocated_objects).should be_kind_of(Integer)
GC.stat[:total_allocated_objects].should be_kind_of(Integer)
end
+
+ it "raises an error if argument is not nil, a symbol, or a hash" do
+ -> { GC.stat(7) }.should raise_error(TypeError, "non-hash or symbol given")
+ end
+
+ it "raises an error if an unknown key is given" do
+ -> { GC.stat(:foo) }.should raise_error(ArgumentError, "unknown key: foo")
+ end
end
diff --git a/spec/ruby/core/gc/total_time_spec.rb b/spec/ruby/core/gc/total_time_spec.rb
new file mode 100644
index 0000000000..9b4f16e603
--- /dev/null
+++ b/spec/ruby/core/gc/total_time_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "3.1" do
+ describe "GC.total_time" do
+ it "returns an Integer" do
+ GC.total_time.should be_kind_of(Integer)
+ end
+
+ it "increases as collections are run" do
+ time_before = GC.total_time
+ GC.start
+ GC.total_time.should > time_before
+ end
+ end
+end
diff --git a/spec/ruby/core/integer/plus_spec.rb b/spec/ruby/core/integer/plus_spec.rb
index be626c3305..511a436872 100644
--- a/spec/ruby/core/integer/plus_spec.rb
+++ b/spec/ruby/core/integer/plus_spec.rb
@@ -40,4 +40,19 @@ describe "Integer#+" do
-> { @bignum + :symbol}.should raise_error(TypeError)
end
end
+
+ it "can be redefined" do
+ code = <<~RUBY
+ class Integer
+ alias_method :old_plus, :+
+ def +(other)
+ self - other
+ end
+ end
+ result = 1 + 2
+ Integer.alias_method :+, :old_plus
+ print result
+ RUBY
+ ruby_exe(code).should == "-1"
+ end
end
diff --git a/spec/ruby/core/kernel/clone_spec.rb b/spec/ruby/core/kernel/clone_spec.rb
index f9daa2badc..38ae1984c0 100644
--- a/spec/ruby/core/kernel/clone_spec.rb
+++ b/spec/ruby/core/kernel/clone_spec.rb
@@ -31,10 +31,10 @@ describe "Kernel#clone" do
describe "with no arguments" do
it "copies frozen state from the original" do
o2 = @obj.clone
+ o2.should_not.frozen?
+
@obj.freeze
o3 = @obj.clone
-
- o2.should_not.frozen?
o3.should.frozen?
end
@@ -44,6 +44,30 @@ describe "Kernel#clone" do
end
end
+ describe "with freeze: nil" do
+ ruby_version_is ""..."3.0" do
+ it "raises ArgumentError" do
+ -> { @obj.clone(freeze: nil) }.should raise_error(ArgumentError, /unexpected value for freeze: NilClass/)
+ end
+ end
+
+ ruby_version_is "3.0" do
+ it "copies frozen state from the original, like #clone without arguments" do
+ o2 = @obj.clone(freeze: nil)
+ o2.should_not.frozen?
+
+ @obj.freeze
+ o3 = @obj.clone(freeze: nil)
+ o3.should.frozen?
+ end
+
+ it "copies frozen?" do
+ o = "".freeze.clone(freeze: nil)
+ o.frozen?.should be_true
+ end
+ end
+ end
+
describe "with freeze: true" do
it 'makes a frozen copy if the original is frozen' do
@obj.freeze
@@ -112,6 +136,14 @@ describe "Kernel#clone" do
end
end
+ describe "with freeze: anything else" do
+ it 'raises ArgumentError when passed not true/false/nil' do
+ -> { @obj.clone(freeze: 1) }.should raise_error(ArgumentError, /unexpected value for freeze: Integer/)
+ -> { @obj.clone(freeze: "") }.should raise_error(ArgumentError, /unexpected value for freeze: String/)
+ -> { @obj.clone(freeze: Object.new) }.should raise_error(ArgumentError, /unexpected value for freeze: Object/)
+ end
+ end
+
it "copies instance variables" do
clone = @obj.clone
clone.one.should == 1
diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb
index 8de1407b92..541a4c075e 100644
--- a/spec/ruby/core/kernel/fixtures/classes.rb
+++ b/spec/ruby/core/kernel/fixtures/classes.rb
@@ -281,9 +281,14 @@ module KernelSpecs
@two = two
end
- def initialize_copy(other)
+ def initialize_copy(other, **kw)
ScratchPad.record object_id
end
+
+ # define to support calling #clone with optional :freeze keyword argument
+ def initialize_clone(other, **kw)
+ super(other) # to call #initialize_copy
+ end
end
class Clone
diff --git a/spec/ruby/core/kernel/initialize_clone_spec.rb b/spec/ruby/core/kernel/initialize_clone_spec.rb
new file mode 100644
index 0000000000..2d889f5aad
--- /dev/null
+++ b/spec/ruby/core/kernel/initialize_clone_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../spec_helper'
+
+describe "Kernel#initialize_clone" do
+ it "is a private instance method" do
+ Kernel.should have_private_instance_method(:initialize_clone)
+ end
+
+ it "returns the receiver" do
+ a = Object.new
+ b = Object.new
+ a.send(:initialize_clone, b).should == a
+ end
+
+ it "calls #initialize_copy" do
+ a = Object.new
+ b = Object.new
+ a.should_receive(:initialize_copy).with(b)
+ a.send(:initialize_clone, b)
+ end
+
+ ruby_version_is "3.0" do
+ it "accepts a :freeze keyword argument for obj.clone(freeze: value)" do
+ a = Object.new
+ b = Object.new
+ a.send(:initialize_clone, b, freeze: true).should == a
+ end
+ end
+end
diff --git a/spec/ruby/core/kernel/initialize_dup_spec.rb b/spec/ruby/core/kernel/initialize_dup_spec.rb
new file mode 100644
index 0000000000..6dff34b7ad
--- /dev/null
+++ b/spec/ruby/core/kernel/initialize_dup_spec.rb
@@ -0,0 +1,20 @@
+require_relative '../../spec_helper'
+
+describe "Kernel#initialize_dup" do
+ it "is a private instance method" do
+ Kernel.should have_private_instance_method(:initialize_dup)
+ end
+
+ it "returns the receiver" do
+ a = Object.new
+ b = Object.new
+ a.send(:initialize_dup, b).should == a
+ end
+
+ it "calls #initialize_copy" do
+ a = Object.new
+ b = Object.new
+ a.should_receive(:initialize_copy).with(b)
+ a.send(:initialize_dup, b)
+ end
+end
diff --git a/spec/ruby/core/kernel/instance_variables_spec.rb b/spec/ruby/core/kernel/instance_variables_spec.rb
index 831f0662a2..677d8bb7b2 100644
--- a/spec/ruby/core/kernel/instance_variables_spec.rb
+++ b/spec/ruby/core/kernel/instance_variables_spec.rb
@@ -25,5 +25,16 @@ describe "Kernel#instance_variables" do
a.instance_variable_set("@test", 1)
a.instance_variables.should == [:@test]
end
+
+ it "returns the instances variables in the order declared" do
+ c = Class.new do
+ def initialize
+ @c = 1
+ @a = 2
+ @b = 3
+ end
+ end
+ c.new.instance_variables.should == [:@c, :@a, :@b]
+ end
end
end
diff --git a/spec/ruby/core/kernel/print_spec.rb b/spec/ruby/core/kernel/print_spec.rb
index c8c4453d1e..7e7c9b822d 100644
--- a/spec/ruby/core/kernel/print_spec.rb
+++ b/spec/ruby/core/kernel/print_spec.rb
@@ -5,6 +5,18 @@ describe "Kernel#print" do
it "is a private method" do
Kernel.should have_private_instance_method(:print)
end
+
+ it "delegates to $stdout" do
+ -> { print :arg }.should output("arg")
+ end
+
+ it "prints $_ when no arguments are given" do
+ orig_value = $_
+ $_ = 'foo'
+ -> { print }.should output("foo")
+ ensure
+ $_ = orig_value
+ end
end
describe "Kernel.print" do
diff --git a/spec/ruby/core/kernel/warn_spec.rb b/spec/ruby/core/kernel/warn_spec.rb
index 511e741f32..7df6fa72d1 100644
--- a/spec/ruby/core/kernel/warn_spec.rb
+++ b/spec/ruby/core/kernel/warn_spec.rb
@@ -212,6 +212,70 @@ describe "Kernel#warn" do
-> { warn('foo', **h) }.should complain("foo\n")
end
+ ruby_version_is '3.0' do
+ it "calls Warning.warn without keyword arguments if Warning.warn does not accept keyword arguments" do
+ verbose = $VERBOSE
+ $VERBOSE = false
+ class << Warning
+ alias_method :_warn, :warn
+ def warn(message)
+ ScratchPad.record(message)
+ end
+ end
+
+ begin
+ ScratchPad.clear
+ Kernel.warn("Chunky bacon!")
+ ScratchPad.recorded.should == "Chunky bacon!\n"
+
+ Kernel.warn("Deprecated bacon!", category: :deprecated)
+ ScratchPad.recorded.should == "Deprecated bacon!\n"
+ ensure
+ class << Warning
+ remove_method :warn
+ alias_method :warn, :_warn
+ remove_method :_warn
+ end
+ $VERBOSE = verbose
+ end
+ end
+
+ it "calls Warning.warn with category: nil if Warning.warn accepts keyword arguments" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+
+ it "calls Warning.warn with given category keyword converted to a symbol" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n", category: :deprecated)
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!", category: 'deprecated')
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "calls Warning.warn with no keyword arguments" do
+ Warning.should_receive(:warn).with("Chunky bacon!\n")
+ verbose = $VERBOSE
+ $VERBOSE = false
+ begin
+ Kernel.warn("Chunky bacon!")
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+ end
+
it "does not call Warning.warn if self is the Warning module" do
# RubyGems redefines Kernel#warn so we need to use a subprocess and disable RubyGems here
code = <<-RUBY
diff --git a/spec/ruby/core/matchdata/captures_spec.rb b/spec/ruby/core/matchdata/captures_spec.rb
index 8c0d2978b7..58d4620709 100644
--- a/spec/ruby/core/matchdata/captures_spec.rb
+++ b/spec/ruby/core/matchdata/captures_spec.rb
@@ -1,7 +1,15 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#captures" do
it "returns an array of the match captures" do
/(.)(.)(\d+)(\d)/.match("THX1138.").captures.should == ["H","X","113","8"]
end
+
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).captures.each { |c| c.should be_an_instance_of(String) }
+ end
+ end
end
diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb
index 26550ac94d..3b976cb1c4 100644
--- a/spec/ruby/core/matchdata/element_reference_spec.rb
+++ b/spec/ruby/core/matchdata/element_reference_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#[]" do
it "acts as normal array indexing [index]" do
@@ -20,6 +21,13 @@ describe "MatchData#[]" do
it "supports ranges [start..end]" do
/(.)(.)(\d+)(\d)/.match("THX1138.")[1..3].should == %w|H X 113|
end
+
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str)[0..-1].each { |m| m.should be_an_instance_of(String) }
+ end
+ end
end
describe "MatchData#[Symbol]" do
diff --git a/spec/ruby/core/matchdata/fixtures/classes.rb b/spec/ruby/core/matchdata/fixtures/classes.rb
new file mode 100644
index 0000000000..54795636e5
--- /dev/null
+++ b/spec/ruby/core/matchdata/fixtures/classes.rb
@@ -0,0 +1,3 @@
+module MatchDataSpecs
+ class MyString < String; end
+end
diff --git a/spec/ruby/core/matchdata/post_match_spec.rb b/spec/ruby/core/matchdata/post_match_spec.rb
index 4ae51f107e..1a4ca0a83f 100644
--- a/spec/ruby/core/matchdata/post_match_spec.rb
+++ b/spec/ruby/core/matchdata/post_match_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#post_match" do
it "returns the string after the match equiv. special var $'" do
@@ -33,4 +34,11 @@ describe "MatchData#post_match" do
str = "abc".force_encoding Encoding::ISO_8859_1
str.match(/c/).post_match.encoding.should equal(Encoding::ISO_8859_1)
end
+
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).post_match.should be_an_instance_of(String)
+ end
+ end
end
diff --git a/spec/ruby/core/matchdata/pre_match_spec.rb b/spec/ruby/core/matchdata/pre_match_spec.rb
index 824612c84c..9b50336c7d 100644
--- a/spec/ruby/core/matchdata/pre_match_spec.rb
+++ b/spec/ruby/core/matchdata/pre_match_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#pre_match" do
it "returns the string before the match, equiv. special var $`" do
@@ -33,4 +34,11 @@ describe "MatchData#pre_match" do
str = "abc".force_encoding Encoding::ISO_8859_1
str.match(/a/).pre_match.encoding.should equal(Encoding::ISO_8859_1)
end
+
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138: The Movie")
+ /(.)(.)(\d+)(\d)/.match(str).pre_match.should be_an_instance_of(String)
+ end
+ end
end
diff --git a/spec/ruby/core/matchdata/to_a_spec.rb b/spec/ruby/core/matchdata/to_a_spec.rb
index 6231d096fb..50f5a161a5 100644
--- a/spec/ruby/core/matchdata/to_a_spec.rb
+++ b/spec/ruby/core/matchdata/to_a_spec.rb
@@ -1,7 +1,15 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#to_a" do
it "returns an array of matches" do
/(.)(.)(\d+)(\d)/.match("THX1138.").to_a.should == ["HX1138", "H", "X", "113", "8"]
end
+
+ ruby_version_is "3.0" do
+ it "returns instances of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str)[0..-1].to_a.each { |m| m.should be_an_instance_of(String) }
+ end
+ end
end
diff --git a/spec/ruby/core/matchdata/to_s_spec.rb b/spec/ruby/core/matchdata/to_s_spec.rb
index 9e213bb342..aab0955ae1 100644
--- a/spec/ruby/core/matchdata/to_s_spec.rb
+++ b/spec/ruby/core/matchdata/to_s_spec.rb
@@ -1,7 +1,15 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "MatchData#to_s" do
it "returns the entire matched string" do
/(.)(.)(\d+)(\d)/.match("THX1138.").to_s.should == "HX1138"
end
+
+ ruby_version_is "3.0" do
+ it "returns an instance of String when given a String subclass" do
+ str = MatchDataSpecs::MyString.new("THX1138.")
+ /(.)(.)(\d+)(\d)/.match(str).to_s.should be_an_instance_of(String)
+ end
+ end
end
diff --git a/spec/ruby/core/numeric/clone_spec.rb b/spec/ruby/core/numeric/clone_spec.rb
index e3bf0a9e7c..c3b06ca0c9 100644
--- a/spec/ruby/core/numeric/clone_spec.rb
+++ b/spec/ruby/core/numeric/clone_spec.rb
@@ -22,4 +22,11 @@ describe "Numeric#clone" do
it "raises ArgumentError if passed freeze: false" do
-> { 1.clone(freeze: false) }.should raise_error(ArgumentError, /can't unfreeze/)
end
+
+ ruby_version_is "3.0" do
+ it "does not change frozen status if passed freeze: nil" do
+ value = 1
+ value.clone(freeze: nil).should equal(value)
+ end
+ end
end
diff --git a/spec/ruby/core/numeric/quo_spec.rb b/spec/ruby/core/numeric/quo_spec.rb
index 5c952b11a9..b4a23fd476 100644
--- a/spec/ruby/core/numeric/quo_spec.rb
+++ b/spec/ruby/core/numeric/quo_spec.rb
@@ -52,4 +52,13 @@ describe "Numeric#quo" do
obj.quo(19).should == 1.quo(20)
end
+
+ it "raises a ZeroDivisionError if the given argument is zero and not a Float" do
+ -> { 1.quo(0) }.should raise_error(ZeroDivisionError)
+ end
+
+ it "returns infinity if the given argument is zero and is a Float" do
+ (1.quo(0.0)).to_s.should == 'Infinity'
+ (-1.quo(0.0)).to_s.should == '-Infinity'
+ end
end
diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb
index 624fa71f5f..4c69073854 100644
--- a/spec/ruby/core/range/step_spec.rb
+++ b/spec/ruby/core/range/step_spec.rb
@@ -481,6 +481,32 @@ describe "Range#step" do
end
end
+ ruby_version_is "2.7" do
+ context "when begin is not defined and end is numeric" do
+ it "returns an instance of Enumerator::ArithmeticSequence" do
+ eval("(..10)").step.class.should == Enumerator::ArithmeticSequence
+ end
+ end
+ end
+
+ context "when range is endless" do
+ it "returns an instance of Enumerator::ArithmeticSequence when begin is numeric" do
+ (1..).step.class.should == Enumerator::ArithmeticSequence
+ end
+
+ it "returns an instance of Enumerator when begin is not numeric" do
+ ("a"..).step.class.should == Enumerator
+ end
+ end
+
+ ruby_version_is "2.7" do
+ context "when range is beginless and endless" do
+ it "returns an instance of Enumerator" do
+ Range.new(nil, nil).step.class.should == Enumerator
+ end
+ end
+ end
+
context "when begin and end are not numerics" do
it "returns an instance of Enumerator" do
("a".."z").step.class.should == Enumerator
diff --git a/spec/ruby/core/string/each_grapheme_cluster_spec.rb b/spec/ruby/core/string/each_grapheme_cluster_spec.rb
index 632f2337f1..b45d89ecb0 100644
--- a/spec/ruby/core/string/each_grapheme_cluster_spec.rb
+++ b/spec/ruby/core/string/each_grapheme_cluster_spec.rb
@@ -6,4 +6,12 @@ describe "String#each_grapheme_cluster" do
it_behaves_like :string_chars, :each_grapheme_cluster
it_behaves_like :string_grapheme_clusters, :each_grapheme_cluster
it_behaves_like :string_each_char_without_block, :each_grapheme_cluster
+
+ ruby_version_is '3.0' do
+ it "yields String instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("abc").each_grapheme_cluster { |s| a << s.class }
+ a.should == [String, String, String]
+ end
+ end
end
diff --git a/spec/ruby/core/string/force_encoding_spec.rb b/spec/ruby/core/string/force_encoding_spec.rb
index 2fe5f79c0f..f37aaf9eb4 100644
--- a/spec/ruby/core/string/force_encoding_spec.rb
+++ b/spec/ruby/core/string/force_encoding_spec.rb
@@ -60,7 +60,7 @@ describe "String#force_encoding" do
end
it "does not transcode self" do
- str = "\u{8612}"
+ str = "é"
str.dup.force_encoding('utf-16le').should_not == str.encode('utf-16le')
end
diff --git a/spec/ruby/core/string/scan_spec.rb b/spec/ruby/core/string/scan_spec.rb
index 024e97022a..5f86dbbecc 100644
--- a/spec/ruby/core/string/scan_spec.rb
+++ b/spec/ruby/core/string/scan_spec.rb
@@ -198,4 +198,12 @@ describe "String#scan with pattern and block" do
third.should == 'c';
end
end
+
+ ruby_version_is '3.0' do
+ it "yields String instances for subclasses" do
+ a = []
+ StringSpecs::MyString.new("abc").scan(/./) { |s| a << s.class }
+ a.should == [String, String, String]
+ end
+ end
end
diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb
index 4da44a7992..3137399291 100644
--- a/spec/ruby/core/string/scrub_spec.rb
+++ b/spec/ruby/core/string/scrub_spec.rb
@@ -56,7 +56,9 @@ describe "String#scrub with a custom replacement" do
it "replaces invalid byte sequences in frozen strings" do
x81 = [0x81].pack('C').force_encoding('utf-8')
(-"abc\u3042#{x81}").scrub("*").should == "abc\u3042*"
- utf16_str = ("abc".encode('UTF-16LE').bytes + [0x81]).pack('c*').force_encoding('UTF-16LE')
+
+ leading_surrogate = [0x00, 0xD8]
+ utf16_str = ("abc".encode('UTF-16LE').bytes + leading_surrogate).pack('c*').force_encoding('UTF-16LE')
(-(utf16_str)).scrub("*".encode('UTF-16LE')).should == "abc*".encode('UTF-16LE')
end
diff --git a/spec/ruby/core/string/shared/eql.rb b/spec/ruby/core/string/shared/eql.rb
index 85b861f4f1..b57d6895ff 100644
--- a/spec/ruby/core/string/shared/eql.rb
+++ b/spec/ruby/core/string/shared/eql.rb
@@ -21,7 +21,7 @@ describe :string_eql_value, shared: true do
end
it "considers encoding compatibility" do
- "hello".force_encoding("utf-8").send(@method, "hello".force_encoding("utf-32le")).should be_false
+ "abcd".force_encoding("utf-8").send(@method, "abcd".force_encoding("utf-32le")).should be_false
end
it "ignores subclass differences" do
diff --git a/spec/ruby/core/string/shared/length.rb b/spec/ruby/core/string/shared/length.rb
index b9eae5170f..e931961455 100644
--- a/spec/ruby/core/string/shared/length.rb
+++ b/spec/ruby/core/string/shared/length.rb
@@ -36,4 +36,20 @@ describe :string_length, shared: true do
concat.force_encoding(Encoding::ASCII_8BIT)
concat.size.should == 4
end
+
+ it "adds 1 for every invalid byte in UTF-8" do
+ "\xF4\x90\x80\x80".size.should == 4
+ "a\xF4\x90\x80\x80b".size.should == 6
+ "é\xF4\x90\x80\x80è".size.should == 6
+ end
+
+ it "adds 1 (and not 2) for a incomplete surrogate in UTF-16" do
+ "\x00\xd8".force_encoding("UTF-16LE").size.should == 1
+ "\xd8\x00".force_encoding("UTF-16BE").size.should == 1
+ end
+
+ it "adds 1 for a broken sequence in UTF-32" do
+ "\x04\x03\x02\x01".force_encoding("UTF-32LE").size.should == 1
+ "\x01\x02\x03\x04".force_encoding("UTF-32BE").size.should == 1
+ end
end
diff --git a/spec/ruby/core/string/valid_encoding_spec.rb b/spec/ruby/core/string/valid_encoding_spec.rb
index d5bf31710f..be7cef7a8e 100644
--- a/spec/ruby/core/string/valid_encoding_spec.rb
+++ b/spec/ruby/core/string/valid_encoding_spec.rb
@@ -43,10 +43,10 @@ describe "String#valid_encoding?" do
str.force_encoding('KOI8-R').valid_encoding?.should be_true
str.force_encoding('KOI8-U').valid_encoding?.should be_true
str.force_encoding('Shift_JIS').valid_encoding?.should be_false
- str.force_encoding('UTF-16BE').valid_encoding?.should be_false
- str.force_encoding('UTF-16LE').valid_encoding?.should be_false
- str.force_encoding('UTF-32BE').valid_encoding?.should be_false
- str.force_encoding('UTF-32LE').valid_encoding?.should be_false
+ "\xD8\x00".force_encoding('UTF-16BE').valid_encoding?.should be_false
+ "\x00\xD8".force_encoding('UTF-16LE').valid_encoding?.should be_false
+ "\x04\x03\x02\x01".force_encoding('UTF-32BE').valid_encoding?.should be_false
+ "\x01\x02\x03\x04".force_encoding('UTF-32LE').valid_encoding?.should be_false
str.force_encoding('Windows-1251').valid_encoding?.should be_true
str.force_encoding('IBM437').valid_encoding?.should be_true
str.force_encoding('IBM737').valid_encoding?.should be_true
diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb
index a346cf535b..f51cc87de5 100644
--- a/spec/ruby/core/warning/element_reference_spec.rb
+++ b/spec/ruby/core/warning/element_reference_spec.rb
@@ -12,5 +12,11 @@ ruby_version_is '2.7' do
it "raises for unknown category" do
-> { Warning[:noop] }.should raise_error(ArgumentError, /unknown category: noop/)
end
+
+ it "raises for non-Symbol category" do
+ -> { Warning[42] }.should raise_error(TypeError)
+ -> { Warning[false] }.should raise_error(TypeError)
+ -> { Warning["noop"] }.should raise_error(TypeError)
+ end
end
end
diff --git a/spec/ruby/core/warning/element_set_spec.rb b/spec/ruby/core/warning/element_set_spec.rb
index 3b0ea45c9b..611060fb3a 100644
--- a/spec/ruby/core/warning/element_set_spec.rb
+++ b/spec/ruby/core/warning/element_set_spec.rb
@@ -27,5 +27,11 @@ ruby_version_is '2.7' do
it "raises for unknown category" do
-> { Warning[:noop] = false }.should raise_error(ArgumentError, /unknown category: noop/)
end
+
+ it "raises for non-Symbol category" do
+ -> { Warning[42] = false }.should raise_error(TypeError)
+ -> { Warning[false] = false }.should raise_error(TypeError)
+ -> { Warning["noop"] = false }.should raise_error(TypeError)
+ end
end
end
diff --git a/spec/ruby/core/warning/warn_spec.rb b/spec/ruby/core/warning/warn_spec.rb
index 2ded6a109d..5ccff3aa2b 100644
--- a/spec/ruby/core/warning/warn_spec.rb
+++ b/spec/ruby/core/warning/warn_spec.rb
@@ -51,7 +51,6 @@ describe "Warning.warn" do
end
end
-
ruby_version_is '3.0' do
it "is called by Kernel.warn with nil category keyword" do
Warning.should_receive(:warn).with("Chunky bacon!\n", category: nil)
@@ -69,7 +68,7 @@ describe "Warning.warn" do
verbose = $VERBOSE
$VERBOSE = false
begin
- Kernel.warn("Chunky bacon!", category: 'deprecated')
+ Kernel.warn("Chunky bacon!", category: "deprecated")
ensure
$VERBOSE = verbose
end
diff --git a/spec/ruby/language/class_variable_spec.rb b/spec/ruby/language/class_variable_spec.rb
index 9a4b36e82b..f98deaa081 100644
--- a/spec/ruby/language/class_variable_spec.rb
+++ b/spec/ruby/language/class_variable_spec.rb
@@ -94,6 +94,12 @@ ruby_version_is "3.0" do
}.should raise_error(RuntimeError, 'class variable access from toplevel')
end
+ it "does not raise an error when checking if defined from the toplevel scope" do
+ -> {
+ eval "defined?(@@cvar_toplevel1)"
+ }.should_not raise_error
+ end
+
it "raises a RuntimeError when a class variable is overtaken in an ancestor class" do
parent = Class.new()
subclass = Class.new(parent)
diff --git a/spec/ruby/language/regexp/encoding_spec.rb b/spec/ruby/language/regexp/encoding_spec.rb
index 8e2a294b95..febc3fdb37 100644
--- a/spec/ruby/language/regexp/encoding_spec.rb
+++ b/spec/ruby/language/regexp/encoding_spec.rb
@@ -38,6 +38,10 @@ describe "Regexps with encoding modifiers" do
/#{/./}/n.match("\303\251").to_a.should == ["\303"]
end
+ it "warns when using /n with a match string with non-ASCII characters and an encoding other than ASCII-8BIT" do
+ -> { /./n.match("\303\251".force_encoding('utf-8')) }.should complain(%r{historical binary regexp match /.../n against UTF-8 string})
+ end
+
it 'uses US-ASCII as /n encoding if all chars are 7-bit' do
/./n.encoding.should == Encoding::US_ASCII
end
@@ -117,6 +121,19 @@ describe "Regexps with encoding modifiers" do
-> { /\A[[:space:]]*\z/ =~ " ".encode("UTF-16LE") }.should raise_error(Encoding::CompatibilityError)
end
+ it "raises Encoding::CompatibilityError when the regexp has a fixed, non-ASCII-compatible encoding" do
+ -> { Regexp.new("".force_encoding("UTF-16LE"), Regexp::FIXEDENCODING) =~ " ".encode("UTF-8") }.should raise_error(Encoding::CompatibilityError)
+ end
+
+ it "raises Encoding::CompatibilityError when the regexp has a fixed encoding and the match string has non-ASCII characters" do
+ -> { Regexp.new("".force_encoding("US-ASCII"), Regexp::FIXEDENCODING) =~ "\303\251".force_encoding('UTF-8') }.should raise_error(Encoding::CompatibilityError)
+ end
+
+ it "raises ArgumentError when trying to match a broken String" do
+ s = "\x80".force_encoding('UTF-8')
+ -> { s =~ /./ }.should raise_error(ArgumentError, "invalid byte sequence in UTF-8")
+ end
+
it "computes the Regexp Encoding for each interpolated Regexp instance" do
make_regexp = -> str { /#{str}/ }
diff --git a/spec/ruby/library/fiber/resume_spec.rb b/spec/ruby/library/fiber/resume_spec.rb
index 39d14bdda0..8b7c104a6f 100644
--- a/spec/ruby/library/fiber/resume_spec.rb
+++ b/spec/ruby/library/fiber/resume_spec.rb
@@ -10,6 +10,12 @@ describe "Fiber#resume" do
fiber2.resume
-> { fiber2.resume }.should raise_error(FiberError)
end
+
+ it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
+ root_fiber = Fiber.current
+ fiber1 = Fiber.new { root_fiber.resume }
+ -> { fiber1.resume }.should raise_error(FiberError, /double resume/)
+ end
end
ruby_version_is '3.0' do
@@ -19,5 +25,11 @@ describe "Fiber#resume" do
fiber2.resume.should == 10
fiber2.resume.should == 20
end
+
+ it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
+ root_fiber = Fiber.current
+ fiber1 = Fiber.new { root_fiber.resume }
+ -> { fiber1.resume }.should raise_error(FiberError, /attempt to resume a resuming fiber/)
+ end
end
end
diff --git a/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb b/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb
index f2d779e577..dcc6dbbf17 100644
--- a/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb
+++ b/spec/ruby/library/rexml/element/each_element_with_attribute_spec.rb
@@ -12,23 +12,23 @@ ruby_version_is ''...'3.0' do
@son.attributes["name"] = "Fred"
@document.root << @father
@document.root << @son
- @childs = []
+ @children = []
end
- it "returns childs with attribute" do
- @document.each_element_with_attribute("name") { |elem| @childs << elem }
- @childs[0].should == @father
- @childs[1].should == @son
+ it "returns children with attribute" do
+ @document.each_element_with_attribute("name") { |elem| @children << elem }
+ @children[0].should == @father
+ @children[1].should == @son
end
it "takes attribute value as second argument" do
@document.each_element_with_attribute("name", "Fred"){ |elem| elem.should == @son }
end
- it "takes max number of childs as third argument" do
- @document.each_element_with_attribute("name", nil, 1) { |elem| @childs << elem }
- @childs.size.should == 1
- @childs[0].should == @father
+ it "takes max number of children as third argument" do
+ @document.each_element_with_attribute("name", nil, 1) { |elem| @children << elem }
+ @children.size.should == 1
+ @children[0].should == @father
end
it "takes XPath filter as fourth argument" do
diff --git a/spec/ruby/library/rexml/element/each_element_with_text_spec.rb b/spec/ruby/library/rexml/element/each_element_with_text_spec.rb
index 8f9d062c99..a4a200d237 100644
--- a/spec/ruby/library/rexml/element/each_element_with_text_spec.rb
+++ b/spec/ruby/library/rexml/element/each_element_with_text_spec.rb
@@ -16,10 +16,10 @@ ruby_version_is ''...'3.0' do
@document.root << @joe
@document.root << @fred
@document.root << @another
- @childs = []
+ @children = []
end
- it "returns childs with text" do
+ it "returns children with text" do
@document.each_element_with_text("Joe"){|c| c.should == @joe}
end
diff --git a/spec/ruby/library/rexml/element/has_text_spec.rb b/spec/ruby/library/rexml/element/has_text_spec.rb
index de19fe0763..206c167ae6 100644
--- a/spec/ruby/library/rexml/element/has_text_spec.rb
+++ b/spec/ruby/library/rexml/element/has_text_spec.rb
@@ -11,7 +11,7 @@ ruby_version_is ''...'3.0' do
e.has_text?.should be_true
end
- it "returns false if it has no Text childs" do
+ it "returns false if it has no Text children" do
e = REXML::Element.new("Person")
e.has_text?.should be_false
end
diff --git a/spec/ruby/library/rexml/node/parent_spec.rb b/spec/ruby/library/rexml/node/parent_spec.rb
index 07425e8f36..43c3a747e0 100644
--- a/spec/ruby/library/rexml/node/parent_spec.rb
+++ b/spec/ruby/library/rexml/node/parent_spec.rb
@@ -14,7 +14,7 @@ ruby_version_is ''...'3.0' do
e.should.parent?
end
- # This includes attributes, CDatas and declarations.
+ # This includes attributes, CData and declarations.
it "returns false for Texts" do
e = REXML::Text.new("foo")
e.should_not.parent?
diff --git a/spec/ruby/library/rexml/shared/elements_to_a.rb b/spec/ruby/library/rexml/shared/elements_to_a.rb
index 388250d8b3..b7169f0b2e 100644
--- a/spec/ruby/library/rexml/shared/elements_to_a.rb
+++ b/spec/ruby/library/rexml/shared/elements_to_a.rb
@@ -19,7 +19,7 @@ describe :rexml_elements_to_a, shared: true do
# always needs the first param (even if it's nil).
# A patch was submitted:
# http://rubyforge.org/tracker/index.php?func=detail&aid=19354&group_id=426&atid=1698
- it "returns all childs if xpath is nil" do
+ it "returns all children if xpath is nil" do
@e.elements.send(@method).should == [@first, @second]
end
diff --git a/spec/ruby/library/stringio/ungetbyte_spec.rb b/spec/ruby/library/stringio/ungetbyte_spec.rb
index 2f082acbf6..87b27b837e 100644
--- a/spec/ruby/library/stringio/ungetbyte_spec.rb
+++ b/spec/ruby/library/stringio/ungetbyte_spec.rb
@@ -12,7 +12,7 @@ describe "StringIO#ungetbyte" do
io.string.should == 'Shis is a simple string.'
end
- it "ungets a single byte from a string in the middle of a multibyte characte" do
+ it "ungets a single byte from a string in the middle of a multibyte character" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
diff --git a/spec/ruby/library/stringscanner/check_until_spec.rb b/spec/ruby/library/stringscanner/check_until_spec.rb
index e92ae5a2e9..ad222fd76b 100644
--- a/spec/ruby/library/stringscanner/check_until_spec.rb
+++ b/spec/ruby/library/stringscanner/check_until_spec.rb
@@ -12,4 +12,10 @@ describe "StringScanner#check_until" do
@s.matched.should == "a"
@s.check_until(/test/).should == "This is a test"
end
+
+ it "raises TypeError if given a String" do
+ -> {
+ @s.check_until('T')
+ }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ end
end
diff --git a/spec/ruby/library/stringscanner/exist_spec.rb b/spec/ruby/library/stringscanner/exist_spec.rb
index beafadc07b..ff860a0d3e 100644
--- a/spec/ruby/library/stringscanner/exist_spec.rb
+++ b/spec/ruby/library/stringscanner/exist_spec.rb
@@ -21,4 +21,10 @@ describe "StringScanner#exist?" do
@s.scan(/This is/)
@s.exist?(/i/).should == nil
end
+
+ it "raises TypeError if given a String" do
+ -> {
+ @s.exist?('T')
+ }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ end
end
diff --git a/spec/ruby/library/stringscanner/matched_size_spec.rb b/spec/ruby/library/stringscanner/matched_size_spec.rb
index a36bd3aafe..d9c338a07e 100644
--- a/spec/ruby/library/stringscanner/matched_size_spec.rb
+++ b/spec/ruby/library/stringscanner/matched_size_spec.rb
@@ -1,7 +1,24 @@
require_relative '../../spec_helper'
-require_relative 'shared/matched_size'
require 'strscan'
describe "StringScanner#matched_size" do
- it_behaves_like :strscan_matched_size, :matched_size
+ before :each do
+ @s = StringScanner.new("This is a test")
+ end
+
+ it "returns the size of the most recent match" do
+ @s.check(/This/)
+ @s.matched_size.should == 4
+ @s.matched_size.should == 4
+ @s.scan(//)
+ @s.matched_size.should == 0
+ end
+
+ it "returns nil if there was no recent match" do
+ @s.matched_size.should == nil
+ @s.check(/\d+/)
+ @s.matched_size.should == nil
+ @s.terminate
+ @s.matched_size.should == nil
+ end
end
diff --git a/spec/ruby/library/stringscanner/scan_until_spec.rb b/spec/ruby/library/stringscanner/scan_until_spec.rb
index 94239db50e..6b7782572d 100644
--- a/spec/ruby/library/stringscanner/scan_until_spec.rb
+++ b/spec/ruby/library/stringscanner/scan_until_spec.rb
@@ -20,4 +20,10 @@ describe "StringScanner#scan_until" do
@s.scan(/T/)
@s.scan_until(/^h/).should == "h"
end
+
+ it "raises TypeError if given a String" do
+ -> {
+ @s.scan_until('T')
+ }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ end
end
diff --git a/spec/ruby/library/stringscanner/search_full_spec.rb b/spec/ruby/library/stringscanner/search_full_spec.rb
index da9067e012..7d2a714fa5 100644
--- a/spec/ruby/library/stringscanner/search_full_spec.rb
+++ b/spec/ruby/library/stringscanner/search_full_spec.rb
@@ -27,4 +27,10 @@ describe "StringScanner#search_full" do
@s.search_full(/This/, true, true).should == "This"
@s.pos.should == 4
end
+
+ it "raises TypeError if given a String" do
+ -> {
+ @s.search_full('T', true, true)
+ }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ end
end
diff --git a/spec/ruby/library/stringscanner/shared/matched_size.rb b/spec/ruby/library/stringscanner/shared/matched_size.rb
deleted file mode 100644
index 92174733f7..0000000000
--- a/spec/ruby/library/stringscanner/shared/matched_size.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-describe :strscan_matched_size, shared: true do
- before :each do
- @s = StringScanner.new("This is a test")
- end
-
- it "returns the size of the most recent match" do
- @s.check(/This/)
- @s.send(@method).should == 4
- @s.send(@method).should == 4
- @s.scan(//)
- @s.send(@method).should == 0
- end
-
- it "returns nil if there was no recent match" do
- @s.send(@method).should == nil
- @s.check(/\d+/)
- @s.send(@method).should == nil
- @s.terminate
- @s.send(@method).should == nil
- end
-end
diff --git a/spec/ruby/library/stringscanner/size_spec.rb b/spec/ruby/library/stringscanner/size_spec.rb
new file mode 100644
index 0000000000..3e475489e3
--- /dev/null
+++ b/spec/ruby/library/stringscanner/size_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#size" do
+ before :each do
+ @s = StringScanner.new("This is a test")
+ end
+
+ it "returns the number of captures groups of the last match" do
+ @s.scan(/(.)(.)(.)/)
+ @s.size.should == 4
+ end
+
+ it "returns nil if there is no last match" do
+ @s.size.should == nil
+ end
+end
diff --git a/spec/ruby/library/stringscanner/skip_until_spec.rb b/spec/ruby/library/stringscanner/skip_until_spec.rb
index 73eb91b8ad..7b56f13e4f 100644
--- a/spec/ruby/library/stringscanner/skip_until_spec.rb
+++ b/spec/ruby/library/stringscanner/skip_until_spec.rb
@@ -15,4 +15,10 @@ describe "StringScanner#skip_until" do
it "returns nil if no match was found" do
@s.skip_until(/d+/).should == nil
end
+
+ it "raises TypeError if given a String" do
+ -> {
+ @s.skip_until('T')
+ }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ end
end
diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb
index c2424668b9..a2d8b3e38a 100644
--- a/spec/ruby/optional/capi/class_spec.rb
+++ b/spec/ruby/optional/capi/class_spec.rb
@@ -12,6 +12,7 @@ autoload :ClassIdUnderAutoload, "#{object_path}/class_id_under_autoload_spec"
describe :rb_path_to_class, shared: true do
it "returns a class or module from a scoped String" do
@s.send(@method, "CApiClassSpecs::A::B").should equal(CApiClassSpecs::A::B)
+ @s.send(@method, "CApiClassSpecs::A::M").should equal(CApiClassSpecs::A::M)
end
it "resolves autoload constants" do
@@ -27,7 +28,9 @@ describe :rb_path_to_class, shared: true do
end
it "raises a TypeError if the constant is not a class or module" do
- -> { @s.send(@method, "CApiClassSpecs::A::C") }.should raise_error(TypeError)
+ -> {
+ @s.send(@method, "CApiClassSpecs::A::C")
+ }.should raise_error(TypeError, 'CApiClassSpecs::A::C does not refer to class/module')
end
it "raises an ArgumentError even if a constant in the path exists on toplevel" do
diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c
index 099363c951..2a21304a10 100644
--- a/spec/ruby/optional/capi/ext/string_spec.c
+++ b/spec/ruby/optional/capi/ext/string_spec.c
@@ -577,6 +577,14 @@ static VALUE string_spec_rb_str_catf(VALUE self, VALUE mesg) {
return rb_str_catf(mesg, "fmt %d %d number", 41, 6);
}
+static VALUE string_spec_rb_str_locktmp(VALUE self, VALUE str) {
+ return rb_str_locktmp(str);
+}
+
+static VALUE string_spec_rb_str_unlocktmp(VALUE self, VALUE str) {
+ return rb_str_unlocktmp(str);
+}
+
void Init_string_spec(void) {
VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject);
rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2);
@@ -672,6 +680,8 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_utf8_str_new_cstr", string_spec_rb_utf8_str_new_cstr, 0);
rb_define_method(cls, "rb_str_vcatf", string_spec_rb_str_vcatf, 1);
rb_define_method(cls, "rb_str_catf", string_spec_rb_str_catf, 1);
+ rb_define_method(cls, "rb_str_locktmp", string_spec_rb_str_locktmp, 1);
+ rb_define_method(cls, "rb_str_unlocktmp", string_spec_rb_str_unlocktmp, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/fixtures/class.rb b/spec/ruby/optional/capi/fixtures/class.rb
index dbb0b69967..193c7174e0 100644
--- a/spec/ruby/optional/capi/fixtures/class.rb
+++ b/spec/ruby/optional/capi/fixtures/class.rb
@@ -87,5 +87,8 @@ class CApiClassSpecs
class B
end
+
+ module M
+ end
end
end
diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb
index 3cd88a7390..ce387ffa49 100644
--- a/spec/ruby/optional/capi/string_spec.rb
+++ b/spec/ruby/optional/capi/string_spec.rb
@@ -1209,4 +1209,31 @@ end
str.should == "test fmt 41 6 number"
end
end
+
+ describe "rb_str_locktmp" do
+ it "raises an error when trying to lock an already locked string" do
+ str = "test"
+ @s.rb_str_locktmp(str).should == str
+ -> { @s.rb_str_locktmp(str) }.should raise_error(RuntimeError, 'temporal locking already locked string')
+ end
+
+ it "locks a string so that modifications would raise an error" do
+ str = "test"
+ @s.rb_str_locktmp(str).should == str
+ -> { str.upcase! }.should raise_error(RuntimeError, 'can\'t modify string; temporarily locked')
+ end
+ end
+
+ describe "rb_str_unlocktmp" do
+ it "unlocks a locked string" do
+ str = "test"
+ @s.rb_str_locktmp(str)
+ @s.rb_str_unlocktmp(str).should == str
+ str.upcase!.should == "TEST"
+ end
+
+ it "raises an error when trying to unlock an already unlocked string" do
+ -> { @s.rb_str_unlocktmp("test") }.should raise_error(RuntimeError, 'temporal unlocking already unlocked string')
+ end
+ end
end