Projects

Ticket #762: test_regexp.rb

File test_regexp.rb, 29.3 KB (added by watson1978@…, 23 months ago)
Line 
1module Kernel
2  def require_relative(path)
3    require File.join(File.dirname(caller[0]), path.to_str)
4  end
5end
6
7require 'test/unit'
8require_relative 'envutil'
9
10class TestRegexp < Test::Unit::TestCase
11  def setup
12    @verbose = $VERBOSE
13    $VERBOSE = nil
14  end
15
16  def teardown
17    $VERBOSE = @verbose
18  end
19
20  def test_ruby_core_27247
21    assert_match(/(a){2}z/, "aaz")
22  end
23
24  def test_ruby_dev_24643
25    assert_nothing_raised("[ruby-dev:24643]") {
26      /(?:(?:[a]*[a])?b)*a*$/ =~ "aabaaca"
27    }
28  end
29
30  def test_ruby_talk_116455
31    assert_match(/^(\w{2,}).* ([A-Za-z\xa2\xc0-\xff]{2,}?)$/n, "Hallo Welt")
32  end
33
34  def test_ruby_dev_24887
35    assert_equal("a".gsub(/a\Z/, ""), "")
36  end
37
38  def test_yoshidam_net_20041111_1
39    s = "[\xC2\xA0-\xC3\xBE]"
40    assert_match(Regexp.new(s, nil, "u"), "\xC3\xBE")
41  end
42
43  def test_yoshidam_net_20041111_2
44    assert_raise(RegexpError) do
45      s = "[\xFF-\xFF]".force_encoding("utf-8")
46      Regexp.new(s, nil, "u")
47    end
48  end
49
50  def test_ruby_dev_31309
51    assert_equal('Ruby', 'Ruby'.sub(/[^a-z]/i, '-'))
52  end
53
54  def test_assert_normal_exit
55    # moved from knownbug.  It caused core.
56    Regexp.union("a", "a")
57  end
58
59  def test_to_s
60    assert_equal '(?-mix:\x00)', Regexp.new("\0").to_s
61  end
62
63  def test_union
64    assert_equal :ok, begin
65      Regexp.union(
66        "a",
67        Regexp.new("\xc2\xa1".force_encoding("euc-jp")),
68        Regexp.new("\xc2\xa1".force_encoding("utf-8")))
69      :ng
70    rescue ArgumentError
71      :ok
72    end
73  end
74
75  def test_named_capture
76    m = /&(?<foo>.*?);/.match("aaa &amp; yyy")
77    assert_equal("amp", m["foo"])
78    assert_equal("amp", m[:foo])
79    assert_equal(5, m.begin(:foo))
80    assert_equal(8, m.end(:foo))
81    assert_equal([5,8], m.offset(:foo))
82
83    assert_equal("aaa [amp] yyy",
84      "aaa &amp; yyy".sub(/&(?<foo>.*?);/, '[\k<foo>]'))
85
86    assert_equal('#<MatchData "&amp; y" foo:"amp">',
87      /&(?<foo>.*?); (y)/.match("aaa &amp; yyy").inspect)
88    assert_equal('#<MatchData "&amp; y" 1:"amp" 2:"y">',
89      /&(.*?); (y)/.match("aaa &amp; yyy").inspect)
90    assert_equal('#<MatchData "&amp; y" foo:"amp" bar:"y">',
91      /&(?<foo>.*?); (?<bar>y)/.match("aaa &amp; yyy").inspect)
92    assert_equal('#<MatchData "&amp; y" foo:"amp" foo:"y">',
93      /&(?<foo>.*?); (?<foo>y)/.match("aaa &amp; yyy").inspect)
94
95    /(?<id>[A-Za-z_]+)/ =~ "!abc"
96    assert_equal("abc", Regexp.last_match(:id))
97
98    /a/ =~ "b" # doesn't match.
99    assert_equal(nil, Regexp.last_match)
100    assert_equal(nil, Regexp.last_match(1))
101    assert_equal(nil, Regexp.last_match(:foo))
102
103    assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.names)
104    assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.names)
105    assert_equal([], /(.)(.)/.names)
106
107    assert_equal(["foo", "bar"], /(?<foo>.)(?<bar>.)/.match("ab").names)
108    assert_equal(["foo"], /(?<foo>.)(?<foo>.)/.match("ab").names)
109    assert_equal([], /(.)(.)/.match("ab").names)
110
111    assert_equal({"foo"=>[1], "bar"=>[2]},
112                 /(?<foo>.)(?<bar>.)/.named_captures)
113    assert_equal({"foo"=>[1, 2]},
114                 /(?<foo>.)(?<foo>.)/.named_captures)
115    assert_equal({}, /(.)(.)/.named_captures)
116
117    assert_equal("a[b]c", "abc".sub(/(?<x>[bc])/, "[\\k<x>]"))
118
119    assert_equal("o", "foo"[/(?<bar>o)/, "bar"])
120
121    s = "foo"
122    s[/(?<bar>o)/, "bar"] = "baz"
123    assert_equal("fbazo", s)
124  end
125
126  def test_assign_named_capture
127    assert_equal("a", eval('/(?<foo>.)/ =~ "a"; foo'))
128    assert_equal("a", eval('foo = 1; /(?<foo>.)/ =~ "a"; foo'))
129    assert_equal("a", eval('1.times {|foo| /(?<foo>.)/ =~ "a"; break foo }'))
130    assert_nothing_raised { eval('/(?<Foo>.)/ =~ "a"') }
131    assert_nil(eval('/(?<Foo>.)/ =~ "a"; defined? Foo'))
132  end
133
134  def test_assign_named_capture_to_reserved_word
135    /(?<nil>.)/ =~ "a"
136    assert(!local_variables.include?(:nil), "[ruby-dev:32675]")
137  end
138
139  def test_match_regexp
140    r = /./
141    m = r.match("a")
142    assert_equal(r, m.regexp)
143    re = /foo/
144    assert_equal(re, re.match("foo").regexp)
145  end
146
147  def test_source
148    assert_equal('', //.source)
149  end
150
151  def test_inspect
152    assert_equal('//', //.inspect)
153    assert_equal('//i', //i.inspect)
154    assert_equal('/\//i', /\//i.inspect)
155    assert_equal('/\//i', %r"#{'/'}"i.inspect)
156    assert_equal('/\/x/i', /\/x/i.inspect)
157    assert_equal('/\x00/i', /#{"\0"}/i.inspect)
158    assert_equal("/\n/i", /#{"\n"}/i.inspect)
159    s = [0xff].pack("C")
160    assert_equal('/\/'+s+'/i', /\/#{s}/i.inspect)
161  end
162
163  def test_char_to_option
164    assert_equal("BAR", "FOOBARBAZ"[/b../i])
165    assert_equal("bar", "foobarbaz"[/  b  .  .  /x])
166    assert_equal("bar\n", "foo\nbar\nbaz"[/b.../m])
167    assert_raise(SyntaxError) { eval('//z') }
168  end
169
170  def test_char_to_option_kcode
171    assert_equal("bar", "foobarbaz"[/b../s])
172    assert_equal("bar", "foobarbaz"[/b../e])
173    assert_equal("bar", "foobarbaz"[/b../u])
174  end
175
176  def test_to_s2
177    assert_equal('(?-mix:foo)', /(?:foo)/.to_s)
178    assert_equal('(?m-ix:foo)', /(?:foo)/m.to_s)
179    assert_equal('(?mi-x:foo)', /(?:foo)/mi.to_s)
180    assert_equal('(?mix:foo)', /(?:foo)/mix.to_s)
181    assert_equal('(?m-ix:foo)', /(?m-ix:foo)/.to_s)
182    assert_equal('(?mi-x:foo)', /(?mi-x:foo)/.to_s)
183    assert_equal('(?mix:foo)', /(?mix:foo)/.to_s)
184    assert_equal('(?mix:)', /(?mix)/.to_s)
185    assert_equal('(?-mix:(?mix:foo) )', /(?mix:foo) /.to_s)
186  end
187
188  def test_casefold_p
189    assert_equal(false, /a/.casefold?)
190    assert_equal(true, /a/i.casefold?)
191    assert_equal(false, /(?i:a)/.casefold?)
192  end
193
194  def test_options
195    assert_equal(Regexp::IGNORECASE, /a/i.options)
196    assert_equal(Regexp::EXTENDED, /a/x.options)
197    assert_equal(Regexp::MULTILINE, /a/m.options)
198  end
199
200  def test_match_init_copy
201    m = /foo/.match("foo")
202    assert_equal(/foo/, m.dup.regexp)
203    assert_raise(TypeError) do
204      m.instance_eval { initialize_copy(nil) }
205    end
206    assert_equal([0, 3], m.offset(0))
207    assert_equal(/foo/, m.dup.regexp)
208  end
209
210  def test_match_size
211    m = /(.)(.)(\d+)(\d)/.match("THX1138.")
212    assert_equal(5, m.size)
213  end
214
215  def test_match_offset_begin_end
216    m = /(?<x>b..)/.match("foobarbaz")
217    assert_equal([3, 6], m.offset("x"))
218    assert_equal(3, m.begin("x"))
219    assert_equal(6, m.end("x"))
220    assert_raise(IndexError) { m.offset("y") }
221    assert_raise(IndexError) { m.offset(2) }
222    assert_raise(IndexError) { m.begin(2) }
223    assert_raise(IndexError) { m.end(2) }
224
225    m = /(?<x>q..)?/.match("foobarbaz")
226    assert_equal([nil, nil], m.offset("x"))
227    assert_equal(nil, m.begin("x"))
228    assert_equal(nil, m.end("x"))
229
230    m = /\A\u3042(.)(.)?(.)\z/.match("\u3042\u3043\u3044")
231    assert_equal([1, 2], m.offset(1))
232    assert_equal([nil, nil], m.offset(2))
233    assert_equal([2, 3], m.offset(3))
234  end
235
236  def test_match_to_s
237    m = /(?<x>b..)/.match("foobarbaz")
238    assert_equal("bar", m.to_s)
239  end
240
241  def test_match_pre_post
242    m = /(?<x>b..)/.match("foobarbaz")
243    assert_equal("foo", m.pre_match)
244    assert_equal("baz", m.post_match)
245  end
246
247  def test_match_array
248    m = /(...)(...)(...)(...)?/.match("foobarbaz")
249    assert_equal(["foobarbaz", "foo", "bar", "baz", nil], m.to_a)
250  end
251
252  def test_match_captures
253    m = /(...)(...)(...)(...)?/.match("foobarbaz")
254    assert_equal(["foo", "bar", "baz", nil], m.captures)
255  end
256
257  def test_match_aref
258    m = /(...)(...)(...)(...)?/.match("foobarbaz")
259    assert_equal("foo", m[1])
260    assert_equal(["foo", "bar", "baz"], m[1..3])
261    assert_nil(m[5])
262    assert_raise(IndexError) { m[:foo] }
263  end
264
265  def test_match_values_at
266    m = /(...)(...)(...)(...)?/.match("foobarbaz")
267    assert_equal(["foo", "bar", "baz"], m.values_at(1, 2, 3))
268  end
269
270  def test_match_string
271    m = /(?<x>b..)/.match("foobarbaz")
272    assert_equal("foobarbaz", m.string)
273  end
274
275  def test_match_inspect
276    m = /(...)(...)(...)(...)?/.match("foobarbaz")
277    assert_equal('#<MatchData "foobarbaz" 1:"foo" 2:"bar" 3:"baz" 4:nil>', m.inspect)
278  end
279
280  def test_initialize
281    assert_raise(ArgumentError) { Regexp.new }
282    assert_equal(/foo/, Regexp.new(/foo/, Regexp::IGNORECASE))
283    re = /foo/
284    assert_raise(SecurityError) do
285      Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
286    end
287    re.taint
288    assert_raise(SecurityError) do
289      Thread.new { $SAFE = 4; re.instance_eval { initialize(re) } }.join
290    end
291
292    assert_equal(Encoding.find("US-ASCII"), Regexp.new("b..", nil, "n").encoding)
293    assert_equal("bar", "foobarbaz"[Regexp.new("b..", nil, "n")])
294    assert_equal(//n, Regexp.new("", nil, "n"))
295
296    arg_encoding_none = 32 # ARG_ENCODING_NONE is implementation defined value
297    assert_equal(arg_encoding_none, Regexp.new("", nil, "n").options)
298    assert_equal(arg_encoding_none, Regexp.new("", nil, "N").options)
299
300    assert_raise(RegexpError) { Regexp.new(")(") }
301  end
302
303  def test_unescape
304    assert_raise(ArgumentError) { s = '\\'; /#{ s }/ }
305    assert_equal(/\xFF/n, /#{ s="\\xFF" }/n)
306    assert_equal(/\177/, (s = '\177'; /#{ s }/))
307    assert_raise(ArgumentError) { s = '\u'; /#{ s }/ }
308    assert_raise(ArgumentError) { s = '\u{ ffffffff }'; /#{ s }/ }
309    assert_raise(ArgumentError) { s = '\u{ ffffff }'; /#{ s }/ }
310    assert_raise(ArgumentError) { s = '\u{ ffff X }'; /#{ s }/ }
311    assert_raise(ArgumentError) { s = '\u{ }'; /#{ s }/ }
312    assert_equal("b", "abc"[(s = '\u{0062}'; /#{ s }/)])
313    assert_equal("b", "abc"[(s = '\u0062'; /#{ s }/)])
314    assert_raise(ArgumentError) { s = '\u0'; /#{ s }/ }
315    assert_raise(ArgumentError) { s = '\u000X'; /#{ s }/ }
316    assert_raise(ArgumentError) { s = "\xff" + '\u3042'; /#{ s }/ }
317    assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{ s }/ }
318    assert_raise(SyntaxError) { s = ''; eval(%q(/\u#{ s }/)) }
319
320    assert_equal(/a/, eval(%q(s="\u0061";/#{s}/n)))
321    assert_raise(RegexpError) { s = "\u3042"; eval(%q(/#{s}/n)) }
322    assert_raise(RegexpError) { s = "\u0061"; eval(%q(/\u3042#{s}/n)) }
323    assert_raise(RegexpError) { s1=[0xff].pack("C"); s2="\u3042"; eval(%q(/#{s1}#{s2}/)) }
324
325    assert_raise(ArgumentError) { s = '\x'; /#{ s }/ }
326
327    assert_equal("\xe1", [0x00, 0xe1, 0xff].pack("C*")[/\M-a/])
328    assert_equal("\xdc", [0x00, 0xdc, 0xff].pack("C*")[/\M-\\/])
329    assert_equal("\x8a", [0x00, 0x8a, 0xff].pack("C*")[/\M-\n/])
330    assert_equal("\x89", [0x00, 0x89, 0xff].pack("C*")[/\M-\t/])
331    assert_equal("\x8d", [0x00, 0x8d, 0xff].pack("C*")[/\M-\r/])
332    assert_equal("\x8c", [0x00, 0x8c, 0xff].pack("C*")[/\M-\f/])
333    assert_equal("\x8b", [0x00, 0x8b, 0xff].pack("C*")[/\M-\v/])
334    assert_equal("\x87", [0x00, 0x87, 0xff].pack("C*")[/\M-\a/])
335    assert_equal("\x9b", [0x00, 0x9b, 0xff].pack("C*")[/\M-\e/])
336    assert_equal("\x01", [0x00, 0x01, 0xff].pack("C*")[/\C-a/])
337
338    assert_raise(ArgumentError) { s = '\M'; /#{ s }/ }
339    assert_raise(ArgumentError) { s = '\M-\M-a'; /#{ s }/ }
340    assert_raise(ArgumentError) { s = '\M-\\'; /#{ s }/ }
341
342    assert_raise(ArgumentError) { s = '\C'; /#{ s }/ }
343    assert_raise(ArgumentError) { s = '\c'; /#{ s }/ }
344    assert_raise(ArgumentError) { s = '\C-\C-a'; /#{ s }/ }
345
346    assert_raise(ArgumentError) { s = '\M-\z'; /#{ s }/ }
347    assert_raise(ArgumentError) { s = '\M-\777'; /#{ s }/ }
348
349    assert_equal("\u3042\u3042", "\u3042\u3042"[(s = "\u3042" + %q(\xe3\x81\x82); /#{s}/)])
350    assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3); /#{s}/ }
351    assert_raise(ArgumentError) { s = "\u3042" + %q(\xe3\xe3); /#{s}/ }
352    assert_raise(ArgumentError) { s = '\u3042' + [0xff].pack("C"); /#{s}/ }
353
354    assert_raise(SyntaxError) { eval("/\u3042/n") }
355
356    s = ".........."
357    5.times { s.sub!(".", "") }
358    assert_equal(".....", s)
359  end
360
361  def test_equal
362    assert_equal(true, /abc/ == /abc/)
363    assert_equal(false, /abc/ == /abc/m)
364    assert_equal(false, /abc/ == /abd/)
365  end
366
367  def test_match
368    assert_nil(//.match(nil))
369    assert_equal("abc", /.../.match(:abc)[0])
370    assert_raise(TypeError) { /.../.match(Object.new)[0] }
371    assert_equal("bc", /../.match('abc', 1)[0])
372    assert_equal("bc", /../.match('abc', -2)[0])
373    assert_nil(/../.match("abc", -4))
374    assert_nil(/../.match("abc", 4))
375    assert_equal('\x', /../n.match("\u3042" + '\x', 1)[0])
376
377    r = nil
378    /.../.match("abc") {|m| r = m[0] }
379    assert_equal("abc", r)
380
381    $_ = "abc"; assert_equal(1, ~/bc/)
382    $_ = "abc"; assert_nil(~/d/)
383    $_ = nil; assert_nil(~/./)
384  end
385
386  def test_eqq
387    assert_equal(false, /../ === nil)
388  end
389
390  def test_quote
391    assert_equal("\xff", Regexp.quote([0xff].pack("C")))
392    assert_equal("\\ ", Regexp.quote("\ "))
393    assert_equal("\\t", Regexp.quote("\t"))
394    assert_equal("\\n", Regexp.quote("\n"))
395    assert_equal("\\r", Regexp.quote("\r"))
396    assert_equal("\\f", Regexp.quote("\f"))
397    assert_equal("\\v", Regexp.quote("\v"))
398    assert_equal("\u3042\\t", Regexp.quote("\u3042\t"))
399    assert_equal("\\t\xff", Regexp.quote("\t" + [0xff].pack("C")))
400  end
401
402  def test_try_convert
403    assert_equal(/re/, Regexp.try_convert(/re/))
404    assert_nil(Regexp.try_convert("re"))
405
406    o = Object.new
407    assert_nil(Regexp.try_convert(o))
408    def o.to_regexp() /foo/ end
409    assert_equal(/foo/, Regexp.try_convert(o))
410  end
411
412  def test_union2
413    assert_equal(/(?!)/, Regexp.union)
414    assert_equal(/foo/, Regexp.union(/foo/))
415    assert_equal(/foo/, Regexp.union([/foo/]))
416    assert_equal(/\t/, Regexp.union("\t"))
417    assert_equal(/(?-mix:\u3042)|(?-mix:\u3042)/, Regexp.union(/\u3042/, /\u3042/))
418    assert_equal("\u3041", "\u3041"[Regexp.union(/\u3042/, "\u3041")])
419  end
420
421  def test_dup
422    assert_equal(//, //.dup)
423    assert_raise(TypeError) { //.instance_eval { initialize_copy(nil) } }
424  end
425
426  def test_regsub
427    assert_equal("fooXXXbaz", "foobarbaz".sub!(/bar/, "XXX"))
428    s = [0xff].pack("C")
429    assert_equal(s, "X".sub!(/./, s))
430    assert_equal('\\' + s, "X".sub!(/./, '\\' + s))
431    assert_equal('\k', "foo".sub!(/.../, '\k'))
432    assert_raise(RuntimeError) { "foo".sub!(/(?<x>o)/, '\k<x') }
433    assert_equal('foo[bar]baz', "foobarbaz".sub!(/(b..)/, '[\0]'))
434    assert_equal('foo[foo]baz', "foobarbaz".sub!(/(b..)/, '[\`]'))
435    assert_equal('foo[baz]baz', "foobarbaz".sub!(/(b..)/, '[\\\']'))
436    assert_equal('foo[r]baz', "foobarbaz".sub!(/(b)(.)(.)/, '[\+]'))
437    assert_equal('foo[\\]baz', "foobarbaz".sub!(/(b..)/, '[\\\\]'))
438    assert_equal('foo[\z]baz', "foobarbaz".sub!(/(b..)/, '[\z]'))
439  end
440
441  def test_KCODE
442    assert_nil($KCODE)
443    assert_nothing_raised { $KCODE = nil }
444    assert_equal(false, $=)
445    assert_nothing_raised { $= = nil }
446  end
447
448  def test_match_setter
449    /foo/ =~ "foo"
450    m = $~
451    /bar/ =~ "bar"
452    $~ = m
453    assert_equal("foo", $&)
454  end
455
456  def test_last_match
457    /(...)(...)(...)(...)?/.match("foobarbaz")
458    assert_equal("foobarbaz", Regexp.last_match(0))
459    assert_equal("foo", Regexp.last_match(1))
460    assert_nil(Regexp.last_match(5))
461    assert_nil(Regexp.last_match(-1))
462  end
463
464  def test_getter
465    alias $__REGEXP_TEST_LASTMATCH__ $&
466    alias $__REGEXP_TEST_PREMATCH__ $`
467    alias $__REGEXP_TEST_POSTMATCH__ $'
468    alias $__REGEXP_TEST_LASTPARENMATCH__ $+
469    /(b)(.)(.)/.match("foobarbaz")
470    assert_equal("bar", $__REGEXP_TEST_LASTMATCH__)
471    assert_equal("foo", $__REGEXP_TEST_PREMATCH__)
472    assert_equal("baz", $__REGEXP_TEST_POSTMATCH__)
473    assert_equal("r", $__REGEXP_TEST_LASTPARENMATCH__)
474
475    /(...)(...)(...)/.match("foobarbaz")
476    assert_equal("baz", $+)
477  end
478
479  def test_rindex_regexp
480    assert_equal(3, "foobarbaz\u3042".rindex(/b../n, 5))
481  end
482
483  def test_taint
484    m = Thread.new do
485      "foo"[/foo/]
486      $SAFE = 4
487      /foo/.match("foo")
488    end.value
489    assert(m.tainted?)
490    assert_nothing_raised('[ruby-core:26137]') {
491      m = proc {$SAFE = 4; %r"#{ }"o}.call
492    }
493    assert(m.tainted?)
494  end
495
496  def check(re, ss, fs = [])
497    re = Regexp.new(re) unless re.is_a?(Regexp)
498    ss = [ss] unless ss.is_a?(Array)
499    ss.each do |e, s|
500      s ||= e
501      assert_match(re, s)
502      m = re.match(s)
503      assert_equal(e, m[0])
504    end
505    fs = [fs] unless fs.is_a?(Array)
506    fs.each {|s| assert_no_match(re, s) }
507  end
508
509  def failcheck(re)
510    assert_raise(RegexpError) { %r"#{ re }" }
511  end
512
513  def test_parse
514    check(/\*\+\?\{\}\|\(\)\<\>\`\'/, "*+?{}|()<>`'")
515    check(/\A\w\W\z/, %w(a. b!), %w(.. ab))
516    check(/\A.\b.\b.\B.\B.\z/, %w(a.aaa .a...), %w(aaaaa .....))
517    check(/\A\s\S\z/, [' a', "\n."], ['  ', "\n\n", 'a '])
518    check(/\A\d\D\z/, '0a', %w(00 aa))
519    check(/\A\h\H\z/, %w(0g ag BH), %w(a0 af GG))
520    check(/\Afoo\Z\s\z/, "foo\n", ["foo", "foo\nbar"])
521    assert_equal(%w(a b c), "abc def".scan(/\G\w/))
522    check(/\A\u3042\z/, "\u3042", ["", "\u3043", "a"])
523    check(/\A(..)\1\z/, %w(abab ....), %w(abba aba))
524    failcheck('\1')
525    check(/\A\80\z/, "80", ["\100", ""])
526    check(/\A\77\z/, "?")
527    check(/\A\78\z/, "\7" + '8', ["\100", ""])
528    check(/\A\Qfoo\E\z/, "QfooE")
529    check(/\Aa++\z/, "aaa")
530    check('\Ax]\z', "x]")
531    check(/x#foo/x, "x", "#foo")
532    check(/\Ax#foo#{ "\n" }x\z/x, "xx", ["x", "x#foo\nx"])
533    check(/\A\p{Alpha}\z/, ["a", "z"], [".", "", ".."])
534    check(/\A\p{^Alpha}\z/, [".", "!"], ["!a", ""])
535    check(/\A\n\z/, "\n")
536    check(/\A\t\z/, "\t")
537    check(/\A\r\z/, "\r")
538    check(/\A\f\z/, "\f")
539    check(/\A\a\z/, "\007")
540    check(/\A\e\z/, "\033")
541    check(/\A\v\z/, "\v")
542    failcheck('(')
543    failcheck('(?foo)')
544    failcheck('/\p{foobarbazqux}/')
545    failcheck('/\p{foobarbazqux' + 'a' * 1000 + '}/')
546    failcheck('/[1-\w]/')
547  end
548
549  def test_exec
550    check(/A*B/, %w(B AB AAB AAAB), %w(A))
551    check(/\w*!/, %w(! a! ab! abc!), %w(abc))
552    check(/\w*\W/, %w(! a" ab# abc$), %w(abc))
553    check(/\w*\w/, %w(z az abz abcz), %w(!))
554    check(/[a-z]*\w/, %w(z az abz abcz), %w(!))
555    check(/[a-z]*\W/, %w(! a" ab# abc$), %w(A))
556    check(/((a|bb|ccc|dddd)(1|22|333|4444))/i, %w(a1 bb1 a22), %w(a2 b1))
557    check(/\u0080/, (1..4).map {|i| ["\u0080", "\u0080" * i] }, ["\u0081"])
558    check(/\u0080\u0080/, (2..4).map {|i| ["\u0080" * 2, "\u0080" * i] }, ["\u0081"])
559    check(/\u0080\u0080\u0080/, (3..4).map {|i| ["\u0080" * 3, "\u0080" * i] }, ["\u0081"])
560    check(/\u0080\u0080\u0080\u0080/, (4..4).map {|i| ["\u0080" * 4, "\u0080" * i] }, ["\u0081"])
561    check(/[^\u3042\u3043\u3044]/, %W(a b \u0080 \u3041 \u3045), %W(\u3042 \u3043 \u3044))
562    check(/a.+/m, %W(a\u0080 a\u0080\u0080 a\u0080\u0080\u0080), %W(a))
563    check(/a.+z/m, %W(a\u0080z a\u0080\u0080z a\u0080\u0080\u0080z), %W(az))
564    check(/abc\B.\Bxyz/, %w(abcXxyz abc0xyz), %w(abc|xyz abc-xyz))
565    check(/\Bxyz/, [%w(xyz abcXxyz), %w(xyz abc0xyz)], %w(abc xyz abc-xyz))
566    check(/abc\B/, [%w(abc abcXxyz), %w(abc abc0xyz)], %w(abc xyz abc-xyz))
567    failcheck('(?<foo>abc)\1')
568    check(/^(A+|B+)(?>\g<1>)*[BC]$/, %w(AC BC ABC BAC AABBC), %w(AABB))
569    check(/^(A+|B(?>\g<1>)*)[AC]$/, %w(AAAC BBBAAAAC), %w(BBBAAA))
570    check(/^()(?>\g<1>)*$/, "", "a")
571    check(/^(?>(?=a)(#{ "a" * 1000 }|))++$/, ["a" * 1000, "a" * 2000, "a" * 3000], ["", "a" * 500, "b" * 1000])
572    check(eval('/^(?:a?)?$/'), ["", "a"], ["aa"])
573    check(eval('/^(?:a+)?$/'), ["", "a", "aa"], ["ab"])
574    check(/^(?:a?)+?$/, ["", "a", "aa"], ["ab"])
575    check(/^a??[ab]/, [["a", "a"], ["a", "aa"], ["b", "b"], ["a", "ab"]], ["c"])
576    check(/^(?:a*){3,5}$/, ["", "a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa"], ["b"])
577    check(/^(?:a+){3,5}$/, ["aaa", "aaaa", "aaaaa", "aaaaaa"], ["", "a", "aa", "b"])
578  end
579
580  def test_parse_look_behind
581    check(/(?<=A)B(?=C)/, [%w(B ABC)], %w(aBC ABc aBc))
582    check(/(?<!A)B(?!C)/, [%w(B aBc)], %w(ABC aBC ABc))
583    failcheck('(?<=.*)')
584    failcheck('(?<!.*)')
585    check(/(?<=A|B.)C/, [%w(C AC), %w(C BXC)], %w(C BC))
586    check(/(?<!A|B.)C/, [%w(C C), %w(C BC)], %w(AC BXC))
587  end
588
589  def test_parse_kg
590    check(/\A(.)(.)\k<1>(.)\z/, %w(abac abab ....), %w(abcd aaba xxx))
591    check(/\A(.)(.)\k<-1>(.)\z/, %w(abbc abba ....), %w(abcd aaba xxx))
592    check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "aba", "abb")
593    check(/\A(?<n>.)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "abb", "aba")
594    check(/\A(?<x>..)\k<x>\z/, %w(abab ....), %w(abac abba xxx))
595    check(/\A(.)(..)\g<-1>\z/, "abcde", %w(.... ......))
596    failcheck('\k<x>')
597    failcheck('\k<')
598    failcheck('\k<>')
599    failcheck('\k<.>')
600    failcheck('\k<x.>')
601    failcheck('\k<1.>')
602    failcheck('\k<x')
603    failcheck('\k<x+')
604    failcheck('()\k<-2>')
605    failcheck('()\g<-2>')
606    check(/\A(?<x>.)(?<x>.)\k<x>\z/, %w(aba abb), %w(abc .. ....))
607    check(/\A(?<x>.)(?<x>.)\k<x>\z/i, %w(aba ABa abb ABb), %w(abc .. ....))
608    check('\k\g', "kg")
609    failcheck('(.\g<1>)')
610    failcheck('(.\g<2>)')
611    failcheck('(?=\g<1>)')
612    failcheck('((?=\g<1>))')
613    failcheck('(\g<1>|.)')
614    failcheck('(.|\g<1>)')
615    check(/(!)(?<=(a)|\g<1>)/, ["!"], %w(a))
616    check(/^(a|b\g<1>c)$/, %w(a bac bbacc bbbaccc), %w(bbac bacc))
617    check(/^(a|b\g<2>c)(B\g<1>C){0}$/, %w(a bBaCc bBbBaCcCc bBbBbBaCcCcCc), %w(bBbBaCcC BbBaCcCc))
618    check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+0>){0}\g<x>\g<y>\z/, "XXaXbXXa", %w(XXabXa abb))
619    check(/\A(?<n>.|X\g<n>)(?<x>\g<n>){0}(?<y>\k<n+1>){0}\g<x>\g<y>\z/, "XaXXbXXb", %w(aXXbXb aba))
620    failcheck('(?<x>)(?<x>)(\g<x>)')
621    check(/^(?<x>foo)(bar)\k<x>/, %w(foobarfoo), %w(foobar barfoo))
622    check(/^(?<a>f)(?<a>o)(?<a>o)(?<a>b)(?<a>a)(?<a>r)(?<a>b)(?<a>a)(?<a>z)\k<a>{9}$/, %w(foobarbazfoobarbaz foobarbazbazbarfoo foobarbazzabraboof), %w(foobar barfoo))
623  end
624
625  def test_parse_curly_brace
626    check(/\A{/, ["{", ["{", "{x"]])
627    check(/\A{ /, ["{ ", ["{ ", "{ x"]])
628    check(/\A{,}\z/, "{,}")
629    check(/\A{}\z/, "{}")
630    check(/\Aa{0}+\z/, "", %w(a aa aab))
631    check(/\Aa{1}+\z/, %w(a aa), ["", "aab"])
632    check(/\Aa{1,2}b{1,2}\z/, %w(ab aab abb aabb), ["", "aaabb", "abbb"])
633    check(/(?!x){0,1}/, [ ['', 'ab'], ['', ''] ])
634    check(/c\z{0,1}/, [ ['c', 'abc'], ['c', 'cab']], ['abd'])
635    check(/\A{0,1}a/, [ ['a', 'abc'], ['a', '____abc']], ['bcd'])
636    failcheck('.{100001}')
637    failcheck('.{0,100001}')
638    failcheck('.{1,0}')
639    failcheck('{0}')
640  end
641
642  def test_parse_comment
643    check(/\A(?#foo\)bar)\z/, "", "a")
644    failcheck('(?#')
645  end
646
647  def test_char_type
648    check(/\u3042\d/, ["\u30421", "\u30422"])
649
650    # CClassTable cache test
651    assert_match(/\u3042\d/, "\u30421")
652    assert_match(/\u3042\d/, "\u30422")
653  end
654
655  def test_char_class
656    failcheck('[]')
657    failcheck('[x')
658    check('\A[]]\z', "]", "")
659    check('\A[]\.]+\z', %w(] . ]..]), ["", "["])
660    check(/\A[\u3042]\z/, "\u3042", "\u3042aa")
661    check(/\A[\u3042\x61]+\z/, ["aa\u3042aa", "\u3042\u3042", "a"], ["", "b"])
662    check(/\A[\u3042\x61\x62]+\z/, "abab\u3042abab\u3042")
663    check(/\A[abc]+\z/, "abcba", ["", "ada"])
664    check(/\A[\w][\W]\z/, %w(a. b!), %w(.. ab))
665    check(/\A[\s][\S]\z/, [' a', "\n."], ['  ', "\n\n", 'a '])
666    check(/\A[\d][\D]\z/, '0a', %w(00 aa))
667    check(/\A[\h][\H]\z/, %w(0g ag BH), %w(a0 af GG))
668    check(/\A[\p{Alpha}]\z/, ["a", "z"], [".", "", ".."])
669    check(/\A[\p{^Alpha}]\z/, [".", "!"], ["!a", ""])
670    check(/\A[\xff]\z/, "\xff", ["", "\xfe"])
671    check(/\A[\80]+\z/, "8008", ["\\80", "\100", "\1000"])
672    check(/\A[\77]+\z/, "???")
673    check(/\A[\78]+\z/, "\788\7")
674    check(/\A[\0]\z/, "\0")
675    check(/\A[[:0]]\z/, [":", "0"], ["", ":0"])
676    check(/\A[0-]\z/, ["0", "-"], "0-")
677    check('\A[a-&&\w]\z', "a", "-")
678    check('\A[--0]\z', ["-", "/", "0"], ["", "1"])
679    check('\A[\'--0]\z', %w(* + \( \) 0 ,), ["", ".", "1"])
680    check(/\A[a-b-]\z/, %w(a b -), ["", "c"])
681    check('\A[a-b-&&\w]\z', %w(a b), ["", "-"])
682    check('\A[a-b-&&\W]\z', "-", ["", "a", "b"])
683    check('\A[a-c-e]\z', %w(a b c e), %w(- d)) # is it OK?
684    check(/\A[a-f&&[^b-c]&&[^e]]\z/, %w(a d f), %w(b c e g 0))
685    check(/\A[[^b-c]&&[^e]&&a-f]\z/, %w(a d f), %w(b c e g 0))
686    check(/\A[\n\r\t]\z/, ["\n", "\r", "\t"])
687    failcheck('[9-1]')
688
689    assert_match(/\A\d+\z/, "0123456789")
690    assert_no_match(/\d/, "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19")
691    assert_match(/\A\w+\z/, "09azAZ_")
692    assert_no_match(/\w/, "\uff10\uff19\uff41\uff5a\uff21\uff3a")
693    assert_match(/\A\s+\z/, "\r\n\v\f\r\s")
694    assert_no_match(/\s/, "\u0085")
695  end
696
697  def test_posix_bracket
698    check(/\A[[:alpha:]0]\z/, %w(0 a), %w(1 .))
699    check(/\A[[:^alpha:]0]\z/, %w(0 1 .), "a")
700    check(/\A[[:alpha\:]]\z/, %w(a l p h a :), %w(b 0 1 .))
701    check(/\A[[:alpha:foo]0]\z/, %w(0 a), %w(1 .))
702    check(/\A[[:xdigit:]&&[:alpha:]]\z/, "a", %w(g 0))
703    check('\A[[:abcdefghijklmnopqrstu:]]+\z', "[]")
704    failcheck('[[:alpha')
705    failcheck('[[:alpha:')
706    failcheck('[[:alp:]]')
707
708    assert_match(/\A[[:digit:]]+\z/, "\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19")
709    assert_match(/\A[[:alnum:]]+\z/, "\uff10\uff19\uff41\uff5a\uff21\uff3a")
710    assert_match(/\A[[:space:]]+\z/, "\r\n\v\f\r\s\u0085")
711    assert_match(/\A[[:ascii:]]+\z/, "\x00\x7F")
712    assert_no_match(/[[:ascii:]]/, "\x80\xFF")
713  end
714
715  def test_backward
716    assert_equal(3, "foobar".rindex(/b.r/i))
717    assert_equal(nil, "foovar".rindex(/b.r/i))
718    assert_equal(3, ("foo" + "bar" * 1000).rindex(/#{"bar"*1000}/))
719    assert_equal(4, ("foo\nbar\nbaz\n").rindex(/bar/i))
720  end
721
722  def test_uninitialized
723    assert_raise(TypeError) { Regexp.allocate.hash }
724    assert_raise(TypeError) { Regexp.allocate.eql? Regexp.allocate }
725    assert_raise(TypeError) { Regexp.allocate == Regexp.allocate }
726    assert_raise(TypeError) { Regexp.allocate =~ "" }
727    assert_equal(false, Regexp.allocate === Regexp.allocate)
728    assert_nil(~Regexp.allocate)
729    assert_raise(TypeError) { Regexp.allocate.match("") }
730    assert_raise(TypeError) { Regexp.allocate.to_s }
731    assert_match(/^#<Regexp:.*>$/, Regexp.allocate.inspect)
732    assert_raise(TypeError) { Regexp.allocate.source }
733    assert_raise(TypeError) { Regexp.allocate.casefold? }
734    assert_raise(TypeError) { Regexp.allocate.options }
735    assert_equal(Encoding.find("ASCII-8BIT"), Regexp.allocate.encoding)
736    assert_equal(false, Regexp.allocate.fixed_encoding?)
737    assert_raise(TypeError) { Regexp.allocate.names }
738    assert_raise(TypeError) { Regexp.allocate.named_captures }
739
740    assert_raise(TypeError) { MatchData.allocate.regexp }
741    assert_raise(TypeError) { MatchData.allocate.names }
742    assert_raise(TypeError) { MatchData.allocate.size }
743    assert_raise(TypeError) { MatchData.allocate.length }
744    assert_raise(TypeError) { MatchData.allocate.offset(0) }
745    assert_raise(TypeError) { MatchData.allocate.begin(0) }
746    assert_raise(TypeError) { MatchData.allocate.end(0) }
747    assert_raise(TypeError) { MatchData.allocate.to_a }
748    assert_raise(TypeError) { MatchData.allocate[:foo] }
749    assert_raise(TypeError) { MatchData.allocate.captures }
750    assert_raise(TypeError) { MatchData.allocate.values_at }
751    assert_raise(TypeError) { MatchData.allocate.pre_match }
752    assert_raise(TypeError) { MatchData.allocate.post_match }
753    assert_raise(TypeError) { MatchData.allocate.to_s }
754    assert_match(/^#<MatchData:.*>$/, MatchData.allocate.inspect)
755    assert_raise(TypeError) { MatchData.allocate.string }
756    $~ = MatchData.allocate
757    assert_raise(TypeError) { $& }
758    assert_raise(TypeError) { $` }
759    assert_raise(TypeError) { $' }
760    assert_raise(TypeError) { $+ }
761  end
762
763  def test_unicode
764    assert_match(/^\u3042{0}\p{Any}$/, "a")
765    assert_match(/^\u3042{0}\p{Any}$/, "\u3041")
766    assert_match(/^\u3042{0}\p{Any}$/, "\0")
767    assert_match(/^\p{Lo}{4}$/u, "\u3401\u4E01\u{20001}\u{2A701}")
768    assert_no_match(/^\u3042{0}\p{Any}$/, "\0\0")
769    assert_no_match(/^\u3042{0}\p{Any}$/, "")
770    assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + "\u3042" + '}$/') }
771    assert_raise(SyntaxError) { eval('/^\u3042{0}\p{' + 'a' * 1000 + '}$/') }
772    assert_raise(SyntaxError) { eval('/^\u3042{0}\p{foobarbazqux}$/') }
773    assert_match(/^(\uff21)(a)\1\2$/i, "\uff21A\uff41a")
774    assert_no_match(/^(\uff21)\1$/i, "\uff21A")
775    assert_no_match(/^(\uff41)\1$/i, "\uff41a")
776    assert_match(/^\u00df$/i, "\u00df")
777    assert_match(/^\u00df$/i, "ss")
778    #assert_match(/^(\u00df)\1$/i, "\u00dfss") # this must be bug...
779    assert_match(/^\u00df{2}$/i, "\u00dfss")
780    assert_match(/^\u00c5$/i, "\u00c5")
781    assert_match(/^\u00c5$/i, "\u00e5")
782    assert_match(/^\u00c5$/i, "\u212b")
783    assert_match(/^(\u00c5)\1\1$/i, "\u00c5\u00e5\u212b")
784    assert_match(/^\u0149$/i, "\u0149")
785    assert_match(/^\u0149$/i, "\u02bcn")
786    #assert_match(/^(\u0149)\1$/i, "\u0149\u02bcn") # this must be bug...
787    assert_match(/^\u0149{2}$/i, "\u0149\u02bcn")
788    assert_match(/^\u0390$/i, "\u0390")
789    assert_match(/^\u0390$/i, "\u03b9\u0308\u0301")
790    #assert_match(/^(\u0390)\1$/i, "\u0390\u03b9\u0308\u0301") # this must be bug...
791    assert_match(/^\u0390{2}$/i, "\u0390\u03b9\u0308\u0301")
792    assert_match(/^\ufb05$/i, "\ufb05")
793    assert_match(/^\ufb05$/i, "\ufb06")
794    assert_match(/^\ufb05$/i, "st")
795    #assert_match(/^(\ufb05)\1\1$/i, "\ufb05\ufb06st") # this must be bug...
796    assert_match(/^\ufb05{3}$/i, "\ufb05\ufb06st")
797    assert_match(/^\u03b9\u0308\u0301$/i, "\u0390")
798    assert_nothing_raised { 0x03ffffff.chr("utf-8").size }
799    assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
800  end
801
802  def test_matchdata
803    a = "haystack".match(/hay/)
804    b = "haystack".match(/hay/)
805    assert_equal(a, b, '[ruby-core:24748]')
806    h = {a => 42}
807    assert_equal(42, h[b], '[ruby-core:24748]')
808  end
809
810  def test_regexp_poped
811    assert_nothing_raised { eval("a = 1; /\#{ a }/; a") }
812    assert_nothing_raised { eval("a = 1; /\#{ a }/o; a") }
813  end
814
815  def test_optimize_last_anycharstar
816    s = "1" + " " * 5000000
817    assert_nothing_raised { s.match(/(\d) (.*)/) }
818    assert_equal("1", $1)
819    assert_equal(" " * 4999999, $2)
820  end
821
822  def test_invalid_fragment
823    bug2547 = '[ruby-core:27374]'
824    assert_raise(SyntaxError, bug2547) {eval('/#{"\\\\"}y/')}
825  end
826
827  def test_dup_warn
828    assert_in_out_err('-w', 'x=/[\u3042\u3041]/', [], /\A\z/)
829    assert_in_out_err('-w', 'x=/[\u3042\u3042]/', [], /duplicated/)
830    assert_in_out_err('-w', 'x=/[\u3042\u3041-\u3043]/', [], /duplicated/)
831  end
832
833  def test_property_warn
834    assert_in_out_err('-w', 'x=/\p%s/', [], %r"warning: invalid Unicode Property \\p: /\\p%s/")
835  end
836end