diff --git a/test/test-android/app/language/regexp/anchors_spec.rb b/test/test-android/app/language/regexp/anchors_spec.rb new file mode 100644 index 00000000..524a5993 --- /dev/null +++ b/test/test-android/app/language/regexp/anchors_spec.rb @@ -0,0 +1,166 @@ +describe "Regexps with anchors" do + it 'supports ^ (line start anchor)' do + # Basic matching + /^foo/.match("foo").to_a.should == ["foo"] + /^bar/.match("foo\nbar").to_a.should == ["bar"] + # Basic non-matching + /^foo/.match(" foo").should be_nil + /foo^/.match("foo\n\n\n").should be_nil + + # A bit advanced + /^^^foo/.match("foo").to_a.should == ["foo"] + (/^[^f]/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["\n"] + (/($^)($^)/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["", "", ""] + + # Different start of line chars +=begin # MacRuby's regexps consider \r as a new line + /^bar/.match("foo\rbar").should be_nil +=end + /^bar/.match("foo\0bar").should be_nil + + # Trivial + /^/.match("foo").to_a.should == [""] + + # Grouping + /(^foo)/.match("foo").to_a.should == ["foo", "foo"] + /(^)/.match("foo").to_a.should == ["", ""] + /(foo\n^)(^bar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo\n", "bar"] + end + + it 'does not match ^ after trailing \n' do + /^(?!\A)/.match("foo\n").should be_nil # There is no (empty) line after a trailing \n + end + + it 'supports $ (line end anchor)' do + # Basic matching + /foo$/.match("foo").to_a.should == ["foo"] + /foo$/.match("foo\nbar").to_a.should == ["foo"] + # Basic non-matching + /foo$/.match("foo ").should be_nil + /$foo/.match("\n\n\nfoo").should be_nil + + # A bit advanced + /foo$$$/.match("foo").to_a.should == ["foo"] + (/[^o]$/ =~ "foo\n\n").should == ("foo\n".size - 1) and $~.to_a.should == ["\n"] + + # Different end of line chars +=begin # MacRuby's regexps consider \r as a new line + /foo$/.match("foo\r\nbar").should be_nil +=endif + /foo$/.match("foo\0bar").should be_nil + + # Trivial + (/$/ =~ "foo").should == "foo".size and $~.to_a.should == [""] + + # Grouping + /(foo$)/.match("foo").to_a.should == ["foo", "foo"] + (/($)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""] + /(foo$)($\nbar)/.match("foo\nbar").to_a.should == ["foo\nbar", "foo", "\nbar"] + end + + it 'supports \A (string start anchor)' do + # Basic matching + /\Afoo/.match("foo").to_a.should == ["foo"] + # Basic non-matching + /\Abar/.match("foo\nbar").should be_nil + /\Afoo/.match(" foo").should be_nil + + # A bit advanced + /\A\A\Afoo/.match("foo").to_a.should == ["foo"] + /(\A\Z)(\A\Z)/.match("").to_a.should == ["", "", ""] + + # Different start of line chars + /\Abar/.match("foo\0bar").should be_nil + + # Grouping + /(\Afoo)/.match("foo").to_a.should == ["foo", "foo"] + /(\A)/.match("foo").to_a.should == ["", ""] + end + + it 'supports \Z (string end anchor, including before trailing \n)' do + # Basic matching + /foo\Z/.match("foo").to_a.should == ["foo"] + /foo\Z/.match("foo\n").to_a.should == ["foo"] + # Basic non-matching + /foo\Z/.match("foo\nbar").should be_nil + /foo\Z/.match("foo ").should be_nil + + # A bit advanced + /foo\Z\Z\Z/.match("foo\n").to_a.should == ["foo"] + (/($\Z)($\Z)/ =~ "foo\n").should == "foo".size and $~.to_a.should == ["", "", ""] + (/(\z\Z)(\z\Z)/ =~ "foo\n").should == "foo\n".size and $~.to_a.should == ["", "", ""] + + # Different end of line chars + /foo\Z/.match("foo\0bar").should be_nil +=begin # MacRuby's regexps consider \r as a new line + /foo\Z/.match("foo\r\n").should be_nil +=end + + # Grouping + /(foo\Z)/.match("foo").to_a.should == ["foo", "foo"] + (/(\Z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""] + end + + it 'supports \z (string end anchor)' do + # Basic matching + /foo\z/.match("foo").to_a.should == ["foo"] + # Basic non-matching + /foo\z/.match("foo\nbar").should be_nil + /foo\z/.match("foo\n").should be_nil + /foo\z/.match("foo ").should be_nil + + # A bit advanced + /foo\z\z\z/.match("foo").to_a.should == ["foo"] + (/($\z)($\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", "", ""] + + # Different end of line chars + /foo\z/.match("foo\0bar").should be_nil + /foo\z/.match("foo\r\nbar").should be_nil + + # Grouping + /(foo\z)/.match("foo").to_a.should == ["foo", "foo"] + (/(\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", ""] + end + + it 'supports \b (word boundary)' do + # Basic matching + /foo\b/.match("foo").to_a.should == ["foo"] + /foo\b/.match("foo\n").to_a.should == ["foo"] + LanguageSpecs.white_spaces.scan(/./).each do |c| + /foo\b/.match("foo" + c).to_a.should == ["foo"] + end + LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c| + /foo\b/.match("foo" + c).to_a.should == ["foo"] + end + /foo\b/.match("foo\0").to_a.should == ["foo"] + # Basic non-matching + /foo\b/.match("foobar").should be_nil + /foo\b/.match("foo123").should be_nil + /foo\b/.match("foo_").should be_nil + end + + it 'supports \B (non-word-boundary)' do + # Basic matching + /foo\B/.match("foobar").to_a.should == ["foo"] + /foo\B/.match("foo123").to_a.should == ["foo"] + /foo\B/.match("foo_").to_a.should == ["foo"] + # Basic non-matching + /foo\B/.match("foo").should be_nil + /foo\B/.match("foo\n").should be_nil + LanguageSpecs.white_spaces.scan(/./).each do |c| + /foo\B/.match("foo" + c).should be_nil + end + LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c| + /foo\B/.match("foo" + c).should be_nil + end + /foo\B/.match("foo\0").should be_nil + end + + it 'supports (?= ) (positive lookahead)' do + /foo.(?=bar)/.match("foo1 foo2bar").to_a.should == ["foo2"] + end + + it 'supports (?! ) (negative lookahead)' do + /foo.(?!bar)/.match("foo1bar foo2").to_a.should == ["foo2"] + end +end diff --git a/test/test-android/app/language/regexp/back-references_spec.rb b/test/test-android/app/language/regexp/back-references_spec.rb new file mode 100644 index 00000000..feff9a0f --- /dev/null +++ b/test/test-android/app/language/regexp/back-references_spec.rb @@ -0,0 +1,49 @@ +describe "Regexps with back-references" do + it 'saves match data in the $~ pseudo-global variable' do + "hello" =~ /l+/ + $~.to_a.should == ["ll"] + end + + it 'saves captures in numbered $[1-9] variables' do + "1234567890" =~ /(1)(2)(3)(4)(5)(6)(7)(8)(9)(0)/ + $~.to_a.should == ["1234567890", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"] + $1.should == "1" + $2.should == "2" + $3.should == "3" + $4.should == "4" + $5.should == "5" + $6.should == "6" + $7.should == "7" + $8.should == "8" + $9.should == "9" + end + + it 'will not clobber capture variables across threads' do + cap1, cap2, cap3 = nil + "foo" =~ /(o+)/ + cap1 = [$~.to_a, $1] + Thread.start do + cap2 = [$~.to_a, $1] + "bar" =~ /(a)/ + cap3 = [$~.to_a, $1] + end.join + cap4 = [$~.to_a, $1] + cap1.should == [["oo", "oo"], "oo"] + cap2.should == [[], nil] + cap3.should == [["a", "a"], "a"] + cap4.should == [["oo", "oo"], "oo"] + end + + it 'supports \ (backreference to previous group match)' do + /(foo.)\1/.match("foo1foo1").to_a.should == ["foo1foo1", "foo1"] + /(foo.)\1/.match("foo1foo2").should be_nil + end + +=begin + not_compliant_on :ironruby, :macruby do + it 'resets nested \ backreference before match of outer subexpression' do + /(a\1?){2}/.match("aaaa").to_a.should == ["aa", "a"] + end + end +=end +end