зеркало из https://github.com/github/ruby.git
Update to ruby/spec@cbfaf51
This commit is contained in:
Родитель
44f42413e6
Коммит
6582df26dc
|
@ -0,0 +1,11 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerable#compact" do
|
||||
it 'returns array without nil elements' do
|
||||
arr = EnumerableSpecs::Numerous.new(nil, 1, 2, nil, true)
|
||||
arr.compact.should == [1, 2, true]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,6 +16,10 @@ describe "Enumerator::Lazy" do
|
|||
]
|
||||
lazy_methods += [:chunk_while, :uniq]
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
lazy_methods += [:compact]
|
||||
end
|
||||
|
||||
Enumerator::Lazy.instance_methods(false).should include(*lazy_methods)
|
||||
end
|
||||
end
|
||||
|
@ -26,3 +30,13 @@ describe "Enumerator::Lazy#lazy" do
|
|||
lazy.lazy.should equal(lazy)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerator::Lazy#compact" do
|
||||
it 'returns array without nil elements' do
|
||||
arr = [1, nil, 3, false, 5].to_enum.lazy.compact
|
||||
arr.should be_an_instance_of(Enumerator::Lazy)
|
||||
arr.force.should == [1, 3, false, 5]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -159,10 +159,10 @@ describe :file_fnmatch, shared: true do
|
|||
end
|
||||
|
||||
it "does not match leading periods in filenames with wildcards by default" do
|
||||
File.send(@method, '*', '.profile').should == false
|
||||
File.send(@method, '*', 'home/.profile').should == true
|
||||
File.send(@method, '*/*', 'home/.profile').should == true
|
||||
File.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME).should == false
|
||||
File.should_not.send(@method, '*', '.profile')
|
||||
File.should.send(@method, '*', 'home/.profile')
|
||||
File.should.send(@method, '*/*', 'home/.profile')
|
||||
File.should_not.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME)
|
||||
end
|
||||
|
||||
it "matches patterns with leading periods to dotfiles by default" do
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe "Range#clone" do
|
||||
it "duplicates the range" do
|
||||
original = (1..3)
|
||||
copy = original.clone
|
||||
copy.begin.should == 1
|
||||
copy.end.should == 3
|
||||
copy.should_not.exclude_end?
|
||||
copy.should_not.equal? original
|
||||
|
||||
original = ("a"..."z")
|
||||
copy = original.clone
|
||||
copy.begin.should == "a"
|
||||
copy.end.should == "z"
|
||||
copy.should.exclude_end?
|
||||
copy.should_not.equal? original
|
||||
end
|
||||
|
||||
it "maintains the frozen state" do
|
||||
(1..2).clone.frozen?.should == (1..2).frozen?
|
||||
(1..).clone.frozen?.should == (1..).frozen?
|
||||
Range.new(1, 2).clone.frozen?.should == Range.new(1, 2).frozen?
|
||||
Class.new(Range).new(1, 2).clone.frozen?.should == Class.new(Range).new(1, 2).frozen?
|
||||
end
|
||||
end
|
|
@ -2,10 +2,12 @@ require_relative '../../spec_helper'
|
|||
|
||||
describe "Range#dup" do
|
||||
it "duplicates the range" do
|
||||
copy = (1..3).dup
|
||||
original = (1..3)
|
||||
copy = original.dup
|
||||
copy.begin.should == 1
|
||||
copy.end.should == 3
|
||||
copy.should_not.exclude_end?
|
||||
copy.should_not.equal?(original)
|
||||
|
||||
copy = ("a"..."z").dup
|
||||
copy.begin.should == "a"
|
||||
|
|
|
@ -65,5 +65,15 @@ describe "Range.new" do
|
|||
|
||||
range_exclude.should_not == range_include
|
||||
end
|
||||
|
||||
ruby_version_is "3.0" do
|
||||
it "creates a frozen range if the class is Range.class" do
|
||||
Range.new(1, 2).should.frozen?
|
||||
end
|
||||
|
||||
it "does not create a frozen range if the class is not Range.class" do
|
||||
Class.new(Range).new(1, 2).should_not.frozen?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,6 +17,11 @@ describe :regexp_quote, shared: true do
|
|||
Regexp.send(@method, str).should == '\+\[\]\('
|
||||
end
|
||||
|
||||
it "works for broken strings" do
|
||||
Regexp.send(@method, "a.\x85b.".force_encoding("US-ASCII")).should =="a\\.\x85b\\.".force_encoding("US-ASCII")
|
||||
Regexp.send(@method, "a.\x80".force_encoding("UTF-8")).should == "a\\.\x80".force_encoding("UTF-8")
|
||||
end
|
||||
|
||||
it "sets the encoding of the result to US-ASCII if there are only US-ASCII characters present in the input String" do
|
||||
str = "abc".force_encoding("euc-jp")
|
||||
Regexp.send(@method, str).encoding.should == Encoding::US_ASCII
|
||||
|
|
|
@ -9,8 +9,26 @@ describe "Regexp#source" do
|
|||
/x(.)xz/.source.should == "x(.)xz"
|
||||
end
|
||||
|
||||
it "will remove escape characters" do
|
||||
/foo\/bar/.source.should == "foo/bar"
|
||||
it "keeps escape sequences as is" do
|
||||
/\x20\+/.source.should == '\x20\+'
|
||||
end
|
||||
|
||||
describe "escaping" do
|
||||
it "keeps escaping of metacharacter" do
|
||||
/\$/.source.should == "\\$"
|
||||
end
|
||||
|
||||
it "keeps escaping of metacharacter used as a terminator" do
|
||||
%r+\++.source.should == "\\+"
|
||||
end
|
||||
|
||||
it "removes escaping of non-metacharacter used as a terminator" do
|
||||
%r@\@@.source.should == "@"
|
||||
end
|
||||
|
||||
it "keeps escaping of non-metacharacter not used as a terminator" do
|
||||
/\@/.source.should == "\\@"
|
||||
end
|
||||
end
|
||||
|
||||
not_supported_on :opal do
|
||||
|
|
|
@ -10,6 +10,7 @@ describe "String#capitalize" do
|
|||
"hello".capitalize.should == "Hello"
|
||||
"HELLO".capitalize.should == "Hello"
|
||||
"123ABC".capitalize.should == "123abc"
|
||||
"abcdef"[1...-1].capitalize.should == "Bcde"
|
||||
end
|
||||
|
||||
describe "full Unicode case mapping" do
|
||||
|
@ -37,7 +38,7 @@ describe "String#capitalize" do
|
|||
end
|
||||
|
||||
it "handles non-ASCII substrings properly" do
|
||||
"garçon"[1..-1].capitalize(:ascii).should == "Arçon"
|
||||
"garçon"[1...-1].capitalize(:ascii).should == "Arço"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ describe "String#delete_prefix" do
|
|||
r.should == s
|
||||
end
|
||||
|
||||
it "does not remove partial bytes, only full characters" do
|
||||
"\xe3\x81\x82".delete_prefix("\xe3").should == "\xe3\x81\x82"
|
||||
end
|
||||
|
||||
it "doesn't set $~" do
|
||||
$~ = nil
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ describe "String#delete_suffix" do
|
|||
r.should == s
|
||||
end
|
||||
|
||||
it "does not remove partial bytes, only full characters" do
|
||||
"\xe3\x81\x82".delete_suffix("\x82").should == "\xe3\x81\x82"
|
||||
end
|
||||
|
||||
it "doesn't set $~" do
|
||||
$~ = nil
|
||||
|
||||
|
|
|
@ -27,6 +27,10 @@ describe "String#downcase" do
|
|||
it "does not downcase non-ASCII characters" do
|
||||
"CÅR".downcase(:ascii).should == "cÅr"
|
||||
end
|
||||
|
||||
it "works with substrings" do
|
||||
"prefix TÉ"[-2..-1].downcase(:ascii).should == "tÉ"
|
||||
end
|
||||
end
|
||||
|
||||
describe "full Unicode case mapping adapted for Turkic languages" do
|
||||
|
|
|
@ -10,6 +10,7 @@ describe "String#encoding" do
|
|||
it "is equal to the source encoding by default" do
|
||||
s = StringSpecs::ISO88599Encoding.new
|
||||
s.cedilla.encoding.should == s.source_encoding
|
||||
s.cedilla.encode("utf-8").should == 350.chr(Encoding::UTF_8) # S-cedilla
|
||||
end
|
||||
|
||||
it "returns the given encoding if #force_encoding has been called" do
|
||||
|
|
|
@ -4,6 +4,6 @@ module StringSpecs
|
|||
def source_encoding; __ENCODING__; end
|
||||
def x_escape; [0xDF].pack('C').force_encoding("iso-8859-9"); end
|
||||
def ascii_only; "glark"; end
|
||||
def cedilla; "Ş"; end
|
||||
def cedilla; "Þ"; end # S-cedilla
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,20 @@ describe "String#include? with String" do
|
|||
StringSpecs::MyString.new("hello").include?(StringSpecs::MyString.new("lo")).should == true
|
||||
end
|
||||
|
||||
it "returns true if both strings are empty" do
|
||||
"".should.include?("")
|
||||
"".force_encoding("EUC-JP").should.include?("")
|
||||
"".should.include?("".force_encoding("EUC-JP"))
|
||||
"".force_encoding("EUC-JP").should.include?("".force_encoding("EUC-JP"))
|
||||
end
|
||||
|
||||
it "returns true if the RHS is empty" do
|
||||
"a".should.include?("")
|
||||
"a".force_encoding("EUC-JP").should.include?("")
|
||||
"a".should.include?("".force_encoding("EUC-JP"))
|
||||
"a".force_encoding("EUC-JP").should.include?("".force_encoding("EUC-JP"))
|
||||
end
|
||||
|
||||
it "tries to convert other to string using to_str" do
|
||||
other = mock('lo')
|
||||
other.should_receive(:to_str).and_return("lo")
|
||||
|
|
|
@ -19,6 +19,21 @@ describe "String#inspect" do
|
|||
].should be_computed_by(:inspect)
|
||||
end
|
||||
|
||||
it "returns a string with special characters replaced with \\<char> notation for UTF-16" do
|
||||
pairs = [
|
||||
["\a", '"\\a"'],
|
||||
["\b", '"\\b"'],
|
||||
["\t", '"\\t"'],
|
||||
["\n", '"\\n"'],
|
||||
["\v", '"\\v"'],
|
||||
["\f", '"\\f"'],
|
||||
["\r", '"\\r"'],
|
||||
["\e", '"\\e"']
|
||||
].map { |str, result| [str.encode('UTF-16LE'), result] }
|
||||
|
||||
pairs.should be_computed_by(:inspect)
|
||||
end
|
||||
|
||||
it "returns a string with \" and \\ escaped with a backslash" do
|
||||
[ ["\"", '"\\""'],
|
||||
["\\", '"\\\\"']
|
||||
|
@ -311,6 +326,11 @@ describe "String#inspect" do
|
|||
"\xF0\x9F".inspect.should == '"\\xF0\\x9F"'
|
||||
end
|
||||
|
||||
it "works for broken US-ASCII strings" do
|
||||
s = "©".force_encoding("US-ASCII")
|
||||
s.inspect.should == '"\xC2\xA9"'
|
||||
end
|
||||
|
||||
describe "when default external is UTF-8" do
|
||||
before :each do
|
||||
@extenc, Encoding.default_external = Encoding.default_external, Encoding::UTF_8
|
||||
|
|
|
@ -10,6 +10,14 @@ describe "String#lstrip" do
|
|||
" hello world ".lstrip.should == "hello world "
|
||||
"\n\r\t\n\v\r hello world ".lstrip.should == "hello world "
|
||||
"hello".lstrip.should == "hello"
|
||||
" こにちわ".lstrip.should == "こにちわ"
|
||||
end
|
||||
|
||||
it "works with lazy substrings" do
|
||||
" hello "[1...-1].lstrip.should == "hello "
|
||||
" hello world "[1...-1].lstrip.should == "hello world "
|
||||
"\n\r\t\n\v\r hello world "[1...-1].lstrip.should == "hello world "
|
||||
" こにちわ "[1...-1].lstrip.should == "こにちわ"
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
|
@ -27,20 +35,26 @@ describe "String#lstrip!" do
|
|||
a.should == "hello "
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "strips leading \\0" do
|
||||
a = "\000 \000hello\000 \000"
|
||||
a.lstrip!
|
||||
a.should == "hello\000 \000"
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil if no modifications were made" do
|
||||
a = "hello"
|
||||
a.lstrip!.should == nil
|
||||
a.should == "hello"
|
||||
end
|
||||
|
||||
it "makes a string empty if it is only whitespace" do
|
||||
"".lstrip!.should == nil
|
||||
" ".lstrip.should == ""
|
||||
" ".lstrip.should == ""
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "removes leading NULL bytes and whitespace" do
|
||||
a = "\000 \000hello\000 \000"
|
||||
a.lstrip!
|
||||
a.should == "hello\000 \000"
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a FrozenError on a frozen instance that is modified" do
|
||||
-> { " hello ".freeze.lstrip! }.should raise_error(FrozenError)
|
||||
end
|
||||
|
@ -51,9 +65,13 @@ describe "String#lstrip!" do
|
|||
-> { "".freeze.lstrip! }.should raise_error(FrozenError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if the first codepoint is invalid" do
|
||||
it "raises an ArgumentError if the first non-space codepoint is invalid" do
|
||||
s = "\xDFabc".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
-> { s.lstrip! }.should raise_error(ArgumentError)
|
||||
|
||||
s = " \xDFabc".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
-> { s.lstrip! }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,4 +25,9 @@ describe "String#ord" do
|
|||
it "raises an ArgumentError if called on an empty String" do
|
||||
-> { ''.ord }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError if the character is broken" do
|
||||
s = "©".force_encoding("US-ASCII")
|
||||
-> { s.ord }.should raise_error(ArgumentError, "invalid byte sequence in US-ASCII")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,6 +29,14 @@ describe "String#reverse" do
|
|||
it "reverses a string with multi byte characters" do
|
||||
"微軟正黑體".reverse.should == "體黑正軟微"
|
||||
end
|
||||
|
||||
it "works with a broken string" do
|
||||
str = "微軟\xDF\xDE正黑體".force_encoding(Encoding::UTF_8)
|
||||
|
||||
str.valid_encoding?.should be_false
|
||||
|
||||
str.reverse.should == "體黑正\xDE\xDF軟微"
|
||||
end
|
||||
end
|
||||
|
||||
describe "String#reverse!" do
|
||||
|
@ -55,4 +63,13 @@ describe "String#reverse!" do
|
|||
str.reverse!
|
||||
str.should == "體黑正軟微"
|
||||
end
|
||||
|
||||
it "works with a broken string" do
|
||||
str = "微軟\xDF\xDE正黑體".force_encoding(Encoding::UTF_8)
|
||||
|
||||
str.valid_encoding?.should be_false
|
||||
str.reverse!
|
||||
|
||||
str.should == "體黑正\xDE\xDF軟微"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,6 +11,14 @@ describe "String#rstrip" do
|
|||
" hello world \n\r\t\n\v\r".rstrip.should == " hello world"
|
||||
"hello".rstrip.should == "hello"
|
||||
"hello\x00".rstrip.should == "hello"
|
||||
"こにちわ ".rstrip.should == "こにちわ"
|
||||
end
|
||||
|
||||
it "works with lazy substrings" do
|
||||
" hello "[1...-1].rstrip.should == " hello"
|
||||
" hello world "[1...-1].rstrip.should == " hello world"
|
||||
" hello world \n\r\t\n\v\r"[1...-1].rstrip.should == " hello world"
|
||||
" こにちわ "[1...-1].rstrip.should == "こにちわ"
|
||||
end
|
||||
|
||||
it "returns a copy of self with all trailing whitespace and NULL bytes removed" do
|
||||
|
@ -37,6 +45,20 @@ describe "String#rstrip!" do
|
|||
a.should == "hello"
|
||||
end
|
||||
|
||||
it "makes a string empty if it is only whitespace" do
|
||||
"".rstrip!.should == nil
|
||||
" ".rstrip.should == ""
|
||||
" ".rstrip.should == ""
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "removes trailing NULL bytes and whitespace" do
|
||||
a = "\000 goodbye \000"
|
||||
a.rstrip!
|
||||
a.should == "\000 goodbye"
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a FrozenError on a frozen instance that is modified" do
|
||||
-> { " hello ".freeze.rstrip! }.should raise_error(FrozenError)
|
||||
end
|
||||
|
@ -47,9 +69,13 @@ describe "String#rstrip!" do
|
|||
-> { "".freeze.rstrip! }.should raise_error(FrozenError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if the last codepoint is invalid" do
|
||||
it "raises an ArgumentError if the last non-space codepoint is invalid" do
|
||||
s = "abc\xDF".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
-> { s.rstrip! }.should raise_error(ArgumentError)
|
||||
|
||||
s = "abc\xDF ".force_encoding(Encoding::UTF_8)
|
||||
s.valid_encoding?.should be_false
|
||||
-> { s.rstrip! }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,6 +36,12 @@ describe "String#setbyte" do
|
|||
str.valid_encoding?.should be_true
|
||||
str.setbyte(2,253)
|
||||
str.valid_encoding?.should be_false
|
||||
|
||||
str = "ABC"
|
||||
str.setbyte(0, 0x20) # ' '
|
||||
str.should.valid_encoding?
|
||||
str.setbyte(0, 0xE3)
|
||||
str.should_not.valid_encoding?
|
||||
end
|
||||
|
||||
it "regards a negative index as counting from the end of the String" do
|
||||
|
|
|
@ -38,6 +38,16 @@ describe :string_dedup, shared: true do
|
|||
dynamic.send(@method).should equal("this string is frozen".send(@method).freeze)
|
||||
end
|
||||
|
||||
it "does not deduplicate a frozen string when it has instance variables" do
|
||||
dynamic = %w(this string is frozen).join(' ')
|
||||
dynamic.instance_variable_set(:@a, 1)
|
||||
dynamic.freeze
|
||||
|
||||
dynamic.send(@method).should_not equal("this string is frozen".freeze)
|
||||
dynamic.send(@method).should_not equal("this string is frozen".send(@method).freeze)
|
||||
dynamic.send(@method).should equal(dynamic)
|
||||
end
|
||||
|
||||
ruby_version_is "3.0" do
|
||||
it "interns the provided string if it is frozen" do
|
||||
dynamic = "this string is unique and frozen #{rand}".freeze
|
||||
|
|
|
@ -455,6 +455,14 @@ describe "String#split with Regexp" do
|
|||
a.should == ["Chunky", "Bacon"]
|
||||
end
|
||||
|
||||
it "yields each split substring with default pattern for a lazy substring" do
|
||||
a = []
|
||||
returned_object = "chunky bacon"[1...-1].split { |str| a << str.capitalize }
|
||||
|
||||
returned_object.should == "hunky baco"
|
||||
a.should == ["Hunky", "Baco"]
|
||||
end
|
||||
|
||||
it "yields each split substring with default pattern for a non-ASCII string" do
|
||||
a = []
|
||||
returned_object = "l'été arrive bientôt".split { |str| a << str }
|
||||
|
@ -463,6 +471,14 @@ describe "String#split with Regexp" do
|
|||
a.should == ["l'été", "arrive", "bientôt"]
|
||||
end
|
||||
|
||||
it "yields each split substring with default pattern for a non-ASCII lazy substring" do
|
||||
a = []
|
||||
returned_object = "l'été arrive bientôt"[1...-1].split { |str| a << str }
|
||||
|
||||
returned_object.should == "'été arrive bientô"
|
||||
a.should == ["'été", "arrive", "bientô"]
|
||||
end
|
||||
|
||||
it "yields the string when limit is 1" do
|
||||
a = []
|
||||
returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize }
|
||||
|
|
|
@ -5,4 +5,14 @@ require_relative '../../shared/string/start_with'
|
|||
|
||||
describe "String#start_with?" do
|
||||
it_behaves_like :start_with, :to_s
|
||||
|
||||
# Here and not in the shared examples because this is invalid as a Symbol
|
||||
it "does not check that we are not starting to match at the head of a character" do
|
||||
"\xA9".should.start_with?("\xA9") # A9 is not a character head for UTF-8
|
||||
end
|
||||
|
||||
it "does not check we are matching only part of a character" do
|
||||
"\xe3\x81\x82".size.should == 1
|
||||
"\xe3\x81\x82".should.start_with?("\xe3")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,6 +35,12 @@ describe "String#strip!" do
|
|||
a.should == "hello"
|
||||
end
|
||||
|
||||
it "makes a string empty if it is only whitespace" do
|
||||
"".strip!.should == nil
|
||||
" ".strip.should == ""
|
||||
" ".strip.should == ""
|
||||
end
|
||||
|
||||
ruby_version_is '3.0' do
|
||||
it "removes leading and trailing NULL bytes and whitespace" do
|
||||
a = "\000 goodbye \000"
|
||||
|
|
|
@ -28,6 +28,10 @@ describe "String#swapcase" do
|
|||
it "does not swapcase non-ASCII characters" do
|
||||
"aßet".swapcase(:ascii).should == "AßET"
|
||||
end
|
||||
|
||||
it "works with substrings" do
|
||||
"prefix aTé"[-3..-1].swapcase(:ascii).should == "Até"
|
||||
end
|
||||
end
|
||||
|
||||
describe "full Unicode case mapping adapted for Turkic languages" do
|
||||
|
|
|
@ -27,6 +27,10 @@ describe "String#upcase" do
|
|||
it "does not upcase non-ASCII characters" do
|
||||
"aßet".upcase(:ascii).should == "AßET"
|
||||
end
|
||||
|
||||
it "works with substrings" do
|
||||
"prefix té"[-2..-1].upcase(:ascii).should == "Té"
|
||||
end
|
||||
end
|
||||
|
||||
describe "full Unicode case mapping adapted for Turkic languages" do
|
||||
|
|
|
@ -10,6 +10,14 @@ describe "Literal Ranges" do
|
|||
(1...10).should == Range.new(1, 10, true)
|
||||
end
|
||||
|
||||
it "creates a simple range as an object literal" do
|
||||
ary = []
|
||||
2.times do
|
||||
ary.push(1..3)
|
||||
end
|
||||
ary[0].should.equal?(ary[1])
|
||||
end
|
||||
|
||||
it "creates endless ranges" do
|
||||
(1..).should == Range.new(1, nil)
|
||||
(1...).should == Range.new(1, nil, true)
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative '../fixtures/classes'
|
||||
|
||||
# TODO: synchronize with spec/core/regexp/new_spec.rb -
|
||||
# escaping is also tested there
|
||||
describe "Regexps with escape characters" do
|
||||
it "they're supported" do
|
||||
it "supports escape sequences" do
|
||||
/\t/.match("\t").to_a.should == ["\t"] # horizontal tab
|
||||
/\v/.match("\v").to_a.should == ["\v"] # vertical tab
|
||||
/\n/.match("\n").to_a.should == ["\n"] # newline
|
||||
|
@ -15,9 +17,7 @@ describe "Regexps with escape characters" do
|
|||
# \nnn octal char (encoded byte value)
|
||||
end
|
||||
|
||||
it "support quoting meta-characters via escape sequence" do
|
||||
/\\/.match("\\").to_a.should == ["\\"]
|
||||
/\//.match("/").to_a.should == ["/"]
|
||||
it "supports quoting meta-characters via escape sequence" do
|
||||
# parenthesis, etc
|
||||
/\(/.match("(").to_a.should == ["("]
|
||||
/\)/.match(")").to_a.should == [")"]
|
||||
|
@ -25,6 +25,8 @@ describe "Regexps with escape characters" do
|
|||
/\]/.match("]").to_a.should == ["]"]
|
||||
/\{/.match("{").to_a.should == ["{"]
|
||||
/\}/.match("}").to_a.should == ["}"]
|
||||
/\</.match("<").to_a.should == ["<"]
|
||||
/\>/.match(">").to_a.should == [">"]
|
||||
# alternation separator
|
||||
/\|/.match("|").to_a.should == ["|"]
|
||||
# quantifiers
|
||||
|
@ -37,11 +39,81 @@ describe "Regexps with escape characters" do
|
|||
/\$/.match("$").to_a.should == ["$"]
|
||||
end
|
||||
|
||||
it "supports quoting meta-characters via escape sequence when used as a terminator" do
|
||||
# parenthesis, etc
|
||||
# %r[[, %r((, etc literals - are forbidden
|
||||
%r(\().match("(").to_a.should == ["("]
|
||||
%r(\)).match(")").to_a.should == [")"]
|
||||
%r)\().match("(").to_a.should == ["("]
|
||||
%r)\)).match(")").to_a.should == [")"]
|
||||
|
||||
%r[\[].match("[").to_a.should == ["["]
|
||||
%r[\]].match("]").to_a.should == ["]"]
|
||||
%r]\[].match("[").to_a.should == ["["]
|
||||
%r]\]].match("]").to_a.should == ["]"]
|
||||
|
||||
%r{\{}.match("{").to_a.should == ["{"]
|
||||
%r{\}}.match("}").to_a.should == ["}"]
|
||||
%r}\{}.match("{").to_a.should == ["{"]
|
||||
%r}\}}.match("}").to_a.should == ["}"]
|
||||
|
||||
%r<\<>.match("<").to_a.should == ["<"]
|
||||
%r<\>>.match(">").to_a.should == [">"]
|
||||
%r>\<>.match("<").to_a.should == ["<"]
|
||||
%r>\>>.match(">").to_a.should == [">"]
|
||||
|
||||
# alternation separator
|
||||
%r|\||.match("|").to_a.should == ["|"]
|
||||
# quantifiers
|
||||
%r?\??.match("?").to_a.should == ["?"]
|
||||
%r.\...match(".").to_a.should == ["."]
|
||||
%r*\**.match("*").to_a.should == ["*"]
|
||||
%r+\++.match("+").to_a.should == ["+"]
|
||||
# line anchors
|
||||
%r^\^^.match("^").to_a.should == ["^"]
|
||||
%r$\$$.match("$").to_a.should == ["$"]
|
||||
end
|
||||
|
||||
it "supports quoting non-meta-characters via escape sequence when used as a terminator" do
|
||||
non_meta_character_terminators = [
|
||||
'!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`', '/', '=', '~'
|
||||
]
|
||||
|
||||
non_meta_character_terminators.each do |c|
|
||||
pattern = eval("%r" + c + "\\" + c + c)
|
||||
pattern.match(c).to_a.should == [c]
|
||||
end
|
||||
end
|
||||
|
||||
it "does not change semantics of escaped non-meta-character when used as a terminator" do
|
||||
all_terminators = [*("!".."/"), *(":".."@"), *("[".."`"), *("{".."~")]
|
||||
meta_character_terminators = ["$", "^", "*", "+", ".", "?", "|", "}", ")", ">", "]"]
|
||||
special_cases = ['(', '{', '[', '<', '\\']
|
||||
|
||||
# it should be equivalent to
|
||||
# [ '!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`', '/', '=', '~' ]
|
||||
non_meta_character_terminators = all_terminators - meta_character_terminators - special_cases
|
||||
|
||||
non_meta_character_terminators.each do |c|
|
||||
pattern = eval("%r" + c + "\\" + c + c)
|
||||
pattern.should == /#{c}/
|
||||
end
|
||||
end
|
||||
|
||||
it "does not change semantics of escaped meta-character when used as a terminator" do
|
||||
meta_character_terminators = ["$", "^", "*", "+", ".", "?", "|", "}", ")", ">", "]"]
|
||||
|
||||
meta_character_terminators.each do |c|
|
||||
pattern = eval("%r" + c + "\\" + c + c)
|
||||
pattern.should == eval("/\\#{c}/")
|
||||
end
|
||||
end
|
||||
|
||||
it "allows any character to be escaped" do
|
||||
/\y/.match("y").to_a.should == ["y"]
|
||||
end
|
||||
|
||||
it "support \\x (hex characters)" do
|
||||
it "supports \\x (hex characters)" do
|
||||
/\xA/.match("\nxyz").to_a.should == ["\n"]
|
||||
/\x0A/.match("\n").to_a.should == ["\n"]
|
||||
/\xAA/.match("\nA").should be_nil
|
||||
|
@ -53,7 +125,7 @@ describe "Regexps with escape characters" do
|
|||
# \x{7HHHHHHH} wide hexadecimal char (character code point value)
|
||||
end
|
||||
|
||||
it "support \\c (control characters)" do
|
||||
it "supports \\c (control characters)" do
|
||||
#/\c \c@\c`/.match("\00\00\00").to_a.should == ["\00\00\00"]
|
||||
/\c#\cc\cC/.match("\03\03\03").to_a.should == ["\03\03\03"]
|
||||
/\c'\cG\cg/.match("\a\a\a").to_a.should == ["\a\a\a"]
|
||||
|
|
|
@ -96,7 +96,6 @@ describe "Literal Regexps" do
|
|||
/./.match("\0").to_a.should == ["\0"]
|
||||
end
|
||||
|
||||
|
||||
it "supports | (alternations)" do
|
||||
/a|b/.match("a").to_a.should == ["a"]
|
||||
end
|
||||
|
@ -161,26 +160,6 @@ describe "Literal Regexps" do
|
|||
pattern.should_not =~ 'T'
|
||||
end
|
||||
|
||||
escapable_terminators = ['!', '"', '#', '%', '&', "'", ',', '-', ':', ';', '@', '_', '`']
|
||||
|
||||
it "supports escaping characters when used as a terminator" do
|
||||
escapable_terminators.each do |c|
|
||||
ref = "(?-mix:#{c})"
|
||||
pattern = eval("%r" + c + "\\" + c + c)
|
||||
pattern.to_s.should == ref
|
||||
end
|
||||
end
|
||||
|
||||
it "treats an escaped non-escapable character normally when used as a terminator" do
|
||||
all_terminators = [*("!".."/"), *(":".."@"), *("[".."`"), *("{".."~")]
|
||||
special_cases = ['(', '{', '[', '<', '\\', '=', '~']
|
||||
(all_terminators - special_cases - escapable_terminators).each do |c|
|
||||
ref = "(?-mix:\\#{c})"
|
||||
pattern = eval("%r" + c + "\\" + c + c)
|
||||
pattern.to_s.should == ref
|
||||
end
|
||||
end
|
||||
|
||||
it "support handling unicode 9.0 characters with POSIX bracket expressions" do
|
||||
char_lowercase = "\u{104D8}" # OSAGE SMALL LETTER A
|
||||
/[[:lower:]]/.match(char_lowercase).to_s.should == char_lowercase
|
||||
|
|
|
@ -89,6 +89,12 @@ describe :stringio_read_no_arguments, shared: true do
|
|||
@io.send(@method)
|
||||
@io.pos.should eql(7)
|
||||
end
|
||||
|
||||
it "correctly update the current position in bytes when multi-byte characters are used" do
|
||||
@io.print("example\u03A3") # Overwrite the original string with 8 characters containing 9 bytes.
|
||||
@io.send(@method)
|
||||
@io.pos.should eql(9)
|
||||
end
|
||||
end
|
||||
|
||||
describe :stringio_read_nil, shared: true do
|
||||
|
|
|
@ -128,10 +128,16 @@ describe "C-API Encoding function" do
|
|||
|
||||
describe "rb_enc_mbc_to_codepoint" do
|
||||
it "returns the correct codepoint for the given character and size" do
|
||||
@s.rb_enc_mbc_to_codepoint("é", 2).should == 0x00E9
|
||||
@s.rb_enc_mbc_to_codepoint("éa", 2).should == 0x00E9
|
||||
@s.rb_enc_mbc_to_codepoint("éa", 1).should == 0xC3
|
||||
@s.rb_enc_mbc_to_codepoint("éa", 3).should == 0x00E9
|
||||
@s.rb_enc_mbc_to_codepoint("é").should == 0xE9
|
||||
end
|
||||
|
||||
it "returns 0 if p == e" do
|
||||
@s.rb_enc_mbc_to_codepoint("").should == 0
|
||||
end
|
||||
|
||||
it "returns the raw byte if incomplete character in UTF-8" do
|
||||
@s.rb_enc_mbc_to_codepoint("\xC3").should == 0xC3
|
||||
@s.rb_enc_mbc_to_codepoint("\x80").should == 0x80
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -630,6 +636,7 @@ describe "C-API Encoding function" do
|
|||
it "returns the correct case fold for the given string" do
|
||||
@s.ONIGENC_MBC_CASE_FOLD("lower").should == ["l", 1]
|
||||
@s.ONIGENC_MBC_CASE_FOLD("Upper").should == ["u", 1]
|
||||
@s.ONIGENC_MBC_CASE_FOLD("ABC"[1..-1]).should == ["b", 1]
|
||||
end
|
||||
|
||||
it "works with other encodings" do
|
||||
|
|
|
@ -120,10 +120,9 @@ static VALUE encoding_spec_rb_enc_from_index(VALUE self, VALUE index) {
|
|||
return rb_str_new2(rb_enc_from_index(NUM2INT(index))->name);
|
||||
}
|
||||
|
||||
static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str, VALUE offset) {
|
||||
int o = FIX2INT(offset);
|
||||
static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str) {
|
||||
char *p = RSTRING_PTR(str);
|
||||
char *e = p + o;
|
||||
char *e = RSTRING_END(str);
|
||||
return INT2FIX(rb_enc_mbc_to_codepoint(p, e, rb_enc_get(str)));
|
||||
}
|
||||
|
||||
|
@ -341,7 +340,7 @@ void Init_encoding_spec(void) {
|
|||
rb_define_method(cls, "rb_enc_isalnum", encoding_spec_rb_enc_isalnum, 2);
|
||||
rb_define_method(cls, "rb_enc_isspace", encoding_spec_rb_enc_isspace, 2);
|
||||
rb_define_method(cls, "rb_enc_from_index", encoding_spec_rb_enc_from_index, 1);
|
||||
rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 2);
|
||||
rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 1);
|
||||
rb_define_method(cls, "rb_enc_mbcput", encoding_spec_rb_enc_mbcput, 2);
|
||||
rb_define_method(cls, "rb_enc_from_encoding", encoding_spec_rb_enc_from_encoding, 1);
|
||||
rb_define_method(cls, "rb_enc_get", encoding_spec_rb_enc_get, 1);
|
||||
|
|
|
@ -39,6 +39,41 @@ describe :file_executable, shared: true do
|
|||
-> { @object.send(@method, nil) }.should raise_error(TypeError)
|
||||
-> { @object.send(@method, false) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_superuser do
|
||||
context "when run by a superuser" do
|
||||
before :each do
|
||||
@file = tmp('temp3.txt')
|
||||
touch @file
|
||||
end
|
||||
|
||||
after :each do
|
||||
rm_r @file
|
||||
end
|
||||
|
||||
it "returns true if file owner has permission to execute" do
|
||||
File.chmod(0766, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "returns true if group has permission to execute" do
|
||||
File.chmod(0676, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "returns true if other have permission to execute" do
|
||||
File.chmod(0667, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "return false if nobody has permission to execute" do
|
||||
File.chmod(0666, @file)
|
||||
@object.send(@method, @file).should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_executable_missing, shared: true do
|
||||
|
|
|
@ -37,6 +37,41 @@ describe :file_executable_real, shared: true do
|
|||
-> { @object.send(@method, nil) }.should raise_error(TypeError)
|
||||
-> { @object.send(@method, false) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_real_superuser do
|
||||
context "when run by a real superuser" do
|
||||
before :each do
|
||||
@file = tmp('temp3.txt')
|
||||
touch @file
|
||||
end
|
||||
|
||||
after :each do
|
||||
rm_r @file
|
||||
end
|
||||
|
||||
it "returns true if file owner has permission to execute" do
|
||||
File.chmod(0766, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "returns true if group has permission to execute" do
|
||||
File.chmod(0676, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "returns true if other have permission to execute" do
|
||||
File.chmod(0667, @file)
|
||||
@object.send(@method, @file).should == true
|
||||
end
|
||||
|
||||
it "return false if nobody has permission to execute" do
|
||||
File.chmod(0666, @file)
|
||||
@object.send(@method, @file).should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_executable_real_missing, shared: true do
|
||||
|
|
|
@ -24,6 +24,22 @@ describe :file_readable, shared: true do
|
|||
it "accepts an object that has a #to_path method" do
|
||||
@object.send(@method, mock_to_path(@file2)).should == true
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_superuser do
|
||||
context "when run by a superuser" do
|
||||
it "returns true unconditionally" do
|
||||
file = tmp('temp.txt')
|
||||
touch file
|
||||
|
||||
File.chmod(0333, file)
|
||||
@object.send(@method, file).should == true
|
||||
|
||||
rm_r file
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_readable_missing, shared: true do
|
||||
|
|
|
@ -14,6 +14,22 @@ describe :file_readable_real, shared: true do
|
|||
it "accepts an object that has a #to_path method" do
|
||||
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_real_superuser do
|
||||
context "when run by a real superuser" do
|
||||
it "returns true unconditionally" do
|
||||
file = tmp('temp.txt')
|
||||
touch file
|
||||
|
||||
File.chmod(0333, file)
|
||||
@object.send(@method, file).should == true
|
||||
|
||||
rm_r file
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_readable_real_missing, shared: true do
|
||||
|
|
|
@ -19,6 +19,22 @@ describe :file_writable, shared: true do
|
|||
it "accepts an object that has a #to_path method" do
|
||||
File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true }
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_superuser do
|
||||
context "when run by a superuser" do
|
||||
it "returns true unconditionally" do
|
||||
file = tmp('temp.txt')
|
||||
touch file
|
||||
|
||||
File.chmod(0555, file)
|
||||
@object.send(@method, file).should == true
|
||||
|
||||
rm_r file
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_writable_missing, shared: true do
|
||||
|
|
|
@ -24,6 +24,22 @@ describe :file_writable_real, shared: true do
|
|||
-> { @object.send(@method, nil) }.should raise_error(TypeError)
|
||||
-> { @object.send(@method, false) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
as_real_superuser do
|
||||
context "when run by a real superuser" do
|
||||
it "returns true unconditionally" do
|
||||
file = tmp('temp.txt')
|
||||
touch file
|
||||
|
||||
File.chmod(0555, file)
|
||||
@object.send(@method, file).should == true
|
||||
|
||||
rm_r file
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :file_writable_real_missing, shared: true do
|
||||
|
|
|
@ -38,7 +38,7 @@ describe :end_with, shared: true do
|
|||
it "uses only the needed arguments" do
|
||||
find = mock('h')
|
||||
find.should_not_receive(:to_str)
|
||||
"hello".send(@method).should.end_with?("o",find)
|
||||
"hello".send(@method).should.end_with?("o", find)
|
||||
end
|
||||
|
||||
it "works for multibyte strings" do
|
||||
|
@ -51,4 +51,11 @@ describe :end_with, shared: true do
|
|||
"あれ".send(@method).end_with?(pat)
|
||||
end.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
|
||||
it "checks that we are starting to match at the head of a character" do
|
||||
"\xC3\xA9".send(@method).should_not.end_with?("\xA9")
|
||||
"\xe3\x81\x82".send(@method).should_not.end_with?("\x82")
|
||||
"ab".force_encoding("UTF-16BE").send(@method).should_not.end_with?(
|
||||
"b".force_encoding("UTF-16BE"))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,4 +69,8 @@ describe :start_with, shared: true do
|
|||
Regexp.last_match.should be_nil
|
||||
$1.should be_nil
|
||||
end
|
||||
|
||||
it "does not check that we are not matching part of a character" do
|
||||
"\xC3\xA9".send(@method).should.start_with?("\xC3")
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче