import { murmurHash3 } from '../hash'
import { webcrypto } from 'crypto'

describe('murmurHash3', () => {
  test('it hashes', () => {
    expect(murmurHash3('foo', 0)).toEqual(4138058784)
    // test suite from https://en.wikipedia.org/wiki/MurmurHash
    expect(murmurHash3('', 0x00000000)).toEqual(0x00000000)
    expect(murmurHash3('', 0x00000001)).toEqual(0x514e28b7)
    expect(murmurHash3('', 0xffffffff)).toEqual(0x81f16f39)
    expect(murmurHash3('test', 0x00000000)).toEqual(0xba6bd213)
    expect(murmurHash3('test', 0x9747b28c)).toEqual(0x704b81dc)
    expect(murmurHash3('Hello, world!', 0x00000000)).toEqual(0xc0363e43)
    expect(murmurHash3('Hello, world!', 0x9747b28c)).toEqual(0x24884cba)
    expect(murmurHash3('The quick brown fox jumps over the lazy dog', 0x00000000)).toEqual(0x2e4ff723)
    expect(murmurHash3('The quick brown fox jumps over the lazy dog', 0x9747b28c)).toEqual(0x2fa826cd)
  })

  test('it produces different hashes for different keys', () => {
    expect(murmurHash3('foo', 0)).toEqual(4138058784)
    expect(murmurHash3('bar', 0)).toEqual(1158584717)
  })

  test('it produces different hashes for different seeds', () => {
    expect(murmurHash3('foo', 0)).toEqual(4138058784)
    expect(murmurHash3('foo', 1)).toEqual(884891506)
  })

  test('it produces hashes between 0 and 2^32 (exclusive)', () => {
    let min = Number.MAX_SAFE_INTEGER
    let max = 0
    const iterations = 100000
    for (let i = 0; i < iterations; i++) {
      const hash = murmurHash3(webcrypto.randomUUID(), 0)
      if (hash < min) {
        min = hash
      }
      if (hash > max) {
        max = hash
      }
    }
    expect(min).toBeGreaterThan(0)
    expect(max).toBeLessThan(Math.pow(2, 32))
  })
})
