r18455 reverted.
[ruby-svn.git] / test / strscan / test_stringscanner.rb
blobff1eb7a298eb564f228c065ab8fb2500ae9fbbf8
2 # test/strscan/test_stringscanner.rb
5 require 'strscan'
6 require 'test/unit'
8 class TestStringScanner < Test::Unit::TestCase
9   def test_s_new
10     s = StringScanner.new('test string')
11     assert_instance_of StringScanner, s
12     assert_equal false, s.eos?
13     assert_equal false, s.tainted?
15     str = 'test string'
16     str.taint
17     s = StringScanner.new(str, false)
18     assert_instance_of StringScanner, s
19     assert_equal false, s.eos?
20     assert_same str, s.string
21     assert_equal true, s.string.tainted?
23     str = 'test string'
24     str.taint
25     s = StringScanner.new(str)
26     assert_equal true, s.string.tainted?
27   end
29   UNINIT_ERROR = ArgumentError
31   def test_s_allocate
32     s = StringScanner.allocate
33     assert_equal '#<StringScanner (uninitialized)>', s.inspect.sub(/StringScanner_C/, 'StringScanner')
34     assert_raises(UNINIT_ERROR) { s.eos? }
35     assert_raises(UNINIT_ERROR) { s.scan(/a/) }
36     s.string = 'test'
37     assert_equal '#<StringScanner 0/4 @ "test">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
38     assert_nothing_raised(UNINIT_ERROR) { s.eos? }
39     assert_equal false, s.eos?
40   end
42   def test_s_mustc
43     assert_nothing_raised(NotImplementedError) {
44         StringScanner.must_C_version
45     }
46   end
48   def test_dup
49     s = StringScanner.new('test string')
50     d = s.dup
51     assert_equal s.inspect, d.inspect
52     assert_equal s.string, d.string
53     assert_equal s.pos, d.pos
54     assert_equal s.matched?, d.matched?
55     assert_equal s.eos?, d.eos?
57     s = StringScanner.new('test string')
58     s.scan(/test/)
59     d = s.dup
60     assert_equal s.inspect, d.inspect
61     assert_equal s.string, d.string
62     assert_equal s.pos, d.pos
63     assert_equal s.matched?, d.matched?
64     assert_equal s.eos?, d.eos?
66     s = StringScanner.new('test string')
67     s.scan(/test/)
68     s.scan(/NOT MATCH/)
69     d = s.dup
70     assert_equal s.inspect, d.inspect
71     assert_equal s.string, d.string
72     assert_equal s.pos, d.pos
73     assert_equal s.matched?, d.matched?
74     assert_equal s.eos?, d.eos?
76     s = StringScanner.new('test string')
77     s.terminate
78     d = s.dup
79     assert_equal s.inspect, d.inspect
80     assert_equal s.string, d.string
81     assert_equal s.pos, d.pos
82     assert_equal s.matched?, d.matched?
83     assert_equal s.eos?, d.eos?
84   end
86   def test_const_Version
87     assert_instance_of String, StringScanner::Version
88     assert_equal true, StringScanner::Version.frozen?
89   end
91   def test_const_Id
92     assert_instance_of String, StringScanner::Id
93     assert_equal true, StringScanner::Id.frozen?
94   end
96   def test_inspect
97     str = 'test string'
98     str.taint
99     s = StringScanner.new(str, false)
100     assert_instance_of String, s.inspect
101     assert_equal s.inspect, s.inspect
102     assert_equal '#<StringScanner 0/11 @ "test ...">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
103     s.get_byte
104     assert_equal '#<StringScanner 1/11 "t" @ "est s...">', s.inspect.sub(/StringScanner_C/, 'StringScanner')
105     assert_equal true, s.inspect.tainted?
107     s = StringScanner.new("\n")
108     assert_equal '#<StringScanner 0/1 @ "\n">', s.inspect
109   end
111   def test_eos?
112     s = StringScanner.new('test string')
113     assert_equal false, s.eos?
114     assert_equal false, s.eos?
115     s.scan(/\w+/)
116     assert_equal false, s.eos?
117     assert_equal false, s.eos?
118     s.scan(/\s+/)
119     s.scan(/\w+/)
120     assert_equal true, s.eos?
121     assert_equal true, s.eos?
122     s.scan(/\w+/)
123     assert_equal true, s.eos?
125     s = StringScanner.new('test')
126     s.scan(/te/)
127     s.string.replace ''
128     assert_equal true, s.eos?
129   end
131   def test_bol?
132     s = StringScanner.new("a\nbbb\n\ncccc\nddd\r\neee")
133     assert_equal true, s.bol?
134     assert_equal true, s.bol?
135     s.scan(/a/)
136     assert_equal false, s.bol?
137     assert_equal false, s.bol?
138     s.scan(/\n/)
139     assert_equal true, s.bol?
140     s.scan(/b/)
141     assert_equal false, s.bol?
142     s.scan(/b/)
143     assert_equal false, s.bol?
144     s.scan(/b/)
145     assert_equal false, s.bol?
146     s.scan(/\n/)
147     assert_equal true, s.bol?
148     s.unscan
149     assert_equal false, s.bol?
150     s.scan(/\n/)
151     s.scan(/\n/)
152     assert_equal true, s.bol?
153     s.scan(/c+\n/)
154     assert_equal true, s.bol?
155     s.scan(/d+\r\n/)
156     assert_equal true, s.bol?
157     s.scan(/e+/)
158     assert_equal false, s.bol?
159   end
161   def test_string
162     s = StringScanner.new('test')
163     assert_equal 'test', s.string
164     s.string = 'a'
165     assert_equal 'a', s.string
166     s.scan(/a/)
167     s.string = 'b'
168     assert_equal 0, s.pos
169   end
171   def test_pos
172     s = StringScanner.new('test string')
173     assert_equal 0, s.pos
174     s.get_byte
175     assert_equal 1, s.pos
176     s.get_byte
177     assert_equal 2, s.pos
178     s.terminate
179     assert_equal 11, s.pos
180   end
182   def test_concat
183     s = StringScanner.new('a')
184     s.scan(/a/)
185     s.concat 'b'
186     assert_equal false, s.eos?
187     assert_equal 'b', s.scan(/b/)
188     assert_equal true, s.eos?
189     s.concat 'c'
190     assert_equal false, s.eos?
191     assert_equal 'c', s.scan(/c/)
192     assert_equal true, s.eos?
193   end
195   def test_scan
196     s = StringScanner.new('stra strb strc', true)
197     tmp = s.scan(/\w+/)
198     assert_equal 'stra', tmp
199     assert_equal false, tmp.tainted?
201     tmp = s.scan(/\s+/)
202     assert_equal ' ', tmp
203     assert_equal false, tmp.tainted?
205     assert_equal 'strb', s.scan(/\w+/)
206     assert_equal ' ',    s.scan(/\s+/)
208     tmp = s.scan(/\w+/)
209     assert_equal 'strc', tmp
210     assert_equal false, tmp.tainted?
212     assert_nil           s.scan(/\w+/)
213     assert_nil           s.scan(/\w+/)
216     str = 'stra strb strc'
217     str.taint
218     s = StringScanner.new(str, false)
219     tmp = s.scan(/\w+/)
220     assert_equal 'stra', tmp
221     assert_equal true, tmp.tainted?
223     tmp = s.scan(/\s+/)
224     assert_equal ' ', tmp
225     assert_equal true, tmp.tainted?
227     assert_equal 'strb', s.scan(/\w+/)
228     assert_equal ' ',    s.scan(/\s+/)
230     tmp = s.scan(/\w+/)
231     assert_equal 'strc', tmp
232     assert_equal true, tmp.tainted?
234     assert_nil           s.scan(/\w+/)
235     assert_nil           s.scan(/\w+/)
237     s = StringScanner.new('test')
238     s.scan(/te/)
239     # This assumes #string does not duplicate string,
240     # but it is implementation specific issue.
241     # DO NOT RELY ON THIS FEATURE.
242     s.string.replace ''
243     # unspecified: assert_equal 2, s.pos
244     assert_equal nil, s.scan(/test/)
246     # [ruby-bugs:4361]
247     s = StringScanner.new("")
248     assert_equal "", s.scan(//)
249     assert_equal "", s.scan(//)
250   end
252   def test_skip
253     s = StringScanner.new('stra strb strc', true)
254     assert_equal 4, s.skip(/\w+/)
255     assert_equal 1, s.skip(/\s+/)
256     assert_equal 4, s.skip(/\w+/)
257     assert_equal 1, s.skip(/\s+/)
258     assert_equal 4, s.skip(/\w+/)
259     assert_nil      s.skip(/\w+/)
260     assert_nil      s.skip(/\s+/)
261     assert_equal true, s.eos?
263     s = StringScanner.new('test')
264     s.scan(/te/)
265     s.string.replace ''
266     assert_equal nil, s.skip(/./)
268     # [ruby-bugs:4361]
269     s = StringScanner.new("")
270     assert_equal 0, s.skip(//)
271     assert_equal 0, s.skip(//)
272   end
274   def test_getch
275     s = StringScanner.new('abcde')
276     assert_equal 'a', s.getch
277     assert_equal 'b', s.getch
278     assert_equal 'c', s.getch
279     assert_equal 'd', s.getch
280     assert_equal 'e', s.getch
281     assert_nil        s.getch
283     str = 'abc'
284     str.taint
285     s = StringScanner.new(str)
286     assert_equal true, s.getch.tainted?
287     assert_equal true, s.getch.tainted?
288     assert_equal true, s.getch.tainted?
289     assert_nil s.getch
291     s = StringScanner.new("\244\242".force_encoding("euc-jp"))
292     assert_equal "\244\242".force_encoding("euc-jp"), s.getch
293     assert_nil s.getch
295     s = StringScanner.new('test')
296     s.scan(/te/)
297     s.string.replace ''
298     assert_equal nil, s.getch
299   end
301   def test_get_byte
302     s = StringScanner.new('abcde')
303     assert_equal 'a', s.get_byte
304     assert_equal 'b', s.get_byte
305     assert_equal 'c', s.get_byte
306     assert_equal 'd', s.get_byte
307     assert_equal 'e', s.get_byte
308     assert_nil        s.get_byte
309     assert_nil        s.get_byte
311     str = 'abc'
312     str.taint
313     s = StringScanner.new(str)
314     assert_equal true, s.get_byte.tainted?
315     assert_equal true, s.get_byte.tainted?
316     assert_equal true, s.get_byte.tainted?
317     assert_nil s.get_byte
319     s = StringScanner.new("\244\242".force_encoding("euc-jp"))
320     assert_equal "\244".force_encoding("euc-jp"), s.get_byte
321     assert_equal "\242".force_encoding("euc-jp"), s.get_byte
322     assert_nil s.get_byte
324     s = StringScanner.new('test')
325     s.scan(/te/)
326     s.string.replace ''
327     assert_equal nil, s.get_byte
328   end
330   def test_matched
331     s = StringScanner.new('stra strb strc')
332     s.scan(/\w+/)
333     assert_equal 'stra', s.matched
334     assert_equal false, s.matched.tainted?
335     s.scan(/\s+/)
336     assert_equal ' ', s.matched
337     s.scan(/\w+/)
338     assert_equal 'strb', s.matched
339     s.scan(/\s+/)
340     assert_equal ' ', s.matched
341     s.scan(/\w+/)
342     assert_equal 'strc', s.matched
343     s.scan(/\w+/)
344     assert_nil s.matched
345     s.getch
346     assert_nil s.matched
348     s = StringScanner.new('stra strb strc')
349     s.getch
350     assert_equal 's', s.matched
351     assert_equal false, s.matched.tainted?
352     s.get_byte
353     assert_equal 't', s.matched
354     assert_equal 't', s.matched
355     assert_equal false, s.matched.tainted?
357     str = 'test'
358     str.taint
359     s = StringScanner.new(str)
360     s.scan(/\w+/)
361     assert_equal true, s.matched.tainted?
362     assert_equal true, s.matched.tainted?
363   end
365   def test_AREF
366     s = StringScanner.new('stra strb strc')
368     s.scan(/\w+/)
369     assert_nil           s[-2]
370     assert_equal 'stra', s[-1]
371     assert_equal 'stra', s[0]
372     assert_nil           s[1]
374     assert_equal false,  s[-1].tainted?
375     assert_equal false,  s[0].tainted?
377     s.skip(/\s+/)
378     assert_nil           s[-2]
379     assert_equal ' ',    s[-1]
380     assert_equal ' ',    s[0]
381     assert_nil           s[1]
383     s.scan(/(s)t(r)b/)
384     assert_nil           s[-100]
385     assert_nil           s[-4]
386     assert_equal 'strb', s[-3]
387     assert_equal 's',    s[-2]
388     assert_equal 'r',    s[-1]
389     assert_equal 'strb', s[0]
390     assert_equal 's',    s[1]
391     assert_equal 'r',    s[2]
392     assert_nil           s[3]
393     assert_nil           s[100]
395     s.scan(/\s+/)
397     s.getch
398     assert_nil           s[-2]
399     assert_equal 's',    s[-1]
400     assert_equal 's',    s[0]
401     assert_nil           s[1]
403     s.get_byte
404     assert_nil           s[-2]
405     assert_equal 't',    s[-1]
406     assert_equal 't',    s[0]
407     assert_nil           s[1]
409     s.scan(/.*/)
410     s.scan(/./)
411     assert_nil           s[0]
412     assert_nil           s[0]
415     s = StringScanner.new("\244\242".force_encoding("euc-jp"))
416     s.getch
417     assert_equal "\244\242".force_encoding("euc-jp"), s[0]
419     str = 'test'
420     str.taint
421     s = StringScanner.new(str)
422     s.scan(/(t)(e)(s)(t)/)
423     assert_equal true, s[0].tainted?
424     assert_equal true, s[1].tainted?
425     assert_equal true, s[2].tainted?
426     assert_equal true, s[3].tainted?
427     assert_equal true, s[4].tainted?
428   end
430   def test_pre_match
431     s = StringScanner.new('a b c d e')
432     s.scan(/\w/)
433     assert_equal '', s.pre_match
434     assert_equal false, s.pre_match.tainted?
435     s.skip(/\s/)
436     assert_equal 'a', s.pre_match
437     assert_equal false, s.pre_match.tainted?
438     s.scan(/\w/)
439     assert_equal 'a ', s.pre_match
440     s.scan_until(/c/)
441     assert_equal 'a b ', s.pre_match
442     s.getch
443     assert_equal 'a b c', s.pre_match
444     s.get_byte
445     assert_equal 'a b c ', s.pre_match
446     s.get_byte
447     assert_equal 'a b c d', s.pre_match
448     s.scan(/never match/)
449     assert_nil s.pre_match
451     str = 'test string'
452     str.taint
453     s = StringScanner.new(str)
454     s.scan(/\w+/)
455     assert_equal true, s.pre_match.tainted?
456     s.scan(/\s+/)
457     assert_equal true, s.pre_match.tainted?
458     s.scan(/\w+/)
459     assert_equal true, s.pre_match.tainted?
460   end
462   def test_post_match
463     s = StringScanner.new('a b c d e')
464     s.scan(/\w/)
465     assert_equal ' b c d e', s.post_match
466     s.skip(/\s/)
467     assert_equal 'b c d e', s.post_match
468     s.scan(/\w/)
469     assert_equal ' c d e', s.post_match
470     s.scan_until(/c/)
471     assert_equal ' d e', s.post_match
472     s.getch
473     assert_equal 'd e', s.post_match
474     s.get_byte
475     assert_equal ' e', s.post_match
476     s.get_byte
477     assert_equal 'e', s.post_match
478     s.scan(/never match/)
479     assert_nil s.post_match
480     s.scan(/./)
481     assert_equal '', s.post_match
482     s.scan(/./)
483     assert_nil s.post_match
485     str = 'test string'
486     str.taint
487     s = StringScanner.new(str)
488     s.scan(/\w+/)
489     assert_equal true, s.post_match.tainted?
490     s.scan(/\s+/)
491     assert_equal true, s.post_match.tainted?
492     s.scan(/\w+/)
493     assert_equal true, s.post_match.tainted?
494   end
496   def test_terminate
497     s = StringScanner.new('ssss')
498     s.getch
499     s.terminate
500     assert_equal true, s.eos?
501     s.terminate
502     assert_equal true, s.eos?
503   end
505   def test_reset
506     s = StringScanner.new('ssss')
507     s.getch
508     s.reset
509     assert_equal 0, s.pos
510     s.scan(/\w+/)
511     s.reset
512     assert_equal 0, s.pos
513     s.reset
514     assert_equal 0, s.pos
515   end
517   def test_matched_size
518     s = StringScanner.new('test string')
519     assert_nil s.matched_size
520     s.scan(/test/)
521     assert_equal 4, s.matched_size
522     assert_equal 4, s.matched_size
523     s.scan(//)
524     assert_equal 0, s.matched_size
525     s.scan(/x/)
526     assert_nil s.matched_size
527     assert_nil s.matched_size
528     s.terminate
529     assert_nil s.matched_size
531     # obsolete
532     s = StringScanner.new('test string')
533     assert_nil s.matchedsize
534     s.scan(/test/)
535     assert_equal 4, s.matched_size
536     s.terminate
537     assert_nil s.matched_size
538   end
540   def test_encoding
541     ss = StringScanner.new("\xA1\xA2".force_encoding("euc-jp"))
542     assert_equal(Encoding::EUC_JP, ss.scan(/./e).encoding)
543   end
545   def test_generic_regexp
546     ss = StringScanner.new("\xA1\xA2".force_encoding("euc-jp"))
547     t = ss.scan(/./)
548     assert_equal("\xa1\xa2".force_encoding("euc-jp"), t)
549   end
551   def test_set_pos
552     s = StringScanner.new("test string")
553     s.pos = 7
554     assert_equal("ring", s.rest)
555   end
557   def test_match_p
558     s = StringScanner.new("test string")
559     assert_equal(4, s.match?(/\w+/))
560     assert_equal(4, s.match?(/\w+/))
561     assert_equal(nil, s.match?(/\s+/))
562   end
564   def test_check
565     s = StringScanner.new("Foo Bar Baz")
566     assert_equal("Foo", s.check(/Foo/))
567     assert_equal(0, s.pos)
568     assert_equal("Foo", s.matched)
569     assert_equal(nil, s.check(/Bar/))
570     assert_equal(nil, s.matched)
571   end
573   def test_scan_full
574     s = StringScanner.new("Foo Bar Baz")
575     assert_equal(4, s.scan_full(/Foo /, false, false))
576     assert_equal(0, s.pos)
577     assert_equal(nil, s.scan_full(/Baz/, false, false))
578     assert_equal("Foo ", s.scan_full(/Foo /, false, true))
579     assert_equal(0, s.pos)
580     assert_equal(nil, s.scan_full(/Baz/, false, false))
581     assert_equal(4, s.scan_full(/Foo /, true, false))
582     assert_equal(4, s.pos)
583     assert_equal(nil, s.scan_full(/Baz /, false, false))
584     assert_equal("Bar ", s.scan_full(/Bar /, true, true))
585     assert_equal(8, s.pos)
586     assert_equal(nil, s.scan_full(/az/, false, false))
587   end
589   def test_exist_p
590     s = StringScanner.new("test string")
591     assert_equal(3, s.exist?(/s/))
592     assert_equal(0, s.pos)
593     s.scan(/test/)
594     assert_equal(2, s.exist?(/s/))
595     assert_equal(4, s.pos)
596     assert_equal(nil, s.exist?(/e/))
597   end
599   def test_skip_until
600     s = StringScanner.new("Foo Bar Baz")
601     assert_equal(3, s.skip_until(/Foo/))
602     assert_equal(3, s.pos)
603     assert_equal(4, s.skip_until(/Bar/))
604     assert_equal(7, s.pos)
605     assert_equal(nil, s.skip_until(/Qux/))
606   end
608   def test_check_until
609     s = StringScanner.new("Foo Bar Baz")
610     assert_equal("Foo", s.check_until(/Foo/))
611     assert_equal(0, s.pos)
612     assert_equal("Foo Bar", s.check_until(/Bar/))
613     assert_equal(0, s.pos)
614     assert_equal(nil, s.check_until(/Qux/))
615   end
617   def test_search_full
618     s = StringScanner.new("Foo Bar Baz")
619     assert_equal(8, s.search_full(/Bar /, false, false))
620     assert_equal(0, s.pos)
621     assert_equal("Foo Bar ", s.search_full(/Bar /, false, true))
622     assert_equal(0, s.pos)
623     assert_equal(8, s.search_full(/Bar /, true, false))
624     assert_equal(8, s.pos)
625     assert_equal("Baz", s.search_full(/az/, true, true))
626     assert_equal(11, s.pos)
627   end
629   def test_peek
630     s = StringScanner.new("test string")
631     assert_equal("test st", s.peek(7))
632     assert_equal("test st", s.peek(7))
633     s.scan(/test/)
634     assert_equal(" stri", s.peek(5))
635     assert_equal(" string", s.peek(10))
636     s.scan(/ string/)
637     assert_equal("", s.peek(10))
638   end
640   def test_unscan
641     s = StringScanner.new('test string')
642     assert_equal("test", s.scan(/\w+/))
643     s.unscan
644     assert_equal("te", s.scan(/../))
645     assert_equal(nil, s.scan(/\d/))
646     assert_raise(ScanError) { s.unscan }
647   end
649   def test_rest
650     s = StringScanner.new('test string')
651     assert_equal("test string", s.rest)
652     s.scan(/test/)
653     assert_equal(" string", s.rest)
654     s.scan(/ string/)
655     assert_equal("", s.rest)
656     s.scan(/ string/)
657   end
659   def test_rest_size
660     s = StringScanner.new('test string')
661     assert_equal(11, s.rest_size)
662     s.scan(/test/)
663     assert_equal(7, s.rest_size)
664     s.scan(/ string/)
665     assert_equal(0, s.rest_size)
666     s.scan(/ string/)
667   end
669   def test_inspect
670     s = StringScanner.new('test string test')
671     s.scan(/test strin/)
672     assert_equal('#<StringScanner 10/16 "...strin" @ "g tes...">', s.inspect)
673   end