DEFINITIONS
This source file includes following functions.
1 require 'runit/testcase'
2 require 'runit/cui/testrunner'
3
4 if $".grep(/\bdbm.so\b/).empty?
5 begin
6 require './dbm'
7 rescue LoadError
8 require 'dbm'
9 end
10 end
11
12 def uname_s
13 require 'rbconfig'
14 case Config::CONFIG['host_os']
15 when 'cygwin'
16 require 'Win32API'
17 uname = Win32API.new 'cygwin1', 'uname', 'P', 'I'
18 utsname = ' ' * 100
19 raise 'cannot get system name' if uname.call(utsname) == -1
20
21 utsname.unpack('A20' * 5)[0]
22 else
23 Config::CONFIG['host_os']
24 end
25 end
26
27 SYSTEM = uname_s
28
29 class TestDBM < RUNIT::TestCase
30 def setup
31 @path = "tmptest_dbm_"
32 assert_instance_of(DBM, @dbm = DBM.new(@path))
33
34 # prepare to make readonly DBM file
35 DBM.open("tmptest_dbm_rdonly", 0400) {|dbm|
36 dbm['foo'] = 'FOO'
37 }
38 assert_instance_of(DBM, @dbm_rdonly = DBM.new("tmptest_dbm_rdonly", nil))
39 end
40 def teardown
41 assert_nil(@dbm.close)
42 assert_nil(@dbm_rdonly.close)
43 GC.start
44 File.delete *Dir.glob("tmptest_dbm*").to_a
45 p Dir.glob("tmptest_dbm*") if $DEBUG
46 end
47
48 def check_size(expect, dbm=@dbm)
49 assert_equals(expect, dbm.size)
50 n = 0
51 dbm.each { n+=1 }
52 assert_equals(expect, n)
53 if expect == 0
54 assert_equals(true, dbm.empty?)
55 else
56 assert_equals(false, dbm.empty?)
57 end
58 end
59
60 def test_version
61 STDERR.print DBM::VERSION
62 end
63
64 def test_s_new_has_no_block
65 # DBM.new ignore the block
66 foo = true
67 assert_instance_of(DBM, dbm = DBM.new("tmptest_dbm") { foo = false })
68 assert_equals(foo, true)
69 assert_nil(dbm.close)
70 end
71 def test_s_open_no_create
72 assert_nil(dbm = DBM.open("tmptest_dbm", nil))
73 ensure
74 dbm.close if dbm
75 end
76 def test_s_open_with_block
77 assert_equals(DBM.open("tmptest_dbm") { :foo }, :foo)
78 end
79 def test_s_open_lock
80 fork() {
81 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
82 sleep 2
83 }
84 begin
85 sleep 1
86 assert_exception(Errno::EWOULDBLOCK) {
87 begin
88 assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644))
89 rescue Errno::EAGAIN, Errno::EACCES, Errno::EINVAL
90 raise Errno::EWOULDBLOCK
91 end
92 }
93 ensure
94 Process.wait
95 end
96 end
97
98 =begin
99 # Is it guaranteed on many OS?
100 def test_s_open_lock_one_process
101 # locking on one process
102 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
103 assert_exception(Errno::EWOULDBLOCK) {
104 begin
105 DBM.open("tmptest_dbm", 0644)
106 rescue Errno::EAGAIN
107 raise Errno::EWOULDBLOCK
108 end
109 }
110 end
111 =end
112
113 def test_s_open_nolock
114 # dbm 1.8.0 specific
115 if not defined? DBM::NOLOCK
116 return
117 end
118
119 fork() {
120 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644,
121 DBM::NOLOCK))
122 sleep 2
123 }
124 sleep 1
125 begin
126 dbm2 = nil
127 assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
128 assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644))
129 }
130 ensure
131 Process.wait
132 dbm2.close if dbm2
133 end
134
135 p Dir.glob("tmptest_dbm*") if $DEBUG
136
137 fork() {
138 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0644))
139 sleep 2
140 }
141 begin
142 sleep 1
143 dbm2 = nil
144 assert_no_exception(Errno::EWOULDBLOCK, Errno::EAGAIN, Errno::EACCES) {
145 # this test is failed on Cygwin98 (???)
146 assert_instance_of(DBM, dbm2 = DBM.open("tmptest_dbm", 0644,
147 DBM::NOLOCK))
148 }
149 ensure
150 Process.wait
151 dbm2.close if dbm2
152 end
153 end
154
155 def test_s_open_error
156 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm", 0))
157 assert_exception(Errno::EACCES) {
158 DBM.open("tmptest_dbm", 0)
159 }
160 dbm.close
161 end
162
163 def test_close
164 assert_instance_of(DBM, dbm = DBM.open("tmptest_dbm"))
165 assert_nil(dbm.close)
166
167 # closed DBM file
168 assert_exception(DBMError) { dbm.close }
169 end
170
171 def test_aref
172 assert_equals('bar', @dbm['foo'] = 'bar')
173 assert_equals('bar', @dbm['foo'])
174
175 assert_nil(@dbm['bar'])
176 end
177
178 def test_fetch
179 assert_equals('bar', @dbm['foo']='bar')
180 assert_equals('bar', @dbm.fetch('foo'))
181
182 # key not found
183 assert_exception(IndexError) {
184 @dbm.fetch('bar')
185 }
186
187 # test for `ifnone' arg
188 assert_equals('baz', @dbm.fetch('bar', 'baz'))
189
190 # test for `ifnone' block
191 assert_equals('foobar', @dbm.fetch('bar') {|key| 'foo' + key })
192 end
193
194 def test_aset
195 num = 0
196 2.times {|i|
197 assert_equals('foo', @dbm['foo'] = 'foo')
198 assert_equals('foo', @dbm['foo'])
199 assert_equals('bar', @dbm['foo'] = 'bar')
200 assert_equals('bar', @dbm['foo'])
201
202 num += 1 if i == 0
203 assert_equals(num, @dbm.size)
204
205 # assign nil
206 assert_equals('', @dbm['bar'] = '')
207 assert_equals('', @dbm['bar'])
208
209 num += 1 if i == 0
210 assert_equals(num, @dbm.size)
211
212 # empty string
213 assert_equals('', @dbm[''] = '')
214 assert_equals('', @dbm[''])
215
216 num += 1 if i == 0
217 assert_equals(num, @dbm.size)
218
219 # Fixnum
220 assert_equals('200', @dbm['100'] = '200')
221 assert_equals('200', @dbm['100'])
222
223 num += 1 if i == 0
224 assert_equals(num, @dbm.size)
225
226 # Big key and value
227 assert_equals('y' * 100, @dbm['x' * 100] = 'y' * 100)
228 assert_equals('y' * 100, @dbm['x' * 100])
229
230 num += 1 if i == 0
231 assert_equals(num, @dbm.size)
232 }
233 end
234
235 def test_index
236 assert_equals('bar', @dbm['foo'] = 'bar')
237 assert_equals('foo', @dbm.index('bar'))
238 assert_nil(@dbm['bar'])
239 end
240
241 def test_indexes
242 keys = %w(foo bar baz)
243 values = %w(FOO BAR BAZ)
244 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
245 assert_equals(values.reverse, @dbm.indexes(*keys.reverse))
246 end
247
248 def test_select
249 keys = %w(foo bar baz)
250 values = %w(FOO BAR BAZ)
251 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
252 assert_equals(values.reverse, @dbm.select(*keys.reverse))
253 end
254
255 def test_select_with_block
256 keys = %w(foo bar baz)
257 values = %w(FOO BAR BAZ)
258 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
259 ret = @dbm.select {|k,v|
260 assert_equals(k.upcase, v)
261 k != "bar"
262 }
263 assert_equals([['baz', 'BAZ'], ['foo', 'FOO']],
264 ret.sort)
265 end
266
267 def test_length
268 num = 10
269 assert_equals(0, @dbm.size)
270 num.times {|i|
271 i = i.to_s
272 @dbm[i] = i
273 }
274 assert_equals(num, @dbm.size)
275
276 @dbm.shift
277
278 assert_equals(num - 1, @dbm.size)
279 end
280
281 def test_empty?
282 assert_equals(true, @dbm.empty?)
283 @dbm['foo'] = 'FOO'
284 assert_equals(false, @dbm.empty?)
285 end
286
287 def test_each_pair
288 n = 0
289 @dbm.each_pair { n += 1 }
290 assert_equals(0, n)
291
292 keys = %w(foo bar baz)
293 values = %w(FOO BAR BAZ)
294
295 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
296
297 n = 0
298 ret = @dbm.each_pair {|key, val|
299 assert_not_nil(i = keys.index(key))
300 assert_equals(val, values[i])
301
302 n += 1
303 }
304 assert_equals(keys.size, n)
305 assert_equals(@dbm, ret)
306 end
307
308 def test_each_value
309 n = 0
310 @dbm.each_value { n += 1 }
311 assert_equals(0, n)
312
313 keys = %w(foo bar baz)
314 values = %w(FOO BAR BAZ)
315
316 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
317
318 n = 0
319 ret = @dbm.each_value {|val|
320 assert_not_nil(key = @dbm.index(val))
321 assert_not_nil(i = keys.index(key))
322 assert_equals(val, values[i])
323
324 n += 1
325 }
326 assert_equals(keys.size, n)
327 assert_equals(@dbm, ret)
328 end
329
330 def test_each_key
331 n = 0
332 @dbm.each_key { n += 1 }
333 assert_equals(0, n)
334
335 keys = %w(foo bar baz)
336 values = %w(FOO BAR BAZ)
337
338 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
339
340 n = 0
341 ret = @dbm.each_key {|key|
342 assert_not_nil(i = keys.index(key))
343 assert_equals(@dbm[key], values[i])
344
345 n += 1
346 }
347 assert_equals(keys.size, n)
348 assert_equals(@dbm, ret)
349 end
350
351 def test_keys
352 assert_equals([], @dbm.keys)
353
354 keys = %w(foo bar baz)
355 values = %w(FOO BAR BAZ)
356
357 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
358
359 assert_equals(keys.sort, @dbm.keys.sort)
360 assert_equals(values.sort, @dbm.values.sort)
361 end
362
363 def test_values
364 test_keys
365 end
366
367 def test_shift
368 assert_nil(@dbm.shift)
369 assert_equals(0, @dbm.size)
370
371 keys = %w(foo bar baz)
372 values = %w(FOO BAR BAZ)
373
374 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
375
376 ret_keys = []
377 ret_values = []
378 while ret = @dbm.shift
379 ret_keys.push ret[0]
380 ret_values.push ret[1]
381
382 assert_equals(keys.size - ret_keys.size, @dbm.size)
383 end
384
385 assert_equals(keys.sort, ret_keys.sort)
386 assert_equals(values.sort, ret_values.sort)
387 end
388
389 def test_delete
390 keys = %w(foo bar baz)
391 values = %w(FOO BAR BAZ)
392 key = keys[1]
393
394 assert_nil(@dbm.delete(key))
395 assert_equals(0, @dbm.size)
396
397 @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values
398
399 assert_equals('BAR', @dbm.delete(key))
400 assert_nil(@dbm[key])
401 assert_equals(2, @dbm.size)
402
403 assert_nil(@dbm.delete(key))
404
405 if /^CYGWIN_9/ !~ SYSTEM
406 assert_exception(DBMError) {
407 @dbm_rdonly.delete("foo")
408 }
409
410 assert_nil(@dbm_rdonly.delete("bar"))
411 end
412 end
413 def test_delete_with_block
414 key = 'no called block'
415 @dbm[key] = 'foo'
416 assert_equals('foo', @dbm.delete(key) {|k| k.replace 'called block'})
417 assert_equals('no called block', key)
418 assert_equals(0, @dbm.size)
419
420 key = 'no called block'
421 assert_equals(:blockval,
422 @dbm.delete(key) {|k| k.replace 'called block'; :blockval})
423 assert_equals('called block', key)
424 assert_equals(0, @dbm.size)
425 end
426
427 def test_delete_if
428 v = "0"
429 100.times {@dbm[v] = v; v = v.next}
430
431 ret = @dbm.delete_if {|key, val| key.to_i < 50}
432 assert_equals(@dbm, ret)
433 check_size(50, @dbm)
434
435 ret = @dbm.delete_if {|key, val| key.to_i >= 50}
436 assert_equals(@dbm, ret)
437 check_size(0, @dbm)
438
439 # break
440 v = "0"
441 100.times {@dbm[v] = v; v = v.next}
442 check_size(100, @dbm)
443 n = 0;
444 @dbm.delete_if {|key, val|
445 break if n > 50
446 n+=1
447 true
448 }
449 assert_equals(51, n)
450 check_size(49, @dbm)
451
452 @dbm.clear
453
454 # raise
455 v = "0"
456 100.times {@dbm[v] = v; v = v.next}
457 check_size(100, @dbm)
458 n = 0;
459 begin
460 @dbm.delete_if {|key, val|
461 raise "runtime error" if n > 50
462 n+=1
463 true
464 }
465 rescue
466 end
467 assert_equals(51, n)
468 check_size(49, @dbm)
469 end
470
471 def test_reject
472 v = "0"
473 100.times {@dbm[v] = v; v = v.next}
474
475 hash = @dbm.reject {|key, val| key.to_i < 50}
476 assert_instance_of(Hash, hash)
477 assert_equals(100, @dbm.size)
478
479 assert_equals(50, hash.size)
480 hash.each_pair {|key,val|
481 assert_equals(false, key.to_i < 50)
482 assert_equals(key, val)
483 }
484
485 hash = @dbm.reject {|key, val| key.to_i < 100}
486 assert_instance_of(Hash, hash)
487 assert_equals(true, hash.empty?)
488 end
489
490 def test_clear
491 v = "1"
492 100.times {v = v.next; @dbm[v] = v}
493
494 assert_equals(@dbm, @dbm.clear)
495
496 # validate DBM#size
497 i = 0
498 @dbm.each { i += 1 }
499 assert_equals(@dbm.size, i)
500 assert_equals(0, i)
501 end
502
503 def test_invert
504 v = "0"
505 100.times {@dbm[v] = v; v = v.next}
506
507 hash = @dbm.invert
508 assert_instance_of(Hash, hash)
509 assert_equals(100, hash.size)
510 hash.each_pair {|key, val|
511 assert_equals(key.to_i, val.to_i)
512 }
513 end
514
515 def test_update
516 hash = {}
517 v = "0"
518 100.times {v = v.next; hash[v] = v}
519
520 @dbm["101"] = "101"
521 @dbm.update hash
522 assert_equals(101, @dbm.size)
523 @dbm.each_pair {|key, val|
524 assert_equals(key.to_i, val.to_i)
525 }
526 end
527
528 def test_replace
529 hash = {}
530 v = "0"
531 100.times {v = v.next; hash[v] = v}
532
533 @dbm["101"] = "101"
534 @dbm.replace hash
535 assert_equals(100, @dbm.size)
536 @dbm.each_pair {|key, val|
537 assert_equals(key.to_i, val.to_i)
538 }
539 end
540
541 def test_haskey?
542 assert_equals('bar', @dbm['foo']='bar')
543 assert_equals(true, @dbm.has_key?('foo'))
544 assert_equals(false, @dbm.has_key?('bar'))
545 end
546
547 def test_has_value?
548 assert_equals('bar', @dbm['foo']='bar')
549 assert_equals(true, @dbm.has_value?('bar'))
550 assert_equals(false, @dbm.has_value?('foo'))
551 end
552
553 def test_to_a
554 v = "0"
555 100.times {v = v.next; @dbm[v] = v}
556
557 ary = @dbm.to_a
558 assert_instance_of(Array, ary)
559 assert_equals(100, ary.size)
560 ary.each {|key,val|
561 assert_equals(key.to_i, val.to_i)
562 }
563 end
564
565 def test_to_hash
566 v = "0"
567 100.times {v = v.next; @dbm[v] = v}
568
569 hash = @dbm.to_hash
570 assert_instance_of(Hash, hash)
571 assert_equals(100, hash.size)
572 hash.each {|key,val|
573 assert_equals(key.to_i, val.to_i)
574 }
575 end
576 end
577
578 if $0 == __FILE__
579 if ARGV.size == 0
580 suite = RUNIT::TestSuite.new
581 suite.add_test(TestDBM.suite)
582 else
583 suite = RUNIT::TestSuite.new
584 ARGV.each do |testmethod|
585 suite.add_test(TestDBM.new(testmethod))
586 end
587 end
588
589 RUNIT::CUI::TestRunner.run(suite)
590 end