mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory. [Misc #13792] [ruby-core:82287] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
75bfc6440d
commit
1d15d5f080
4370 changed files with 0 additions and 0 deletions
82
spec/ruby/core/string/shared/chars.rb
Normal file
82
spec/ruby/core/string/shared/chars.rb
Normal file
|
@ -0,0 +1,82 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe :string_chars, shared: true do
|
||||
it "passes each char in self to the given block" do
|
||||
a = []
|
||||
"hello".send(@method) { |c| a << c }
|
||||
a.should == ['h', 'e', 'l', 'l', 'o']
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
s = StringSpecs::MyString.new "hello"
|
||||
s.send(@method){}.should equal(s)
|
||||
end
|
||||
|
||||
|
||||
it "is unicode aware" do
|
||||
"\303\207\342\210\202\303\251\306\222g".send(@method).to_a.should ==
|
||||
["\303\207", "\342\210\202", "\303\251", "\306\222", "g"]
|
||||
end
|
||||
|
||||
with_feature :encoding do
|
||||
it "returns characters in the same encoding as self" do
|
||||
"&%".force_encoding('Shift_JIS').send(@method).to_a.all? {|c| c.encoding.name.should == 'Shift_JIS'}
|
||||
"&%".encode('ASCII-8BIT').send(@method).to_a.all? {|c| c.encoding.name.should == 'ASCII-8BIT'}
|
||||
end
|
||||
|
||||
it "works with multibyte characters" do
|
||||
s = "\u{8987}".force_encoding("UTF-8")
|
||||
s.bytesize.should == 3
|
||||
s.send(@method).to_a.should == [s]
|
||||
end
|
||||
|
||||
it "works if the String's contents is invalid for its encoding" do
|
||||
xA4 = [0xA4].pack('C')
|
||||
xA4.force_encoding('UTF-8')
|
||||
xA4.valid_encoding?.should be_false
|
||||
xA4.send(@method).to_a.should == [xA4.force_encoding("UTF-8")]
|
||||
end
|
||||
|
||||
it "returns a different character if the String is transcoded" do
|
||||
s = "\u{20AC}".force_encoding('UTF-8')
|
||||
s.encode('UTF-8').send(@method).to_a.should == ["\u{20AC}".force_encoding('UTF-8')]
|
||||
s.encode('iso-8859-15').send(@method).to_a.should == [
|
||||
[0xA4].pack('C').force_encoding('iso-8859-15')]
|
||||
s.encode('iso-8859-15').encode('UTF-8').send(@method).to_a.should == [
|
||||
"\u{20AC}".force_encoding('UTF-8')]
|
||||
end
|
||||
|
||||
it "uses the String's encoding to determine what characters it contains" do
|
||||
s = "\u{24B62}"
|
||||
|
||||
s.force_encoding('UTF-8').send(@method).to_a.should == [
|
||||
s.force_encoding('UTF-8')
|
||||
]
|
||||
s.force_encoding('BINARY').send(@method).to_a.should == [
|
||||
[0xF0].pack('C').force_encoding('BINARY'),
|
||||
[0xA4].pack('C').force_encoding('BINARY'),
|
||||
[0xAD].pack('C').force_encoding('BINARY'),
|
||||
[0xA2].pack('C').force_encoding('BINARY')
|
||||
]
|
||||
s.force_encoding('SJIS').send(@method).to_a.should == [
|
||||
[0xF0,0xA4].pack('CC').force_encoding('SJIS'),
|
||||
[0xAD].pack('C').force_encoding('SJIS'),
|
||||
[0xA2].pack('C').force_encoding('SJIS')
|
||||
]
|
||||
end
|
||||
|
||||
it "taints resulting strings when self is tainted" do
|
||||
str = "hello"
|
||||
|
||||
str.send(@method) do |x|
|
||||
x.tainted?.should == false
|
||||
end
|
||||
|
||||
str.dup.taint.send(@method) do |x|
|
||||
x.tainted?.should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
56
spec/ruby/core/string/shared/codepoints.rb
Normal file
56
spec/ruby/core/string/shared/codepoints.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
# -*- encoding: binary -*-
|
||||
describe :string_codepoints, shared: true do
|
||||
it "raises an ArgumentError when self has an invalid encoding and a method is called on the returned Enumerator" do
|
||||
s = "\xDF".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
lambda { s.send(@method).to_a }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "yields each codepoint to the block if one is given" do
|
||||
codepoints = []
|
||||
"abcd".send(@method) do |codepoint|
|
||||
codepoints << codepoint
|
||||
end
|
||||
codepoints.should == [97, 98, 99, 100]
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if self's encoding is invalid and a block is given" do
|
||||
s = "\xDF".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
lambda { s.send(@method) { } }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "returns codepoints as Fixnums" do
|
||||
"glark\u{20}".send(@method).to_a.each do |codepoint|
|
||||
codepoint.should be_an_instance_of(Fixnum)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns one codepoint for each character" do
|
||||
s = "\u{9876}\u{28}\u{1987}"
|
||||
s.send(@method).to_a.size.should == s.chars.to_a.size
|
||||
end
|
||||
|
||||
it "works for multibyte characters" do
|
||||
s = "\u{9819}"
|
||||
s.bytesize.should == 3
|
||||
s.send(@method).to_a.should == [38937]
|
||||
end
|
||||
|
||||
it "returns the codepoint corresponding to the character's position in the String's encoding" do
|
||||
"\u{787}".send(@method).to_a.should == [1927]
|
||||
end
|
||||
|
||||
it "round-trips to the original String using Integer#chr" do
|
||||
s = "\u{13}\u{7711}\u{1010}"
|
||||
s2 = ""
|
||||
s.send(@method) {|n| s2 << n.chr(Encoding::UTF_8)}
|
||||
s.should == s2
|
||||
end
|
||||
|
||||
it "is synonomous with #bytes for Strings which are single-byte optimisable" do
|
||||
s = "(){}".encode('ascii')
|
||||
s.ascii_only?.should be_true
|
||||
s.send(@method).to_a.should == s.bytes.to_a
|
||||
end
|
||||
end
|
160
spec/ruby/core/string/shared/concat.rb
Normal file
160
spec/ruby/core/string/shared/concat.rb
Normal file
|
@ -0,0 +1,160 @@
|
|||
describe :string_concat, shared: true do
|
||||
it "concatenates the given argument to self and returns self" do
|
||||
str = 'hello '
|
||||
str.send(@method, 'world').should equal(str)
|
||||
str.should == "hello world"
|
||||
end
|
||||
|
||||
it "converts the given argument to a String using to_str" do
|
||||
obj = mock('world!')
|
||||
obj.should_receive(:to_str).and_return("world!")
|
||||
a = 'hello '.send(@method, obj)
|
||||
a.should == 'hello world!'
|
||||
end
|
||||
|
||||
it "raises a TypeError if the given argument can't be converted to a String" do
|
||||
lambda { 'hello '.send(@method, []) }.should raise_error(TypeError)
|
||||
lambda { 'hello '.send(@method, mock('x')) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError when self is frozen" do
|
||||
a = "hello"
|
||||
a.freeze
|
||||
|
||||
lambda { a.send(@method, "") }.should raise_error(RuntimeError)
|
||||
lambda { a.send(@method, "test") }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "returns a String when given a subclass instance" do
|
||||
a = "hello"
|
||||
a.send(@method, StringSpecs::MyString.new(" world"))
|
||||
a.should == "hello world"
|
||||
a.should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "returns an instance of same class when called on a subclass" do
|
||||
str = StringSpecs::MyString.new("hello")
|
||||
str.send(@method, " world")
|
||||
str.should == "hello world"
|
||||
str.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "taints self if other is tainted" do
|
||||
"x".send(@method, "".taint).tainted?.should == true
|
||||
"x".send(@method, "y".taint).tainted?.should == true
|
||||
end
|
||||
|
||||
it "untrusts self if other is untrusted" do
|
||||
"x".send(@method, "".untrust).untrusted?.should == true
|
||||
"x".send(@method, "y".untrust).untrusted?.should == true
|
||||
end
|
||||
|
||||
describe "with Integer" do
|
||||
it "concatencates the argument interpreted as a codepoint" do
|
||||
b = "".send(@method, 33)
|
||||
b.should == "!"
|
||||
|
||||
b.encode!(Encoding::UTF_8)
|
||||
b.send(@method, 0x203D)
|
||||
b.should == "!\u203D"
|
||||
end
|
||||
|
||||
# #5855
|
||||
it "returns a ASCII-8BIT string if self is US-ASCII and the argument is between 128-255 (inclusive)" do
|
||||
a = ("".encode(Encoding::US_ASCII).send(@method, 128))
|
||||
a.encoding.should == Encoding::ASCII_8BIT
|
||||
a.should == 128.chr
|
||||
|
||||
a = ("".encode(Encoding::US_ASCII).send(@method, 255))
|
||||
a.encoding.should == Encoding::ASCII_8BIT
|
||||
a.should == 255.chr
|
||||
end
|
||||
|
||||
it "raises RangeError if the argument is an invalid codepoint for self's encoding" do
|
||||
lambda { "".encode(Encoding::US_ASCII).send(@method, 256) }.should raise_error(RangeError)
|
||||
lambda { "".encode(Encoding::EUC_JP).send(@method, 0x81) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "raises RangeError if the argument is negative" do
|
||||
lambda { "".send(@method, -200) }.should raise_error(RangeError)
|
||||
lambda { "".send(@method, -bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "doesn't call to_int on its argument" do
|
||||
x = mock('x')
|
||||
x.should_not_receive(:to_int)
|
||||
|
||||
lambda { "".send(@method, x) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError when self is frozen" do
|
||||
a = "hello"
|
||||
a.freeze
|
||||
|
||||
lambda { a.send(@method, 0) }.should raise_error(RuntimeError)
|
||||
lambda { a.send(@method, 33) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_concat_encoding, shared: true do
|
||||
describe "when self is in an ASCII-incompatible encoding incompatible with the argument's encoding" do
|
||||
it "uses self's encoding if both are empty" do
|
||||
"".encode("UTF-16LE").send(@method, "").encoding.should == Encoding::UTF_16LE
|
||||
end
|
||||
|
||||
it "uses self's encoding if the argument is empty" do
|
||||
"x".encode("UTF-16LE").send(@method, "").encoding.should == Encoding::UTF_16LE
|
||||
end
|
||||
|
||||
it "uses the argument's encoding if self is empty" do
|
||||
"".encode("UTF-16LE").send(@method, "x".encode("UTF-8")).encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "raises Encoding::CompatibilityError if neither are empty" do
|
||||
lambda { "x".encode("UTF-16LE").send(@method, "y".encode("UTF-8")) }.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the argument is in an ASCII-incompatible encoding incompatible with self's encoding" do
|
||||
it "uses self's encoding if both are empty" do
|
||||
"".encode("UTF-8").send(@method, "".encode("UTF-16LE")).encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "uses self's encoding if the argument is empty" do
|
||||
"x".encode("UTF-8").send(@method, "".encode("UTF-16LE")).encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "uses the argument's encoding if self is empty" do
|
||||
"".encode("UTF-8").send(@method, "x".encode("UTF-16LE")).encoding.should == Encoding::UTF_16LE
|
||||
end
|
||||
|
||||
it "raises Encoding::CompatibilityError if neither are empty" do
|
||||
lambda { "x".encode("UTF-8").send(@method, "y".encode("UTF-16LE")) }.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when self and the argument are in different ASCII-compatible encodings" do
|
||||
it "uses self's encoding if both are ASCII-only" do
|
||||
"abc".encode("UTF-8").send(@method, "123".encode("SHIFT_JIS")).encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "uses self's encoding if the argument is ASCII-only" do
|
||||
"\u00E9".encode("UTF-8").send(@method, "123".encode("ISO-8859-1")).encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "uses the argument's encoding if self is ASCII-only" do
|
||||
"abc".encode("UTF-8").send(@method, "\u00E9".encode("ISO-8859-1")).encoding.should == Encoding::ISO_8859_1
|
||||
end
|
||||
|
||||
it "raises Encoding::CompatibilityError if neither are ASCII-only" do
|
||||
lambda { "\u00E9".encode("UTF-8").send(@method, "\u00E9".encode("ISO-8859-1")) }.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when self is ASCII-8BIT and argument is US-ASCII" do
|
||||
it "uses ASCII-8BIT encoding" do
|
||||
"abc".encode("ASCII-8BIT").send(@method, "123".encode("US-ASCII")).encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
end
|
||||
end
|
26
spec/ruby/core/string/shared/each_char_without_block.rb
Normal file
26
spec/ruby/core/string/shared/each_char_without_block.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe :string_each_char_without_block, shared: true do
|
||||
describe "when no block is given" do
|
||||
it "returns an enumerator" do
|
||||
enum = "hello".send(@method)
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
enum.to_a.should == ['h', 'e', 'l', 'l', 'o']
|
||||
end
|
||||
|
||||
describe "returned enumerator" do
|
||||
describe "size" do
|
||||
it "should return the size of the string" do
|
||||
str = "hello"
|
||||
str.send(@method).size.should == str.size
|
||||
str = "ola"
|
||||
str.send(@method).size.should == str.size
|
||||
str = "\303\207\342\210\202\303\251\306\222g"
|
||||
str.send(@method).size.should == str.size
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
33
spec/ruby/core/string/shared/each_codepoint_without_block.rb
Normal file
33
spec/ruby/core/string/shared/each_codepoint_without_block.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# -*- encoding: binary -*-
|
||||
describe :string_each_codepoint_without_block, shared: true do
|
||||
describe "when no block is given" do
|
||||
it "returns an Enumerator" do
|
||||
"".send(@method).should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
it "returns an Enumerator even when self has an invalid encoding" do
|
||||
s = "\xDF".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
s.send(@method).should be_an_instance_of(Enumerator)
|
||||
end
|
||||
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "should return the size of the string" do
|
||||
str = "hello"
|
||||
str.send(@method).size.should == str.size
|
||||
str = "ola"
|
||||
str.send(@method).size.should == str.size
|
||||
str = "\303\207\342\210\202\303\251\306\222g"
|
||||
str.send(@method).size.should == str.size
|
||||
end
|
||||
|
||||
it "should return the size of the string even when the string has an invalid encoding" do
|
||||
s = "\xDF".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
s.send(@method).size.should == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
136
spec/ruby/core/string/shared/each_line.rb
Normal file
136
spec/ruby/core/string/shared/each_line.rb
Normal file
|
@ -0,0 +1,136 @@
|
|||
describe :string_each_line, shared: true do
|
||||
it "splits using default newline separator when none is specified" do
|
||||
a = []
|
||||
"one\ntwo\r\nthree".send(@method) { |s| a << s }
|
||||
a.should == ["one\n", "two\r\n", "three"]
|
||||
|
||||
b = []
|
||||
"hello\n\n\nworld".send(@method) { |s| b << s }
|
||||
b.should == ["hello\n", "\n", "\n", "world"]
|
||||
|
||||
c = []
|
||||
"\n\n\n\n\n".send(@method) {|s| c << s}
|
||||
c.should == ["\n", "\n", "\n", "\n", "\n"]
|
||||
end
|
||||
|
||||
it "splits self using the supplied record separator and passes each substring to the block" do
|
||||
a = []
|
||||
"one\ntwo\r\nthree".send(@method, "\n") { |s| a << s }
|
||||
a.should == ["one\n", "two\r\n", "three"]
|
||||
|
||||
b = []
|
||||
"hello\nworld".send(@method, 'l') { |s| b << s }
|
||||
b.should == [ "hel", "l", "o\nworl", "d" ]
|
||||
|
||||
c = []
|
||||
"hello\n\n\nworld".send(@method, "\n") { |s| c << s }
|
||||
c.should == ["hello\n", "\n", "\n", "world"]
|
||||
end
|
||||
|
||||
it "taints substrings that are passed to the block if self is tainted" do
|
||||
"one\ntwo\r\nthree".taint.send(@method) { |s| s.tainted?.should == true }
|
||||
|
||||
"x.y.".send(@method, ".".taint) { |s| s.tainted?.should == false }
|
||||
end
|
||||
|
||||
it "passes self as a whole to the block if the separator is nil" do
|
||||
a = []
|
||||
"one\ntwo\r\nthree".send(@method, nil) { |s| a << s }
|
||||
a.should == ["one\ntwo\r\nthree"]
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.5' do
|
||||
it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do
|
||||
a = []
|
||||
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
|
||||
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n"]
|
||||
|
||||
a = []
|
||||
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
|
||||
a.should == ["hello\nworld\n\n\n", "and\nuniverse\n\n\n\n\n", "dog"]
|
||||
end
|
||||
end
|
||||
|
||||
quarantine! do # Currently fails on Travis
|
||||
ruby_version_is '2.5' do
|
||||
it "yields paragraphs (broken by 2 or more successive newlines) when passed ''" do
|
||||
a = []
|
||||
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\n".send(@method, '') { |s| a << s }
|
||||
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n"]
|
||||
|
||||
a = []
|
||||
"hello\nworld\n\n\nand\nuniverse\n\n\n\n\ndog".send(@method, '') { |s| a << s }
|
||||
a.should == ["hello\nworld\n\n", "and\nuniverse\n\n", "dog"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "uses $/" do
|
||||
before :each do
|
||||
@before_separator = $/
|
||||
end
|
||||
|
||||
after :each do
|
||||
$/ = @before_separator
|
||||
end
|
||||
|
||||
it "as the separator when none is given" do
|
||||
[
|
||||
"", "x", "x\ny", "x\ry", "x\r\ny", "x\n\r\r\ny",
|
||||
"hello hullo bello"
|
||||
].each do |str|
|
||||
["", "llo", "\n", "\r", nil].each do |sep|
|
||||
expected = []
|
||||
str.send(@method, sep) { |x| expected << x }
|
||||
|
||||
$/ = sep
|
||||
|
||||
actual = []
|
||||
str.send(@method) { |x| actual << x }
|
||||
|
||||
actual.should == expected
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "yields subclass instances for subclasses" do
|
||||
a = []
|
||||
StringSpecs::MyString.new("hello\nworld").send(@method) { |s| a << s.class }
|
||||
a.should == [StringSpecs::MyString, StringSpecs::MyString]
|
||||
end
|
||||
|
||||
it "returns self" do
|
||||
s = "hello\nworld"
|
||||
(s.send(@method) {}).should equal(s)
|
||||
end
|
||||
|
||||
it "tries to convert the separator to a string using to_str" do
|
||||
separator = mock('l')
|
||||
separator.should_receive(:to_str).and_return("l")
|
||||
|
||||
a = []
|
||||
"hello\nworld".send(@method, separator) { |s| a << s }
|
||||
a.should == [ "hel", "l", "o\nworl", "d" ]
|
||||
end
|
||||
|
||||
it "does not care if the string is modified while substituting" do
|
||||
str = "hello\nworld."
|
||||
out = []
|
||||
str.send(@method){|x| out << x; str[-1] = '!' }.should == "hello\nworld!"
|
||||
out.should == ["hello\n", "world."]
|
||||
end
|
||||
|
||||
it "raises a TypeError when the separator can't be converted to a string" do
|
||||
lambda { "hello world".send(@method, false) {} }.should raise_error(TypeError)
|
||||
lambda { "hello world".send(@method, mock('x')) {} }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "accepts a string separator" do
|
||||
"hello world".send(@method, ?o).to_a.should == ["hello", " wo", "rld"]
|
||||
end
|
||||
|
||||
it "raises a TypeError when the separator is a symbol" do
|
||||
lambda { "hello world".send(@method, :o).to_a }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
17
spec/ruby/core/string/shared/each_line_without_block.rb
Normal file
17
spec/ruby/core/string/shared/each_line_without_block.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
describe :string_each_line_without_block, shared: true do
|
||||
describe "when no block is given" do
|
||||
it "returns an enumerator" do
|
||||
enum = "hello world".send(@method, ' ')
|
||||
enum.should be_an_instance_of(Enumerator)
|
||||
enum.to_a.should == ["hello ", "world"]
|
||||
end
|
||||
|
||||
describe "returned Enumerator" do
|
||||
describe "size" do
|
||||
it "should return nil" do
|
||||
"hello world".send(@method, ' ').size.should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
247
spec/ruby/core/string/shared/encode.rb
Normal file
247
spec/ruby/core/string/shared/encode.rb
Normal file
|
@ -0,0 +1,247 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
describe :string_encode, shared: true do
|
||||
describe "when passed no options" do
|
||||
it "transcodes to Encoding.default_internal when set" do
|
||||
Encoding.default_internal = Encoding::UTF_8
|
||||
str = [0xA4, 0xA2].pack('CC').force_encoding Encoding::EUC_JP
|
||||
str.send(@method).should == "あ"
|
||||
end
|
||||
|
||||
it "transcodes a 7-bit String despite no generic converting being available" do
|
||||
lambda do
|
||||
Encoding::Converter.new Encoding::Emacs_Mule, Encoding::ASCII_8BIT
|
||||
end.should raise_error(Encoding::ConverterNotFoundError)
|
||||
|
||||
Encoding.default_internal = Encoding::Emacs_Mule
|
||||
str = "\x79".force_encoding Encoding::ASCII_8BIT
|
||||
|
||||
str.send(@method).should == "y".force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
|
||||
it "raises an Encoding::ConverterNotFoundError when no conversion is possible" do
|
||||
Encoding.default_internal = Encoding::Emacs_Mule
|
||||
str = [0x80].pack('C').force_encoding Encoding::ASCII_8BIT
|
||||
lambda { str.send(@method) }.should raise_error(Encoding::ConverterNotFoundError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed to encoding" do
|
||||
it "accepts a String argument" do
|
||||
str = [0xA4, 0xA2].pack('CC').force_encoding Encoding::EUC_JP
|
||||
str.send(@method, "utf-8").should == "あ"
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the object to an Encoding" do
|
||||
enc = mock("string encode encoding")
|
||||
enc.should_receive(:to_str).and_return("utf-8")
|
||||
|
||||
str = [0xA4, 0xA2].pack('CC').force_encoding Encoding::EUC_JP
|
||||
str.send(@method, enc).should == "あ"
|
||||
end
|
||||
|
||||
it "transcodes to the passed encoding" do
|
||||
str = [0xA4, 0xA2].pack('CC').force_encoding Encoding::EUC_JP
|
||||
str.send(@method, Encoding::UTF_8).should == "あ"
|
||||
end
|
||||
|
||||
it "transcodes Japanese multibyte characters" do
|
||||
str = "あいうえお"
|
||||
str.send(@method, Encoding::ISO_2022_JP).should ==
|
||||
"\e\x24\x42\x24\x22\x24\x24\x24\x26\x24\x28\x24\x2A\e\x28\x42".force_encoding(Encoding::ISO_2022_JP)
|
||||
end
|
||||
|
||||
it "transcodes a 7-bit String despite no generic converting being available" do
|
||||
lambda do
|
||||
Encoding::Converter.new Encoding::Emacs_Mule, Encoding::ASCII_8BIT
|
||||
end.should raise_error(Encoding::ConverterNotFoundError)
|
||||
|
||||
str = "\x79".force_encoding Encoding::ASCII_8BIT
|
||||
str.send(@method, Encoding::Emacs_Mule).should == "y".force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
|
||||
it "raises an Encoding::ConverterNotFoundError when no conversion is possible" do
|
||||
str = [0x80].pack('C').force_encoding Encoding::ASCII_8BIT
|
||||
lambda do
|
||||
str.send(@method, Encoding::Emacs_Mule)
|
||||
end.should raise_error(Encoding::ConverterNotFoundError)
|
||||
end
|
||||
|
||||
it "raises an Encoding::ConverterNotFoundError for an invalid encoding" do
|
||||
lambda do
|
||||
"abc".send(@method, "xyz")
|
||||
end.should raise_error(Encoding::ConverterNotFoundError)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed options" do
|
||||
it "does not process transcoding options if not transcoding" do
|
||||
result = "あ\ufffdあ".send(@method, undef: :replace)
|
||||
result.should == "あ\ufffdあ"
|
||||
end
|
||||
|
||||
it "calls #to_hash to convert the object" do
|
||||
options = mock("string encode options")
|
||||
options.should_receive(:to_hash).and_return({ undef: :replace })
|
||||
|
||||
result = "あ\ufffdあ".send(@method, options)
|
||||
result.should == "あ\ufffdあ"
|
||||
end
|
||||
|
||||
it "transcodes to Encoding.default_internal when set" do
|
||||
Encoding.default_internal = Encoding::UTF_8
|
||||
str = [0xA4, 0xA2].pack('CC').force_encoding Encoding::EUC_JP
|
||||
str.send(@method, invalid: :replace).should == "あ"
|
||||
end
|
||||
|
||||
it "raises an Encoding::ConverterNotFoundError when no conversion is possible despite 'invalid: :replace, undef: :replace'" do
|
||||
Encoding.default_internal = Encoding::Emacs_Mule
|
||||
str = [0x80].pack('C').force_encoding Encoding::ASCII_8BIT
|
||||
lambda do
|
||||
str.send(@method, invalid: :replace, undef: :replace)
|
||||
end.should raise_error(Encoding::ConverterNotFoundError)
|
||||
end
|
||||
|
||||
it "replaces invalid characters when replacing Emacs-Mule encoded strings" do
|
||||
got = [0x80].pack('C').force_encoding('Emacs-Mule').send(@method, invalid: :replace)
|
||||
|
||||
got.should == "?".encode('Emacs-Mule')
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed to, from" do
|
||||
it "transcodes between the encodings ignoring the String encoding" do
|
||||
str = "あ"
|
||||
result = [0xA6, 0xD0, 0x8F, 0xAB, 0xE4, 0x8F, 0xAB, 0xB1].pack('C8')
|
||||
result.force_encoding Encoding::EUC_JP
|
||||
str.send(@method, "euc-jp", "ibm437").should == result
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the from object to an Encoding" do
|
||||
enc = mock("string encode encoding")
|
||||
enc.should_receive(:to_str).and_return("ibm437")
|
||||
|
||||
str = "あ"
|
||||
result = [0xA6, 0xD0, 0x8F, 0xAB, 0xE4, 0x8F, 0xAB, 0xB1].pack('C8')
|
||||
result.force_encoding Encoding::EUC_JP
|
||||
|
||||
str.send(@method, "euc-jp", enc).should == result
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed to, options" do
|
||||
it "replaces undefined characters in the destination encoding" do
|
||||
result = "あ?あ".send(@method, Encoding::EUC_JP, undef: :replace)
|
||||
# testing for: "\xA4\xA2?\xA4\xA2"
|
||||
xA4xA2 = [0xA4, 0xA2].pack('CC')
|
||||
result.should == "#{xA4xA2}?#{xA4xA2}".force_encoding("euc-jp")
|
||||
end
|
||||
|
||||
it "replaces invalid characters in the destination encoding" do
|
||||
xFF = [0xFF].pack('C').force_encoding('utf-8')
|
||||
"ab#{xFF}c".send(@method, Encoding::ISO_8859_1, invalid: :replace).should == "ab?c"
|
||||
end
|
||||
|
||||
it "calls #to_hash to convert the options object" do
|
||||
options = mock("string encode options")
|
||||
options.should_receive(:to_hash).and_return({ undef: :replace })
|
||||
|
||||
result = "あ?あ".send(@method, Encoding::EUC_JP, options)
|
||||
xA4xA2 = [0xA4, 0xA2].pack('CC').force_encoding('utf-8')
|
||||
result.should == "#{xA4xA2}?#{xA4xA2}".force_encoding("euc-jp")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed to, from, options" do
|
||||
it "replaces undefined characters in the destination encoding" do
|
||||
str = "あ?あ".force_encoding Encoding::ASCII_8BIT
|
||||
result = str.send(@method, "euc-jp", "utf-8", undef: :replace)
|
||||
xA4xA2 = [0xA4, 0xA2].pack('CC').force_encoding('utf-8')
|
||||
result.should == "#{xA4xA2}?#{xA4xA2}".force_encoding("euc-jp")
|
||||
end
|
||||
|
||||
it "replaces invalid characters in the destination encoding" do
|
||||
xFF = [0xFF].pack('C').force_encoding('utf-8')
|
||||
str = "ab#{xFF}c".force_encoding Encoding::ASCII_8BIT
|
||||
str.send(@method, "iso-8859-1", "utf-8", invalid: :replace).should == "ab?c"
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the to object to an encoding" do
|
||||
to = mock("string encode to encoding")
|
||||
to.should_receive(:to_str).and_return("iso-8859-1")
|
||||
|
||||
xFF = [0xFF].pack('C').force_encoding('utf-8')
|
||||
str = "ab#{xFF}c".force_encoding Encoding::ASCII_8BIT
|
||||
str.send(@method, to, "utf-8", invalid: :replace).should == "ab?c"
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the from object to an encoding" do
|
||||
from = mock("string encode to encoding")
|
||||
from.should_receive(:to_str).and_return("utf-8")
|
||||
|
||||
xFF = [0xFF].pack('C').force_encoding('utf-8')
|
||||
str = "ab#{xFF}c".force_encoding Encoding::ASCII_8BIT
|
||||
str.send(@method, "iso-8859-1", from, invalid: :replace).should == "ab?c"
|
||||
end
|
||||
|
||||
it "calls #to_hash to convert the options object" do
|
||||
options = mock("string encode options")
|
||||
options.should_receive(:to_hash).and_return({ invalid: :replace })
|
||||
|
||||
xFF = [0xFF].pack('C').force_encoding('utf-8')
|
||||
str = "ab#{xFF}c".force_encoding Encoding::ASCII_8BIT
|
||||
str.send(@method, "iso-8859-1", "utf-8", options).should == "ab?c"
|
||||
end
|
||||
end
|
||||
|
||||
describe "given the xml: :text option" do
|
||||
it "replaces all instances of '&' with '&'" do
|
||||
'& and &'.send(@method, "UTF-8", xml: :text).should == '& and &'
|
||||
end
|
||||
|
||||
it "replaces all instances of '<' with '<'" do
|
||||
'< and <'.send(@method, "UTF-8", xml: :text).should == '< and <'
|
||||
end
|
||||
|
||||
it "replaces all instances of '>' with '>'" do
|
||||
'> and >'.send(@method, "UTF-8", xml: :text).should == '> and >'
|
||||
end
|
||||
|
||||
it "does not replace '\"'" do
|
||||
'" and "'.send(@method, "UTF-8", xml: :text).should == '" and "'
|
||||
end
|
||||
|
||||
it "replaces undefined characters with their upper-case hexadecimal numeric character references" do
|
||||
'ürst'.send(@method, Encoding::US_ASCII, xml: :text).should == 'ürst'
|
||||
end
|
||||
end
|
||||
|
||||
describe "given the xml: :attr option" do
|
||||
it "surrounds the encoded text with double-quotes" do
|
||||
'abc'.send(@method, "UTF-8", xml: :attr).should == '"abc"'
|
||||
end
|
||||
|
||||
it "replaces all instances of '&' with '&'" do
|
||||
'& and &'.send(@method, "UTF-8", xml: :attr).should == '"& and &"'
|
||||
end
|
||||
|
||||
it "replaces all instances of '<' with '<'" do
|
||||
'< and <'.send(@method, "UTF-8", xml: :attr).should == '"< and <"'
|
||||
end
|
||||
|
||||
it "replaces all instances of '>' with '>'" do
|
||||
'> and >'.send(@method, "UTF-8", xml: :attr).should == '"> and >"'
|
||||
end
|
||||
|
||||
it "replaces all instances of '\"' with '"'" do
|
||||
'" and "'.send(@method, "UTF-8", xml: :attr).should == '"" and ""'
|
||||
end
|
||||
|
||||
it "replaces undefined characters with their upper-case hexadecimal numeric character references" do
|
||||
'ürst'.send(@method, Encoding::US_ASCII, xml: :attr).should == '"ürst"'
|
||||
end
|
||||
end
|
||||
|
||||
it "raises ArgumentError if the value of the :xml option is not :text or :attr" do
|
||||
lambda { ''.send(@method, "UTF-8", xml: :other) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
34
spec/ruby/core/string/shared/eql.rb
Normal file
34
spec/ruby/core/string/shared/eql.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# -*- encoding: binary -*-
|
||||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe :string_eql_value, shared: true do
|
||||
it "returns true if self <=> string returns 0" do
|
||||
'hello'.send(@method, 'hello').should be_true
|
||||
end
|
||||
|
||||
it "returns false if self <=> string does not return 0" do
|
||||
"more".send(@method, "MORE").should be_false
|
||||
"less".send(@method, "greater").should be_false
|
||||
end
|
||||
|
||||
it "ignores encoding difference of compatible string" do
|
||||
"hello".force_encoding("utf-8").send(@method, "hello".force_encoding("iso-8859-1")).should be_true
|
||||
end
|
||||
|
||||
it "considers encoding difference of incompatible string" do
|
||||
"\xff".force_encoding("utf-8").send(@method, "\xff".force_encoding("iso-8859-1")).should be_false
|
||||
end
|
||||
|
||||
it "considers encoding compatibility" do
|
||||
"hello".force_encoding("utf-8").send(@method, "hello".force_encoding("utf-32le")).should be_false
|
||||
end
|
||||
|
||||
it "ignores subclass differences" do
|
||||
a = "hello"
|
||||
b = StringSpecs::MyString.new("hello")
|
||||
|
||||
a.send(@method, b).should be_true
|
||||
b.send(@method, a).should be_true
|
||||
end
|
||||
end
|
29
spec/ruby/core/string/shared/equal_value.rb
Normal file
29
spec/ruby/core/string/shared/equal_value.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
require File.expand_path('../../../../spec_helper', __FILE__)
|
||||
require File.expand_path('../../fixtures/classes', __FILE__)
|
||||
|
||||
describe :string_equal_value, shared: true do
|
||||
it "returns false if obj does not respond to to_str" do
|
||||
'hello'.send(@method, 5).should be_false
|
||||
not_supported_on :opal do
|
||||
'hello'.send(@method, :hello).should be_false
|
||||
end
|
||||
'hello'.send(@method, mock('x')).should be_false
|
||||
end
|
||||
|
||||
it "returns obj == self if obj responds to to_str" do
|
||||
obj = Object.new
|
||||
|
||||
# String#== merely checks if #to_str is defined. It does
|
||||
# not call it.
|
||||
obj.stub!(:to_str)
|
||||
|
||||
# Don't use @method for :== in `obj.should_recerive(:==)`
|
||||
obj.should_receive(:==).and_return(true)
|
||||
|
||||
'hello'.send(@method, obj).should be_true
|
||||
end
|
||||
|
||||
it "is not fooled by NUL characters" do
|
||||
"abc\0def".send(@method, "abc\0xyz").should be_false
|
||||
end
|
||||
end
|
28
spec/ruby/core/string/shared/length.rb
Normal file
28
spec/ruby/core/string/shared/length.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# encoding: utf-8
|
||||
|
||||
describe :string_length, shared: true do
|
||||
it "returns the length of self" do
|
||||
"".send(@method).should == 0
|
||||
"\x00".send(@method).should == 1
|
||||
"one".send(@method).should == 3
|
||||
"two".send(@method).should == 3
|
||||
"three".send(@method).should == 5
|
||||
"four".send(@method).should == 4
|
||||
end
|
||||
|
||||
with_feature :encoding do
|
||||
it "returns the length of a string in different encodings" do
|
||||
utf8_str = 'こにちわ' * 100
|
||||
utf8_str.size.should == 400
|
||||
utf8_str.encode(Encoding::UTF_32BE).size.should == 400
|
||||
utf8_str.encode(Encoding::SHIFT_JIS).size.should == 400
|
||||
end
|
||||
|
||||
it "returns the length of the new self after encoding is changed" do
|
||||
str = 'こにちわ'
|
||||
str.send(@method)
|
||||
|
||||
str.force_encoding('ASCII-8BIT').send(@method).should == 12
|
||||
end
|
||||
end
|
||||
end
|
75
spec/ruby/core/string/shared/replace.rb
Normal file
75
spec/ruby/core/string/shared/replace.rb
Normal file
|
@ -0,0 +1,75 @@
|
|||
describe :string_replace, shared: true do
|
||||
it "returns self" do
|
||||
a = "a"
|
||||
a.send(@method, "b").should equal(a)
|
||||
end
|
||||
|
||||
it "replaces the content of self with other" do
|
||||
a = "some string"
|
||||
a.send(@method, "another string")
|
||||
a.should == "another string"
|
||||
end
|
||||
|
||||
it "taints self if other is tainted" do
|
||||
a = ""
|
||||
b = "".taint
|
||||
a.send(@method, b)
|
||||
a.tainted?.should == true
|
||||
end
|
||||
|
||||
it "does not untaint self if other is untainted" do
|
||||
a = "".taint
|
||||
b = ""
|
||||
a.send(@method, b)
|
||||
a.tainted?.should == true
|
||||
end
|
||||
|
||||
it "untrusts self if other is untrusted" do
|
||||
a = ""
|
||||
b = "".untrust
|
||||
a.send(@method, b)
|
||||
a.untrusted?.should == true
|
||||
end
|
||||
|
||||
it "does not trust self if other is trusted" do
|
||||
a = "".untrust
|
||||
b = ""
|
||||
a.send(@method, b)
|
||||
a.untrusted?.should == true
|
||||
end
|
||||
|
||||
it "replaces the encoding of self with that of other" do
|
||||
a = "".encode("UTF-16LE")
|
||||
b = "".encode("UTF-8")
|
||||
a.send(@method, b)
|
||||
a.encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "carries over the encoding invalidity" do
|
||||
a = "\u{8765}".force_encoding('ascii')
|
||||
"".send(@method, a).valid_encoding?.should be_false
|
||||
end
|
||||
|
||||
it "tries to convert other to string using to_str" do
|
||||
other = mock('x')
|
||||
other.should_receive(:to_str).and_return("converted to a string")
|
||||
"hello".send(@method, other).should == "converted to a string"
|
||||
end
|
||||
|
||||
it "raises a TypeError if other can't be converted to string" do
|
||||
lambda { "hello".send(@method, 123) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, []) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, mock('x')) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a RuntimeError on a frozen instance that is modified" do
|
||||
a = "hello".freeze
|
||||
lambda { a.send(@method, "world") }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
# see [ruby-core:23666]
|
||||
it "raises a RuntimeError on a frozen instance when self-replacing" do
|
||||
a = "hello".freeze
|
||||
lambda { a.send(@method, a) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
557
spec/ruby/core/string/shared/slice.rb
Normal file
557
spec/ruby/core/string/shared/slice.rb
Normal file
|
@ -0,0 +1,557 @@
|
|||
describe :string_slice, shared: true do
|
||||
it "returns the character code of the character at the given index" do
|
||||
"hello".send(@method, 0).should == ?h
|
||||
"hello".send(@method, -1).should == ?o
|
||||
end
|
||||
|
||||
it "returns nil if index is outside of self" do
|
||||
"hello".send(@method, 20).should == nil
|
||||
"hello".send(@method, -20).should == nil
|
||||
|
||||
"".send(@method, 0).should == nil
|
||||
"".send(@method, -1).should == nil
|
||||
end
|
||||
|
||||
it "calls to_int on the given index" do
|
||||
"hello".send(@method, 0.5).should == ?h
|
||||
|
||||
obj = mock('1')
|
||||
obj.should_receive(:to_int).and_return(1)
|
||||
"hello".send(@method, obj).should == ?e
|
||||
end
|
||||
|
||||
it "raises a TypeError if the given index is nil" do
|
||||
lambda { "hello".send(@method, nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError if the given index can't be converted to an Integer" do
|
||||
lambda { "hello".send(@method, mock('x')) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, {}) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, []) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a RangeError if the index is too big" do
|
||||
lambda { "hello".send(@method, bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_index_length, shared: true do
|
||||
it "returns the substring starting at the given index with the given length" do
|
||||
"hello there".send(@method, 0,0).should == ""
|
||||
"hello there".send(@method, 0,1).should == "h"
|
||||
"hello there".send(@method, 0,3).should == "hel"
|
||||
"hello there".send(@method, 0,6).should == "hello "
|
||||
"hello there".send(@method, 0,9).should == "hello the"
|
||||
"hello there".send(@method, 0,12).should == "hello there"
|
||||
|
||||
"hello there".send(@method, 1,0).should == ""
|
||||
"hello there".send(@method, 1,1).should == "e"
|
||||
"hello there".send(@method, 1,3).should == "ell"
|
||||
"hello there".send(@method, 1,6).should == "ello t"
|
||||
"hello there".send(@method, 1,9).should == "ello ther"
|
||||
"hello there".send(@method, 1,12).should == "ello there"
|
||||
|
||||
"hello there".send(@method, 3,0).should == ""
|
||||
"hello there".send(@method, 3,1).should == "l"
|
||||
"hello there".send(@method, 3,3).should == "lo "
|
||||
"hello there".send(@method, 3,6).should == "lo the"
|
||||
"hello there".send(@method, 3,9).should == "lo there"
|
||||
|
||||
"hello there".send(@method, 4,0).should == ""
|
||||
"hello there".send(@method, 4,3).should == "o t"
|
||||
"hello there".send(@method, 4,6).should == "o ther"
|
||||
"hello there".send(@method, 4,9).should == "o there"
|
||||
|
||||
"foo".send(@method, 2,1).should == "o"
|
||||
"foo".send(@method, 3,0).should == ""
|
||||
"foo".send(@method, 3,1).should == ""
|
||||
|
||||
"".send(@method, 0,0).should == ""
|
||||
"".send(@method, 0,1).should == ""
|
||||
|
||||
"x".send(@method, 0,0).should == ""
|
||||
"x".send(@method, 0,1).should == "x"
|
||||
"x".send(@method, 1,0).should == ""
|
||||
"x".send(@method, 1,1).should == ""
|
||||
|
||||
"x".send(@method, -1,0).should == ""
|
||||
"x".send(@method, -1,1).should == "x"
|
||||
|
||||
"hello there".send(@method, -3,2).should == "er"
|
||||
end
|
||||
|
||||
it "always taints resulting strings when self is tainted" do
|
||||
str = "hello world"
|
||||
str.taint
|
||||
|
||||
str.send(@method, 0,0).tainted?.should == true
|
||||
str.send(@method, 0,1).tainted?.should == true
|
||||
str.send(@method, 2,1).tainted?.should == true
|
||||
end
|
||||
|
||||
it "returns a string with the same encoding" do
|
||||
s = "hello there"
|
||||
s.send(@method, 1, 9).encoding.should == s.encoding
|
||||
|
||||
a = "hello".force_encoding("binary")
|
||||
b = " there".force_encoding("ISO-8859-1")
|
||||
c = (a + b).force_encoding(Encoding::US_ASCII)
|
||||
|
||||
c.send(@method, 0, 5).encoding.should == Encoding::US_ASCII
|
||||
c.send(@method, 5, 6).encoding.should == Encoding::US_ASCII
|
||||
c.send(@method, 1, 3).encoding.should == Encoding::US_ASCII
|
||||
c.send(@method, 8, 2).encoding.should == Encoding::US_ASCII
|
||||
c.send(@method, 1, 10).encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
|
||||
it "returns nil if the offset falls outside of self" do
|
||||
"hello there".send(@method, 20,3).should == nil
|
||||
"hello there".send(@method, -20,3).should == nil
|
||||
|
||||
"".send(@method, 1,0).should == nil
|
||||
"".send(@method, 1,1).should == nil
|
||||
|
||||
"".send(@method, -1,0).should == nil
|
||||
"".send(@method, -1,1).should == nil
|
||||
|
||||
"x".send(@method, 2,0).should == nil
|
||||
"x".send(@method, 2,1).should == nil
|
||||
|
||||
"x".send(@method, -2,0).should == nil
|
||||
"x".send(@method, -2,1).should == nil
|
||||
end
|
||||
|
||||
it "returns nil if the length is negative" do
|
||||
"hello there".send(@method, 4,-3).should == nil
|
||||
"hello there".send(@method, -4,-3).should == nil
|
||||
end
|
||||
|
||||
it "calls to_int on the given index and the given length" do
|
||||
"hello".send(@method, 0.5, 1).should == "h"
|
||||
"hello".send(@method, 0.5, 2.5).should == "he"
|
||||
"hello".send(@method, 1, 2.5).should == "el"
|
||||
|
||||
obj = mock('2')
|
||||
obj.should_receive(:to_int).exactly(4).times.and_return(2)
|
||||
|
||||
"hello".send(@method, obj, 1).should == "l"
|
||||
"hello".send(@method, obj, obj).should == "ll"
|
||||
"hello".send(@method, 0, obj).should == "he"
|
||||
end
|
||||
|
||||
it "raises a TypeError when idx or length can't be converted to an integer" do
|
||||
lambda { "hello".send(@method, mock('x'), 0) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, 0, mock('x')) }.should raise_error(TypeError)
|
||||
|
||||
# I'm deliberately including this here.
|
||||
# It means that str.send(@method, other, idx) isn't supported.
|
||||
lambda { "hello".send(@method, "", 0) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given index or the given length is nil" do
|
||||
lambda { "hello".send(@method, 1, nil) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, nil, 1) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, nil, nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a RangeError if the index or length is too big" do
|
||||
lambda { "hello".send(@method, bignum_value, 1) }.should raise_error(RangeError)
|
||||
lambda { "hello".send(@method, 0, bignum_value) }.should raise_error(RangeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0,0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1,4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "handles repeated application" do
|
||||
"hello world".send(@method, 6, 5).send(@method, 0, 1).should == 'w'
|
||||
"hello world".send(@method, 6, 5).send(@method, 0, 5).should == 'world'
|
||||
|
||||
"hello world".send(@method, 6, 5).send(@method, 1, 1).should == 'o'
|
||||
"hello world".send(@method, 6, 5).send(@method, 1, 4).should == 'orld'
|
||||
|
||||
"hello world".send(@method, 6, 5).send(@method, 4, 1).should == 'd'
|
||||
"hello world".send(@method, 6, 5).send(@method, 5, 0).should == ''
|
||||
|
||||
"hello world".send(@method, 6, 0).send(@method, -1, 0).should == nil
|
||||
"hello world".send(@method, 6, 0).send(@method, 1, 1).should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_range, shared: true do
|
||||
it "returns the substring given by the offsets of the range" do
|
||||
"hello there".send(@method, 1..1).should == "e"
|
||||
"hello there".send(@method, 1..3).should == "ell"
|
||||
"hello there".send(@method, 1...3).should == "el"
|
||||
"hello there".send(@method, -4..-2).should == "her"
|
||||
"hello there".send(@method, -4...-2).should == "he"
|
||||
"hello there".send(@method, 5..-1).should == " there"
|
||||
"hello there".send(@method, 5...-1).should == " ther"
|
||||
|
||||
"".send(@method, 0..0).should == ""
|
||||
|
||||
"x".send(@method, 0..0).should == "x"
|
||||
"x".send(@method, 0..1).should == "x"
|
||||
"x".send(@method, 0...1).should == "x"
|
||||
"x".send(@method, 0..-1).should == "x"
|
||||
|
||||
"x".send(@method, 1..1).should == ""
|
||||
"x".send(@method, 1..-1).should == ""
|
||||
end
|
||||
|
||||
it "returns nil if the beginning of the range falls outside of self" do
|
||||
"hello there".send(@method, 12..-1).should == nil
|
||||
"hello there".send(@method, 20..25).should == nil
|
||||
"hello there".send(@method, 20..1).should == nil
|
||||
"hello there".send(@method, -20..1).should == nil
|
||||
"hello there".send(@method, -20..-1).should == nil
|
||||
|
||||
"".send(@method, -1..-1).should == nil
|
||||
"".send(@method, -1...-1).should == nil
|
||||
"".send(@method, -1..0).should == nil
|
||||
"".send(@method, -1...0).should == nil
|
||||
end
|
||||
|
||||
it "returns an empty string if range.begin is inside self and > real end" do
|
||||
"hello there".send(@method, 1...1).should == ""
|
||||
"hello there".send(@method, 4..2).should == ""
|
||||
"hello".send(@method, 4..-4).should == ""
|
||||
"hello there".send(@method, -5..-6).should == ""
|
||||
"hello there".send(@method, -2..-4).should == ""
|
||||
"hello there".send(@method, -5..-6).should == ""
|
||||
"hello there".send(@method, -5..2).should == ""
|
||||
|
||||
"".send(@method, 0...0).should == ""
|
||||
"".send(@method, 0..-1).should == ""
|
||||
"".send(@method, 0...-1).should == ""
|
||||
|
||||
"x".send(@method, 0...0).should == ""
|
||||
"x".send(@method, 0...-1).should == ""
|
||||
"x".send(@method, 1...1).should == ""
|
||||
"x".send(@method, 1...-1).should == ""
|
||||
end
|
||||
|
||||
it "always taints resulting strings when self is tainted" do
|
||||
str = "hello world"
|
||||
str.taint
|
||||
|
||||
str.send(@method, 0..0).tainted?.should == true
|
||||
str.send(@method, 0...0).tainted?.should == true
|
||||
str.send(@method, 0..1).tainted?.should == true
|
||||
str.send(@method, 0...1).tainted?.should == true
|
||||
str.send(@method, 2..3).tainted?.should == true
|
||||
str.send(@method, 2..0).tainted?.should == true
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, 0...0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 0..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, 1..4).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "calls to_int on range arguments" do
|
||||
from = mock('from')
|
||||
to = mock('to')
|
||||
|
||||
# So we can construct a range out of them...
|
||||
from.should_receive(:<=>).twice.and_return(0)
|
||||
|
||||
from.should_receive(:to_int).twice.and_return(1)
|
||||
to.should_receive(:to_int).twice.and_return(-2)
|
||||
|
||||
"hello there".send(@method, from..to).should == "ello ther"
|
||||
"hello there".send(@method, from...to).should == "ello the"
|
||||
end
|
||||
|
||||
it "works with Range subclasses" do
|
||||
a = "GOOD"
|
||||
range_incl = StringSpecs::MyRange.new(1, 2)
|
||||
range_excl = StringSpecs::MyRange.new(-3, -1, true)
|
||||
|
||||
a.send(@method, range_incl).should == "OO"
|
||||
a.send(@method, range_excl).should == "OO"
|
||||
end
|
||||
|
||||
it "handles repeated application" do
|
||||
"hello world".send(@method, 6..11).send(@method, 0..0).should == 'w'
|
||||
"hello world".send(@method, 6..11).send(@method, 0..4).should == 'world'
|
||||
|
||||
"hello world".send(@method, 6..11).send(@method, 1..1).should == 'o'
|
||||
"hello world".send(@method, 6..11).send(@method, 1..4).should == 'orld'
|
||||
|
||||
"hello world".send(@method, 6..11).send(@method, 4..4).should == 'd'
|
||||
"hello world".send(@method, 6..11).send(@method, 5..4).should == ''
|
||||
|
||||
"hello world".send(@method, 6..5).send(@method, -1..-1).should == nil
|
||||
"hello world".send(@method, 6..5).send(@method, 1..1).should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_regexp, shared: true do
|
||||
it "returns the matching portion of self" do
|
||||
"hello there".send(@method, /[aeiou](.)\1/).should == "ell"
|
||||
"".send(@method, //).should == ""
|
||||
end
|
||||
|
||||
it "returns nil if there is no match" do
|
||||
"hello there".send(@method, /xyz/).should == nil
|
||||
end
|
||||
|
||||
not_supported_on :opal do
|
||||
it "always taints resulting strings when self or regexp is tainted" do
|
||||
strs = ["hello world"]
|
||||
strs += strs.map { |s| s.dup.taint }
|
||||
|
||||
strs.each do |str|
|
||||
str.send(@method, //).tainted?.should == str.tainted?
|
||||
str.send(@method, /hello/).tainted?.should == str.tainted?
|
||||
|
||||
tainted_re = /./
|
||||
tainted_re.taint
|
||||
|
||||
str.send(@method, tainted_re).tainted?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
it "returns an untrusted string if the regexp is untrusted" do
|
||||
"hello".send(@method, /./.untrust).untrusted?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, //).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /../).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
'hello'.send(@method, /./)
|
||||
$~[0].should == 'h'
|
||||
|
||||
'hello'.send(@method, /not/)
|
||||
$~.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_regexp_index, shared: true do
|
||||
it "returns the capture for the given index" do
|
||||
"hello there".send(@method, /[aeiou](.)\1/, 0).should == "ell"
|
||||
"hello there".send(@method, /[aeiou](.)\1/, 1).should == "l"
|
||||
"hello there".send(@method, /[aeiou](.)\1/, -1).should == "l"
|
||||
|
||||
"har".send(@method, /(.)(.)(.)/, 0).should == "har"
|
||||
"har".send(@method, /(.)(.)(.)/, 1).should == "h"
|
||||
"har".send(@method, /(.)(.)(.)/, 2).should == "a"
|
||||
"har".send(@method, /(.)(.)(.)/, 3).should == "r"
|
||||
"har".send(@method, /(.)(.)(.)/, -1).should == "r"
|
||||
"har".send(@method, /(.)(.)(.)/, -2).should == "a"
|
||||
"har".send(@method, /(.)(.)(.)/, -3).should == "h"
|
||||
end
|
||||
|
||||
it "always taints resulting strings when self or regexp is tainted" do
|
||||
strs = ["hello world"]
|
||||
strs += strs.map { |s| s.dup.taint }
|
||||
|
||||
strs.each do |str|
|
||||
str.send(@method, //, 0).tainted?.should == str.tainted?
|
||||
str.send(@method, /hello/, 0).tainted?.should == str.tainted?
|
||||
|
||||
str.send(@method, /(.)(.)(.)/, 0).tainted?.should == str.tainted?
|
||||
str.send(@method, /(.)(.)(.)/, 1).tainted?.should == str.tainted?
|
||||
str.send(@method, /(.)(.)(.)/, -1).tainted?.should == str.tainted?
|
||||
str.send(@method, /(.)(.)(.)/, -2).tainted?.should == str.tainted?
|
||||
|
||||
tainted_re = /(.)(.)(.)/
|
||||
tainted_re.taint
|
||||
|
||||
str.send(@method, tainted_re, 0).tainted?.should == true
|
||||
str.send(@method, tainted_re, 1).tainted?.should == true
|
||||
str.send(@method, tainted_re, -1).tainted?.should == true
|
||||
end
|
||||
end
|
||||
|
||||
not_supported_on :opal do
|
||||
it "returns an untrusted string if the regexp is untrusted" do
|
||||
"hello".send(@method, /(.)/.untrust, 1).untrusted?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil if there is no match" do
|
||||
"hello there".send(@method, /(what?)/, 1).should == nil
|
||||
end
|
||||
|
||||
it "returns nil if there is no capture for the given index" do
|
||||
"hello there".send(@method, /[aeiou](.)\1/, 2).should == nil
|
||||
# You can't refer to 0 using negative indices
|
||||
"hello there".send(@method, /[aeiou](.)\1/, -2).should == nil
|
||||
end
|
||||
|
||||
it "calls to_int on the given index" do
|
||||
obj = mock('2')
|
||||
obj.should_receive(:to_int).and_return(2)
|
||||
|
||||
"har".send(@method, /(.)(.)(.)/, 1.5).should == "h"
|
||||
"har".send(@method, /(.)(.)(.)/, obj).should == "a"
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given index can't be converted to Integer" do
|
||||
lambda { "hello".send(@method, /(.)(.)(.)/, mock('x')) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, /(.)(.)(.)/, {}) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, /(.)(.)(.)/, []) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given index is nil" do
|
||||
lambda { "hello".send(@method, /(.)(.)(.)/, nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(.)(.)/, 0).should be_an_instance_of(StringSpecs::MyString)
|
||||
s.send(@method, /(.)(.)/, 1).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
'hello'.send(@method, /.(.)/, 0)
|
||||
$~[0].should == 'he'
|
||||
|
||||
'hello'.send(@method, /.(.)/, 1)
|
||||
$~[1].should == 'e'
|
||||
|
||||
'hello'.send(@method, /not/, 0)
|
||||
$~.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_string, shared: true do
|
||||
it "returns other_str if it occurs in self" do
|
||||
s = "lo"
|
||||
"hello there".send(@method, s).should == s
|
||||
end
|
||||
|
||||
it "taints resulting strings when other is tainted" do
|
||||
strs = ["", "hello world", "hello"]
|
||||
strs += strs.map { |s| s.dup.taint }
|
||||
|
||||
strs.each do |str|
|
||||
strs.each do |other|
|
||||
r = str.send(@method, other)
|
||||
|
||||
r.tainted?.should == !r.nil? & other.tainted?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "doesn't set $~" do
|
||||
$~ = nil
|
||||
|
||||
'hello'.send(@method, 'll')
|
||||
$~.should == nil
|
||||
end
|
||||
|
||||
it "returns nil if there is no match" do
|
||||
"hello there".send(@method, "bye").should == nil
|
||||
end
|
||||
|
||||
it "doesn't call to_str on its argument" do
|
||||
o = mock('x')
|
||||
o.should_not_receive(:to_str)
|
||||
|
||||
lambda { "hello".send(@method, o) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "returns a subclass instance when given a subclass instance" do
|
||||
s = StringSpecs::MyString.new("el")
|
||||
r = "hello".send(@method, s)
|
||||
r.should == "el"
|
||||
r.should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_regexp_group, shared: true do
|
||||
not_supported_on :opal do
|
||||
it "returns the capture for the given name" do
|
||||
"hello there".send(@method, /(?<g>[aeiou](.))/, 'g').should == "el"
|
||||
"hello there".send(@method, /[aeiou](?<g>.)/, 'g').should == "l"
|
||||
|
||||
"har".send(@method, /(?<g>(.)(.)(.))/, 'g').should == "har"
|
||||
"har".send(@method, /(?<h>.)(.)(.)/, 'h').should == "h"
|
||||
"har".send(@method, /(.)(?<a>.)(.)/, 'a').should == "a"
|
||||
"har".send(@method, /(.)(.)(?<r>.)/, 'r').should == "r"
|
||||
"har".send(@method, /(?<h>.)(?<a>.)(?<r>.)/, 'r').should == "r"
|
||||
end
|
||||
|
||||
it "returns the last capture for duplicate names" do
|
||||
"hello there".send(@method, /(?<g>h)(?<g>.)/, 'g').should == "e"
|
||||
"hello there".send(@method, /(?<g>h)(?<g>.)(?<f>.)/, 'g').should == "e"
|
||||
end
|
||||
|
||||
it "returns the innermost capture for nested duplicate names" do
|
||||
"hello there".send(@method, /(?<g>h(?<g>.))/, 'g').should == "e"
|
||||
end
|
||||
|
||||
it "always taints resulting strings when self or regexp is tainted" do
|
||||
strs = ["hello world"]
|
||||
strs += strs.map { |s| s.dup.taint }
|
||||
|
||||
strs.each do |str|
|
||||
str.send(@method, /(?<hi>hello)/, 'hi').tainted?.should == str.tainted?
|
||||
|
||||
str.send(@method, /(?<g>(.)(.)(.))/, 'g').tainted?.should == str.tainted?
|
||||
str.send(@method, /(?<h>.)(.)(.)/, 'h').tainted?.should == str.tainted?
|
||||
str.send(@method, /(.)(?<a>.)(.)/, 'a').tainted?.should == str.tainted?
|
||||
str.send(@method, /(.)(.)(?<r>.)/, 'r').tainted?.should == str.tainted?
|
||||
str.send(@method, /(?<h>.)(?<a>.)(?<r>.)/, 'r').tainted?.should == str.tainted?
|
||||
|
||||
tainted_re = /(?<a>.)(?<b>.)(?<c>.)/
|
||||
tainted_re.taint
|
||||
|
||||
str.send(@method, tainted_re, 'a').tainted?.should be_true
|
||||
str.send(@method, tainted_re, 'b').tainted?.should be_true
|
||||
str.send(@method, tainted_re, 'c').tainted?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil if there is no match" do
|
||||
"hello there".send(@method, /(?<whut>what?)/, 'whut').should be_nil
|
||||
end
|
||||
|
||||
it "raises an IndexError if there is no capture for the given name" do
|
||||
lambda do
|
||||
"hello there".send(@method, /[aeiou](.)\1/, 'non')
|
||||
end.should raise_error(IndexError)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given name is not a String" do
|
||||
lambda { "hello".send(@method, /(?<q>.)/, mock('x')) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, /(?<q>.)/, {}) }.should raise_error(TypeError)
|
||||
lambda { "hello".send(@method, /(?<q>.)/, []) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises an IndexError when given the empty String as a group name" do
|
||||
lambda { "hello".send(@method, /(?<q>)/, '') }.should raise_error(IndexError)
|
||||
end
|
||||
|
||||
it "returns subclass instances" do
|
||||
s = StringSpecs::MyString.new("hello")
|
||||
s.send(@method, /(?<q>.)/, 'q').should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "sets $~ to MatchData when there is a match and nil when there's none" do
|
||||
'hello'.send(@method, /(?<hi>.(.))/, 'hi')
|
||||
$~[0].should == 'he'
|
||||
|
||||
'hello'.send(@method, /(?<non>not)/, 'non')
|
||||
$~.should be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_slice_symbol, shared: true do
|
||||
it "raises TypeError" do
|
||||
lambda { 'hello'.send(@method, :hello) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
88
spec/ruby/core/string/shared/succ.rb
Normal file
88
spec/ruby/core/string/shared/succ.rb
Normal file
|
@ -0,0 +1,88 @@
|
|||
# -*- encoding: binary -*-
|
||||
describe :string_succ, shared: true do
|
||||
it "returns an empty string for empty strings" do
|
||||
"".send(@method).should == ""
|
||||
end
|
||||
|
||||
it "returns the successor by increasing the rightmost alphanumeric (digit => digit, letter => letter with same case)" do
|
||||
"abcd".send(@method).should == "abce"
|
||||
"THX1138".send(@method).should == "THX1139"
|
||||
|
||||
"<<koala>>".send(@method).should == "<<koalb>>"
|
||||
"==A??".send(@method).should == "==B??"
|
||||
end
|
||||
|
||||
it "increases non-alphanumerics (via ascii rules) if there are no alphanumerics" do
|
||||
"***".send(@method).should == "**+"
|
||||
"**`".send(@method).should == "**a"
|
||||
end
|
||||
|
||||
it "increases the next best alphanumeric (jumping over non-alphanumerics) if there is a carry" do
|
||||
"dz".send(@method).should == "ea"
|
||||
"HZ".send(@method).should == "IA"
|
||||
"49".send(@method).should == "50"
|
||||
|
||||
"izz".send(@method).should == "jaa"
|
||||
"IZZ".send(@method).should == "JAA"
|
||||
"699".send(@method).should == "700"
|
||||
|
||||
"6Z99z99Z".send(@method).should == "7A00a00A"
|
||||
|
||||
"1999zzz".send(@method).should == "2000aaa"
|
||||
"NZ/[]ZZZ9999".send(@method).should == "OA/[]AAA0000"
|
||||
end
|
||||
|
||||
it "increases the next best character if there is a carry for non-alphanumerics" do
|
||||
"(\xFF".send(@method).should == ")\x00"
|
||||
"`\xFF".send(@method).should == "a\x00"
|
||||
"<\xFF\xFF".send(@method).should == "=\x00\x00"
|
||||
end
|
||||
|
||||
it "adds an additional character (just left to the last increased one) if there is a carry and no character left to increase" do
|
||||
"z".send(@method).should == "aa"
|
||||
"Z".send(@method).should == "AA"
|
||||
"9".send(@method).should == "10"
|
||||
|
||||
"zz".send(@method).should == "aaa"
|
||||
"ZZ".send(@method).should == "AAA"
|
||||
"99".send(@method).should == "100"
|
||||
|
||||
"9Z99z99Z".send(@method).should == "10A00a00A"
|
||||
|
||||
"ZZZ9999".send(@method).should == "AAAA0000"
|
||||
"/[]9999".send(@method).should == "/[]10000"
|
||||
"/[]ZZZ9999".send(@method).should == "/[]AAAA0000"
|
||||
"Z/[]ZZZ9999".send(@method).should == "AA/[]AAA0000"
|
||||
|
||||
# non-alphanumeric cases
|
||||
"\xFF".send(@method).should == "\x01\x00"
|
||||
"\xFF\xFF".send(@method).should == "\x01\x00\x00"
|
||||
end
|
||||
|
||||
it "returns subclass instances when called on a subclass" do
|
||||
StringSpecs::MyString.new("").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("a").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
StringSpecs::MyString.new("z").send(@method).should be_an_instance_of(StringSpecs::MyString)
|
||||
end
|
||||
|
||||
it "taints the result if self is tainted" do
|
||||
["", "a", "z", "Z", "9", "\xFF", "\xFF\xFF"].each do |s|
|
||||
s.taint.send(@method).tainted?.should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :string_succ_bang, shared: true do
|
||||
it "is equivalent to succ, but modifies self in place (still returns self)" do
|
||||
["", "abcd", "THX1138"].each do |s|
|
||||
r = s.dup.send(@method)
|
||||
s.send(@method).should equal(s)
|
||||
s.should == r
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a RuntimeError if self is frozen" do
|
||||
lambda { "".freeze.send(@method) }.should raise_error(RuntimeError)
|
||||
lambda { "abcd".freeze.send(@method) }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
9
spec/ruby/core/string/shared/to_a.rb
Normal file
9
spec/ruby/core/string/shared/to_a.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
describe :string_to_a, shared: true do
|
||||
it "returns an empty array for empty strings" do
|
||||
"".send(@method).should == []
|
||||
end
|
||||
|
||||
it "returns an array containing the string for non-empty strings" do
|
||||
"hello".send(@method).should == ["hello"]
|
||||
end
|
||||
end
|
18
spec/ruby/core/string/shared/to_s.rb
Normal file
18
spec/ruby/core/string/shared/to_s.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
describe :string_to_s, shared: true do
|
||||
it "returns self when self.class == String" do
|
||||
a = "a string"
|
||||
a.should equal(a.send(@method))
|
||||
end
|
||||
|
||||
it "returns a new instance of String when called on a subclass" do
|
||||
a = StringSpecs::MyString.new("a string")
|
||||
s = a.send(@method)
|
||||
s.should == "a string"
|
||||
s.should be_an_instance_of(String)
|
||||
end
|
||||
|
||||
it "taints the result when self is tainted" do
|
||||
"x".taint.send(@method).tainted?.should == true
|
||||
StringSpecs::MyString.new("x").taint.send(@method).tainted?.should == true
|
||||
end
|
||||
end
|
24
spec/ruby/core/string/shared/to_sym.rb
Normal file
24
spec/ruby/core/string/shared/to_sym.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
describe :string_to_sym, shared: true do
|
||||
it "returns the symbol corresponding to self" do
|
||||
"Koala".send(@method).should == :Koala
|
||||
'cat'.send(@method).should == :cat
|
||||
'@cat'.send(@method).should == :@cat
|
||||
'cat and dog'.send(@method).should == :"cat and dog"
|
||||
"abc=".send(@method).should == :abc=
|
||||
end
|
||||
|
||||
it "does not special case +(binary) and -(binary)" do
|
||||
"+(binary)".send(@method).should == :"+(binary)"
|
||||
"-(binary)".send(@method).should == :"-(binary)"
|
||||
end
|
||||
|
||||
it "does not special case certain operators" do
|
||||
[ ["!@", :"!@"],
|
||||
["~@", :"~@"],
|
||||
["!(unary)", :"!(unary)"],
|
||||
["~(unary)", :"~(unary)"],
|
||||
["+(unary)", :"+(unary)"],
|
||||
["-(unary)", :"-(unary)"]
|
||||
].should be_computed_by(@method)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue