Files
step3/tests/calculator_panel_test.gd
2026-07-23 05:19:12 -05:00

127 lines
4.4 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends SceneTree
var failures := 0
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
_test_basic_arithmetic()
_test_decimal_and_chained_operations()
_test_percent_and_sign()
_test_square_root()
_test_repeated_equals()
_test_backspace_and_clear()
_test_error_recovery()
await _test_runtime_panel_behavior()
quit(1 if failures > 0 else 0)
func _calculator():
return load("res://scripts/ui/calculator_panel.gd").new()
func _press(calculator, tokens: Array) -> void:
for token in tokens:
calculator.press_token(str(token))
func _test_basic_arithmetic() -> void:
var calculator = _calculator()
_press(calculator, ["9", "+", "6", "="])
_assert(calculator.get_display_text() == "15", "calculator should add operands")
calculator.reset_calculation()
_press(calculator, ["9", "−", "4", "="])
_assert(calculator.get_display_text() == "5", "calculator should subtract operands")
calculator.reset_calculation()
_press(calculator, ["7", "×", "8", "="])
_assert(calculator.get_display_text() == "56", "calculator should multiply operands")
calculator.reset_calculation()
_press(calculator, ["8", "÷", "4", "="])
_assert(calculator.get_display_text() == "2", "calculator should divide operands")
calculator.free()
func _test_decimal_and_chained_operations() -> void:
var calculator = _calculator()
_press(calculator, ["1", ".", "5", "+", "2", ".", "5", "×", "2", "="])
_assert(calculator.get_display_text() == "8", "calculator should evaluate chained handheld operations left to right")
calculator.free()
func _test_percent_and_sign() -> void:
var calculator = _calculator()
_press(calculator, ["5", "%"])
_assert(calculator.get_display_text() == "0.05", "percent should convert the displayed operand to a fraction")
_press(calculator, ["±"])
_assert(calculator.get_display_text() == "-0.05", "sign toggle should negate the displayed operand")
calculator.free()
func _test_square_root() -> void:
var calculator = _calculator()
_press(calculator, ["8", "1", "√"])
_assert(calculator.get_display_text() == "9", "square root should replace the displayed operand")
calculator.free()
func _test_repeated_equals() -> void:
var calculator = _calculator()
_press(calculator, ["5", "+", "2", "=", "="])
_assert(calculator.get_display_text() == "9", "repeated equals should replay the last binary operation")
calculator.free()
func _test_backspace_and_clear() -> void:
var calculator = _calculator()
_press(calculator, ["1", "2", "3", "⌫"])
_assert(calculator.get_display_text() == "12", "backspace should remove the final entry digit")
_press(calculator, ["AC"])
_assert(calculator.get_display_text() == "0", "clear should reset the display")
calculator.free()
func _test_error_recovery() -> void:
var calculator = _calculator()
_press(calculator, ["8", "÷", "0", "="])
_assert(calculator.get_display_text() == "Error", "division by zero should display an error")
_press(calculator, ["4"])
_assert(calculator.get_display_text() == "4", "digit entry should recover from an error")
_press(calculator, ["±", "√"])
_assert(calculator.get_display_text() == "Error", "square root of a negative operand should display an error")
calculator.free()
func _test_runtime_panel_behavior() -> void:
var host := Control.new()
host.size = Vector2(360, 640)
root.add_child(host)
var calculator = _calculator()
host.add_child(calculator)
await process_frame
calculator.open_panel()
await process_frame
_assert(calculator.visible, "calculator should open as a floating panel")
_assert(calculator.size.x <= 336.0, "calculator should fit a narrow web viewport")
_press(calculator, ["2", "+", "3", "="])
calculator.close_panel()
calculator.open_panel()
_assert(calculator.get_display_text() == "5", "closing and reopening should preserve the active-session value")
calculator.position = Vector2(1000, 1000)
calculator._clamp_to_viewport()
_assert(calculator.position.x + calculator.size.x <= calculator.get_viewport_rect().size.x, "calculator dragging should remain horizontally bounded")
_assert(calculator.position.y + calculator.size.y <= calculator.get_viewport_rect().size.y, "calculator dragging should remain vertically bounded")
calculator.reset_calculation()
_assert(calculator.get_display_text() == "0", "session reset should clear calculator state")
host.queue_free()
await process_frame
func _assert(condition: bool, message: String) -> void:
if condition:
return
failures += 1
push_error(message)