mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
ffd0820ab3
This removes the related tests, and puts the related specs behind version guards. This affects all code in lib, including some libraries that may want to support older versions of Ruby.
201 lines
5.6 KiB
Ruby
201 lines
5.6 KiB
Ruby
# -*- encoding: utf-8 -*-
|
|
require_relative '../../spec_helper'
|
|
require_relative 'fixtures/classes'
|
|
|
|
describe "String#scan" do
|
|
it "returns an array containing all matches" do
|
|
"cruel world".scan(/\w+/).should == ["cruel", "world"]
|
|
"cruel world".scan(/.../).should == ["cru", "el ", "wor"]
|
|
|
|
# Edge case
|
|
"hello".scan(//).should == ["", "", "", "", "", ""]
|
|
"".scan(//).should == [""]
|
|
end
|
|
|
|
it "respects unicode when the pattern collapses to nothing" do
|
|
str = "こにちわ"
|
|
reg = %r!!
|
|
str.scan(reg).should == ["", "", "", "", ""]
|
|
end
|
|
|
|
it "stores groups as arrays in the returned arrays" do
|
|
"hello".scan(/()/).should == [[""]] * 6
|
|
"hello".scan(/()()/).should == [["", ""]] * 6
|
|
"cruel world".scan(/(...)/).should == [["cru"], ["el "], ["wor"]]
|
|
"cruel world".scan(/(..)(..)/).should == [["cr", "ue"], ["l ", "wo"]]
|
|
end
|
|
|
|
it "scans for occurrences of the string if pattern is a string" do
|
|
"one two one two".scan('one').should == ["one", "one"]
|
|
"hello.".scan('.').should == ['.']
|
|
end
|
|
|
|
it "sets $~ to MatchData of last match and nil when there's none" do
|
|
'hello.'.scan(/.(.)/)
|
|
$~[0].should == 'o.'
|
|
|
|
'hello.'.scan(/not/)
|
|
$~.should == nil
|
|
|
|
'hello.'.scan('l')
|
|
$~.begin(0).should == 3
|
|
$~[0].should == 'l'
|
|
|
|
'hello.'.scan('not')
|
|
$~.should == nil
|
|
end
|
|
|
|
it "supports \\G which matches the end of the previous match / string start for first match" do
|
|
"one two one two".scan(/\G\w+/).should == ["one"]
|
|
"one two one two".scan(/\G\w+\s*/).should == ["one ", "two ", "one ", "two"]
|
|
"one two one two".scan(/\G\s*\w+/).should == ["one", " two", " one", " two"]
|
|
end
|
|
|
|
it "tries to convert pattern to a string via to_str" do
|
|
obj = mock('o')
|
|
obj.should_receive(:to_str).and_return("o")
|
|
"o_o".scan(obj).should == ["o", "o"]
|
|
end
|
|
|
|
it "raises a TypeError if pattern isn't a Regexp and can't be converted to a String" do
|
|
-> { "cruel world".scan(5) }.should raise_error(TypeError)
|
|
not_supported_on :opal do
|
|
-> { "cruel world".scan(:test) }.should raise_error(TypeError)
|
|
end
|
|
-> { "cruel world".scan(mock('x')) }.should raise_error(TypeError)
|
|
end
|
|
|
|
ruby_version_is ''...'2.7' do
|
|
it "taints the results if the String argument is tainted" do
|
|
a = "hello hello hello".scan("hello".taint)
|
|
a.each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results when passed a String argument if self is tainted" do
|
|
a = "hello hello hello".taint.scan("hello")
|
|
a.each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results if the Regexp argument is tainted" do
|
|
a = "hello".scan(/./.taint)
|
|
a.each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results when passed a Regexp argument if self is tainted" do
|
|
a = "hello".taint.scan(/./)
|
|
a.each { |m| m.tainted?.should be_true }
|
|
end
|
|
end
|
|
|
|
# jruby/jruby#5513
|
|
it "does not raise any errors when passed a multi-byte string" do
|
|
"あああaaaあああ".scan("あああ").should == ["あああ", "あああ"]
|
|
end
|
|
end
|
|
|
|
describe "String#scan with pattern and block" do
|
|
it "returns self" do
|
|
s = "foo"
|
|
s.scan(/./) {}.should equal(s)
|
|
s.scan(/roar/) {}.should equal(s)
|
|
end
|
|
|
|
it "passes each match to the block as one argument: an array" do
|
|
a = []
|
|
"cruel world".scan(/\w+/) { |*w| a << w }
|
|
a.should == [["cruel"], ["world"]]
|
|
end
|
|
|
|
it "passes groups to the block as one argument: an array" do
|
|
a = []
|
|
"cruel world".scan(/(..)(..)/) { |w| a << w }
|
|
a.should == [["cr", "ue"], ["l ", "wo"]]
|
|
end
|
|
|
|
it "sets $~ for access from the block" do
|
|
str = "hello"
|
|
|
|
matches = []
|
|
offsets = []
|
|
|
|
str.scan(/([aeiou])/) do
|
|
md = $~
|
|
md.string.should == str
|
|
matches << md.to_a
|
|
offsets << md.offset(0)
|
|
str
|
|
end
|
|
|
|
matches.should == [["e", "e"], ["o", "o"]]
|
|
offsets.should == [[1, 2], [4, 5]]
|
|
|
|
matches = []
|
|
offsets = []
|
|
|
|
str.scan("l") do
|
|
md = $~
|
|
md.string.should == str
|
|
matches << md.to_a
|
|
offsets << md.offset(0)
|
|
str
|
|
end
|
|
|
|
matches.should == [["l"], ["l"]]
|
|
offsets.should == [[2, 3], [3, 4]]
|
|
end
|
|
|
|
it "restores $~ after leaving the block" do
|
|
[/./, "l"].each do |pattern|
|
|
old_md = nil
|
|
"hello".scan(pattern) do
|
|
old_md = $~
|
|
"ok".match(/./)
|
|
"x"
|
|
end
|
|
|
|
$~[0].should == old_md[0]
|
|
$~.string.should == "hello"
|
|
end
|
|
end
|
|
|
|
it "sets $~ to MatchData of last match and nil when there's none for access from outside" do
|
|
'hello.'.scan('l') { 'x' }
|
|
$~.begin(0).should == 3
|
|
$~[0].should == 'l'
|
|
|
|
'hello.'.scan('not') { 'x' }
|
|
$~.should == nil
|
|
|
|
'hello.'.scan(/.(.)/) { 'x' }
|
|
$~[0].should == 'o.'
|
|
|
|
'hello.'.scan(/not/) { 'x' }
|
|
$~.should == nil
|
|
end
|
|
|
|
ruby_version_is ''...'2.7' do
|
|
it "taints the results if the String argument is tainted" do
|
|
"hello hello hello".scan("hello".taint).each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results when passed a String argument if self is tainted" do
|
|
"hello hello hello".taint.scan("hello").each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results if the Regexp argument is tainted" do
|
|
"hello".scan(/./.taint).each { |m| m.tainted?.should be_true }
|
|
end
|
|
|
|
it "taints the results when passed a Regexp argument if self is tainted" do
|
|
"hello".taint.scan(/./).each { |m| m.tainted?.should be_true }
|
|
end
|
|
end
|
|
|
|
it "passes block arguments as individual arguments when blocks are provided" do
|
|
"a b c\na b c\na b c".scan(/(\w*) (\w*) (\w*)/) do |first,second,third|
|
|
first.should == 'a';
|
|
second.should == 'b';
|
|
third.should == 'c';
|
|
end
|
|
end
|
|
end
|