## Tests for SnapPoint — attachment node on furniture.
extends GutTest

const SnapPointScript: GDScript = preload("res://scripts/objects/snap_point.gd")

var _snap: SnapPoint
var _char: Character


func before_each() -> void:
	_snap = SnapPointScript.new()
	_snap.pose = "sitting"
	add_child_autofree(_snap)
	_char = preload("res://scenes/characters/Character.tscn").instantiate() as Character
	add_child_autofree(_char)


func test_is_free_when_no_occupant() -> void:
	assert_true(_snap.is_free())


func test_is_not_free_when_occupied() -> void:
	_snap.snap(_char)
	assert_false(_snap.is_free())


func test_snap_sets_occupant() -> void:
	_snap.snap(_char)
	assert_eq(_snap.occupant, _char)


func test_unsnap_clears_occupant() -> void:
	_snap.snap(_char)
	_snap.unsnap()
	assert_null(_snap.occupant)


func test_accepts_any_character_when_baby_only_false() -> void:
	assert_true(_snap.accepts(_char))


func test_does_not_accept_when_occupied() -> void:
	_snap.snap(_char)
	var other: Character = preload("res://scenes/characters/Character.tscn").instantiate() as Character
	add_child_autofree(other)
	assert_false(_snap.accepts(other))


func test_baby_only_rejects_healthy_character() -> void:
	_snap.baby_only = true
	var cd: CharacterData = CharacterData.new()
	cd.state = CharacterData.State.HEALTHY
	_char.data = cd
	assert_false(_snap.accepts(_char))


func test_baby_only_accepts_baby_state_character() -> void:
	_snap.baby_only = true
	var cd: CharacterData = CharacterData.new()
	cd.state = CharacterData.State.BABY
	_char.data = cd
	assert_true(_snap.accepts(_char))


func test_snap_emits_character_snapped() -> void:
	watch_signals(_snap)
	_snap.snap(_char)
	assert_signal_emitted(_snap, "character_snapped")


func test_unsnap_emits_character_unsnapped() -> void:
	_snap.snap(_char)
	watch_signals(_snap)
	_snap.unsnap()
	assert_signal_emitted(_snap, "character_unsnapped")
