summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-11-27 14:55:31 +0100
committerBenoit Daloze <eregontp@gmail.com>2020-11-27 14:55:31 +0100
commitf02d2f82bf10351f480ea312f40cb840e2437f93 (patch)
tree0b53098bffe6dacadb09880183ebcaea06e95153 /spec
parentf0bfa266d70651dc295a63b026938b246693499b (diff)
Update to ruby/spec@ac878ad
Diffstat (limited to 'spec')
-rw-r--r--spec/ruby/core/dir/fixtures/common.rb3
-rw-r--r--spec/ruby/core/dir/glob_spec.rb16
-rw-r--r--spec/ruby/core/dir/shared/glob.rb3
-rw-r--r--spec/ruby/core/hash/ruby2_keywords_hash_spec.rb47
-rw-r--r--spec/ruby/core/kernel/backtick_spec.rb4
-rw-r--r--spec/ruby/core/proc/shared/to_s.rb9
-rw-r--r--spec/ruby/core/string/fixtures/classes.rb11
-rw-r--r--spec/ruby/core/string/gsub_spec.rb5
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb10
-rw-r--r--spec/ruby/default.mspec1
-rw-r--r--spec/ruby/language/block_spec.rb8
-rw-r--r--spec/ruby/language/hash_spec.rb6
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb6
-rw-r--r--spec/ruby/library/pathname/pathname_spec.rb30
-rw-r--r--spec/ruby/optional/capi/exception_spec.rb45
-rw-r--r--spec/ruby/optional/capi/ext/exception_spec.c8
-rw-r--r--spec/ruby/shared/rational/coerce.rb5
17 files changed, 214 insertions, 3 deletions
diff --git a/spec/ruby/core/dir/fixtures/common.rb b/spec/ruby/core/dir/fixtures/common.rb
index 96dba56c93..71b1438b72 100644
--- a/spec/ruby/core/dir/fixtures/common.rb
+++ b/spec/ruby/core/dir/fixtures/common.rb
@@ -36,6 +36,8 @@ module DirSpecs
.dotfile
.dotsubdir/.dotfile
.dotsubdir/nondotfile
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
deeply/.dotfile
deeply/nested/.dotfile.ext
@@ -160,6 +162,7 @@ module DirSpecs
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb
index d4888ee147..9b6e2b2d3d 100644
--- a/spec/ruby/core/dir/glob_spec.rb
+++ b/spec/ruby/core/dir/glob_spec.rb
@@ -59,6 +59,8 @@ describe "Dir.glob" do
deeply/nested/directory/
deeply/nested/directory/structure/
dir/
+ nested/
+ nested/.dotsubir/
special/
special/test{1}/
subdir_one/
@@ -68,6 +70,18 @@ describe "Dir.glob" do
Dir.glob('**/', File::FNM_DOTMATCH).sort.should == expected
end
+ it "recursively matches files and directories in nested dot subdirectory with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
+ expected = %w[
+ nested/.
+ nested/.dotsubir
+ nested/.dotsubir/.
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
+ ]
+
+ Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
+ end
+
# This is a separate case to check **/ coming after a constant
# directory as well.
it "recursively matches any subdirectories except './' or '../' with '**/' and option File::FNM_DOTMATCH" do
@@ -80,6 +94,8 @@ describe "Dir.glob" do
./deeply/nested/directory/
./deeply/nested/directory/structure/
./dir/
+ ./nested/
+ ./nested/.dotsubir/
./special/
./special/test{1}/
./subdir_one/
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index fcaa0d8a43..f6d41ba209 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -53,6 +53,7 @@ describe :dir_glob, shared: true do
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
@@ -156,6 +157,7 @@ describe :dir_glob, shared: true do
dir_filename_ordering
file_one.ext
file_two.ext
+ nested
nondotfile
special
subdir_one
@@ -177,6 +179,7 @@ describe :dir_glob, shared: true do
deeply/nested/directory/
deeply/nested/directory/structure/
dir/
+ nested/
special/
special/test{1}/
subdir_one/
diff --git a/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb b/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
new file mode 100644
index 0000000000..005886a482
--- /dev/null
+++ b/spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
@@ -0,0 +1,47 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "2.7" do
+ describe "Hash.ruby2_keywords_hash?" do
+ it "returns false if the Hash is not a keywords Hash" do
+ Hash.ruby2_keywords_hash?({}).should == false
+ end
+
+ it "returns true if the Hash is a keywords Hash marked by Module#ruby2_keywords" do
+ obj = Class.new {
+ ruby2_keywords def m(*args)
+ args.last
+ end
+ }.new
+ Hash.ruby2_keywords_hash?(obj.m(a: 1)).should == true
+ end
+
+ it "raises TypeError for non-Hash" do
+ -> { Hash.ruby2_keywords_hash?(nil) }.should raise_error(TypeError)
+ end
+ end
+
+ describe "Hash.ruby2_keywords_hash" do
+ it "returns a copy of a Hash and marks the copy as a keywords Hash" do
+ h = {a: 1}.freeze
+ kw = Hash.ruby2_keywords_hash(h)
+ Hash.ruby2_keywords_hash?(h).should == false
+ Hash.ruby2_keywords_hash?(kw).should == true
+ kw.should == h
+ end
+
+ it "returns an instance of the subclass if called on an instance of a subclass of Hash" do
+ h = HashSpecs::MyHash.new
+ h[:a] = 1
+ kw = Hash.ruby2_keywords_hash(h)
+ kw.class.should == HashSpecs::MyHash
+ Hash.ruby2_keywords_hash?(h).should == false
+ Hash.ruby2_keywords_hash?(kw).should == true
+ kw.should == h
+ end
+
+ it "raises TypeError for non-Hash" do
+ -> { Hash.ruby2_keywords_hash(nil) }.should raise_error(TypeError)
+ end
+ end
+end
diff --git a/spec/ruby/core/kernel/backtick_spec.rb b/spec/ruby/core/kernel/backtick_spec.rb
index 391583b539..045bb598cd 100644
--- a/spec/ruby/core/kernel/backtick_spec.rb
+++ b/spec/ruby/core/kernel/backtick_spec.rb
@@ -36,6 +36,10 @@ describe "Kernel#`" do
end
platform_is_not :windows do
+ it "handles invalid UTF-8 bytes in command" do
+ `echo "testing\xC2 a non UTF-8 string"`.should == "testing\xC2 a non UTF-8 string\n"
+ end
+
it "sets $? to the exit status of the executed sub-process" do
ip = 'world'
`echo disc #{ip}`
diff --git a/spec/ruby/core/proc/shared/to_s.rb b/spec/ruby/core/proc/shared/to_s.rb
index 7edd11b1e1..7f167a3d9d 100644
--- a/spec/ruby/core/proc/shared/to_s.rb
+++ b/spec/ruby/core/proc/shared/to_s.rb
@@ -33,8 +33,13 @@ describe :proc_to_s, shared: true do
describe "for a proc created with UnboundMethod#to_proc" do
it "returns a description including '(lambda)' and optionally including file and line number" do
- def hello; end
- method("hello").to_proc.send(@method).should =~ /^#<Proc:([^ ]*?)(#{sep}#{Regexp.escape __FILE__}:#{__LINE__ })? \(lambda\)>$/
+ def hello; end
+ s = method("hello").to_proc.send(@method)
+ if s.include? __FILE__
+ s.should =~ /^#<Proc:([^ ]*?)#{sep}#{Regexp.escape __FILE__}:#{__LINE__ - 3} \(lambda\)>$/
+ else
+ s.should =~ /^#<Proc:([^ ]*?) \(lambda\)>$/
+ end
end
it "has a binary encoding" do
diff --git a/spec/ruby/core/string/fixtures/classes.rb b/spec/ruby/core/string/fixtures/classes.rb
index 1cc7600abb..26fcd51b5d 100644
--- a/spec/ruby/core/string/fixtures/classes.rb
+++ b/spec/ruby/core/string/fixtures/classes.rb
@@ -46,4 +46,15 @@ module StringSpecs
self.replace(str)
end
end
+
+ class SpecialVarProcessor
+ def process(match)
+ if $~ != nil
+ str = $~[0]
+ else
+ str = "unset"
+ end
+ "<#{str}>"
+ end
+ end
end
diff --git a/spec/ruby/core/string/gsub_spec.rb b/spec/ruby/core/string/gsub_spec.rb
index 54a2be0fed..6789199ff3 100644
--- a/spec/ruby/core/string/gsub_spec.rb
+++ b/spec/ruby/core/string/gsub_spec.rb
@@ -475,6 +475,11 @@ describe "String#gsub with pattern and block" do
offsets.should == [[1, 2], [4, 5]]
end
+ it "does not set $~ for procs created from methods" do
+ str = "hello"
+ str.gsub("l", &StringSpecs::SpecialVarProcessor.new.method(:process)).should == "he<unset><unset>o"
+ end
+
it "restores $~ after leaving the block" do
[/./, "l"].each do |pattern|
old_md = nil
diff --git a/spec/ruby/core/string/unpack/w_spec.rb b/spec/ruby/core/string/unpack/w_spec.rb
index 166ae58869..011c75f5c4 100644
--- a/spec/ruby/core/string/unpack/w_spec.rb
+++ b/spec/ruby/core/string/unpack/w_spec.rb
@@ -23,3 +23,13 @@ describe "String#unpack with directive 'w'" do
"\x01\x02\x03".unpack("w w").should == [1, 2]
end
end
+
+describe "String#unpack with directive 'w*'" do
+
+ it "decodes BER-compressed integers" do
+ "\x01\x02\x03\x04".unpack("w*").should == [1, 2, 3, 4]
+ "\x00\xCE\x0F\x84\x80\x80\x80\x80\x80\x80\x80\x80\x00\x01\x00".unpack("w*").should == [0, 9999, 2**65, 1, 0]
+ "\x81\x80\x80\x80\x80\x80\x80\x80\x80\x00\x90\x80\x80\x80\x80\x80\x80\x80\x03\x01\x02".unpack("w*").should == [2**63, (2**60 + 3), 1, 2]
+ end
+
+end
diff --git a/spec/ruby/default.mspec b/spec/ruby/default.mspec
index 6fd6d2bf9c..a0dc69c03d 100644
--- a/spec/ruby/default.mspec
+++ b/spec/ruby/default.mspec
@@ -45,5 +45,6 @@ class MSpecScript
set :toplevel_constants_excludes, [
/\wSpecs?$/,
/^CS_CONST/,
+ /^CSL_CONST/,
]
end
diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb
index 45a8ec5f9a..b2a3cc84c4 100644
--- a/spec/ruby/language/block_spec.rb
+++ b/spec/ruby/language/block_spec.rb
@@ -873,7 +873,7 @@ describe "Post-args" do
end.call(1, 2, 3).should == [[], 1, 2, 3]
end
- it "are required" do
+ it "are required for a lambda" do
-> {
-> *a, b do
[a, b]
@@ -881,6 +881,12 @@ describe "Post-args" do
}.should raise_error(ArgumentError)
end
+ it "are assigned to nil when not enough arguments are given to a proc" do
+ proc do |a, *b, c|
+ [a, b, c]
+ end.call.should == [nil, [], nil]
+ end
+
describe "with required args" do
it "gathers remaining args in the splat" do
diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb
index 630c9d2364..d6600ddb4a 100644
--- a/spec/ruby/language/hash_spec.rb
+++ b/spec/ruby/language/hash_spec.rb
@@ -149,6 +149,12 @@ describe "Hash literal" do
-> { {**obj} }.should raise_error(TypeError)
end
+ it "raises a TypeError if the object does not respond to #to_hash" do
+ obj = 42
+ -> { {**obj} }.should raise_error(TypeError)
+ -> { {a: 1, **obj} }.should raise_error(TypeError)
+ end
+
it "does not change encoding of literal string keys during creation" do
binary_hash = HashStringsBinary.literal_hash
utf8_hash = HashStringsUTF8.literal_hash
diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb
index 5f4221e213..0cf1e9b6f4 100644
--- a/spec/ruby/language/regexp/character_classes_spec.rb
+++ b/spec/ruby/language/regexp/character_classes_spec.rb
@@ -609,6 +609,12 @@ describe "Regexp with character classes" do
"루비(Ruby)".match(/\p{Hangul}+/u).to_a.should == ["루비"]
end
+ ruby_bug "#17340", ''...'3.0' do
+ it "raises a RegexpError for an unterminated unicode property" do
+ -> { Regexp.new('\p{') }.should raise_error(RegexpError)
+ end
+ end
+
it "supports \\X (unicode 9.0 with UTR #51 workarounds)" do
# simple emoji without any fancy modifier or ZWJ
/\X/.match("\u{1F98A}").to_a.should == ["🦊"]
diff --git a/spec/ruby/library/pathname/pathname_spec.rb b/spec/ruby/library/pathname/pathname_spec.rb
new file mode 100644
index 0000000000..7d63fe86e3
--- /dev/null
+++ b/spec/ruby/library/pathname/pathname_spec.rb
@@ -0,0 +1,30 @@
+require_relative '../../spec_helper'
+require 'pathname'
+
+describe "Kernel#Pathname" do
+ it "is a private instance method" do
+ Kernel.should have_private_instance_method(:Pathname)
+ end
+
+ it "is also a public method" do
+ Kernel.should have_method(:Pathname)
+ end
+
+ ruby_version_is ''...'2.7' do
+ it "returns a new pathname when called with a pathname argument" do
+ path = Pathname('foo')
+ new_path = Pathname(path)
+
+ path.should_not.equal?(new_path)
+ end
+ end
+
+ ruby_version_is '2.7' do
+ it "returns same argument when called with a pathname argument" do
+ path = Pathname('foo')
+ new_path = Pathname(path)
+
+ path.should.equal?(new_path)
+ end
+ end
+end
diff --git a/spec/ruby/optional/capi/exception_spec.rb b/spec/ruby/optional/capi/exception_spec.rb
index 62d7d3706e..9e82e5c7dd 100644
--- a/spec/ruby/optional/capi/exception_spec.rb
+++ b/spec/ruby/optional/capi/exception_spec.rb
@@ -55,4 +55,49 @@ describe "C-API Exception function" do
-> { @s.rb_set_errinfo("error") }.should raise_error(TypeError)
end
end
+
+ describe "rb_make_exception" do
+ it "returns a RuntimeError when given a String argument" do
+ e = @s.rb_make_exception(["Message"])
+ e.class.should == RuntimeError
+ e.message.should == "Message"
+ end
+
+ it "returns the exception when given an Exception argument" do
+ exc = Exception.new
+ e = @s.rb_make_exception([exc])
+ e.should == exc
+ end
+
+ it "returns the exception with the given class and message" do
+ e = @s.rb_make_exception([Exception, "Message"])
+ e.class.should == Exception
+ e.message.should == "Message"
+ end
+
+ it "returns the exception with the given class, message, and backtrace" do
+ e = @s.rb_make_exception([Exception, "Message", ["backtrace 1"]])
+ e.class.should == Exception
+ e.message.should == "Message"
+ e.backtrace.should == ["backtrace 1"]
+ end
+
+ it "raises a TypeError for incorrect types" do
+ -> { @s.rb_make_exception([nil]) }.should raise_error(TypeError)
+ -> { @s.rb_make_exception([Object.new]) }.should raise_error(TypeError)
+ obj = Object.new
+ def obj.exception
+ "not exception type"
+ end
+ -> { @s.rb_make_exception([obj]) }.should raise_error(TypeError)
+ end
+
+ it "raises an ArgumentError for too many arguments" do
+ -> { @s.rb_make_exception([Exception, "Message", ["backtrace 1"], "extra"]) }.should raise_error(ArgumentError)
+ end
+
+ it "returns nil for empty arguments" do
+ @s.rb_make_exception([]).should == nil
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/ext/exception_spec.c b/spec/ruby/optional/capi/ext/exception_spec.c
index cdd86b183e..7250792b70 100644
--- a/spec/ruby/optional/capi/ext/exception_spec.c
+++ b/spec/ruby/optional/capi/ext/exception_spec.c
@@ -32,6 +32,13 @@ VALUE exception_spec_rb_set_errinfo(VALUE self, VALUE exc) {
return Qnil;
}
+
+VALUE exception_spec_rb_make_exception(VALUE self, VALUE ary) {
+ int argc = RARRAY_LENINT(ary);
+ VALUE *argv = RARRAY_PTR(ary);
+ return rb_make_exception(argc, argv);
+}
+
void Init_exception_spec(void) {
VALUE cls = rb_define_class("CApiExceptionSpecs", rb_cObject);
rb_define_method(cls, "rb_exc_new", exception_spec_rb_exc_new, 1);
@@ -39,6 +46,7 @@ void Init_exception_spec(void) {
rb_define_method(cls, "rb_exc_new3", exception_spec_rb_exc_new3, 1);
rb_define_method(cls, "rb_exc_raise", exception_spec_rb_exc_raise, 1);
rb_define_method(cls, "rb_set_errinfo", exception_spec_rb_set_errinfo, 1);
+ rb_define_method(cls, "rb_make_exception", exception_spec_rb_make_exception, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/shared/rational/coerce.rb b/spec/ruby/shared/rational/coerce.rb
index ffb118e2a7..ccc8901ba0 100644
--- a/spec/ruby/shared/rational/coerce.rb
+++ b/spec/ruby/shared/rational/coerce.rb
@@ -17,6 +17,11 @@ describe :rational_coerce, shared: true do
result.last.is_a?(Rational).should be_true
end
+ it "coerces to Rational, when given a Complex" do
+ Rational(3, 4).coerce(Complex(5)).should == [Rational(5, 1), Rational(3, 4)]
+ Rational(12, 4).coerce(Complex(5, 1)).should == [Complex(5, 1), Complex(3)]
+ end
+
it "returns [argument, self] when given a Rational" do
Rational(3, 7).coerce(Rational(9, 2)).should == [Rational(9, 2), Rational(3, 7)]
end