412 lines
16 KiB
GDScript
412 lines
16 KiB
GDScript
extends SceneTree
|
|
|
|
## Test suite for ValueStepper component
|
|
##
|
|
## Tests data loading, value navigation, and input handling.
|
|
|
|
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
|
|
|
var stepper_scene: PackedScene
|
|
var stepper_instance: Control
|
|
var test_viewport: SubViewport
|
|
var original_language: String
|
|
|
|
func _initialize():
|
|
# Wait for autoloads to initialize
|
|
await process_frame
|
|
await process_frame
|
|
|
|
run_tests()
|
|
|
|
# Exit after tests complete
|
|
quit()
|
|
|
|
func run_tests():
|
|
TestHelper.print_test_header("ValueStepper Component")
|
|
|
|
# Store original settings
|
|
var settings_manager = root.get_node("SettingsManager")
|
|
original_language = settings_manager.get_setting("language")
|
|
|
|
# Setup test environment
|
|
setup_test_environment()
|
|
|
|
# Run test suites
|
|
test_basic_functionality()
|
|
test_data_source_loading()
|
|
test_value_navigation()
|
|
test_custom_values()
|
|
test_input_handling()
|
|
test_visual_feedback()
|
|
test_settings_integration()
|
|
test_boundary_conditions()
|
|
test_error_handling()
|
|
|
|
# Cleanup
|
|
cleanup_tests()
|
|
|
|
TestHelper.print_test_footer("ValueStepper Component")
|
|
|
|
func setup_test_environment():
|
|
TestHelper.print_step("Test Environment Setup")
|
|
|
|
# Load ValueStepper scene
|
|
stepper_scene = load("res://scenes/ui/components/ValueStepper.tscn")
|
|
TestHelper.assert_not_null(stepper_scene, "ValueStepper scene loads successfully")
|
|
|
|
# Create test viewport for isolated testing
|
|
test_viewport = SubViewport.new()
|
|
test_viewport.size = Vector2i(400, 200)
|
|
root.add_child(test_viewport)
|
|
|
|
# Instance ValueStepper in test viewport
|
|
if stepper_scene:
|
|
stepper_instance = stepper_scene.instantiate()
|
|
test_viewport.add_child(stepper_instance)
|
|
TestHelper.assert_not_null(stepper_instance, "ValueStepper instance created successfully")
|
|
|
|
# Wait for initialization
|
|
await process_frame
|
|
await process_frame
|
|
|
|
func test_basic_functionality():
|
|
TestHelper.print_step("Basic Functionality")
|
|
|
|
if not stepper_instance:
|
|
TestHelper.assert_true(false, "ValueStepper instance not available for testing")
|
|
return
|
|
|
|
# Test that ValueStepper has expected properties
|
|
var expected_properties = ["data_source", "custom_format_function", "values", "display_names", "current_index"]
|
|
for prop in expected_properties:
|
|
TestHelper.assert_true(prop in stepper_instance, "ValueStepper has property: " + prop)
|
|
|
|
# Test that ValueStepper has expected methods
|
|
var expected_methods = ["change_value", "setup_custom_values", "get_current_value", "set_current_value", "set_highlighted", "handle_input_action", "get_control_name"]
|
|
TestHelper.assert_has_methods(stepper_instance, expected_methods, "ValueStepper component methods")
|
|
|
|
# Test signals
|
|
TestHelper.assert_true(stepper_instance.has_signal("value_changed"), "ValueStepper has value_changed signal")
|
|
|
|
# Test UI components
|
|
TestHelper.assert_not_null(stepper_instance.left_button, "Left button is available")
|
|
TestHelper.assert_not_null(stepper_instance.right_button, "Right button is available")
|
|
TestHelper.assert_not_null(stepper_instance.value_display, "Value display label is available")
|
|
|
|
# Test UI component types
|
|
TestHelper.assert_true(stepper_instance.left_button is Button, "Left button is Button type")
|
|
TestHelper.assert_true(stepper_instance.right_button is Button, "Right button is Button type")
|
|
TestHelper.assert_true(stepper_instance.value_display is Label, "Value display is Label type")
|
|
|
|
func test_data_source_loading():
|
|
TestHelper.print_step("Data Source Loading")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Test default language data source
|
|
TestHelper.assert_equal("language", stepper_instance.data_source, "Default data source is language")
|
|
|
|
# Test that values are loaded
|
|
TestHelper.assert_not_null(stepper_instance.values, "Values array is initialized")
|
|
TestHelper.assert_not_null(stepper_instance.display_names, "Display names array is initialized")
|
|
TestHelper.assert_true(stepper_instance.values is Array, "Values is Array type")
|
|
TestHelper.assert_true(stepper_instance.display_names is Array, "Display names is Array type")
|
|
|
|
# Test that language data is loaded correctly
|
|
if stepper_instance.data_source == "language":
|
|
TestHelper.assert_true(stepper_instance.values.size() > 0, "Language values loaded")
|
|
TestHelper.assert_true(stepper_instance.display_names.size() > 0, "Language display names loaded")
|
|
TestHelper.assert_equal(stepper_instance.values.size(), stepper_instance.display_names.size(), "Values and display names arrays have same size")
|
|
|
|
# Test that current language is properly selected
|
|
var current_lang = root.get_node("SettingsManager").get_setting("language")
|
|
var expected_index = stepper_instance.values.find(current_lang)
|
|
if expected_index >= 0:
|
|
TestHelper.assert_equal(expected_index, stepper_instance.current_index, "Current language index set correctly")
|
|
|
|
# Test resolution data source
|
|
var resolution_stepper = stepper_scene.instantiate()
|
|
resolution_stepper.data_source = "resolution"
|
|
test_viewport.add_child(resolution_stepper)
|
|
await process_frame
|
|
|
|
TestHelper.assert_true(resolution_stepper.values.size() > 0, "Resolution values loaded")
|
|
TestHelper.assert_contains(resolution_stepper.values, "1920x1080", "Resolution data contains expected value")
|
|
|
|
resolution_stepper.queue_free()
|
|
|
|
# Test difficulty data source
|
|
var difficulty_stepper = stepper_scene.instantiate()
|
|
difficulty_stepper.data_source = "difficulty"
|
|
test_viewport.add_child(difficulty_stepper)
|
|
await process_frame
|
|
|
|
TestHelper.assert_true(difficulty_stepper.values.size() > 0, "Difficulty values loaded")
|
|
TestHelper.assert_contains(difficulty_stepper.values, "normal", "Difficulty data contains expected value")
|
|
TestHelper.assert_equal(1, difficulty_stepper.current_index, "Difficulty defaults to normal")
|
|
|
|
difficulty_stepper.queue_free()
|
|
|
|
func test_value_navigation():
|
|
TestHelper.print_step("Value Navigation")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Store original state
|
|
var original_index = stepper_instance.current_index
|
|
var original_value = stepper_instance.get_current_value()
|
|
|
|
# Test forward navigation
|
|
var initial_value = stepper_instance.get_current_value()
|
|
stepper_instance.change_value(1)
|
|
var next_value = stepper_instance.get_current_value()
|
|
TestHelper.assert_not_equal(initial_value, next_value, "Forward navigation changes value")
|
|
|
|
# Test backward navigation
|
|
stepper_instance.change_value(-1)
|
|
var back_value = stepper_instance.get_current_value()
|
|
TestHelper.assert_equal(initial_value, back_value, "Backward navigation returns to original value")
|
|
|
|
# Test wrap-around forward
|
|
var max_index = stepper_instance.values.size() - 1
|
|
stepper_instance.current_index = max_index
|
|
stepper_instance.change_value(1)
|
|
TestHelper.assert_equal(0, stepper_instance.current_index, "Forward navigation wraps to beginning")
|
|
|
|
# Test wrap-around backward
|
|
stepper_instance.current_index = 0
|
|
stepper_instance.change_value(-1)
|
|
TestHelper.assert_equal(max_index, stepper_instance.current_index, "Backward navigation wraps to end")
|
|
|
|
# Restore original state
|
|
stepper_instance.current_index = original_index
|
|
stepper_instance._update_display()
|
|
|
|
func test_custom_values():
|
|
TestHelper.print_step("Custom Values")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Store original state
|
|
var original_values = stepper_instance.values.duplicate()
|
|
var original_display_names = stepper_instance.display_names.duplicate()
|
|
var original_index = stepper_instance.current_index
|
|
|
|
# Test custom values without display names
|
|
var custom_values = ["apple", "banana", "cherry"]
|
|
stepper_instance.setup_custom_values(custom_values)
|
|
|
|
TestHelper.assert_equal(3, stepper_instance.values.size(), "Custom values set correctly")
|
|
TestHelper.assert_equal("apple", stepper_instance.values[0], "First custom value correct")
|
|
TestHelper.assert_equal(0, stepper_instance.current_index, "Index reset to 0 for custom values")
|
|
TestHelper.assert_equal("apple", stepper_instance.get_current_value(), "Current value matches first custom value")
|
|
|
|
# Test custom values with display names
|
|
var custom_display_names = ["Red Apple", "Yellow Banana", "Red Cherry"]
|
|
stepper_instance.setup_custom_values(custom_values, custom_display_names)
|
|
|
|
TestHelper.assert_equal(3, stepper_instance.display_names.size(), "Custom display names set correctly")
|
|
TestHelper.assert_equal("Red Apple", stepper_instance.display_names[0], "First display name correct")
|
|
|
|
# Test navigation with custom values
|
|
stepper_instance.change_value(1)
|
|
TestHelper.assert_equal("banana", stepper_instance.get_current_value(), "Navigation works with custom values")
|
|
|
|
# Test set_current_value
|
|
stepper_instance.set_current_value("cherry")
|
|
TestHelper.assert_equal("cherry", stepper_instance.get_current_value(), "set_current_value works correctly")
|
|
TestHelper.assert_equal(2, stepper_instance.current_index, "Index updated correctly by set_current_value")
|
|
|
|
# Test invalid value
|
|
stepper_instance.set_current_value("grape")
|
|
TestHelper.assert_equal("cherry", stepper_instance.get_current_value(), "Invalid value doesn't change current value")
|
|
|
|
# Restore original state
|
|
stepper_instance.values = original_values
|
|
stepper_instance.display_names = original_display_names
|
|
stepper_instance.current_index = original_index
|
|
stepper_instance._update_display()
|
|
|
|
func test_input_handling():
|
|
TestHelper.print_step("Input Handling")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Store original state
|
|
var original_value = stepper_instance.get_current_value()
|
|
|
|
# Test left input action
|
|
var left_handled = stepper_instance.handle_input_action("move_left")
|
|
TestHelper.assert_true(left_handled, "Left input action handled")
|
|
TestHelper.assert_not_equal(original_value, stepper_instance.get_current_value(), "Left action changes value")
|
|
|
|
# Test right input action
|
|
var right_handled = stepper_instance.handle_input_action("move_right")
|
|
TestHelper.assert_true(right_handled, "Right input action handled")
|
|
TestHelper.assert_equal(original_value, stepper_instance.get_current_value(), "Right action returns to original value")
|
|
|
|
# Test invalid input action
|
|
var invalid_handled = stepper_instance.handle_input_action("invalid_action")
|
|
TestHelper.assert_false(invalid_handled, "Invalid input action not handled")
|
|
|
|
# Test button press simulation
|
|
if stepper_instance.left_button:
|
|
var before_left = stepper_instance.get_current_value()
|
|
stepper_instance._on_left_button_pressed()
|
|
TestHelper.assert_not_equal(before_left, stepper_instance.get_current_value(), "Left button press changes value")
|
|
|
|
if stepper_instance.right_button:
|
|
var before_right = stepper_instance.get_current_value()
|
|
stepper_instance._on_right_button_pressed()
|
|
TestHelper.assert_equal(original_value, stepper_instance.get_current_value(), "Right button press returns to original")
|
|
|
|
func test_visual_feedback():
|
|
TestHelper.print_step("Visual Feedback")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Store original visual properties
|
|
var original_scale = stepper_instance.scale
|
|
var original_modulate = stepper_instance.modulate
|
|
|
|
# Test highlighting
|
|
stepper_instance.set_highlighted(true)
|
|
TestHelper.assert_true(stepper_instance.is_highlighted, "Highlighted state set correctly")
|
|
TestHelper.assert_true(stepper_instance.scale.x > original_scale.x, "Scale increased when highlighted")
|
|
|
|
# Test unhighlighting
|
|
stepper_instance.set_highlighted(false)
|
|
TestHelper.assert_false(stepper_instance.is_highlighted, "Highlighted state cleared correctly")
|
|
TestHelper.assert_equal(original_scale, stepper_instance.scale, "Scale restored when unhighlighted")
|
|
TestHelper.assert_equal(original_modulate, stepper_instance.modulate, "Modulate restored when unhighlighted")
|
|
|
|
# Test display update
|
|
if stepper_instance.value_display:
|
|
var current_text = stepper_instance.value_display.text
|
|
TestHelper.assert_true(current_text.length() > 0, "Value display has text content")
|
|
TestHelper.assert_not_equal("N/A", current_text, "Value display shows valid content")
|
|
|
|
func test_settings_integration():
|
|
TestHelper.print_step("Settings Integration")
|
|
|
|
if not stepper_instance or stepper_instance.data_source != "language":
|
|
return
|
|
|
|
# Store original language
|
|
var original_lang = root.get_node("SettingsManager").get_setting("language")
|
|
|
|
# Test that changing language stepper updates settings
|
|
var available_languages = stepper_instance.values
|
|
if available_languages.size() > 1:
|
|
# Find a different language
|
|
var target_lang = null
|
|
for lang in available_languages:
|
|
if lang != original_lang:
|
|
target_lang = lang
|
|
break
|
|
|
|
if target_lang:
|
|
stepper_instance.set_current_value(target_lang)
|
|
stepper_instance._apply_value_change(target_lang, stepper_instance.current_index)
|
|
|
|
# Verify setting was updated
|
|
var updated_lang = root.get_node("SettingsManager").get_setting("language")
|
|
TestHelper.assert_equal(target_lang, updated_lang, "Language setting updated correctly")
|
|
|
|
# Restore original language
|
|
root.get_node("SettingsManager").set_setting("language", original_lang)
|
|
|
|
func test_boundary_conditions():
|
|
TestHelper.print_step("Boundary Conditions")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Test empty values array
|
|
var empty_stepper = stepper_scene.instantiate()
|
|
empty_stepper.data_source = "unknown" # Will result in empty arrays
|
|
test_viewport.add_child(empty_stepper)
|
|
await process_frame
|
|
|
|
TestHelper.assert_equal("", empty_stepper.get_current_value(), "Empty values array returns empty string")
|
|
|
|
# Test change_value with empty array
|
|
empty_stepper.change_value(1) # Should not crash
|
|
TestHelper.assert_true(true, "change_value handles empty array gracefully")
|
|
|
|
empty_stepper.queue_free()
|
|
|
|
# Test index bounds
|
|
if stepper_instance.values.size() > 0:
|
|
# Test negative index handling
|
|
stepper_instance.current_index = -1
|
|
stepper_instance._update_display()
|
|
TestHelper.assert_equal("N/A", stepper_instance.value_display.text, "Negative index shows N/A")
|
|
|
|
# Test out-of-bounds index handling
|
|
stepper_instance.current_index = stepper_instance.values.size()
|
|
stepper_instance._update_display()
|
|
TestHelper.assert_equal("N/A", stepper_instance.value_display.text, "Out-of-bounds index shows N/A")
|
|
|
|
# Restore valid index
|
|
stepper_instance.current_index = 0
|
|
stepper_instance._update_display()
|
|
|
|
func test_error_handling():
|
|
TestHelper.print_step("Error Handling")
|
|
|
|
if not stepper_instance:
|
|
return
|
|
|
|
# Test unknown data source
|
|
var unknown_stepper = stepper_scene.instantiate()
|
|
unknown_stepper.data_source = "invalid_source"
|
|
test_viewport.add_child(unknown_stepper)
|
|
await process_frame
|
|
|
|
# Should not crash and should handle gracefully
|
|
TestHelper.assert_true(true, "Unknown data source handled gracefully")
|
|
unknown_stepper.queue_free()
|
|
|
|
# Test get_control_name
|
|
var control_name = stepper_instance.get_control_name()
|
|
TestHelper.assert_true(control_name.ends_with("_stepper"), "Control name has correct suffix")
|
|
TestHelper.assert_true(control_name.begins_with(stepper_instance.data_source), "Control name includes data source")
|
|
|
|
# Test custom values with mismatched arrays
|
|
var values_3 = ["a", "b", "c"]
|
|
var names_2 = ["A", "B"]
|
|
stepper_instance.setup_custom_values(values_3, names_2)
|
|
|
|
# Should handle gracefully - display_names should be duplicated from values
|
|
TestHelper.assert_equal(3, stepper_instance.values.size(), "Values array size preserved")
|
|
TestHelper.assert_equal(2, stepper_instance.display_names.size(), "Display names size preserved as provided")
|
|
|
|
# Test navigation with mismatched arrays
|
|
stepper_instance.current_index = 2 # Index where display_names doesn't exist
|
|
stepper_instance._update_display()
|
|
TestHelper.assert_equal("c", stepper_instance.value_display.text, "Falls back to value when display name missing")
|
|
|
|
func cleanup_tests():
|
|
TestHelper.print_step("Cleanup")
|
|
|
|
# Restore original language setting
|
|
root.get_node("SettingsManager").set_setting("language", original_language)
|
|
|
|
# Clean up stepper instance
|
|
if stepper_instance and is_instance_valid(stepper_instance):
|
|
stepper_instance.queue_free()
|
|
|
|
# Clean up test viewport
|
|
if test_viewport and is_instance_valid(test_viewport):
|
|
test_viewport.queue_free()
|
|
|
|
# Wait for cleanup
|
|
await process_frame
|
|
|
|
TestHelper.assert_true(true, "Test cleanup completed") |