aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2019-05-28 22:41:48 +0200
committerBenoit Daloze <eregontp@gmail.com>2019-05-28 22:41:48 +0200
commita66bc2c01194a9c017c874a30db5b3b6bd95e966 (patch)
tree598d6375b44fd86f90c3477c73086f6fcf08d76c /spec/ruby/core
parentd070523e7be4b95914adeef9a10401fba7718c5a (diff)
downloadruby-a66bc2c01194a9c017c874a30db5b3b6bd95e966.tar.gz
Update to ruby/spec@9a501a8
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/enumerable/shared/find.rb4
-rw-r--r--spec/ruby/core/exception/backtrace_spec.rb15
-rw-r--r--spec/ruby/core/exception/cause_spec.rb12
-rw-r--r--spec/ruby/core/file/expand_path_spec.rb2
-rw-r--r--spec/ruby/core/hash/constructor_spec.rb2
-rw-r--r--spec/ruby/core/hash/hash_spec.rb8
-rw-r--r--spec/ruby/core/hash/merge_spec.rb18
-rw-r--r--spec/ruby/core/kernel/autoload_spec.rb2
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb11
-rw-r--r--spec/ruby/core/module/name_spec.rb6
-rw-r--r--spec/ruby/core/proc/new_spec.rb11
-rw-r--r--spec/ruby/core/proc/shared/call_arguments.rb22
-rw-r--r--spec/ruby/core/regexp/compile_spec.rb13
-rw-r--r--spec/ruby/core/regexp/new_spec.rb13
-rw-r--r--spec/ruby/core/regexp/shared/new.rb (renamed from spec/ruby/core/regexp/shared/new_ascii_8bit.rb)198
-rw-r--r--spec/ruby/core/regexp/shared/new_ascii.rb464
-rw-r--r--spec/ruby/core/string/uminus_spec.rb17
17 files changed, 204 insertions, 614 deletions
diff --git a/spec/ruby/core/enumerable/shared/find.rb b/spec/ruby/core/enumerable/shared/find.rb
index 5c097509cd..3435ce3658 100644
--- a/spec/ruby/core/enumerable/shared/find.rb
+++ b/spec/ruby/core/enumerable/shared/find.rb
@@ -49,6 +49,10 @@ describe :enumerable_find, shared: true do
@empty.send(@method, fail_proc) {|e| true}.should == "yay"
end
+ it "ignores the ifnone argument when nil" do
+ @numerous.send(@method, nil) {|e| false }.should == nil
+ end
+
it "passes through the values yielded by #each_with_index" do
[:a, :b].each_with_index.send(@method) { |x, i| ScratchPad << [x, i]; nil }
ScratchPad.recorded.should == [[:a, 0], [:b, 1]]
diff --git a/spec/ruby/core/exception/backtrace_spec.rb b/spec/ruby/core/exception/backtrace_spec.rb
index 70c75bda1e..5e140f8d9b 100644
--- a/spec/ruby/core/exception/backtrace_spec.rb
+++ b/spec/ruby/core/exception/backtrace_spec.rb
@@ -65,4 +65,19 @@ describe "Exception#backtrace" do
e.backtrace[0].should == "backtrace first"
end
end
+
+ it "returns the same array after duping" do
+ begin
+ raise
+ rescue RuntimeError => err
+ bt = err.backtrace
+ err.dup.backtrace.should equal(bt)
+
+ new_bt = ['hi']
+ err.set_backtrace new_bt
+
+ err.backtrace.should == new_bt
+ err.dup.backtrace.should equal(new_bt)
+ end
+ end
end
diff --git a/spec/ruby/core/exception/cause_spec.rb b/spec/ruby/core/exception/cause_spec.rb
index 007df41366..cf4aaeb188 100644
--- a/spec/ruby/core/exception/cause_spec.rb
+++ b/spec/ruby/core/exception/cause_spec.rb
@@ -41,4 +41,16 @@ describe "Exception#cause" do
e.cause.should equal(cause)
}
end
+
+ it "is not set to the exception itself when it is re-raised" do
+ -> {
+ begin
+ raise RuntimeError
+ rescue RuntimeError => e
+ raise e
+ end
+ }.should raise_error(RuntimeError) { |e|
+ e.cause.should == nil
+ }
+ end
end
diff --git a/spec/ruby/core/file/expand_path_spec.rb b/spec/ruby/core/file/expand_path_spec.rb
index 90aa44e2c4..1d972023a3 100644
--- a/spec/ruby/core/file/expand_path_spec.rb
+++ b/spec/ruby/core/file/expand_path_spec.rb
@@ -225,6 +225,8 @@ platform_is_not :windows do
user = ENV.delete("USER")
begin
Etc.getlogin != nil
+ rescue
+ false
ensure
ENV["USER"] = user
end
diff --git a/spec/ruby/core/hash/constructor_spec.rb b/spec/ruby/core/hash/constructor_spec.rb
index d32117b5a1..14674a018b 100644
--- a/spec/ruby/core/hash/constructor_spec.rb
+++ b/spec/ruby/core/hash/constructor_spec.rb
@@ -54,7 +54,7 @@ describe "Hash.[]" do
end
ruby_version_is "2.7" do
- it "ignores elements that are not arrays" do
+ it "raises for elements that are not arrays" do
-> {
Hash[[:a]].should == {}
}.should raise_error(ArgumentError)
diff --git a/spec/ruby/core/hash/hash_spec.rb b/spec/ruby/core/hash/hash_spec.rb
index 7c26f02640..3649d4d8de 100644
--- a/spec/ruby/core/hash/hash_spec.rb
+++ b/spec/ruby/core/hash/hash_spec.rb
@@ -11,6 +11,14 @@ describe "Hash#hash" do
{ 0=>2, 11=>1 }.hash.should == { 11=>1, 0=>2 }.hash
end
+ it "returns a value in which element values do not cancel each other out" do
+ { a: 2, b: 2 }.hash.should_not == { a: 7, b: 7 }.hash
+ end
+
+ it "returns a value in which element keys and values do not cancel each other out" do
+ { :a => :a }.hash.should_not == { :b => :b }.hash
+ end
+
it "generates a hash for recursive hash structures" do
h = {}
h[:a] = h
diff --git a/spec/ruby/core/hash/merge_spec.rb b/spec/ruby/core/hash/merge_spec.rb
index e90beae87a..54abcb816d 100644
--- a/spec/ruby/core/hash/merge_spec.rb
+++ b/spec/ruby/core/hash/merge_spec.rb
@@ -63,6 +63,24 @@ describe "Hash#merge" do
merge_pairs.should == each_pairs
end
+ it "preserves the order of merged elements" do
+ h1 = { 1 => 2, 3 => 4, 5 => 6 }
+ h2 = { 1 => 7 }
+ merge_pairs = []
+ h1.merge(h2).each_pair { |k, v| merge_pairs << [k, v] }
+ merge_pairs.should == [[1,7], [3, 4], [5, 6]]
+ end
+
+ it "preserves the order of merged elements for large hashes" do
+ h1 = {}
+ h2 = {}
+ merge_pairs = []
+ expected_pairs = []
+ (1..100).each { |x| h1[x] = x; h2[101 - x] = x; expected_pairs << [x, 101 - x] }
+ h1.merge(h2).each_pair { |k, v| merge_pairs << [k, v] }
+ merge_pairs.should == expected_pairs
+ end
+
ruby_version_is "2.6" do
it "accepts multiple hashes" do
result = { a: 1 }.merge({ b: 2 }, { c: 3 }, { d: 4 })
diff --git a/spec/ruby/core/kernel/autoload_spec.rb b/spec/ruby/core/kernel/autoload_spec.rb
index 3e7a63ede0..68732a69ef 100644
--- a/spec/ruby/core/kernel/autoload_spec.rb
+++ b/spec/ruby/core/kernel/autoload_spec.rb
@@ -57,7 +57,7 @@ describe "Kernel#autoload" do
end
describe "when Object is frozen" do
- it "raises a FrozenError before defining the constant" do
+ it "raises a #{frozen_error_class} before defining the constant" do
ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "#{frozen_error_class} - nil"
end
end
diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb
index b041a95d4b..53a0b3197d 100644
--- a/spec/ruby/core/marshal/dump_spec.rb
+++ b/spec/ruby/core/marshal/dump_spec.rb
@@ -449,14 +449,13 @@ describe "Marshal.dump" do
zone = ":\tzoneI\"\bAST\x06:\x06EF" # Last is 'F' (US-ASCII)
[ "#{base}#{offset}#{zone}", "#{base}#{zone}#{offset}" ].should include(dump)
end
-
- it "dumps the zone, but not the offset if zone is UTC" do
- dump = Marshal.dump(@utc)
- zone = ":\tzoneI\"\bUTC\x06:\x06EF" # Last is 'F' (US-ASCII)
- dump.should == "\x04\bIu:\tTime\r#{@utc_dump}\x06#{zone}"
- end
end
+ it "dumps the zone, but not the offset if zone is UTC" do
+ dump = Marshal.dump(@utc)
+ zone = ":\tzoneI\"\bUTC\x06:\x06EF" # Last is 'F' (US-ASCII)
+ dump.should == "\x04\bIu:\tTime\r#{@utc_dump}\x06#{zone}"
+ end
end
describe "with an Exception" do
diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb
index 5b0fd88729..d64684319c 100644
--- a/spec/ruby/core/module/name_spec.rb
+++ b/spec/ruby/core/module/name_spec.rb
@@ -15,13 +15,13 @@ describe "Module#name" do
it "is not nil for a nested module created with the module keyword" do
m = Module.new
module m::N; end
- m::N.name.should =~ /#<Module:0x[0-9a-f]+>::N/
+ m::N.name.should =~ /\A#<Module:0x[0-9a-f]+>::N\z/
end
it "changes when the module is reachable through a constant path" do
m = Module.new
module m::N; end
- m::N.name.should =~ /#<Module:0x[0-9a-f]+>::N/
+ m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
ModuleSpecs::Anonymous::WasAnnon = m::N
m::N.name.should == "ModuleSpecs::Anonymous::WasAnnon"
end
@@ -42,7 +42,7 @@ describe "Module#name" do
module m::Child; end
child = m::Child
m.send(:remove_const, :Child)
- child.name.should =~ /#<Module:0x[0-9a-f]+>::Child/
+ child.name.should =~ /\A#<Module:0x\h+>::Child\z/
end
it "is set when opened with the module keyword" do
diff --git a/spec/ruby/core/proc/new_spec.rb b/spec/ruby/core/proc/new_spec.rb
index 7579bfe1b6..60a7320e4b 100644
--- a/spec/ruby/core/proc/new_spec.rb
+++ b/spec/ruby/core/proc/new_spec.rb
@@ -190,6 +190,17 @@ describe "Proc.new without a block" do
prc.call.should == "hello"
end
+
+ it "uses the implicit block from an enclosing method when called inside a block" do
+ def some_method
+ proc do |&block|
+ Proc.new
+ end.call { "failing" }
+ end
+ prc = some_method { "hello" }
+
+ prc.call.should == "hello"
+ end
end
ruby_version_is "2.7" do
diff --git a/spec/ruby/core/proc/shared/call_arguments.rb b/spec/ruby/core/proc/shared/call_arguments.rb
index 2e510b194e..a937bd99d0 100644
--- a/spec/ruby/core/proc/shared/call_arguments.rb
+++ b/spec/ruby/core/proc/shared/call_arguments.rb
@@ -4,4 +4,26 @@ describe :proc_call_block_args, shared: true do
lambda {|&b| b.send(@method)}.send(@method) {1 + 1}.should == 2
proc {|&b| b.send(@method)}.send(@method) {1 + 1}.should == 2
end
+
+ it "yields to the block given at declaration and not to the block argument" do
+ proc_creator = Object.new
+ def proc_creator.create
+ Proc.new do |&b|
+ yield
+ end
+ end
+ a_proc = proc_creator.create { 7 }
+ a_proc.send(@method) { 3 }.should == 7
+ end
+
+ it "can call its block argument declared with a block argument" do
+ proc_creator = Object.new
+ def proc_creator.create(method_name)
+ Proc.new do |&b|
+ yield + b.send(method_name)
+ end
+ end
+ a_proc = proc_creator.create(@method) { 7 }
+ a_proc.call { 3 }.should == 10
+ end
end
diff --git a/spec/ruby/core/regexp/compile_spec.rb b/spec/ruby/core/regexp/compile_spec.rb
index 4088c17c3c..329cb4f753 100644
--- a/spec/ruby/core/regexp/compile_spec.rb
+++ b/spec/ruby/core/regexp/compile_spec.rb
@@ -1,18 +1,15 @@
require_relative '../../spec_helper'
-require_relative 'shared/new_ascii'
-require_relative 'shared/new_ascii_8bit'
+require_relative 'shared/new'
describe "Regexp.compile" do
- it_behaves_like :regexp_new_ascii, :compile
- it_behaves_like :regexp_new_ascii_8bit, :compile
+ it_behaves_like :regexp_new, :compile
end
describe "Regexp.compile given a String" do
- it_behaves_like :regexp_new_string_ascii, :compile
- it_behaves_like :regexp_new_string_ascii_8bit, :compile
+ it_behaves_like :regexp_new_string, :compile
+ it_behaves_like :regexp_new_string_binary, :compile
end
describe "Regexp.compile given a Regexp" do
- it_behaves_like :regexp_new_regexp_ascii, :compile
- it_behaves_like :regexp_new_regexp_ascii_8bit, :compile
+ it_behaves_like :regexp_new_regexp, :compile
end
diff --git a/spec/ruby/core/regexp/new_spec.rb b/spec/ruby/core/regexp/new_spec.rb
index dbac7a5a33..8259b61714 100644
--- a/spec/ruby/core/regexp/new_spec.rb
+++ b/spec/ruby/core/regexp/new_spec.rb
@@ -1,20 +1,17 @@
require_relative '../../spec_helper'
-require_relative 'shared/new_ascii'
-require_relative 'shared/new_ascii_8bit'
+require_relative 'shared/new'
describe "Regexp.new" do
- it_behaves_like :regexp_new_ascii, :new
- it_behaves_like :regexp_new_ascii_8bit, :new
+ it_behaves_like :regexp_new, :new
end
describe "Regexp.new given a String" do
- it_behaves_like :regexp_new_string_ascii, :new
- it_behaves_like :regexp_new_string_ascii_8bit, :new
+ it_behaves_like :regexp_new_string, :new
end
describe "Regexp.new given a Regexp" do
- it_behaves_like :regexp_new_regexp_ascii, :new
- it_behaves_like :regexp_new_regexp_ascii_8bit, :new
+ it_behaves_like :regexp_new_regexp, :new
+ it_behaves_like :regexp_new_string_binary, :compile
end
describe "Regexp.new given a Fixnum" do
diff --git a/spec/ruby/core/regexp/shared/new_ascii_8bit.rb b/spec/ruby/core/regexp/shared/new.rb
index 5110a08380..e8b80ad7c7 100644
--- a/spec/ruby/core/regexp/shared/new_ascii_8bit.rb
+++ b/spec/ruby/core/regexp/shared/new.rb
@@ -1,6 +1,6 @@
# -*- encoding: ascii-8bit -*-
-describe :regexp_new_ascii_8bit, shared: true do
+describe :regexp_new, shared: true do
it "requires one argument and creates a new regular expression object" do
Regexp.send(@method, '').is_a?(Regexp).should == true
end
@@ -24,7 +24,7 @@ describe :regexp_new_ascii_8bit, shared: true do
end
end
-describe :regexp_new_string_ascii_8bit, shared: true do
+describe :regexp_new_string, shared: true do
it "uses the String argument as an unescaped literal to construct a Regexp object" do
Regexp.send(@method, "^hi{2,3}fo.o$").should == /^hi{2,3}fo.o$/
end
@@ -146,6 +146,10 @@ describe :regexp_new_string_ascii_8bit, shared: true do
lambda { Regexp.send(@method, "\\") }.should raise_error(RegexpError)
end
+ it "does not raise a Regexp error if there is an escaped trailing backslash" do
+ lambda { Regexp.send(@method, "\\\\") }.should_not raise_error(RegexpError)
+ end
+
it "accepts a backspace followed by a character" do
Regexp.send(@method, "\\N").should == /#{"\x5c"+"N"}/
end
@@ -158,14 +162,6 @@ describe :regexp_new_string_ascii_8bit, shared: true do
Regexp.send(@method, "\11").should == /#{"\x09"}/
end
- it "accepts a three-digit octal value" do
- Regexp.send(@method, "\315").should == /#{"\xcd"}/
- end
-
- it "interprets a digit following a three-digit octal value as a character" do
- Regexp.send(@method, "\3762").should == /#{"\xfe2"}/
- end
-
it "accepts a one-digit hexadecimal value" do
Regexp.send(@method, "\x9n").should == /#{"\x09n"}/
end
@@ -242,118 +238,6 @@ describe :regexp_new_string_ascii_8bit, shared: true do
Regexp.send(@method, "\C-\e").should == /#{"\x1b"}/
end
- it "accepts '\\c\\n'" do
- Regexp.send(@method, "\C-\n").should == /#{"\x0a"}/
- end
-
- it "accepts '\\c\\t'" do
- Regexp.send(@method, "\C-\t").should == /#{"\x09"}/
- end
-
- it "accepts '\\c\\r'" do
- Regexp.send(@method, "\C-\r").should == /#{"\x0d"}/
- end
-
- it "accepts '\\c\\f'" do
- Regexp.send(@method, "\C-\f").should == /#{"\x0c"}/
- end
-
- it "accepts '\\c\\v'" do
- Regexp.send(@method, "\C-\v").should == /#{"\x0b"}/
- end
-
- it "accepts '\\c\\a'" do
- Regexp.send(@method, "\C-\a").should == /#{"\x07"}/
- end
-
- it "accepts '\\c\\e'" do
- Regexp.send(@method, "\C-\e").should == /#{"\x1b"}/
- end
-
- it "accepts '\\M-\\n'" do
- Regexp.send(@method, "\M-\n").should == /#{"\x8a"}/
- end
-
- it "accepts '\\M-\\t'" do
- Regexp.send(@method, "\M-\t").should == /#{"\x89"}/
- end
-
- it "accepts '\\M-\\r'" do
- Regexp.send(@method, "\M-\r").should == /#{"\x8d"}/
- end
-
- it "accepts '\\M-\\f'" do
- Regexp.send(@method, "\M-\f").should == /#{"\x8c"}/
- end
-
- it "accepts '\\M-\\v'" do
- Regexp.send(@method, "\M-\v").should == /#{"\x8b"}/
- end
-
- it "accepts '\\M-\\a'" do
- Regexp.send(@method, "\M-\a").should == /#{"\x87"}/
- end
-
- it "accepts '\\M-\\e'" do
- Regexp.send(@method, "\M-\e").should == /#{"\x9b"}/
- end
-
- it "accepts '\\M-\\C-\\n'" do
- Regexp.send(@method, "\M-\n").should == /#{"\x8a"}/
- end
-
- it "accepts '\\M-\\C-\\t'" do
- Regexp.send(@method, "\M-\t").should == /#{"\x89"}/
- end
-
- it "accepts '\\M-\\C-\\r'" do
- Regexp.send(@method, "\M-\r").should == /#{"\x8d"}/
- end
-
- it "accepts '\\M-\\C-\\f'" do
- Regexp.send(@method, "\M-\f").should == /#{"\x8c"}/
- end
-
- it "accepts '\\M-\\C-\\v'" do
- Regexp.send(@method, "\M-\v").should == /#{"\x8b"}/
- end
-
- it "accepts '\\M-\\C-\\a'" do
- Regexp.send(@method, "\M-\a").should == /#{"\x87"}/
- end
-
- it "accepts '\\M-\\C-\\e'" do
- Regexp.send(@method, "\M-\e").should == /#{"\x9b"}/
- end
-
- it "accepts '\\M-\\c\\n'" do
- Regexp.send(@method, "\M-\n").should == /#{"\x8a"}/
- end
-
- it "accepts '\\M-\\c\\t'" do
- Regexp.send(@method, "\M-\t").should == /#{"\x89"}/
- end
-
- it "accepts '\\M-\\c\\r'" do
- Regexp.send(@method, "\M-\r").should == /#{"\x8d"}/
- end
-
- it "accepts '\\M-\\c\\f'" do
- Regexp.send(@method, "\M-\f").should == /#{"\x8c"}/
- end
-
- it "accepts '\\M-\\c\\v'" do
- Regexp.send(@method, "\M-\v").should == /#{"\x8b"}/
- end
-
- it "accepts '\\M-\\c\\a'" do
- Regexp.send(@method, "\M-\a").should == /#{"\x87"}/
- end
-
- it "accepts '\\M-\\c\\e'" do
- Regexp.send(@method, "\M-\e").should == /#{"\x9b"}/
- end
-
it "accepts multiple consecutive '\\' characters" do
Regexp.send(@method, "\\\\\\N").should == /#{"\\\\\\"+"N"}/
end
@@ -494,7 +378,75 @@ describe :regexp_new_string_ascii_8bit, shared: true do
end
end
-describe :regexp_new_regexp_ascii_8bit, shared: true do
+describe :regexp_new_string_binary, shared: true do
+ describe "with escaped characters" do
+ it "accepts a three-digit octal value" do
+ Regexp.send(@method, "\315").should == /#{"\xcd"}/
+ end
+
+ it "interprets a digit following a three-digit octal value as a character" do
+ Regexp.send(@method, "\3762").should == /#{"\xfe2"}/
+ end
+
+ it "accepts '\\M-\\n'" do
+ Regexp.send(@method, "\M-\n").should == /#{"\x8a"}/
+ end
+
+ it "accepts '\\M-\\t'" do
+ Regexp.send(@method, "\M-\t").should == /#{"\x89"}/
+ end
+
+ it "accepts '\\M-\\r'" do
+ Regexp.send(@method, "\M-\r").should == /#{"\x8d"}/
+ end
+
+ it "accepts '\\M-\\f'" do
+ Regexp.send(@method, "\M-\f").should == /#{"\x8c"}/
+ end
+
+ it "accepts '\\M-\\v'" do
+ Regexp.send(@method, "\M-\v").should == /#{"\x8b"}/
+ end
+
+ it "accepts '\\M-\\a'" do
+ Regexp.send(@method, "\M-\a").should == /#{"\x87"}/
+ end
+
+ it "accepts '\\M-\\e'" do
+ Regexp.send(@method, "\M-\e").should == /#{"\x9b"}/
+ end
+
+ it "accepts '\\M-\\C-\\n'" do
+ Regexp.send(@method, "\M-\C-\n").should == /#{"\x8a"}/
+ end
+
+ it "accepts '\\M-\\C-\\t'" do
+ Regexp.send(@method, "\M-\C-\t").should == /#{"\x89"}/
+ end
+
+ it "accepts '\\M-\\C-\\r'" do
+ Regexp.send(@method, "\M-\C-\r").should == /#{"\x8d"}/
+ end
+
+ it "accepts '\\M-\\C-\\f'" do
+ Regexp.send(@method, "\M-\C-\f").should == /#{"\x8c"}/
+ end
+
+ it "accepts '\\M-\\C-\\v'" do
+ Regexp.send(@method, "\M-\C-\v").should == /#{"\x8b"}/
+ end
+
+ it "accepts '\\M-\\C-\\a'" do
+ Regexp.send(@method, "\M-\C-\a").should == /#{"\x87"}/
+ end
+
+ it "accepts '\\M-\\C-\\e'" do
+ Regexp.send(@method, "\M-\C-\e").should == /#{"\x9b"}/
+ end
+ end
+end
+
+describe :regexp_new_regexp, shared: true do
it "uses the argument as a literal to construct a Regexp object" do
Regexp.send(@method, /^hi{2,3}fo.o$/).should == /^hi{2,3}fo.o$/
end
diff --git a/spec/ruby/core/regexp/shared/new_ascii.rb b/spec/ruby/core/regexp/shared/new_ascii.rb
deleted file mode 100644
index 98c458312e..0000000000
--- a/spec/ruby/core/regexp/shared/new_ascii.rb
+++ /dev/null
@@ -1,464 +0,0 @@
-# -*- encoding: binary -*-
-describe :regexp_new_ascii, shared: true do
- it "requires one argument and creates a new regular expression object" do
- Regexp.send(@method, '').is_a?(Regexp).should == true
- end
-
- it "works by default for subclasses with overridden #initialize" do
- class RegexpSpecsSubclass < Regexp
- def initialize(*args)
- super
- @args = args
- end
-
- attr_accessor :args
- end
-
- class RegexpSpecsSubclassTwo < Regexp; end
-
- RegexpSpecsSubclass.send(@method, "hi").should be_kind_of(RegexpSpecsSubclass)
- RegexpSpecsSubclass.send(@method, "hi").args.first.should == "hi"
-
- RegexpSpecsSubclassTwo.send(@method, "hi").should be_kind_of(RegexpSpecsSubclassTwo)
- end
-end
-
-describe :regexp_new_string_ascii, shared: true do
- it "uses the String argument as an unescaped literal to construct a Regexp object" do
- Regexp.send(@method, "^hi{2,3}fo.o$").should == /^hi{2,3}fo.o$/
- end
-
- it "raises a RegexpError when passed an incorrect regexp" do
- lambda { Regexp.send(@method, "^[$", 0) }.should raise_error(RegexpError)
- end
-
- it "does not set Regexp options if only given one argument" do
- r = Regexp.send(@method, 'Hi')
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
- end
-
- it "does not set Regexp options if second argument is nil or false" do
- r = Regexp.send(@method, 'Hi', nil)
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
-
- r = Regexp.send(@method, 'Hi', false)
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
- end
-
- it "sets options from second argument if it is one of the Fixnum option constants" do
- r = Regexp.send(@method, 'Hi', Regexp::IGNORECASE)
- (r.options & Regexp::IGNORECASE).should_not == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
-
- r = Regexp.send(@method, 'Hi', Regexp::MULTILINE)
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should_not == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
-
- not_supported_on :opal do
- r = Regexp.send(@method, 'Hi', Regexp::EXTENDED)
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should == 0
- (r.options & Regexp::EXTENDED).should_not == 1
- end
- end
-
- it "accepts a Fixnum of two or more options ORed together as the second argument" do
- r = Regexp.send(@method, 'Hi', Regexp::IGNORECASE | Regexp::EXTENDED)
- (r.options & Regexp::IGNORECASE).should_not == 0
- (r.options & Regexp::MULTILINE).should == 0
- (r.options & Regexp::EXTENDED).should_not == 0
- end
-
- it "treats any non-Fixnum, non-nil, non-false second argument as IGNORECASE" do
- r = Regexp.send(@method, 'Hi', Object.new)
- (r.options & Regexp::IGNORECASE).should_not == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
- end
-
- it "ignores the third argument if it is 'e' or 'euc' (case-insensitive)" do
- lambda {
- Regexp.send(@method, 'Hi', nil, 'e').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'euc').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'E').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'EUC').encoding.should == Encoding::US_ASCII
- }.should complain(/encoding option is ignored/)
- end
-
- it "ignores the third argument if it is 's' or 'sjis' (case-insensitive)" do
- lambda {
- Regexp.send(@method, 'Hi', nil, 's').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'sjis').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'S').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'SJIS').encoding.should == Encoding::US_ASCII
- }.should complain(/encoding option is ignored/)
- end
-
- it "ignores the third argument if it is 'u' or 'utf8' (case-insensitive)" do
- lambda {
- Regexp.send(@method, 'Hi', nil, 'u').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'utf8').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'U').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'UTF8').encoding.should == Encoding::US_ASCII
- }.should complain(/encoding option is ignored/)
- end
-
- it "uses US_ASCII encoding if third argument is 'n' or 'none' (case insensitive) and only ascii characters" do
- Regexp.send(@method, 'Hi', nil, 'n').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'none').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'N').encoding.should == Encoding::US_ASCII
- Regexp.send(@method, 'Hi', nil, 'NONE').encoding.should == Encoding::US_ASCII
- end
-
- it "uses ASCII_8BIT encoding if third argument is 'n' or 'none' (case insensitive) and non-ascii characters" do
- a = "(?:[\x8E\xA1-\xFE])"
- str = "\A(?:#{a}|x*)\z"
-
- Regexp.send(@method, str, nil, 'N').encoding.should == Encoding::ASCII_8BIT
- Regexp.send(@method, str, nil, 'n').encoding.should == Encoding::ASCII_8BIT
- Regexp.send(@method, str, nil, 'none').encoding.should == Encoding::ASCII_8BIT
- Regexp.send(@method, str, nil, 'NONE').encoding.should == Encoding::ASCII_8BIT
- end
-
- describe "with escaped characters" do
- it "raises a Regexp error if there is a trailing backslash" do
- lambda { Regexp.send(@method, "\\") }.should raise_error(RegexpError)
- end
-
- it "does not raise a Regexp error if there is an escaped trailing backslash" do
- lambda { Regexp.send(@method, "\\\\") }.should_not raise_error(RegexpError)
- end
-
- it "accepts a backspace followed by a character" do
- Regexp.send(@method, "\\N").should == /#{"\x5c"+"N"}/
- end
-
- it "accepts a one-digit octal value" do
- Regexp.send(@method, "\0").should == /#{"\x00"}/
- end
-
- it "accepts a two-digit octal value" do
- Regexp.send(@method, "\11").should == /#{"\x09"}/
- end
-
- it "accepts a one-digit hexadecimal value" do
- Regexp.send(@method, "\x9n").should == /#{"\x09n"}/
- end
-
- it "accepts a two-digit hexadecimal value" do
- Regexp.send(@method, "\x23").should == /#{"\x23"}/
- end
-
- it "interprets a digit following a two-digit hexadecimal value as a character" do
- Regexp.send(@method, "\x420").should == /#{"\x420"}/
- end
-
- it "raises a RegexpError if \\x is not followed by any hexadecimal digits" do
- lambda { Regexp.send(@method, "\\" + "xn") }.should raise_error(RegexpError)
- end
-
- it "accepts an escaped string interpolation" do
- Regexp.send(@method, "\#{abc}").should == /#{"\#{abc}"}/
- end
-
- it "accepts '\\n'" do
- Regexp.send(@method, "\n").should == /#{"\x0a"}/
- end
-
- it "accepts '\\t'" do
- Regexp.send(@method, "\t").should == /#{"\x09"}/
- end
-
- it "accepts '\\r'" do
- Regexp.send(@method, "\r").should == /#{"\x0d"}/
- end
-
- it "accepts '\\f'" do
- Regexp.send(@method, "\f").should == /#{"\x0c"}/
- end
-
- it "accepts '\\v'" do
- Regexp.send(@method, "\v").should == /#{"\x0b"}/
- end
-
- it "accepts '\\a'" do
- Regexp.send(@method, "\a").should == /#{"\x07"}/
- end
-
- it "accepts '\\e'" do
- Regexp.send(@method, "\e").should == /#{"\x1b"}/
- end
-
- it "accepts '\\C-\\n'" do
- Regexp.send(@method, "\C-\n").should == /#{"\x0a"}/
- end
-
- it "accepts '\\C-\\t'" do
- Regexp.send(@method, "\C-\t").should == /#{"\x09"}/
- end
-
- it "accepts '\\C-\\r'" do
- Regexp.send(@method, "\C-\r").should == /#{"\x0d"}/
- end
-
- it "accepts '\\C-\\f'" do
- Regexp.send(@method, "\C-\f").should == /#{"\x0c"}/
- end
-
- it "accepts '\\C-\\v'" do
- Regexp.send(@method, "\C-\v").should == /#{"\x0b"}/
- end
-
- it "accepts '\\C-\\a'" do
- Regexp.send(@method, "\C-\a").should == /#{"\x07"}/
- end
-
- it "accepts '\\C-\\e'" do
- Regexp.send(@method, "\C-\e").should == /#{"\x1b"}/
- end
-
- it "accepts '\\c\\n'" do
- Regexp.send(@method, "\C-\n").should == /#{"\x0a"}/
- end
-
- it "accepts '\\c\\t'" do
- Regexp.send(@method, "\C-\t").should == /#{"\x09"}/
- end
-
- it "accepts '\\c\\r'" do
- Regexp.send(@method, "\C-\r").should == /#{"\x0d"}/
- end
-
- it "accepts '\\c\\f'" do
- Regexp.send(@method, "\C-\f").should == /#{"\x0c"}/
- end
-
- it "accepts '\\c\\v'" do
- Regexp.send(@method, "\C-\v").should == /#{"\x0b"}/
- end
-
- it "accepts '\\c\\a'" do
- Regexp.send(@method, "\C-\a").should == /#{"\x07"}/
- end
-
- it "accepts '\\c\\e'" do
- Regexp.send(@method, "\C-\e").should == /#{"\x1b"}/
- end
-
- it "accepts multiple consecutive '\\' characters" do
- Regexp.send(@method, "\\\\\\N").should == /#{"\\\\\\"+"N"}/
- end
-
- it "accepts characters and escaped octal digits" do
- Regexp.send(@method, "abc\076").should == /#{"abc\x3e"}/
- end
-
- it "accepts escaped octal digits and characters" do
- Regexp.send(@method, "\076abc").should == /#{"\x3eabc"}/
- end
-
- it "accepts characters and escaped hexadecimal digits" do
- Regexp.send(@method, "abc\x42").should == /#{"abc\x42"}/
- end
-
- it "accepts escaped hexadecimal digits and characters" do
- Regexp.send(@method, "\x3eabc").should == /#{"\x3eabc"}/
- end
-
- it "accepts escaped hexadecimal and octal digits" do
- Regexp.send(@method, "\061\x42").should == /#{"\x31\x42"}/
- end
-
- it "accepts \\u{H} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{f}").should == /#{"\x0f"}/
- end
-
- it "accepts \\u{HH} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{7f}").should == /#{"\x7f"}/
- end
-
- it "accepts \\u{HHH} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{07f}").should == /#{"\x7f"}/
- end
-
- it "accepts \\u{HHHH} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{0000}").should == /#{"\x00"}/
- end
-
- it "accepts \\u{HHHHH} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{00001}").should == /#{"\x01"}/
- end
-
- it "accepts \\u{HHHHHH} for a single Unicode codepoint" do
- Regexp.send(@method, "\u{000000}").should == /#{"\x00"}/
- end
-
- it "accepts characters followed by \\u{HHHH}" do
- Regexp.send(@method, "abc\u{3042}").should == /#{"abc\u3042"}/
- end
-
- it "accepts \\u{HHHH} followed by characters" do
- Regexp.send(@method, "\u{3042}abc").should == /#{"\u3042abc"}/
- end
-
- it "accepts escaped hexadecimal digits followed by \\u{HHHH}" do
- Regexp.send(@method, "\x42\u{3042}").should == /#{"\x42\u3042"}/
- end
-
- it "accepts escaped octal digits followed by \\u{HHHH}" do
- Regexp.send(@method, "\056\u{3042}").should == /#{"\x2e\u3042"}/
- end
-
- it "accepts a combination of escaped octal and hexadecimal digits and \\u{HHHH}" do
- Regexp.send(@method, "\056\x42\u{3042}\x52\076").should == /#{"\x2e\x42\u3042\x52\x3e"}/
- end
-
- it "accepts \\uHHHH for a single Unicode codepoint" do
- Regexp.send(@method, "\u3042").should == /#{"\u3042"}/
- end
-
- it "accepts characters followed by \\uHHHH" do
- Regexp.send(@method, "abc\u3042").should == /#{"abc\u3042"}/
- end
-
- it "accepts \\uHHHH followed by characters" do
- Regexp.send(@method, "\u3042abc").should == /#{"\u3042abc"}/
- end
-
- it "accepts escaped hexadecimal digits followed by \\uHHHH" do
- Regexp.send(@method, "\x42\u3042").should == /#{"\x42\u3042"}/
- end
-
- it "accepts escaped octal digits followed by \\uHHHH" do
- Regexp.send(@method, "\056\u3042").should == /#{"\x2e\u3042"}/
- end
-
- it "accepts a combination of escaped octal and hexadecimal digits and \\uHHHH" do
- Regexp.send(@method, "\056\x42\u3042\x52\076").should == /#{"\x2e\x42\u3042\x52\x3e"}/
- end
-
- it "raises a RegexpError if less than four digits are given for \\uHHHH" do
- lambda { Regexp.send(@method, "\\" + "u304") }.should raise_error(RegexpError)
- end
-
- it "raises a RegexpError if the \\u{} escape is empty" do
- lambda { Regexp.send(@method, "\\" + "u{}") }.should raise_error(RegexpError)
- end
-
- it "raises a RegexpError if more than six hexadecimal digits are given" do
- lambda { Regexp.send(@method, "\\" + "u{0ffffff}") }.should raise_error(RegexpError)
- end
-
- it "returns a Regexp with US-ASCII encoding if only 7-bit ASCII characters are present regardless of the input String's encoding" do
- Regexp.send(@method, "abc").encoding.should == Encoding::US_ASCII
- end
-
- it "returns a Regexp with source String having US-ASCII encoding if only 7-bit ASCII characters are present regardless of the input String's encoding" do
- Regexp.send(@method, "abc").source.encoding.should == Encoding::US_ASCII
- end
-
- it "returns a Regexp with US-ASCII encoding if UTF-8 escape sequences using only 7-bit ASCII are present" do
- Regexp.send(@method, "\u{61}").encoding.should == Encoding::US_ASCII
- end
-
- it "returns a Regexp with source String having US-ASCII encoding if UTF-8 escape sequences using only 7-bit ASCII are present" do
- Regexp.send(@method, "\u{61}").source.encoding.should == Encoding::US_ASCII
- end
-
- it "returns a Regexp with UTF-8 encoding if any UTF-8 escape sequences outside 7-bit ASCII are present" do
- Regexp.send(@method, "\u{ff}").encoding.should == Encoding::UTF_8
- end
-
- it "returns a Regexp with source String having UTF-8 encoding if any UTF-8 escape sequences outside 7-bit ASCII are present" do
- Regexp.send(@method, "\u{ff}").source.encoding.should == Encoding::UTF_8
- end
-
- it "returns a Regexp with the input String's encoding" do
- str = "\x82\xa0".force_encoding(Encoding::Shift_JIS)
- Regexp.send(@method, str).encoding.should == Encoding::Shift_JIS
- end
-
- it "returns a Regexp with source String having the input String's encoding" do
- str = "\x82\xa0".force_encoding(Encoding::Shift_JIS)
- Regexp.send(@method, str).source.encoding.should == Encoding::Shift_JIS
- end
- end
-end
-
-describe :regexp_new_regexp_ascii, shared: true do
- it "uses the argument as a literal to construct a Regexp object" do
- Regexp.send(@method, /^hi{2,3}fo.o$/).should == /^hi{2,3}fo.o$/
- end
-
- it "preserves any options given in the Regexp literal" do
- (Regexp.send(@method, /Hi/i).options & Regexp::IGNORECASE).should_not == 0
- (Regexp.send(@method, /Hi/m).options & Regexp::MULTILINE).should_not == 0
- not_supported_on :opal do
- (Regexp.send(@method, /Hi/x).options & Regexp::EXTENDED).should_not == 0
- end
-
- not_supported_on :opal do
- r = Regexp.send @method, /Hi/imx
- (r.options & Regexp::IGNORECASE).should_not == 0
- (r.options & Regexp::MULTILINE).should_not == 0
- (r.options & Regexp::EXTENDED).should_not == 0
- end
-
- r = Regexp.send @method, /Hi/
- (r.options & Regexp::IGNORECASE).should == 0
- (r.options & Regexp::MULTILINE).should == 0
- not_supported_on :opal do
- (r.options & Regexp::EXTENDED).should == 0
- end
- end
-
- it "does not honour options given as additional arguments" do
- r = nil
- lambda {
- r = Regexp.send @method, /hi/, Regexp::IGNORECASE
- }.should complain(/flags ignored/)
- (r.options & Regexp::IGNORECASE).should == 0
- end
-
- not_supported_on :opal do
- it "sets the encoding to UTF-8 if the Regexp literal has the 'u' option" do
- Regexp.send(@method, /Hi/u).encoding.should == Encoding::UTF_8
- end
-
- it "sets the encoding to EUC-JP if the Regexp literal has the 'e' option" do
- Regexp.send(@method, /Hi/e).encoding.should == Encoding::EUC_JP
- end
-
- it "sets the encoding to Windows-31J if the Regexp literal has the 's' option" do
- Regexp.send(@method, /Hi/s).encoding.should == Encoding::Windows_31J
- end
-
- it "sets the encoding to US-ASCII if the Regexp literal has the 'n' option and the source String is ASCII only" do
- Regexp.send(@method, /Hi/n).encoding.should == Encoding::US_ASCII
- end
-
- it "sets the encoding to source String's encoding if the Regexp literal has the 'n' option and the source String is not ASCII only" do
- Regexp.send(@method, Regexp.new("\\xff", nil, 'n')).encoding.should == Encoding::ASCII_8BIT
- end
- end
-end
diff --git a/spec/ruby/core/string/uminus_spec.rb b/spec/ruby/core/string/uminus_spec.rb
index fd9e8c1d52..dace04846c 100644
--- a/spec/ruby/core/string/uminus_spec.rb
+++ b/spec/ruby/core/string/uminus_spec.rb
@@ -41,6 +41,23 @@ describe 'String#-@' do
(-dynamic).should_not equal("this string is frozen".freeze)
(-dynamic).should_not equal(-"this string is frozen".freeze)
+ (-dynamic).should == "this string is frozen"
+ end
+
+ it "does not deduplicate tainted strings" do
+ dynamic = %w(this string is frozen).join(' ')
+ dynamic.taint
+ (-dynamic).should_not equal("this string is frozen".freeze)
+ (-dynamic).should_not equal(-"this string is frozen".freeze)
+ (-dynamic).should == "this string is frozen"
+ end
+
+ it "does not deduplicate strings with additional instance variables" do
+ dynamic = %w(this string is frozen).join(' ')
+ dynamic.instance_variable_set(:@foo, :bar)
+ (-dynamic).should_not equal("this string is frozen".freeze)
+ (-dynamic).should_not equal(-"this string is frozen".freeze)
+ (-dynamic).should == "this string is frozen"
end
end