cursor 0.6 → 0.8

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,519 @@
1
+
2
+ # $Id: test.rb,v 1.22 2005/07/21 15:15:38 eric_mahurin Exp $
3
+
4
+ require 'test/unit'
5
+ require 'cursor'
6
+ require 'cursor/usedeleteinsert'
7
+
8
+ # :stopdoc:
9
+
10
+ module Test
11
+ module Unit
12
+ class TestSuite
13
+ def run(result, &progress_block)
14
+ yield(STARTED, name)
15
+ if @tests.size>0 and @tests[0].class.respond_to?:random
16
+ catch(:stop_suite) {
17
+ (@tests[0].class.random*@tests.size).to_i.times do
18
+ test = @tests[rand(@tests.size)]
19
+ catch(:invalid_test) {
20
+ test.run(result, &progress_block)
21
+ }
22
+ end
23
+ }
24
+ else
25
+ @tests.each do |test|
26
+ test.run(result, &progress_block)
27
+ end
28
+ end
29
+ yield(FINISHED, name)
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ ArgArray = Class.new(Array)
36
+
37
+ class Cursor
38
+ class Test < ::Test::Unit::TestCase
39
+ def self.suite(random_iterations=8,random_seed=0,klass='',methods='',flags=0)
40
+ return(::Test::Unit::TestSuite.new()) if !self.respond_to?:seed
41
+ if !(@@output_level||=nil)
42
+ @@output_level = ::Test::Unit::UI::SILENT
43
+ ObjectSpace.each_object(::Test::Unit::AutoRunner) { |runner|
44
+ @@output_level = runner.instance_eval { @output_level }
45
+ }
46
+ end
47
+ if !(@@random_iterations||=nil)
48
+ @@random_iterations = random_iterations.to_f
49
+ end
50
+ if !(@@random_seed||=nil)
51
+ @@random_seed = random_seed.to_i.nonzero? || (srand;srand)
52
+ puts("random_seed: #{@@random_seed}") if @@output_level>=::Test::Unit::UI::NORMAL
53
+ srand(@@random_seed)
54
+ end
55
+ @klass = Regexp.new(klass)
56
+ methods = Regexp.new(methods)
57
+ @reject ||= nil
58
+ public_instance_methods(true).each { |m|
59
+ if matchdata = /^test_\d*(.*)/.match(m.to_s)
60
+ undef_method(m) if @reject&&@reject=~matchdata[1] ||
61
+ !(methods=~matchdata[1])
62
+ end
63
+ }
64
+ @flags = flags
65
+ @use_positions = @flags[0].zero?
66
+ @use_branches = true
67
+ @allow_pruning = false
68
+ self.plant
69
+ super()
70
+ end
71
+ def self.plant
72
+ before = sequence(0,1.5)
73
+ after = sequence(0,1.5,before.class.new)
74
+ cursors = seed(before,after)
75
+ if @klass
76
+ cursors.reject! { |cursor| !(@klass===cursor.class.to_s) }
77
+ end
78
+ return(self.plant) if cursors.empty?
79
+ if @@output_level>=::Test::Unit::UI::NORMAL
80
+ puts("\nnew(#{before.inspect}+#{after.inspect}) -> self")
81
+ end
82
+ @cursors_root = {
83
+ :trunk => cursors,
84
+ :positions => [],
85
+ :branches => [],
86
+ }
87
+ end
88
+ def self.element(offset=0,weight=1)
89
+ elements[rand((weight*(elements.size+offset)).to_i)]
90
+ end
91
+ def self.sequence(offset=0,weight=2,value=empty)
92
+ while v = element(offset,weight)
93
+ value << v
94
+ end
95
+ value
96
+ end
97
+ def self.random
98
+ @@random_iterations
99
+ end
100
+ def self.reject(name,*args,&block)
101
+ false
102
+ end
103
+ def setup
104
+ cursors_tree = self.class.instance_eval{@cursors_root}
105
+ level = 0
106
+ @prune = proc{}
107
+ while (branches = cursors_tree[:branches]).size.nonzero? and
108
+ self.class.instance_eval{@use_branches}&&rand(3).zero?
109
+ i = rand(branches.size)
110
+
111
+ if _closed?(branches[i][:trunk])
112
+ branches.slice!(i)
113
+ break
114
+ else
115
+ @prune = proc { branches.slice!(i) }
116
+ cursors_tree = branches[i]
117
+ level += 1
118
+ end
119
+ end
120
+ if (positions = cursors_tree[:positions]).size.nonzero? and
121
+ self.class.instance_eval{@use_positions}&&rand(3).zero?
122
+ i = rand(positions.size)
123
+ if _closed?(positions[i])
124
+ positions.slice!(i)
125
+ else
126
+ @prune = proc { positions.slice!(i) }
127
+ cursors_tree = {
128
+ :trunk => positions[i],
129
+ :positions => cursors_tree[:positions],
130
+ :branches => cursors_tree[:branches],
131
+ }
132
+ level += 1
133
+ end
134
+ end
135
+ @cursors_tree = cursors_tree
136
+ @cursors = cursors_tree[:trunk]
137
+ @positions = cursors_tree[:positions]
138
+ @branches = cursors_tree[:branches]
139
+ @level = level
140
+ @state = ""
141
+ @exec = nil
142
+ end
143
+ def teardown
144
+ if not passed?
145
+ if @@output_level>=::Test::Unit::UI::PROGRESS_ONLY
146
+ puts("\n#{self.class}")
147
+ puts("random_seed: #{@@random_seed}")
148
+ puts(@call)
149
+ end
150
+ throw(:stop_suite)
151
+ end
152
+ end
153
+
154
+ private
155
+ def _closed?(cursors)
156
+ ret0 = nil
157
+ cursors.each_with_index { |cursor,i|
158
+ i==0 ? ret0 = cursor.closed? : assert_equal(ret0,cursor.closed?)
159
+ }
160
+ ret0
161
+ end
162
+ def _inspect_short(obj,_self=nil)
163
+ if _self and _self.equal?(obj)
164
+ "self"
165
+ else
166
+ obj.inspect.sub(/\A\#\<([\w\:]+?\:0x[\da-f]+).*\>\Z/,'#<\\1>')
167
+ end
168
+ end
169
+ def _inspect_self(obj,_self=nil)
170
+ if _self and _self.equal?(obj)
171
+ "self"
172
+ else
173
+ obj.inspect
174
+ end
175
+ end
176
+ def _inspect_merge(objects,selves=nil)
177
+ _inspect_short(objects[0],selves&&selves[0])
178
+ end
179
+ def _multi_test(name,*args0,&assertion)
180
+ block = args0.pop
181
+ throw(:invalid_test) if self.class.reject(name,*args0,&block)
182
+ cursors = @cursors
183
+ call = @level.zero? ? "self." : "#{_inspect_merge(@cursors)}."
184
+ call += "{" if @exec
185
+ call += name.to_s
186
+ args = args0.collect { |arg|
187
+ ArgArray===arg ? _inspect_merge(arg) : _inspect_short(arg)
188
+ }
189
+ call += "(#{args.join(',')})" if not args.empty?
190
+ call += " {#{block.inspect.sub(/\A\#<Proc\:0x[\da-f]+\@(.*?)\>\Z/,'\\1')}}" if block
191
+ call += "}" if @exec
192
+ @call = call
193
+ print("\n#{call} ") if @@output_level==::Test::Unit::UI::NORMAL
194
+ state = @state
195
+ ret = ArgArray.new
196
+ puts if @@output_level>=::Test::Unit::UI::VERBOSE
197
+ @cursors.each_with_index do |cursor,i|
198
+ @state = state.clone
199
+ initial = cursor.inspect
200
+ args = args0.collect { |arg|
201
+ ArgArray===arg ? arg[i] :
202
+ begin
203
+ arg.clone
204
+ rescue TypeError
205
+ arg
206
+ end
207
+ }
208
+ call = ""
209
+ call += "{" if @exec
210
+ call += name.to_s
211
+ call += "(#{args.inspect[1..-2]})" if not args.empty?
212
+ call += " #{block.inspect}" if block
213
+ call += "}" if @exec
214
+ if @@output_level>=::Test::Unit::UI::VERBOSE
215
+ puts(initial)
216
+ print("#{call} ")
217
+ end
218
+ @cursor = cursor
219
+ if @exec
220
+ ret << @exec.call(cursor,name,*args,&block)
221
+ else
222
+ ret << cursor.__send__(name,*args,&block)
223
+ end
224
+ message = [initial,call,cursor.inspect].join("\n")
225
+ puts("-> #{_inspect_self(ret[-1],cursor)}") if @@output_level>=::Test::Unit::UI::VERBOSE
226
+ #puts(cursor.inspect) if @@output_level>=::Test::Unit::UI::VERBOSE
227
+ assertion[i,ret[-1],cursor,message]
228
+ end
229
+ @call += "-> #{_inspect_merge(ret,@cursors)}"
230
+ print("-> #{_inspect_merge(ret,@cursors)}") if @@output_level==::Test::Unit::UI::NORMAL
231
+ @prune[] if self.class.instance_eval{@allow_pruning}&&rand(2).zero?
232
+ ret
233
+ end
234
+ def _test_equal(name,*args,&block)
235
+ ret0 = nil
236
+ _multi_test(name,*(args << block)) {
237
+ |i,ret,cursor,message|
238
+ i==0 ? ret0 = ret : assert_equal(ret0,ret,message)
239
+ }
240
+ end
241
+ def _exec_position?(cursor,name,*args,&block)
242
+ cursor.position? { cursor.__send__(name,*args,&block) }
243
+ end
244
+ def _test_position?(name,*args,&block)
245
+ ret0 = nil
246
+ @exec = method(:_exec_position?)
247
+ _multi_test(name,*(args << block)) {
248
+ |i,ret,cursor,message|
249
+ i==0 ? ret0 = ret : assert_equal(ret0,ret,message)
250
+ }
251
+ end
252
+ def _test_self(name,*args,&block)
253
+ ret0 = nil
254
+ _multi_test(name,*(args << block)) {
255
+ |i,ret,cursor,message|
256
+ ret0 = ret||nil if i==0
257
+ assert_same(ret0&&cursor,ret,message)
258
+ }
259
+ end
260
+ def _test_position(name,*args,&block)
261
+ new_cursors = ArgArray.new
262
+ ret0 = nil
263
+ _multi_test(name,*(args << block)) {
264
+ |i,ret,cursor,message|
265
+ ret0 = ret if i==0
266
+ if not ret0
267
+ assert_nil(ret,message)
268
+ else
269
+ assert_not_nil(ret,message)
270
+ new_cursors << ret
271
+ end
272
+ }
273
+ @positions << new_cursors if ret0
274
+ end
275
+ def _test_branch(name,*args,&block)
276
+ new_cursors = ArgArray.new
277
+ ret0 = nil
278
+ _multi_test(name,*(args << block)) {
279
+ |i,ret,cursor,message|
280
+ ret0 = ret if i==0
281
+ if not ret0
282
+ assert_nil(ret,message)
283
+ else
284
+ assert_not_nil(ret,message)
285
+ new_cursors << ret
286
+ end
287
+ }
288
+ @branches << {
289
+ :trunk => new_cursors,
290
+ :positions => [],
291
+ :branches => [],
292
+ } if ret0
293
+ end
294
+ def _test_close(name,*args,&block)
295
+ ret0 = nil
296
+ _multi_test(name,*(args << block)) {
297
+ |i,ret,cursor,message|
298
+ i==0 ? ret0 = ret : assert_equal(ret0,ret,message)
299
+ }
300
+ assert_same(true,_closed?(@cursors))
301
+ if @level==0
302
+ self.class.plant
303
+ end
304
+ ret0
305
+ end
306
+
307
+
308
+ def _opt(*args,&block)
309
+ args = args[0,rand(args.size+1)]
310
+ block and rand(2).zero? and args << block[]
311
+ args
312
+ end
313
+ def _ornil(arg)
314
+ rand(2).zero? ? arg : nil
315
+ end
316
+ # responds to ==element
317
+ def _element
318
+ self.class.element
319
+ end
320
+ # responds to ==element
321
+ def _scan_element
322
+ self.class.element
323
+ end
324
+ # responds to [element]
325
+ def _replacer
326
+ lookup = {}
327
+ self.class.elements.each { |e|
328
+ lookup[e] = self.class.element(1)
329
+ }
330
+ lookup
331
+ end
332
+ # responds to <(int), abs (which responds to >(int))
333
+ def _len
334
+ rand(5)-2
335
+ end
336
+ # responds to if and the like (everything)
337
+ def _boolean
338
+ rand(2).zero?
339
+ end
340
+ def _booleannil
341
+ case rand(3)
342
+ when 0 then false
343
+ when 1 then true
344
+ when 2 then nil
345
+ end
346
+ end
347
+ # responds to [int]
348
+ def _read_sequence
349
+ self.class.sequence(0,3)
350
+ end
351
+ # responds to <<element
352
+ def _write_sequence
353
+ self.class.sequence
354
+ end
355
+ # responds to [Integer] returning ==element responder
356
+ def _scan_sequence
357
+ self.class.sequence
358
+ end
359
+ # responds to [Integer] returning ==element responder
360
+ def _scan_sequence
361
+ self.class.sequence
362
+ end
363
+ # responds to [Integer] returning ==element responder
364
+ def _each_sequence
365
+ value = self.class.empty
366
+ value << self.class.element
367
+ while v = self.class.element(0,2)
368
+ value << v
369
+ end
370
+ value
371
+ end
372
+ def _pos
373
+ pos = rand(
374
+ self.class.instance_eval{@cursors_root}[:trunk][0].size.abs.to_i+1
375
+ )
376
+ rand(2).zero? ? -(pos.nonzero?||0.0) : pos
377
+ end
378
+ def _prop_name
379
+ rand(2).zero? ? :first : :last
380
+ end
381
+ def _prop_value
382
+ rand(2).zero? ? "john" : "henry"
383
+ end
384
+ def _indexedwrite
385
+ args = [_ornil(_pos)]
386
+ args << _len if rand(2).zero?
387
+ args << (args[1] ? _write_sequence : _element)
388
+ end
389
+ def _anyposition
390
+ i = rand(@positions.size.nonzero?||throw(:invalid_test))
391
+ @positions[i]
392
+ end
393
+ def _position
394
+ i = rand(@positions.size.nonzero?||throw(:invalid_test))
395
+ if _closed?(@positions[i])
396
+ @positions.slice!(i)
397
+ throw(:invalid_test)
398
+ end
399
+ @positions[i]
400
+ end
401
+ def _deleteposition
402
+ i = rand(@positions.size.nonzero?||throw(:invalid_test))
403
+ if _closed?(@positions[i])
404
+ @positions.slice!(i)
405
+ throw(:invalid_test)
406
+ end
407
+ @positions.slice!(i)
408
+ end
409
+ def _each_code
410
+ proc { |v0| nil } # what to do?
411
+ end
412
+ def _each2_code
413
+ proc { |v0| nil } # what to do?
414
+ end
415
+ def _collect_code
416
+ lookup = {}
417
+ elements = self.class.elements
418
+ elements.each_with_index { |e,i|
419
+ lookup[e] = elements[i+1]
420
+ }
421
+ proc { |v0| lookup[v0] }
422
+ end
423
+ def _collect2_code
424
+ proc { |v0| v0.slice!(0);v0 }
425
+ end
426
+ def _position_code
427
+ elements = self.class.elements
428
+ proc {
429
+ @cursor.scan1next(elements[0]) ||
430
+ @cursor.position? { @cursor.read1next==elements[1] }
431
+ }
432
+ end
433
+
434
+
435
+ public
436
+ define_method("test_delete1after?" ){_test_equal(:delete1after?)}
437
+ define_method("test_delete1before?"){_test_equal(:delete1before?)}
438
+ define_method("test_insert1before" ){_test_equal(:insert1before,_element)}
439
+ define_method("test_insert1after" ){_test_equal(:insert1after,_element)}
440
+ define_method("test_read1next" ){_test_equal(:read1next)}
441
+ define_method("test_read1prev" ){_test_equal(:read1prev)}
442
+ define_method("test_write1next!" ){_test_equal(:write1next!,_element)}
443
+ define_method("test_write1prev!" ){_test_equal(:write1prev!,_element)}
444
+ define_method("test_write1next" ){_test_equal(:write1next,_element)}
445
+ define_method("test_write1prev" ){_test_equal(:write1prev,_element)}
446
+ define_method("test_skip1next" ){_test_equal(:skip1next)}
447
+ define_method("test_skip1prev" ){_test_equal(:skip1prev)}
448
+ define_method("test_delete1after" ){_test_equal(:delete1after)}
449
+ define_method("test_delete1before" ){_test_equal(:delete1before)}
450
+ define_method("test_read1after" ){_test_equal(:read1after)}
451
+ define_method("test_read1before" ){_test_equal(:read1before)}
452
+ define_method("test_write1next?" ){_test_equal(:write1next?,_element)}
453
+ define_method("test_write1prev?" ){_test_equal(:write1prev?,_element)}
454
+ define_method("test_write1after!" ){_test_equal(:write1after!,_element)}
455
+ define_method("test_write1before!" ){_test_equal(:write1before!,_element)}
456
+ define_method("test_write1after" ){_test_equal(:write1after,_element)}
457
+ define_method("test_write1before" ){_test_equal(:write1before,_element)}
458
+ define_method("test_skip1after" ){_test_equal(:skip1after)}
459
+ define_method("test_skip1before" ){_test_equal(:skip1before)}
460
+ define_method("test_write1after?" ){_test_equal(:write1after?,_element)}
461
+ define_method("test_write1before?" ){_test_equal(:write1before?,_element)}
462
+ define_method("test_scan1next" ){_test_equal(:scan1next,_scan_element)}
463
+ define_method("test_scan1prev" ){_test_equal(:scan1prev,_scan_element)}
464
+ define_method("test_modify1next" ){_test_equal(:modify1next,_replacer)}
465
+ define_method("test_modify1prev" ){_test_equal(:modify1prev,_replacer)}
466
+ define_method("test_read" ){_test_equal(:read,_len,*_opt(_booleannil,_read_sequence))}
467
+ define_method("test_read!" ){_test_equal(:read!,*_opt(_boolean,_booleannil,_read_sequence))}
468
+ define_method("test_skip" ){_test_equal(:skip,_len,*_opt(_booleannil))}
469
+ define_method("test_skip!" ){_test_equal(:skip!,*_opt(_boolean,_booleannil))}
470
+ define_method("test_write" ){_test_equal(:write,_write_sequence,*_opt(_boolean,_booleannil,_boolean))}
471
+ define_method("test_write?" ){_test_equal(:write?,_write_sequence,*_opt(_boolean,_boolean,_read_sequence))}
472
+ define_method("test_scan" ){_test_position?(:scan,_scan_sequence,*_opt(_boolean,_booleannil,_read_sequence))}
473
+ define_method("test_scan_until" ){_test_equal(:scan_until,_scan_sequence)} #,*_opt(_boolean,_booleannil,_read_sequence)
474
+ define_method("test_scan_partial"){_test_equal(:scan_partial,_scan_sequence,*_opt(_boolean,_boolean,_read_sequence))}
475
+ define_method("test_modify" ){_test_equal(:modify,_replacer,*_opt(_boolean,_boolean,_read_sequence))}
476
+ define_method("test_pos" ){_test_equal(:pos,*_opt(_boolean))}
477
+ define_method("test_to_i" ){_test_equal(:to_i)}
478
+ define_method("test_to_s" ){_test_equal(:to_s)}
479
+ define_method("test_pos=" ){_test_equal(:pos=,_pos)}
480
+ define_method("test_prop" ){_test_equal(:prop,_prop_name,*_opt(_prop_value))}
481
+ define_method("test_closed?" ){_test_equal(:closed?)}
482
+ define_method("test_close" ){_test_close(:close)}
483
+ define_method("test_1position" ){_test_position(:position,*_opt(_boolean))}
484
+ define_method("test_2position" ){_test_equal(:position,*_opt{_boolean},&_position_code)}
485
+ define_method("test_position=" ){_test_equal(:position=,_position)}
486
+ define_method("test_1position?" ){_test_equal(:position?,*_opt{_anyposition})}
487
+ define_method("test_2position?" ){_test_equal(:position?,*_opt{_boolean},&_position_code)}
488
+ define_method("test_position!" ){_test_self(:position!,*_opt{_deleteposition})}
489
+ define_method("test_<=>" ){_test_equal(:<=>,_position)}
490
+ define_method("test_-" ){_test_equal(:-,_position)}
491
+ define_method("test_+" ){_test_position(:+,_len)}
492
+ define_method("test_succ" ){_test_position(:succ)}
493
+ define_method("test_pred" ){_test_position(:pred)}
494
+ define_method("test_begin" ){_test_position(:begin)}
495
+ define_method("test_end" ){_test_position(:end)}
496
+ define_method("test_size" ){_test_equal(:size)}
497
+ define_method("test_length" ){_test_equal(:length)}
498
+ define_method("test_empty?" ){_test_equal(:empty?)}
499
+ define_method("test_clear" ){_test_equal(:clear)}
500
+ define_method("test_replace" ){_test_self(:replace,_write_sequence)}
501
+ define_method("test_data" ){_test_equal(:data)}
502
+ define_method("test_<<" ){_test_self(:<< ,_element)}
503
+ define_method("test_>>" ){_test_self(:>> ,_element)}
504
+ define_method("test_slice" ){_test_equal(:slice,*_opt(_ornil(_pos),_len))}
505
+ define_method("test_[]" ){_test_equal(:[],*_opt(_ornil(_pos),_len))}
506
+ define_method("test_slice!" ){_test_equal(:slice!,*_opt(_ornil(_pos),_len))}
507
+ define_method("test_1[]=" ){_test_equal(:[]=,*(_opt(_pos) << _element))}
508
+ define_method("test_2[]=" ){_test_equal(:[]=,_ornil(_pos),_len,_write_sequence)}
509
+ define_method("test_1each" ){_test_equal(:each,_ornil(_pos),_boolean,&_each_code)}
510
+ define_method("test_2each" ){_test_equal(:each,_ornil(_pos),_boolean,_each_sequence,&_each2_code)}
511
+ define_method("test_1collect!" ){_test_self(:collect!,_ornil(_pos),_boolean,&_collect_code)}
512
+ define_method("test_2collect!" ){_test_self(:collect!,_ornil(_pos),_boolean,_each_sequence,&_collect2_code)}
513
+ define_method("test_1map!" ){_test_self(:map!,_ornil(_pos),_boolean,&_collect_code)}
514
+ define_method("test_2map!" ){_test_self(:map!,_ornil(_pos),_boolean,_each_sequence,&_collect2_code)}
515
+ end
516
+ end
517
+
518
+ # :startdoc:
519
+