package main

import (
	"testing"
)

func TestMorton(t *testing.T) {
	var x, y uint16 = 0x0000, 0xffff
	var expected uint32 = 0xaaaaaaaa

	actual := morton(x, y)
	if actual != expected {
		t.Errorf("expected %b; got M(%b, %b) = %b", expected, x, y, actual)
	}
	a, b := demorton(expected)
	if a != x || b != y {
		t.Errorf("expected (%b, %b); got (%b, %b)", x, y, a, b)
	}
}

func TestReverse(t *testing.T) {
	var x byte = 0b1101
	var expected byte = 0b10110000

	actual := reverse(uint32(x))
	if actual != expected {
		t.Errorf("expected %b; got %b", expected, actual)
	}
}

func TestReverse32(t *testing.T) {
	var x uint32 = 0xaaaaaaaa
	var expected uint32 = 0x55555555

	actual := reverse32(x)
	if actual != expected {
		t.Errorf("expected %b; got %b", expected, actual)
	}

	x = 0x00000001
	expected = 0x80000000

	actual = reverse32(x)
	if actual != expected {
		t.Errorf("expected %b; got %b", expected, actual)
	}
}

func TestLog2(t *testing.T) {
	var x uint32 = 0x80000000
	var expected uint32 = 31

	actual := log2(x)
	if actual != expected {
		t.Errorf("expected %d; got %d", expected, actual)
	}

	x = 3
	expected = 1
	actual = log2(x)
	if actual != expected {
		t.Errorf("expected %d; got %d", expected, actual)
	}
}

func TestOnes(t *testing.T) {
	var x uint32 = 0xaaaaaaaa
	var expected uint32 = 16

	actual := ones(x)
	if actual != expected {
		t.Errorf("expected %d; got %d", expected, actual)
	}
}

func TestDistance(t *testing.T) {
	a := uint32(0b0000000_00000101_01000101_01111001)
	b := uint32(0b0000000_00000010_01000111_11011001)
	expected := uint32(14)

	actual := distance(a, b)
	if actual != expected {
		t.Errorf("expected %d; got %d", expected, actual)
	}
	actual = distance(b, a)
	if actual != expected {
		t.Errorf("expected %d; got %d", expected, actual)
	}
}
