sequence 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,899 @@
1
+ # Copyright (C) 2006 Caleb Clausen
2
+ # Distributed under the terms of Ruby's license.
3
+ $VERBOSE=1
4
+ require 'test/unit'
5
+
6
+
7
+ require 'sequence'
8
+ require 'sequence/indexed'
9
+ require 'sequence/reversed'
10
+ require 'sequence/position'
11
+ require 'sequence/circular'
12
+ require 'sequence/buffered'
13
+ require 'sequence/shifting'
14
+ require 'sequence/file'
15
+ require 'sequence/list'
16
+ require 'sequence/io'
17
+ require 'tempfile'
18
+
19
+
20
+ BEGIN {
21
+ if seedstr=ENV['SEED']
22
+ seed=seedstr.to_i
23
+ srand seed
24
+ else
25
+ rand;
26
+ seed=srand
27
+ end
28
+
29
+ puts "random seed is #{seed}"
30
+ }
31
+
32
+ $Debug=true
33
+
34
+ class SequenceTests
35
+
36
+ DATA="foo\nbar baz that tough guy talk\ndon't make you a dog"
37
+ DATA.freeze
38
+ OFFSET=12
39
+
40
+
41
+ class Indexed <Test::Unit::TestCase
42
+ def a_seq
43
+ #assert_equal 52==DATA.size
44
+ seq= Sequence::Indexed.new(DATA.dup)
45
+ seq.move(OFFSET)
46
+ return seq
47
+ end
48
+ def absolutes_always_fail; false end
49
+
50
+ #forward decls
51
+ def nop; end
52
+ MOVEPOSMETHODS=%w[test_nearbegin test_nearend
53
+ test_pos
54
+ test_pos=
55
+ test_scanning
56
+ test_readahead
57
+ test_read
58
+ test_slice
59
+ test_slice_empty
60
+ ]
61
+ MODIFYMETHODS=%w[
62
+ test_insert
63
+ test_delete
64
+ test_modify
65
+ test_insert_empty
66
+ test_delete_empty
67
+ test_insert_start
68
+ test_delete_start
69
+ test_insert_end
70
+ test_delete_end
71
+ test_randomized_methods_some_more
72
+ test_write
73
+ test_writeback
74
+ test_write_and_read_joints
75
+ test_insert_and_read_joints
76
+ test_delete_and_read_joint
77
+ test_modify_and_read_joints
78
+ test_pos_munging
79
+ ]
80
+ (MOVEPOSMETHODS+MODIFYMETHODS).each{|m| alias_method m, :nop }
81
+
82
+
83
+
84
+ end
85
+
86
+ class Position <Indexed
87
+ def a_seq
88
+ super.position
89
+ end
90
+ end
91
+ class SubSeq1 <Indexed
92
+ def a_seq
93
+ cu=super.subseq(0..-1)
94
+ cu.pos=OFFSET
95
+ cu
96
+ end
97
+ end
98
+ class SubSeq2 <Indexed
99
+ def a_seq
100
+ seq= Sequence::Indexed.new("0123456789#{DATA}0123456789")
101
+ seq = seq. subseq(10...-10)
102
+ seq.pos=OFFSET
103
+ return seq
104
+ end
105
+ end
106
+ class SubSeq3 <Indexed
107
+ def a_seq
108
+ seq = Sequence::Indexed.new("0123456789#{DATA}0123456789")
109
+ seq = seq. subseq(10,DATA.size)
110
+ seq.pos=OFFSET
111
+ return seq
112
+ end
113
+ end
114
+ class Reversed <Indexed
115
+ def a_seq
116
+ seq =DATA.reverse.to_sequence.reversed
117
+ seq.pos=12
118
+ seq
119
+ end
120
+ end
121
+ class Circular <Indexed
122
+ def a_seq
123
+ seq = Sequence::Circular.new(super,OFFSET)
124
+ end
125
+ undef_method(:test_nearbegin, :test_nearend)
126
+ def absolutes_always_fail; true end
127
+ def randlimit; DATA.size end
128
+ end
129
+ nil&& #disabled for now.... too many size dependancies in tests
130
+ class Big <Indexed
131
+ def a_seq
132
+ seq = Sequence::Indexed.new(DATA.gsub(/[ \n]/,' '*1000+"\\1"))
133
+ seq.move(OFFSET+2000)
134
+ return seq
135
+ end
136
+ undef_method :test_pos
137
+ end
138
+ class Tempfile <Indexed
139
+ @@seq =nil
140
+ @@count=0
141
+ def a_seq
142
+ @@seq and @@seq.data.close(true)
143
+
144
+ tf=::Tempfile.new("test_seq#@@count"); @@count+=1
145
+
146
+ tf.write DATA
147
+
148
+ tf.pos=OFFSET
149
+ @@seq = Sequence::File.new tf
150
+ @@seq.goto OFFSET
151
+ @@seq
152
+ end
153
+ undef_method(:test_insert,:test_delete,:test_modify,:test_insert_empty,:test_delete_empty,:test_insert_start,:test_delete_start,:test_insert_end,:test_delete_end,:test_randomized_methods_some_more)
154
+ undef_method :test_modify_and_read_joints, :test_pos_munging
155
+ undef_method :test_write_and_read_joints, :test_insert_and_read_joints, :test_delete_and_read_joint
156
+ end
157
+
158
+ class List < Indexed
159
+ def a_seq
160
+
161
+ seq = Sequence::List.new(DATA.scan(/.{1,8}/m).map{|str| str.to_sequence})
162
+ seq.pos=OFFSET
163
+ seq
164
+ end
165
+
166
+ def test__lookup_idx
167
+ seq=a_seq
168
+ (0..DATA.size).map{|i|
169
+ assert_equal i/8, seq._lookup_idx(i)
170
+ }
171
+ end
172
+
173
+ end
174
+
175
+ class ListMaxxed < Indexed
176
+ def a_seq
177
+
178
+ seq = Sequence::List.new(DATA.scan(/./m).map{|str| str.to_sequence})
179
+ seq.pos=OFFSET
180
+ seq
181
+ end
182
+ def test__lookup_idx
183
+ seq=a_seq
184
+ (0...DATA.size).map{|i|
185
+ assert_equal i, seq._lookup_idx(i)
186
+ }
187
+ end
188
+ end
189
+
190
+ class List1 < Indexed
191
+ def a_seq
192
+
193
+ seq = Sequence::List.new([DATA.dup.to_sequence])
194
+ seq.pos=OFFSET
195
+ seq
196
+ end
197
+ end
198
+
199
+ class List2 < Indexed
200
+ def a_seq
201
+ mid=DATA.size/2
202
+ seq = Sequence::List.new(
203
+ [DATA[0...mid].to_sequence,
204
+ DATA[mid..-1].to_sequence]
205
+ )
206
+ seq.pos=OFFSET
207
+ seq
208
+ end
209
+ end
210
+
211
+ class ListRandomized < Indexed
212
+ def a_seq
213
+ maxchunk=DATA.size/5
214
+ idx=0
215
+ list=[]
216
+ begin
217
+ len=rand(maxchunk)+1
218
+ list<<DATA[idx,len].to_sequence
219
+ idx+=len
220
+
221
+ end until(idx>=DATA.size)
222
+
223
+ seq= Sequence::List.new(list)
224
+ seq.pos=OFFSET
225
+ seq
226
+
227
+
228
+
229
+ end
230
+ end
231
+
232
+ class IO < Indexed
233
+ def a_seq
234
+ r,w=::IO.pipe
235
+ r=Sequence::IO[r]
236
+ w.write DATA
237
+ r.read(OFFSET)== DATA[0,OFFSET] or raise "predata mismatch inside pipe"
238
+ return r
239
+ end
240
+
241
+ #need to disable tests that move cursor position back or modify data
242
+ undef_method(*(MOVEPOSMETHODS+MODIFYMETHODS))
243
+ end
244
+
245
+
246
+ module SmallScanBuffered
247
+ SequenceTests.constants.each{|k|
248
+ xk= SequenceTests.const_get(k)
249
+ next unless (xk.is_a? Class and xk<=Indexed)
250
+ const_set k, xk=Class.new(xk)
251
+ xk.instance_eval do
252
+ define_method :a_seq do
253
+ result=super
254
+ result.maxmatchlen=6
255
+ result
256
+ end
257
+ end
258
+ }
259
+ end
260
+
261
+ =begin disabled for now; too many failures
262
+ module Buffered
263
+ SequenceTests.constants.each{|k|
264
+ oxk= SequenceTests.const_get(k)
265
+ next unless (oxk<=Indexed rescue nil)
266
+ const_set k, xk=Class.new(SequenceTests::Indexed)
267
+ xk.instance_eval do
268
+ define_method :a_seq do
269
+ #p [::Sequence::Buffered, oxk]
270
+ ::Sequence::Buffered.new(oxk.allocate.a_seq)
271
+ end
272
+ end
273
+ }
274
+ end
275
+ =end
276
+
277
+ module Shifting
278
+ SequenceTests.constants.each{|k|
279
+ oxk= SequenceTests.const_get(k)
280
+ next unless Class===oxk
281
+ const_set k, xk=Class.new(SequenceTests::Indexed)
282
+ xk.instance_eval do
283
+ define_method :a_seq do
284
+ #p [::Sequence::Shifting, oxk]
285
+ ::Sequence::Shifting.new(oxk.allocate.a_seq)
286
+ end
287
+ end
288
+ }
289
+ end
290
+
291
+ class Indexed
292
+ RANDOMIZED_METHODS=[:test_slice,:test_insert,:test_delete,:test_modify]
293
+ undef test_randomized_methods_some_more
294
+ def test_randomized_methods_some_more n=50
295
+ RANDOMIZED_METHODS.each{|m| n.times{send m}}
296
+ end
297
+
298
+ def rand_pos_pair
299
+ [rand(randlimit),rand(randlimit)].sort
300
+ end
301
+
302
+ def randlimit
303
+ DATA.size+1
304
+ end
305
+
306
+
307
+ undef_method(*(MOVEPOSMETHODS+MODIFYMETHODS))
308
+ def test_pos_munging
309
+ (1..3).each{|n|
310
+ seq=a_seq
311
+ assert_equal OFFSET, seq.pos
312
+ seq[seq.pos-4,seq.pos+4]="oook"*n
313
+ assert_equal OFFSET-4, seq.pos
314
+ }
315
+
316
+ end
317
+
318
+ def test_slice_empty; test_slice 0,0 end
319
+
320
+ def test_slice first=nil, last=nil
321
+ seq =a_seq
322
+
323
+ first or (first,last=*rand_pos_pair)
324
+
325
+ assert_equal DATA[first...last], seq[first...last]
326
+ assert_equal DATA[first..last], seq[first..last]
327
+ assert_equal DATA[first,last-first], seq[first,last-first]
328
+ assert_equal DATA[first..last], seq[first..last]
329
+ assert_equal DATA[first], seq[first]
330
+
331
+ assert_equal( (DATA.slice first...last), (seq.slice first...last) )
332
+ assert_equal( (DATA.slice first..last), (seq.slice first..last) )
333
+ assert_equal( (DATA.slice first,last-first), (seq.slice first,last-first) )
334
+ assert_equal( (DATA.slice first..last), (seq.slice first..last) )
335
+ assert_equal( (DATA.slice first), (seq.slice first) )
336
+ end
337
+
338
+
339
+
340
+
341
+ def test_size
342
+ assert_equal DATA.size, a_seq.size
343
+ end
344
+
345
+ def test_read
346
+ seq =a_seq
347
+ assert_equal 'that t', (seq.read 6)
348
+ assert_equal OFFSET+6, seq.pos
349
+ end
350
+
351
+ def test_readahead
352
+ seq =a_seq
353
+ assert_equal 'that t', (seq.readahead 6)
354
+ assert_equal OFFSET, seq.pos
355
+ end
356
+
357
+ def test_pos
358
+ seq =a_seq
359
+ assert_equal OFFSET, seq.pos
360
+ end
361
+
362
+ def test_pos=
363
+ seq =a_seq
364
+ assert_equal OFFSET, seq.pos
365
+ seq.pos=25
366
+ assert_equal 25, seq.pos
367
+ assert_equal 'y talk', (seq.read 6)
368
+ assert_equal 31, seq.pos
369
+ end
370
+
371
+ def test_nearbegin
372
+ seq =a_seq
373
+ seq.pos=5
374
+ assert seq.nearbegin(10)
375
+ assert ! seq.nearbegin(4)
376
+ end
377
+
378
+ def test_nearend
379
+ seq =a_seq
380
+ seq.pos=-5
381
+ assert seq.nearend(10)
382
+ assert ! seq.nearend(4)
383
+ end
384
+
385
+ def test_write
386
+ seq =a_seq
387
+ assert_equal 17, seq.write("gooblesnortembopy")
388
+ assert_equal OFFSET+17, seq.pos
389
+ seq.pos=OFFSET
390
+ assert_equal "gooblesnortembopy", (seq.read 17)
391
+ assert_raises(ArgumentError) { seq.write("gooblesnortembopy"*10) }
392
+ end
393
+
394
+ def test_write_and_read_joints
395
+ table=[[:write,+5], [:writeahead,+0], [:writeback,-0.1], [:writebehind,-5]]
396
+ table.each do|(mname,offs)|
397
+ seq =a_seq
398
+ offs<0 and offs=-offs and seq.move 5
399
+ assert_equal 5, seq.send( mname, ("snark") )
400
+ assert_equal OFFSET+offs.to_i, seq.pos
401
+ # seq.pos=OFFSET
402
+ assert_equal "baz sn", seq[OFFSET-4,6]
403
+ assert_equal "rktoug", seq[OFFSET+3,6]
404
+ assert_equal OFFSET+offs.to_i, seq.pos
405
+ end
406
+ end
407
+
408
+ def test_modify_and_read_joints
409
+ seq =a_seq
410
+ # seq.pos+=2
411
+ assert_equal OFFSET, seq.pos
412
+ assert_equal "snark", seq.modify(15..25,"snark")
413
+ assert_equal OFFSET, seq.pos
414
+ # seq.pos=OFFSET
415
+ assert_equal "thasna", seq[12,6]
416
+ assert_equal "rk tal", seq[18,6]
417
+ end
418
+
419
+
420
+ def test_insert_and_read_joints
421
+ seq =a_seq
422
+ assert_equal "snark", seq.insert(seq.pos,"snark")
423
+ assert_equal OFFSET, seq.pos
424
+ # seq.pos=OFFSET
425
+ assert_equal "baz sn", seq[OFFSET-4,6]
426
+ assert_equal "rkthat", seq[OFFSET+3,6]
427
+ assert_equal OFFSET, seq.pos
428
+ assert_equal "snark", seq.read(5)
429
+ assert_equal OFFSET+5, seq.pos
430
+ end
431
+
432
+ def test_delete_and_read_joint
433
+ seq =a_seq
434
+ assert_equal nil, seq.delete(seq.pos,5)
435
+ assert_equal OFFSET, seq.pos
436
+ # seq.pos=OFFSET
437
+ assert_equal "baz to", seq[OFFSET-4,6]
438
+ assert_equal OFFSET, seq.pos
439
+ assert_equal "tough", seq.read(5)
440
+ assert_equal OFFSET+5, seq.pos
441
+ end
442
+
443
+ def test_writeback
444
+ seq =a_seq
445
+ assert_equal 6, seq.writeback("gooble")
446
+ assert_equal OFFSET-6, seq.pos
447
+ seq.pos=OFFSET
448
+ assert_equal "gooble", (seq.readback 6)
449
+ assert_raises(ArgumentError) { seq.writeback("gooblesnortembopy") }
450
+ end
451
+
452
+ def change_notification(seq,first,oldlen,newlen)
453
+ assert_same @seq, seq
454
+ assert_equal @first, first
455
+ assert_equal @oldlen, oldlen
456
+ assert_equal @newlen, newlen
457
+ @changes_seen +=1
458
+ end
459
+
460
+ def add_test_listener(seq,first,last,newlen)
461
+ @changes_seen=0
462
+ if first<0
463
+ first+=seq.size
464
+ last.zero? and last=seq.size
465
+ end
466
+ last<0 and last+=seq.size
467
+ @seq,@first,@oldlen,@newlen= seq,first,last-first,newlen
468
+ seq.on_change_notify(self)
469
+ end
470
+
471
+ def verify_test_listener expect_count=1
472
+ assert_equal @seq.instance_eval{@change_listeners}.to_a, [self]
473
+ if expect_count!=@changes_seen
474
+ assert_equal @seq.instance_eval{@change_listeners}.to_a, [self]
475
+ assert false
476
+ end
477
+ assert_equal @seq.instance_eval{@change_listeners}.to_a, [self]
478
+ end
479
+
480
+ def test_insert_empty; test_insert 15,15 end
481
+ def test_insert_start; test_insert 0,15 end
482
+ def test_insert_end; test_insert( -15,0 ) end
483
+
484
+ def test_insert(first=nil,last=nil)
485
+ seq =a_seq
486
+ first or (first,last=*rand_pos_pair)
487
+ # puts("first=#{first}, last=#{last}")
488
+ len=last-first
489
+ add_test_listener seq,first,first,len
490
+ assert_equal seq.instance_eval{@change_listeners}.to_a, [self]
491
+ seq.insert first, " "*len
492
+ assert_equal seq.instance_eval{@change_listeners}.to_a, [self]
493
+ verify_test_listener(1)
494
+ end
495
+
496
+
497
+ def test_delete_empty; test_delete 15,15 end
498
+ def test_delete_start; test_delete 0,15 end
499
+ def test_delete_end; test_delete( -15,0 ) end
500
+
501
+
502
+ def test_delete first=nil,last=nil
503
+ seq =a_seq
504
+ first or (first,last=*rand_pos_pair)
505
+ # puts "first=#{first}, last=#{last}"
506
+ len=last-first
507
+ add_test_listener seq,first,last,0
508
+ list=seq.instance_eval{@change_listeners}.to_a
509
+ assert_equal 1, list.size
510
+ assert_equal self.__id__, list.first.__id__
511
+ seq.delete first, len
512
+ assert_equal 1, list.size
513
+ assert_equal self.__id__, list.first.__id__
514
+ verify_test_listener(1)
515
+ end
516
+
517
+
518
+ def test_modify
519
+ seq =a_seq
520
+ first,last=*rand_pos_pair
521
+ oldlen=last-first
522
+ newlen=rand(2*DATA.size)
523
+ add_test_listener seq,first,last,newlen
524
+ #puts "first: #{first}, oldlen: #{oldlen}, newlen: #{newlen}"
525
+ assert_equal seq.instance_eval{@change_listeners}.to_a, [self]
526
+ seq.modify first, oldlen," "*newlen
527
+ assert_equal seq.instance_eval{@change_listeners}.to_a, [self]
528
+ verify_test_listener(1)
529
+ end
530
+
531
+
532
+ def verify_failmatch_status(meth,pat,pos=nil)
533
+ _=(seq =a_seq).send meth,pat
534
+ pos ? seq.pos=pos : pos=OFFSET
535
+ assert_equal nil, _
536
+ assert_equal pos, seq.pos
537
+ assert seq.last_match.nil?
538
+ end
539
+
540
+ def verify_aftermatch_status(seq,pos,matches,starts,pre,post,eof)
541
+ assert_equal pos, seq.pos
542
+ assert seq.last_match
543
+ i=nil
544
+ matches.each_with_index{|m,i|
545
+ assert_equal m, seq.last_match[i]
546
+ }
547
+ assert_equal nil, seq.last_match[i+1]
548
+ assert_equal matches.length, seq.last_match.length
549
+ assert_equal matches, seq.last_match.to_a
550
+ starts.each_with_index{|start,i|
551
+ assert_equal start, seq.last_match.begin(i)
552
+ assert_equal start+matches[i].size, seq.last_match.end(i)
553
+
554
+ assert_equal start, seq.last_match.offset(i).first
555
+ assert_equal start+matches[i].size, seq.last_match.offset(i).last
556
+ }
557
+ assert_equal nil, seq.last_match.begin(i+1)
558
+ assert_equal nil, seq.last_match.end(i+1)
559
+ assert_equal nil, seq.last_match.offset(i+1)
560
+
561
+ assert_equal pre, seq.last_match.pre_match[0..-1]
562
+ assert_equal post, seq.last_match.post_match[0..-1]
563
+ eof and assert seq.last_match.post_match.eof?
564
+ end
565
+
566
+ def verify_scan_methods(rex,offset,matchstr,restargs,backwards=false)
567
+ mappings={
568
+ :scan=>[:to_s,1], :check =>[:to_s,0],
569
+ :skip=>[:size,1], :match? =>[:size,0],
570
+
571
+
572
+
573
+ :scan_until=>[:to_s,1], :check_until=>[:to_s,0],
574
+ :skip_until=>[:size,1], :exist? =>[:size,0],
575
+ }
576
+
577
+ mappings.each{|k,v|
578
+ k=k.to_s.sub(/(_until|\?)?$/) {"back"+$1} if backwards
579
+ seq =a_seq
580
+ seq.pos=offset
581
+ assert_equal matchstr.send( v[0]), seq.send( k, rex)
582
+ factor=v[1]
583
+ factor=-factor if backwards
584
+ verify_aftermatch_status(seq,
585
+ offset+matchstr.size*factor, *restargs
586
+ )
587
+ }
588
+ end
589
+
590
+ def verify_scan_until_methods rex,offset,prematch,matchstr,restargs
591
+ restargs[1][0]==offset and return verify_scan_methods( rex,offset,matchstr,restargs )
592
+ mappings={
593
+ :scan_until=>[:to_s,1],
594
+ :check_until=>[:to_s,0],
595
+ :skip_until=>[:size,1],
596
+ :exist? =>[:size,0]
597
+ }
598
+
599
+ mappings.each{|k,v|
600
+
601
+ (seq =a_seq)
602
+ seq.pos=offset
603
+ assert_equal prematch.send(v[0])+matchstr.send(v[0]), seq.send( k, rex)
604
+ verify_aftermatch_status( seq,offset+(prematch.size+matchstr.size)*v[1],*restargs )
605
+ }
606
+
607
+
608
+ %w[scan skip check match?].each{|meth|
609
+ verify_failmatch_status( meth,rex,offset )
610
+ }
611
+ end
612
+
613
+ def test_scanning
614
+
615
+ assert_equal "that ", a_seq.readahead(5)
616
+
617
+ verify_scan_methods( /th(is|at)/,OFFSET,"that",
618
+ [%W[that at],[OFFSET,OFFSET+2],
619
+ "", " tough guy talk\ndon't make you a dog", false] )
620
+ =begin
621
+ _=(seq =a_seq).scan /th(is|at)/
622
+ assert_equal "that", _
623
+ verify_aftermatch_status(
624
+ seq,16,%W[that at],[OFFSET,OFFSET+2],
625
+ "", " tough guy talk\ndon't make you a dog", false
626
+ )
627
+
628
+ _=(seq =a_seq).check /th(is|at)/
629
+ assert_equal "that", _
630
+ verify_aftermatch_status(
631
+ seq,12,%W[that at],[OFFSET,OFFSET+2],
632
+ "", " tough guy talk\ndon't make you a dog", false
633
+ )
634
+
635
+ _=(seq =a_seq).skip /th(is|at)/
636
+ assert_equal 4, _
637
+ verify_aftermatch_status(
638
+ seq,16,%W[that at],[OFFSET,OFFSET+2],
639
+ "", " tough guy talk\ndon't make you a dog", false
640
+ )
641
+
642
+ _=(seq =a_seq).match? /th(is|at)/
643
+ assert_equal 4, _
644
+ verify_aftermatch_status(
645
+ seq,12,%W[that at],[OFFSET,OFFSET+2],
646
+ "", " tough guy talk\ndon't make you a dog", false
647
+ )
648
+ =end
649
+
650
+ verify_scan_until_methods( /[mb]ake/, OFFSET, "that tough guy talk\ndon't ", "make",
651
+ [%W[make],[OFFSET+26],
652
+ "that tough guy talk\ndon't "," you a dog", false] )
653
+
654
+ =begin
655
+ _=(seq =a_seq).scan_until /[mb]ake/
656
+ assert_equal "that tough guy talk\ndon't make", _
657
+ verify_aftermatch_status(
658
+ seq,16+26,%W[make],[OFFSET+26],
659
+ "that tough guy talk\ndon't "," you a dog", false
660
+ )
661
+
662
+ _=(seq =a_seq).check_until /[mb]ake/
663
+ assert_equal "that tough guy talk\ndon't make", _
664
+ verify_aftermatch_status(
665
+ seq,OFFSET,%W[make],[OFFSET+26],
666
+ "that tough guy talk\ndon't "," you a dog", false
667
+ )
668
+
669
+ _=(seq =a_seq).skip_until /[mb]ake/
670
+ assert_equal 30, _
671
+ verify_aftermatch_status(
672
+ seq,16+26,%W[make],[OFFSET+26],
673
+ "that tough guy talk\ndon't "," you a dog", false
674
+ )
675
+
676
+ _=(seq =a_seq).exist? /[mb]ake/
677
+ assert_equal 30, _
678
+ verify_aftermatch_status(
679
+ seq,OFFSET,%W[make],[OFFSET+26],
680
+ "that tough guy talk\ndon't "," you a dog", false
681
+ )
682
+ =end
683
+
684
+ #ok, and now with anchors
685
+ verify_failmatch_status :scan_until, /[cr]at\Z/
686
+ verify_failmatch_status :scan_until, /you\Z/
687
+ verify_failmatch_status :scan_until, /talk\Z/
688
+
689
+ verify_failmatch_status :exist?, /[cr]at\Z/
690
+ verify_failmatch_status :exist?, /you\Z/
691
+ verify_failmatch_status :exist?, /talk\Z/
692
+
693
+ verify_failmatch_status :check_until, /[cr]at\Z/
694
+ verify_failmatch_status :check_until, /you\Z/
695
+ verify_failmatch_status :check_until, /talk\Z/
696
+
697
+ verify_failmatch_status :skip_until, /[cr]at\Z/
698
+ verify_failmatch_status :skip_until, /you\Z/
699
+ verify_failmatch_status :skip_until, /talk\Z/
700
+
701
+ unless absolutes_always_fail
702
+ verify_scan_until_methods( /(d([^d]+))\Z/,OFFSET,"", "that tough guy talk\ndon't make you a dog",
703
+ [%W[dog dog og],[OFFSET+37,OFFSET+37,OFFSET+38],"that tough guy talk\ndon't make you a ", "", true] )
704
+
705
+ =begin
706
+ _=(seq =a_seq).scan_until /(d([^d]+))\Z/
707
+ assert_equal "that tough guy talk\ndon't make you a dog", _
708
+ verify_aftermatch_status(
709
+ seq,52,%W[dog dog og],[49,49,50],
710
+ "that tough guy talk\ndon't make you a ","", true
711
+ )
712
+
713
+ _=(seq =a_seq).exist? /(d([^d]+))\Z/
714
+ assert_equal 40, _
715
+ verify_aftermatch_status(
716
+ seq,OFFSET,%W[dog dog og],[49,49,50],
717
+ "that tough guy talk\ndon't make you a ","", true
718
+ )
719
+
720
+ _=(seq =a_seq).check_until /(d([^d]+))\Z/
721
+ assert_equal "that tough guy talk\ndon't make you a dog", _
722
+ verify_aftermatch_status(
723
+ seq,12,%W[dog dog og],[49,49,50],
724
+ "that tough guy talk\ndon't make you a ","", true
725
+ )
726
+
727
+ _=(seq =a_seq).skip_until /(d([^d]+))\Z/
728
+ assert_equal 40, _
729
+ verify_aftermatch_status(
730
+ seq,52,%W[dog dog og],[49,49,50],
731
+ "that tough guy talk\ndon't make you a ","", true
732
+ )
733
+ =end
734
+ end
735
+
736
+ #implicitly anchored with anchors
737
+ verify_failmatch_status :scan, /[cr]at\Z/,49
738
+ verify_failmatch_status :scan, /you\Z/,43
739
+ verify_failmatch_status :scan, /talk\Z/,31
740
+
741
+ verify_failmatch_status :check, /[cr]at\Z/,49
742
+ verify_failmatch_status :check, /you\Z/,43
743
+ verify_failmatch_status :check, /talk\Z/,31
744
+
745
+ verify_failmatch_status :skip, /[cr]at\Z/,49
746
+ verify_failmatch_status :skip, /you\Z/,43
747
+ verify_failmatch_status :skip, /talk\Z/,31
748
+
749
+ verify_failmatch_status :exist?, /[cr]at\Z/,49
750
+ verify_failmatch_status :exist?, /you\Z/,43
751
+ verify_failmatch_status :exist?, /talk\Z/,31
752
+
753
+ unless absolutes_always_fail
754
+ verify_scan_methods( /(d([^d]+))\Z/,OFFSET+37, "dog",
755
+ [%W[dog dog og],[OFFSET+37,OFFSET+37,OFFSET+38],"", "", true] )
756
+
757
+
758
+ =begin
759
+ _=(seq =a_seq)
760
+ seq.pos=49 #at 'dog'
761
+ _= seq.scan /(d([^d]+))\Z/
762
+ assert_equal "dog", _
763
+ verify_aftermatch_status(
764
+ seq,52,%W[dog dog og],[49,49,50],"","", true
765
+ )
766
+
767
+ _=(seq =a_seq)
768
+ seq.pos=49 #at 'dog'
769
+ _= seq.match? /(d([^d]+))\Z/
770
+ assert_equal 3, _
771
+ verify_aftermatch_status(
772
+ seq,49,%W[dog dog og],[49,49,50],"","", true
773
+ )
774
+
775
+ _=(seq =a_seq)
776
+ seq.pos=49 #at 'dog'
777
+ _= seq.check /(d([^d]+))\Z/
778
+ assert_equal "dog", _
779
+ verify_aftermatch_status(
780
+ seq,49,%W[dog dog og],[49,49,50],"","", true
781
+ )
782
+
783
+ _=(seq =a_seq)
784
+ seq.pos=49 #at 'dog'
785
+ _= seq.skip /(d([^d]+))\Z/
786
+ assert_equal 3, _
787
+ verify_aftermatch_status(
788
+ seq,52,%W[dog dog og],[49,49,50],"","", true
789
+ )
790
+ =end
791
+ end
792
+ #$ as anchor
793
+ verify_failmatch_status :scan_until, /[cr]at$/
794
+ verify_failmatch_status :scan_until, /you$/
795
+
796
+ verify_failmatch_status :exist?, /[cr]at$/
797
+ verify_failmatch_status :exist?, /you$/
798
+
799
+ verify_failmatch_status :check_until, /[cr]at$/
800
+ verify_failmatch_status :check_until, /you$/
801
+
802
+ verify_failmatch_status :skip_until, /[cr]at$/
803
+ verify_failmatch_status :skip_until, /you$/
804
+
805
+ unless absolutes_always_fail
806
+ verify_scan_until_methods( /(d([^d]+))$/,OFFSET,"", "that tough guy talk\ndon't make you a dog",
807
+ [%W[dog dog og],[OFFSET+37,OFFSET+37,OFFSET+38],"that tough guy talk\ndon't make you a ", "", true] )
808
+
809
+
810
+ =begin
811
+ _=(seq =a_seq).scan_until /(d([^d]+))$/
812
+ assert_equal "that tough guy talk\ndon't make you a dog", _
813
+ verify_aftermatch_status(
814
+ seq,52,%W[dog dog og],[49,49,50],
815
+ "that tough guy talk\ndon't make you a ","", true
816
+ )
817
+
818
+ _=(seq =a_seq).exist? /(d([^d]+))$/
819
+ assert_equal 40, _
820
+ verify_aftermatch_status(
821
+ seq,OFFSET,%W[dog dog og],[49,49,50],
822
+ "that tough guy talk\ndon't make you a ","", true
823
+ )
824
+
825
+ _=(seq =a_seq).check_until /(d([^d]+))$/
826
+ assert_equal "that tough guy talk\ndon't make you a dog", _
827
+ verify_aftermatch_status(
828
+ seq,12,%W[dog dog og],[49,49,50],
829
+ "that tough guy talk\ndon't make you a ","", true
830
+ )
831
+
832
+ _=(seq =a_seq).skip_until /(d([^d]+))$/
833
+ assert_equal 40, _
834
+ verify_aftermatch_status(
835
+ seq,52,%W[dog dog og],[49,49,50],
836
+ "that tough guy talk\ndon't make you a ","", true
837
+ )
838
+ =end
839
+ end
840
+
841
+ verify_scan_until_methods( /(st|[bt])alk$/,OFFSET,"", "that tough guy talk",
842
+ [%W[talk t],[OFFSET+15,OFFSET+15],"that tough guy ","\ndon't make you a dog", false] )
843
+ =begin
844
+ _=(seq =a_seq).scan_until /(st|[bt])alk$/
845
+ assert_equal "that tough guy talk", _
846
+ verify_aftermatch_status(seq,31,%W[talk t],[27,27],"that tough guy ","\ndon't make you a dog",false)
847
+
848
+ _=(seq =a_seq).exist? /(st|[bt])alk$/
849
+ assert_equal 19, _
850
+ verify_aftermatch_status(seq,12,%W[talk t],[27,27],"that tough guy ","\ndon't make you a dog",false)
851
+
852
+ _=(seq =a_seq).check_until /(st|[bt])alk$/
853
+ assert_equal "that tough guy talk", _
854
+ verify_aftermatch_status(seq,12,%W[talk t],[27,27],"that tough guy ","\ndon't make you a dog",false)
855
+
856
+ _=(seq =a_seq).skip_until /(st|[bt])alk$/
857
+ assert_equal 19, _
858
+ verify_aftermatch_status(seq,31,%W[talk t],[27,27],"that tough guy ","\ndon't make you a dog",false)
859
+ =end
860
+ verify_failmatch_status :scan_until, /(bob|talk\Z|(dou(gh)?))/
861
+ verify_failmatch_status :check_until, /(bob|talk\Z|(dou(gh)?))/
862
+ verify_failmatch_status :skip_until, /(bob|talk\Z|(dou(gh)?))/
863
+ verify_failmatch_status :exist?, /(bob|talk\Z|(dou(gh)?))/
864
+
865
+ verify_scan_until_methods( /(bob|you\Z|(tou(gh)?))/,OFFSET, "", "that tough",
866
+ [%W[tough tough tough gh],[OFFSET+5,OFFSET+5,OFFSET+5,OFFSET+8],"that "," guy talk\ndon't make you a dog", false] )
867
+
868
+ _=(seq =a_seq).scan_until( /(bob|you\Z|(tou(gh)?))/ )
869
+ assert_equal "that tough", _
870
+ verify_aftermatch_status(seq,22,%W[tough tough tough gh],[17,17,17,20],"that "," guy talk\ndon't make you a dog",false)
871
+
872
+ _=(seq =a_seq).check_until( /(bob|you\Z|(tou(gh)?))/ )
873
+ assert_equal "that tough", _
874
+ verify_aftermatch_status(seq,12,%W[tough tough tough gh],[17,17,17,20],"that "," guy talk\ndon't make you a dog",false)
875
+
876
+
877
+ _=(seq =a_seq).skip_until( /(bob|you\Z|(tou(gh)?))/ )
878
+ assert_equal 10, _
879
+ verify_aftermatch_status(seq,22,%W[tough tough tough gh],[17,17,17,20],"that "," guy talk\ndon't make you a dog",false)
880
+
881
+
882
+ _=(seq =a_seq).exist?( /(bob|you\Z|(tou(gh)?))/ )
883
+ assert_equal 10, _
884
+ verify_aftermatch_status(seq,12,%W[tough tough tough gh],[17,17,17,20],"that "," guy talk\ndon't make you a dog",false)
885
+
886
+
887
+
888
+
889
+
890
+ seq =a_seq
891
+ _=seq.scanback( /baz $/ )
892
+ assert_equal "baz ",_
893
+ verify_aftermatch_status(seq,8,["baz "],[8],"foo\nbar ","",false)
894
+ end
895
+ end
896
+ end
897
+
898
+
899
+