mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@37e52e5
This commit is contained in:
parent
dbea0be13d
commit
36dde35e02
48 changed files with 811 additions and 64 deletions
135
spec/ruby/language/regexp/empty_checks_spec.rb
Normal file
135
spec/ruby/language/regexp/empty_checks_spec.rb
Normal file
|
@ -0,0 +1,135 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative '../fixtures/classes'
|
||||
|
||||
describe "empty checks in Regexps" do
|
||||
|
||||
it "allow extra empty iterations" do
|
||||
/()?/.match("").to_a.should == ["", ""]
|
||||
/(a*)?/.match("").to_a.should == ["", ""]
|
||||
/(a*)*/.match("").to_a.should == ["", ""]
|
||||
# The bounds are high to avoid DFA-based matchers in implementations
|
||||
# and to check backtracking behavior.
|
||||
/(?:a|()){500,1000}/.match("a" * 500).to_a.should == ["a" * 500, ""]
|
||||
|
||||
# Variations with non-greedy loops.
|
||||
/()??/.match("").to_a.should == ["", nil]
|
||||
/(a*?)?/.match("").to_a.should == ["", ""]
|
||||
/(a*)??/.match("").to_a.should == ["", nil]
|
||||
/(a*?)??/.match("").to_a.should == ["", nil]
|
||||
/(a*?)*/.match("").to_a.should == ["", ""]
|
||||
/(a*)*?/.match("").to_a.should == ["", nil]
|
||||
/(a*?)*?/.match("").to_a.should == ["", nil]
|
||||
end
|
||||
|
||||
it "allow empty iterations in the middle of a loop" do
|
||||
# One empty iteration between a's and b's.
|
||||
/(a|\2b|())*/.match("aaabbb").to_a.should == ["aaabbb", "", ""]
|
||||
/(a|\2b|()){2,4}/.match("aaabbb").to_a.should == ["aaa", "", ""]
|
||||
|
||||
# Two empty iterations between a's and b's.
|
||||
/(a|\2b|\3()|())*/.match("aaabbb").to_a.should == ["aaabbb", "", "", ""]
|
||||
/(a|\2b|\3()|()){2,4}/.match("aaabbb").to_a.should == ["aaa", "", nil, ""]
|
||||
|
||||
# Check that the empty iteration correctly updates the loop counter.
|
||||
/(a|\2b|()){20,24}/.match("a" * 20 + "b" * 5).to_a.should == ["a" * 20 + "b" * 3, "b", ""]
|
||||
|
||||
# Variations with non-greedy loops.
|
||||
/(a|\2b|())*?/.match("aaabbb").to_a.should == ["", nil, nil]
|
||||
/(a|\2b|()){2,4}/.match("aaabbb").to_a.should == ["aaa", "", ""]
|
||||
/(a|\2b|\3()|())*?/.match("aaabbb").to_a.should == ["", nil, nil, nil]
|
||||
/(a|\2b|\3()|()){2,4}/.match("aaabbb").to_a.should == ["aaa", "", nil, ""]
|
||||
/(a|\2b|()){20,24}/.match("a" * 20 + "b" * 5).to_a.should == ["a" * 20 + "b" * 3, "b", ""]
|
||||
end
|
||||
|
||||
it "make the Regexp proceed past the quantified expression on failure" do
|
||||
# If the contents of the ()* quantified group are empty (i.e., they fail
|
||||
# the empty check), the loop will abort. It will not try to backtrack
|
||||
# and try other alternatives (e.g. matching the "a") like in other Regexp
|
||||
# dialects such as ECMAScript.
|
||||
/(?:|a)*/.match("aaa").to_a.should == [""]
|
||||
/(?:()|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/(|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/(()|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
|
||||
# Same expressions, but with backreferences, to force the use of non-DFA-based
|
||||
# engines.
|
||||
/()\1(?:|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/()\1(?:()|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()\1(|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()\1(()|a)*/.match("aaa").to_a.should == ["", "", "", ""]
|
||||
|
||||
# Variations with other zero-width contents of the quantified
|
||||
# group: backreferences, capture groups, lookarounds
|
||||
/()(?:\1|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/()(?:()\1|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()(?:(\1)|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()(?:\1()|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()(\1|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()(()\1|a)*/.match("aaa").to_a.should == ["", "", "", ""]
|
||||
/()((\1)|a)*/.match("aaa").to_a.should == ["", "", "", ""]
|
||||
/()(\1()|a)*/.match("aaa").to_a.should == ["", "", "", ""]
|
||||
|
||||
/(?:(?=a)|a)*/.match("aaa").to_a.should == [""]
|
||||
/(?:(?=a)()|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/(?:()(?=a)|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/(?:((?=a))|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/()\1(?:(?=a)|a)*/.match("aaa").to_a.should == ["", ""]
|
||||
/()\1(?:(?=a)()|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()\1(?:()(?=a)|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
/()\1(?:((?=a))|a)*/.match("aaa").to_a.should == ["", "", ""]
|
||||
|
||||
# Variations with non-greedy loops.
|
||||
/(?:|a)*?/.match("aaa").to_a.should == [""]
|
||||
/(?:()|a)*?/.match("aaa").to_a.should == ["", nil]
|
||||
/(|a)*?/.match("aaa").to_a.should == ["", nil]
|
||||
/(()|a)*?/.match("aaa").to_a.should == ["", nil, nil]
|
||||
|
||||
/()\1(?:|a)*?/.match("aaa").to_a.should == ["", ""]
|
||||
/()\1(?:()|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()\1(|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()\1(()|a)*?/.match("aaa").to_a.should == ["", "", nil, nil]
|
||||
|
||||
/()(?:\1|a)*?/.match("aaa").to_a.should == ["", ""]
|
||||
/()(?:()\1|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()(?:(\1)|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()(?:\1()|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()(\1|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()(()\1|a)*?/.match("aaa").to_a.should == ["", "", nil, nil]
|
||||
/()((\1)|a)*?/.match("aaa").to_a.should == ["", "", nil, nil]
|
||||
/()(\1()|a)*?/.match("aaa").to_a.should == ["", "", nil, nil]
|
||||
|
||||
/(?:(?=a)|a)*?/.match("aaa").to_a.should == [""]
|
||||
/(?:(?=a)()|a)*?/.match("aaa").to_a.should == ["", nil]
|
||||
/(?:()(?=a)|a)*?/.match("aaa").to_a.should == ["", nil]
|
||||
/(?:((?=a))|a)*?/.match("aaa").to_a.should == ["", nil]
|
||||
/()\1(?:(?=a)|a)*?/.match("aaa").to_a.should == ["", ""]
|
||||
/()\1(?:(?=a)()|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()\1(?:()(?=a)|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
/()\1(?:((?=a))|a)*?/.match("aaa").to_a.should == ["", "", nil]
|
||||
end
|
||||
|
||||
it "shouldn't cause the Regexp parser to get stuck in a loop" do
|
||||
/(|a|\2b|())*/.match("aaabbb").to_a.should == ["", "", nil]
|
||||
/(a||\2b|())*/.match("aaabbb").to_a.should == ["aaa", "", nil]
|
||||
/(a|\2b||())*/.match("aaabbb").to_a.should == ["aaa", "", nil]
|
||||
/(a|\2b|()|)*/.match("aaabbb").to_a.should == ["aaabbb", "", ""]
|
||||
/(()|a|\3b|())*/.match("aaabbb").to_a.should == ["", "", "", nil]
|
||||
/(a|()|\3b|())*/.match("aaabbb").to_a.should == ["aaa", "", "", nil]
|
||||
/(a|\2b|()|())*/.match("aaabbb").to_a.should == ["aaabbb", "", "", nil]
|
||||
/(a|\3b|()|())*/.match("aaabbb").to_a.should == ["aaa", "", "", nil]
|
||||
/(a|()|())*/.match("aaa").to_a.should == ["aaa", "", "", nil]
|
||||
/^(()|a|())*$/.match("aaa").to_a.should == ["aaa", "", "", nil]
|
||||
|
||||
# Variations with non-greedy loops.
|
||||
/(|a|\2b|())*?/.match("aaabbb").to_a.should == ["", nil, nil]
|
||||
/(a||\2b|())*?/.match("aaabbb").to_a.should == ["", nil, nil]
|
||||
/(a|\2b||())*?/.match("aaabbb").to_a.should == ["", nil, nil]
|
||||
/(a|\2b|()|)*?/.match("aaabbb").to_a.should == ["", nil, nil]
|
||||
/(()|a|\3b|())*?/.match("aaabbb").to_a.should == ["", nil, nil, nil]
|
||||
/(a|()|\3b|())*?/.match("aaabbb").to_a.should == ["", nil, nil, nil]
|
||||
/(a|\2b|()|())*?/.match("aaabbb").to_a.should == ["", nil, nil, nil]
|
||||
/(a|\3b|()|())*?/.match("aaabbb").to_a.should == ["", nil, nil, nil]
|
||||
/(a|()|())*?/.match("aaa").to_a.should == ["", nil, nil, nil]
|
||||
/^(()|a|())*?$/.match("aaa").to_a.should == ["aaa", "a", "", nil]
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue