cursor 0.6 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+