$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'test_helper'
require 'stringio'

include HashLab

class TestHash < Test::Unit::TestCase

  def test_00_banner
    print "\nHashLab"
  end
  
  # Test the simple hash functions
  
  def test_01_simple_hash_functions
    assert_equal 0, h("apple")
    assert_equal 5, h("zebra")

    assert_equal 0, h0("aardvark", 10)
    assert_equal 0, h0("aardvark", 1000)
    assert_equal 5, h0("zymurgy", 10)
    assert_equal 25, h0("zymurgy", 1000)

    assert_equal 0, h1("aardvark", 10)
    assert_equal 0, h1("aardvark", 1000)
    assert_equal 4, h1("zymurgy", 10)
    assert_equal 674, h1("zymurgy", 1000)
  end
  
  # Test radix-26 and hash function that uses it
  
  def test_02_radix26
    assert_equal 783, radix26("bed")
    assert_equal 784, radix26("bee")
    assert_equal 8013894328, radix26("zymurgy")
    
    assert_equal 8, hr("zymurgy", 10)
    assert_equal 28, hr("zymurgy", 100)
    assert_equal 328, hr("zymurgy", 1000)
    assert_equal 4328, hr("zymurgy", 10000)    
  end
  
  # Test the stand-alone insert and lookup methods (w/o bucket)
  
  def test_03_insert_and_lookup
    t = Array.new(10)
    assert_equal 3, insert("duck", t)
    assert_equal 7, insert("husky", t)
    assert_equal 1, insert("bruin", t)
    assert_nil insert("beaver", t)
    
    assert_equal 3, lookup("duck", t)
    assert_equal 1, lookup("bruin", t)
    assert_nil lookup("trojan", t)
  end
  
  # Make a HashTable object, repeat insert and lookup tests, then 
  # capture the output from print_stats to verify the table structure
  
  def test_04_hash_table
    t = HashTable.new(10, :h0)
    assert_equal 3, t.insert("duck")
    assert_equal 1, t.insert("beaver")
    assert_equal 7, t.insert("husky")
    assert_equal 2, t.insert("cougar")
    assert_equal 2, t.insert("cardinal")
    assert_equal 1, t.insert("bear")
    assert_equal 1, t.insert("bruin")
    assert_equal 9, t.insert("trojan")
    assert_equal 8, t.insert("sun devil")
    assert_equal 2, t.insert("wildcat")
    
    assert_equal 3, t.lookup("duck")
    assert_equal 1, t.lookup("bear")
    assert_nil t.lookup("eagle")
    assert_nil t.lookup("buffalo")
    
    oldout = $stdout
    newout = StringIO.new
    $stdout = newout
    t.print_stats
    $stdout = oldout
    lines = newout.string.split("\n")
    
    assert_equal 0, get_value("shortest", lines)
    assert_equal 3, get_value("longest", lines)
    assert_equal 4, get_value("empty", lines)
    assert_equal 1.67, get_value("mean", lines)
  end
  
  def get_value(s, a)
    line = a.grep(Regexp.new(s))[0]
    return line[/\d+\.?\d*/].to_f
  end
  
end