This commit is contained in:
Benoit Daloze 2022-07-27 17:18:25 +02:00
Родитель 44f42413e6
Коммит 6582df26dc
41 изменённых файлов: 527 добавлений и 55 удалений

Просмотреть файл

@ -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 == ""
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 == ""
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