Harbor

branch main
showing the latest snapshot on main
input_test.odin 5.6 KB · Plain text
tests/input_test.odin 0644 Raw
package gpu_tests

import platform "../platform"
import "core:testing"
import window "window:window"

@(test)
test_register_action :: proc(t: ^testing.T) {
	state: platform.Action_State

	id1 := platform.register_action(&state, "jump")
	testing.expect(t, id1 == 1, "first action should be 1")

	id2 := platform.register_action(&state, "shoot")
	testing.expect(t, id2 == 2, "second action should be 2")

	testing.expect(t, platform.get_action_name(&state, id1) == "jump")
	testing.expect(t, platform.get_action_name(&state, id2) == "shoot")
}

@(test)
test_register_invalid :: proc(t: ^testing.T) {
	state: platform.Action_State

	testing.expect(t, platform.get_action_name(&state, 0) == "", "action 0 should be invalid")
	testing.expect(t, platform.get_action_name(&state, 99) == "", "out of range should be empty")
}

@(test)
test_bind_and_query_bindings :: proc(t: ^testing.T) {
	state: platform.Action_State

	id := platform.register_action(&state, "move_left")
	platform.bind_action_key(&state, id, .A)
	platform.bind_action_key(&state, id, .Arrow_Left)

	bindings := platform.get_action_bindings(&state, id)
	testing.expect(t, len(bindings) == 2, "should have 2 bindings")

	// First binding should be Key A
	k1, k1_ok := bindings[0].(window.Key_Code)
	testing.expect(t, k1_ok && k1 == .A, "first binding should be A")

	// Second binding should be Arrow_Left
	k2, k2_ok := bindings[1].(window.Key_Code)
	testing.expect(t, k2_ok && k2 == .Arrow_Left, "second binding should be Arrow_Left")
}

@(test)
test_bind_mouse :: proc(t: ^testing.T) {
	state: platform.Action_State

	id := platform.register_action(&state, "shoot")
	platform.bind_action_key(&state, id, .Z)
	platform.bind_action_mouse(&state, id, .Left)

	bindings := platform.get_action_bindings(&state, id)
	testing.expect(t, len(bindings) == 2, "should have 2 bindings")

	_, is_key := bindings[0].(window.Key_Code)
	testing.expect(t, is_key, "first should be key")

	_, is_mouse := bindings[1].(window.Mouse_Button)
	testing.expect(t, is_mouse, "second should be mouse button")
}

@(test)
test_unbind :: proc(t: ^testing.T) {
	state: platform.Action_State

	id := platform.register_action(&state, "jump")
	platform.bind_action_key(&state, id, .Space)
	platform.bind_action_key(&state, id, .W)

	testing.expect(t, len(platform.get_action_bindings(&state, id)) == 2)

	platform.unbind_action(&state, id)
	testing.expect(
		t,
		len(platform.get_action_bindings(&state, id)) == 0,
		"should have no bindings after unbind",
	)

	// Rebind to a different key
	platform.bind_action_key(&state, id, .Enter)
	bindings := platform.get_action_bindings(&state, id)
	testing.expect(t, len(bindings) == 1, "should have 1 binding after rebind")

	k, ok := bindings[0].(window.Key_Code)
	testing.expect(t, ok && k == .Enter, "rebind should be Enter")
}

@(test)
test_max_bindings :: proc(t: ^testing.T) {
	state: platform.Action_State

	id := platform.register_action(&state, "test")
	platform.bind_action_key(&state, id, .A)
	platform.bind_action_key(&state, id, .B)
	platform.bind_action_key(&state, id, .C)
	platform.bind_action_key(&state, id, .D)
	// 5th should be silently ignored
	platform.bind_action_key(&state, id, .E)

	bindings := platform.get_action_bindings(&state, id)
	testing.expect(t, len(bindings) == 4, "should cap at MAX_BINDINGS_PER_ACTION")
}

@(test)
test_action_pressed :: proc(t: ^testing.T) {
	pstate: platform.Platform_State

	id := platform.register_action(&pstate.actions, "jump")
	platform.bind_action_key(&pstate.actions, id, .Space)

	// Simulate: key not pressed
	testing.expect(t, !platform.is_action_pressed(&pstate, id), "should not be pressed initially")
	testing.expect(t, !platform.is_action_down(&pstate, id), "should not be down initially")

	// Simulate: key pressed this frame (current=true, previous=false)
	pstate.input.keys_current[int(window.Key_Code.Space)] = true
	testing.expect(
		t,
		platform.is_action_pressed(&pstate, id),
		"should be pressed when key just went down",
	)
	testing.expect(t, platform.is_action_down(&pstate, id), "should be down when key is held")

	// Simulate: key held (current=true, previous=true)
	pstate.input.keys_previous[int(window.Key_Code.Space)] = true
	testing.expect(
		t,
		!platform.is_action_pressed(&pstate, id),
		"should not be 'pressed' when held",
	)
	testing.expect(t, platform.is_action_down(&pstate, id), "should still be down")

	// Simulate: key released (current=false, previous=true)
	pstate.input.keys_current[int(window.Key_Code.Space)] = false
	testing.expect(t, platform.is_action_released(&pstate, id), "should be released")
	testing.expect(t, !platform.is_action_down(&pstate, id), "should not be down after release")
}

@(test)
test_action_multiple_bindings :: proc(t: ^testing.T) {
	pstate: platform.Platform_State

	id := platform.register_action(&pstate.actions, "move")
	platform.bind_action_key(&pstate.actions, id, .A)
	platform.bind_action_key(&pstate.actions, id, .Arrow_Left)

	// Neither pressed
	testing.expect(t, !platform.is_action_down(&pstate, id))

	// Only second binding pressed
	pstate.input.keys_current[int(window.Key_Code.Arrow_Left)] = true
	testing.expect(t, platform.is_action_down(&pstate, id), "should be down from Arrow_Left")
	testing.expect(t, platform.is_action_pressed(&pstate, id), "should be pressed from Arrow_Left")
}

@(test)
test_invalid_action_queries :: proc(t: ^testing.T) {
	pstate: platform.Platform_State

	// Querying invalid/unregistered actions should return false
	testing.expect(t, !platform.is_action_pressed(&pstate, 0))
	testing.expect(t, !platform.is_action_down(&pstate, 0))
	testing.expect(t, !platform.is_action_released(&pstate, 0))
	testing.expect(t, !platform.is_action_pressed(&pstate, 99))
}