ext/sdbm/testsdbm.rb


DEFINITIONS

This source file includes following functions.


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