gdlint fixes
This commit is contained in:
@@ -16,5 +16,5 @@ func _on_button_pressed():
|
|||||||
DebugManager.toggle_debug_ui()
|
DebugManager.toggle_debug_ui()
|
||||||
|
|
||||||
|
|
||||||
func _on_debug_ui_toggled(visible: bool):
|
func _on_debug_ui_toggled(is_debug_visible: bool):
|
||||||
button.text = "Debug UI: " + ("ON" if visible else "OFF")
|
button.text = "Debug UI: " + ("ON" if is_debug_visible else "OFF")
|
||||||
|
|||||||
@@ -91,21 +91,21 @@ static func assert_in_range(value: float, min_val: float, max_val: float, messag
|
|||||||
static func assert_float_equal(expected: float, actual: float, tolerance: float = 0.0001, message: String = ""):
|
static func assert_float_equal(expected: float, actual: float, tolerance: float = 0.0001, message: String = ""):
|
||||||
# Handle special cases: both infinity, both negative infinity, both NaN
|
# Handle special cases: both infinity, both negative infinity, both NaN
|
||||||
if is_inf(expected) and is_inf(actual):
|
if is_inf(expected) and is_inf(actual):
|
||||||
var condition = (expected > 0) == (actual > 0) # Same sign of infinity
|
var infinity_condition = (expected > 0) == (actual > 0) # Same sign of infinity
|
||||||
var full_message = "%s (Both infinity values: Expected: %f, Got: %f)" % [message, expected, actual]
|
var infinity_message = "%s (Both infinity values: Expected: %f, Got: %f)" % [message, expected, actual]
|
||||||
assert_true(condition, full_message)
|
assert_true(infinity_condition, infinity_message)
|
||||||
return
|
return
|
||||||
|
|
||||||
if is_nan(expected) and is_nan(actual):
|
if is_nan(expected) and is_nan(actual):
|
||||||
var full_message = "%s (Both NaN values: Expected: %f, Got: %f)" % [message, expected, actual]
|
var nan_message = "%s (Both NaN values: Expected: %f, Got: %f)" % [message, expected, actual]
|
||||||
assert_true(true, full_message) # Both NaN is considered equal
|
assert_true(true, nan_message) # Both NaN is considered equal
|
||||||
return
|
return
|
||||||
|
|
||||||
# Normal floating-point comparison
|
# Normal floating-point comparison
|
||||||
var difference = abs(expected - actual)
|
var difference = abs(expected - actual)
|
||||||
var condition = difference <= tolerance
|
var tolerance_condition = difference <= tolerance
|
||||||
var full_message = "%s (Expected: %f, Got: %f, Difference: %f, Tolerance: %f)" % [message, expected, actual, difference, tolerance]
|
var comparison_message = "%s (Expected: %f, Got: %f, Difference: %f, Tolerance: %f)" % [message, expected, actual, difference, tolerance]
|
||||||
assert_true(condition, full_message)
|
assert_true(tolerance_condition, comparison_message)
|
||||||
|
|
||||||
## Assert that an array contains a specific value
|
## Assert that an array contains a specific value
|
||||||
static func assert_contains(array: Array, value, message: String = ""):
|
static func assert_contains(array: Array, value, message: String = ""):
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ extends SceneTree
|
|||||||
## audio bus configuration, and playback control functionality.
|
## audio bus configuration, and playback control functionality.
|
||||||
## Validates proper audio system initialization and error handling.
|
## Validates proper audio system initialization and error handling.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var audio_manager: Node
|
var audio_manager: Node
|
||||||
var original_music_volume: float
|
var original_music_volume: float
|
||||||
@@ -25,13 +25,13 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("AudioManager")
|
TestHelperClass.print_test_header("AudioManager")
|
||||||
|
|
||||||
# Get reference to AudioManager
|
# Get reference to AudioManager
|
||||||
audio_manager = root.get_node("AudioManager")
|
audio_manager = root.get_node("AudioManager")
|
||||||
if not audio_manager:
|
if not audio_manager:
|
||||||
TestHelper.assert_true(false, "AudioManager autoload not found")
|
TestHelperClass.assert_true(false, "AudioManager autoload not found")
|
||||||
TestHelper.print_test_footer("AudioManager")
|
TestHelperClass.print_test_footer("AudioManager")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Store original settings for restoration
|
# Store original settings for restoration
|
||||||
@@ -54,14 +54,14 @@ func run_tests():
|
|||||||
# Cleanup and restore original state
|
# Cleanup and restore original state
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("AudioManager")
|
TestHelperClass.print_test_footer("AudioManager")
|
||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
# Test that AudioManager has expected properties
|
# Test that AudioManager has expected properties
|
||||||
TestHelper.assert_has_properties(
|
TestHelperClass.assert_has_properties(
|
||||||
audio_manager,
|
audio_manager,
|
||||||
["music_player", "ui_click_player", "click_stream"],
|
["music_player", "ui_click_player", "click_stream"],
|
||||||
"AudioManager properties"
|
"AudioManager properties"
|
||||||
@@ -69,24 +69,24 @@ func test_basic_functionality():
|
|||||||
|
|
||||||
# Test that AudioManager has expected methods
|
# Test that AudioManager has expected methods
|
||||||
var expected_methods = ["update_music_volume", "play_ui_click"]
|
var expected_methods = ["update_music_volume", "play_ui_click"]
|
||||||
TestHelper.assert_has_methods(audio_manager, expected_methods, "AudioManager methods")
|
TestHelperClass.assert_has_methods(audio_manager, expected_methods, "AudioManager methods")
|
||||||
|
|
||||||
# Test that AudioManager has expected constants
|
# Test that AudioManager has expected constants
|
||||||
TestHelper.assert_true("MUSIC_PATH" in audio_manager, "MUSIC_PATH constant exists")
|
TestHelperClass.assert_true("MUSIC_PATH" in audio_manager, "MUSIC_PATH constant exists")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"UI_CLICK_SOUND_PATH" in audio_manager, "UI_CLICK_SOUND_PATH constant exists"
|
"UI_CLICK_SOUND_PATH" in audio_manager, "UI_CLICK_SOUND_PATH constant exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_audio_constants():
|
func test_audio_constants():
|
||||||
TestHelper.print_step("Audio File Constants")
|
TestHelperClass.print_step("Audio File Constants")
|
||||||
|
|
||||||
# Test path format validation
|
# Test path format validation
|
||||||
var music_path = audio_manager.MUSIC_PATH
|
var music_path = audio_manager.MUSIC_PATH
|
||||||
var click_path = audio_manager.UI_CLICK_SOUND_PATH
|
var click_path = audio_manager.UI_CLICK_SOUND_PATH
|
||||||
|
|
||||||
TestHelper.assert_true(music_path.begins_with("res://"), "Music path uses res:// protocol")
|
TestHelperClass.assert_true(music_path.begins_with("res://"), "Music path uses res:// protocol")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
click_path.begins_with("res://"), "Click sound path uses res:// protocol"
|
click_path.begins_with("res://"), "Click sound path uses res:// protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -101,92 +101,92 @@ func test_audio_constants():
|
|||||||
if click_path.ends_with(ext):
|
if click_path.ends_with(ext):
|
||||||
click_has_valid_ext = true
|
click_has_valid_ext = true
|
||||||
|
|
||||||
TestHelper.assert_true(music_has_valid_ext, "Music file has valid audio extension")
|
TestHelperClass.assert_true(music_has_valid_ext, "Music file has valid audio extension")
|
||||||
TestHelper.assert_true(click_has_valid_ext, "Click sound has valid audio extension")
|
TestHelperClass.assert_true(click_has_valid_ext, "Click sound has valid audio extension")
|
||||||
|
|
||||||
# Test that audio files exist
|
# Test that audio files exist
|
||||||
TestHelper.assert_true(ResourceLoader.exists(music_path), "Music file exists at path")
|
TestHelperClass.assert_true(ResourceLoader.exists(music_path), "Music file exists at path")
|
||||||
TestHelper.assert_true(ResourceLoader.exists(click_path), "Click sound file exists at path")
|
TestHelperClass.assert_true(ResourceLoader.exists(click_path), "Click sound file exists at path")
|
||||||
|
|
||||||
|
|
||||||
func test_audio_player_initialization():
|
func test_audio_player_initialization():
|
||||||
TestHelper.print_step("Audio Player Initialization")
|
TestHelperClass.print_step("Audio Player Initialization")
|
||||||
|
|
||||||
# Test music player initialization
|
# Test music player initialization
|
||||||
TestHelper.assert_not_null(audio_manager.music_player, "Music player is initialized")
|
TestHelperClass.assert_not_null(audio_manager.music_player, "Music player is initialized")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.music_player is AudioStreamPlayer, "Music player is AudioStreamPlayer type"
|
audio_manager.music_player is AudioStreamPlayer, "Music player is AudioStreamPlayer type"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.music_player.get_parent() == audio_manager,
|
audio_manager.music_player.get_parent() == audio_manager,
|
||||||
"Music player is child of AudioManager"
|
"Music player is child of AudioManager"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test UI click player initialization
|
# Test UI click player initialization
|
||||||
TestHelper.assert_not_null(audio_manager.ui_click_player, "UI click player is initialized")
|
TestHelperClass.assert_not_null(audio_manager.ui_click_player, "UI click player is initialized")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.ui_click_player is AudioStreamPlayer,
|
audio_manager.ui_click_player is AudioStreamPlayer,
|
||||||
"UI click player is AudioStreamPlayer type"
|
"UI click player is AudioStreamPlayer type"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.ui_click_player.get_parent() == audio_manager,
|
audio_manager.ui_click_player.get_parent() == audio_manager,
|
||||||
"UI click player is child of AudioManager"
|
"UI click player is child of AudioManager"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test audio bus assignment
|
# Test audio bus assignment
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"Music", audio_manager.music_player.bus, "Music player assigned to Music bus"
|
"Music", audio_manager.music_player.bus, "Music player assigned to Music bus"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"SFX", audio_manager.ui_click_player.bus, "UI click player assigned to SFX bus"
|
"SFX", audio_manager.ui_click_player.bus, "UI click player assigned to SFX bus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_stream_loading_and_validation():
|
func test_stream_loading_and_validation():
|
||||||
TestHelper.print_step("Stream Loading and Validation")
|
TestHelperClass.print_step("Stream Loading and Validation")
|
||||||
|
|
||||||
# Test music stream loading
|
# Test music stream loading
|
||||||
TestHelper.assert_not_null(audio_manager.music_player.stream, "Music stream is loaded")
|
TestHelperClass.assert_not_null(audio_manager.music_player.stream, "Music stream is loaded")
|
||||||
if audio_manager.music_player.stream:
|
if audio_manager.music_player.stream:
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.music_player.stream is AudioStream, "Music stream is AudioStream type"
|
audio_manager.music_player.stream is AudioStream, "Music stream is AudioStream type"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test click stream loading
|
# Test click stream loading
|
||||||
TestHelper.assert_not_null(audio_manager.click_stream, "Click stream is loaded")
|
TestHelperClass.assert_not_null(audio_manager.click_stream, "Click stream is loaded")
|
||||||
if audio_manager.click_stream:
|
if audio_manager.click_stream:
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
audio_manager.click_stream is AudioStream, "Click stream is AudioStream type"
|
audio_manager.click_stream is AudioStream, "Click stream is AudioStream type"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test stream resource loading directly
|
# Test stream resource loading directly
|
||||||
var loaded_music = load(audio_manager.MUSIC_PATH)
|
var loaded_music = load(audio_manager.MUSIC_PATH)
|
||||||
TestHelper.assert_not_null(loaded_music, "Music resource loads successfully")
|
TestHelperClass.assert_not_null(loaded_music, "Music resource loads successfully")
|
||||||
TestHelper.assert_true(loaded_music is AudioStream, "Loaded music is AudioStream type")
|
TestHelperClass.assert_true(loaded_music is AudioStream, "Loaded music is AudioStream type")
|
||||||
|
|
||||||
var loaded_click = load(audio_manager.UI_CLICK_SOUND_PATH)
|
var loaded_click = load(audio_manager.UI_CLICK_SOUND_PATH)
|
||||||
TestHelper.assert_not_null(loaded_click, "Click resource loads successfully")
|
TestHelperClass.assert_not_null(loaded_click, "Click resource loads successfully")
|
||||||
TestHelper.assert_true(loaded_click is AudioStream, "Loaded click sound is AudioStream type")
|
TestHelperClass.assert_true(loaded_click is AudioStream, "Loaded click sound is AudioStream type")
|
||||||
|
|
||||||
|
|
||||||
func test_audio_bus_configuration():
|
func test_audio_bus_configuration():
|
||||||
TestHelper.print_step("Audio Bus Configuration")
|
TestHelperClass.print_step("Audio Bus Configuration")
|
||||||
|
|
||||||
# Test that required audio buses exist
|
# Test that required audio buses exist
|
||||||
var music_bus_index = AudioServer.get_bus_index("Music")
|
var music_bus_index = AudioServer.get_bus_index("Music")
|
||||||
var sfx_bus_index = AudioServer.get_bus_index("SFX")
|
var sfx_bus_index = AudioServer.get_bus_index("SFX")
|
||||||
|
|
||||||
TestHelper.assert_true(music_bus_index >= 0, "Music audio bus exists")
|
TestHelperClass.assert_true(music_bus_index >= 0, "Music audio bus exists")
|
||||||
TestHelper.assert_true(sfx_bus_index >= 0, "SFX audio bus exists")
|
TestHelperClass.assert_true(sfx_bus_index >= 0, "SFX audio bus exists")
|
||||||
|
|
||||||
# Test player bus assignments match actual AudioServer buses
|
# Test player bus assignments match actual AudioServer buses
|
||||||
if music_bus_index >= 0:
|
if music_bus_index >= 0:
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"Music", audio_manager.music_player.bus, "Music player correctly assigned to Music bus"
|
"Music", audio_manager.music_player.bus, "Music player correctly assigned to Music bus"
|
||||||
)
|
)
|
||||||
|
|
||||||
if sfx_bus_index >= 0:
|
if sfx_bus_index >= 0:
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"SFX",
|
"SFX",
|
||||||
audio_manager.ui_click_player.bus,
|
audio_manager.ui_click_player.bus,
|
||||||
"UI click player correctly assigned to SFX bus"
|
"UI click player correctly assigned to SFX bus"
|
||||||
@@ -194,29 +194,29 @@ func test_audio_bus_configuration():
|
|||||||
|
|
||||||
|
|
||||||
func test_volume_management():
|
func test_volume_management():
|
||||||
TestHelper.print_step("Volume Management")
|
TestHelperClass.print_step("Volume Management")
|
||||||
|
|
||||||
# Store original volume
|
# Store original volume
|
||||||
var settings_manager = root.get_node("SettingsManager")
|
var settings_manager = root.get_node("SettingsManager")
|
||||||
var original_volume = settings_manager.get_setting("music_volume")
|
var original_volume = settings_manager.get_setting("music_volume")
|
||||||
var was_playing = audio_manager.music_player.playing
|
var _was_playing = audio_manager.music_player.playing
|
||||||
|
|
||||||
# Test volume update to valid range
|
# Test volume update to valid range
|
||||||
audio_manager.update_music_volume(0.5)
|
audio_manager.update_music_volume(0.5)
|
||||||
TestHelper.assert_float_equal(
|
TestHelperClass.assert_float_equal(
|
||||||
linear_to_db(0.5), audio_manager.music_player.volume_db, 0.001, "Music volume set correctly"
|
linear_to_db(0.5), audio_manager.music_player.volume_db, 0.001, "Music volume set correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test volume update to zero (should stop music)
|
# Test volume update to zero (should stop music)
|
||||||
audio_manager.update_music_volume(0.0)
|
audio_manager.update_music_volume(0.0)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
linear_to_db(0.0), audio_manager.music_player.volume_db, "Zero volume set correctly"
|
linear_to_db(0.0), audio_manager.music_player.volume_db, "Zero volume set correctly"
|
||||||
)
|
)
|
||||||
# Note: We don't test playing state as it depends on initialization conditions
|
# Note: We don't test playing state as it depends on initialization conditions
|
||||||
|
|
||||||
# Test volume update to maximum
|
# Test volume update to maximum
|
||||||
audio_manager.update_music_volume(1.0)
|
audio_manager.update_music_volume(1.0)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
linear_to_db(1.0), audio_manager.music_player.volume_db, "Maximum volume set correctly"
|
linear_to_db(1.0), audio_manager.music_player.volume_db, "Maximum volume set correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ func test_volume_management():
|
|||||||
for volume in test_volumes:
|
for volume in test_volumes:
|
||||||
audio_manager.update_music_volume(volume)
|
audio_manager.update_music_volume(volume)
|
||||||
var expected_db = linear_to_db(volume)
|
var expected_db = linear_to_db(volume)
|
||||||
TestHelper.assert_float_equal(
|
TestHelperClass.assert_float_equal(
|
||||||
expected_db,
|
expected_db,
|
||||||
audio_manager.music_player.volume_db,
|
audio_manager.music_player.volume_db,
|
||||||
0.001,
|
0.001,
|
||||||
@@ -237,53 +237,53 @@ func test_volume_management():
|
|||||||
|
|
||||||
|
|
||||||
func test_music_playback_control():
|
func test_music_playback_control():
|
||||||
TestHelper.print_step("Music Playback Control")
|
TestHelperClass.print_step("Music Playback Control")
|
||||||
|
|
||||||
# Test that music player exists and has a stream
|
# Test that music player exists and has a stream
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
audio_manager.music_player, "Music player exists for playback testing"
|
audio_manager.music_player, "Music player exists for playback testing"
|
||||||
)
|
)
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
audio_manager.music_player.stream, "Music player has stream for playback testing"
|
audio_manager.music_player.stream, "Music player has stream for playback testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test playback state management
|
# Test playback state management
|
||||||
# Note: We test the control methods exist and can be called safely
|
# Note: We test the control methods exist and can be called safely
|
||||||
var original_playing = audio_manager.music_player.playing
|
var _original_playing = audio_manager.music_player.playing
|
||||||
|
|
||||||
# Test that playback methods can be called without errors
|
# Test that playback methods can be called without errors
|
||||||
if audio_manager.has_method("_start_music"):
|
if audio_manager.has_method("_start_music"):
|
||||||
# Method exists but is private - test that the logic is sound
|
# Method exists but is private - test that the logic is sound
|
||||||
TestHelper.assert_true(true, "Private _start_music method exists")
|
TestHelperClass.assert_true(true, "Private _start_music method exists")
|
||||||
|
|
||||||
if audio_manager.has_method("_stop_music"):
|
if audio_manager.has_method("_stop_music"):
|
||||||
# Method exists but is private - test that the logic is sound
|
# Method exists but is private - test that the logic is sound
|
||||||
TestHelper.assert_true(true, "Private _stop_music method exists")
|
TestHelperClass.assert_true(true, "Private _stop_music method exists")
|
||||||
|
|
||||||
# Test volume-based playback control
|
# Test volume-based playback control
|
||||||
var settings_manager = root.get_node("SettingsManager")
|
var settings_manager = root.get_node("SettingsManager")
|
||||||
var current_volume = settings_manager.get_setting("music_volume")
|
var current_volume = settings_manager.get_setting("music_volume")
|
||||||
if current_volume > 0.0:
|
if current_volume > 0.0:
|
||||||
audio_manager.update_music_volume(current_volume)
|
audio_manager.update_music_volume(current_volume)
|
||||||
TestHelper.assert_true(true, "Volume-based playback start works")
|
TestHelperClass.assert_true(true, "Volume-based playback start works")
|
||||||
else:
|
else:
|
||||||
audio_manager.update_music_volume(0.0)
|
audio_manager.update_music_volume(0.0)
|
||||||
TestHelper.assert_true(true, "Volume-based playback stop works")
|
TestHelperClass.assert_true(true, "Volume-based playback stop works")
|
||||||
|
|
||||||
|
|
||||||
func test_ui_sound_effects():
|
func test_ui_sound_effects():
|
||||||
TestHelper.print_step("UI Sound Effects")
|
TestHelperClass.print_step("UI Sound Effects")
|
||||||
|
|
||||||
# Test UI click functionality
|
# Test UI click functionality
|
||||||
TestHelper.assert_not_null(audio_manager.ui_click_player, "UI click player exists")
|
TestHelperClass.assert_not_null(audio_manager.ui_click_player, "UI click player exists")
|
||||||
TestHelper.assert_not_null(audio_manager.click_stream, "Click stream is loaded")
|
TestHelperClass.assert_not_null(audio_manager.click_stream, "Click stream is loaded")
|
||||||
|
|
||||||
# Test that play_ui_click can be called safely
|
# Test that play_ui_click can be called safely
|
||||||
var original_stream = audio_manager.ui_click_player.stream
|
var _original_stream = audio_manager.ui_click_player.stream
|
||||||
audio_manager.play_ui_click()
|
audio_manager.play_ui_click()
|
||||||
|
|
||||||
# Verify click stream was assigned to player
|
# Verify click stream was assigned to player
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
audio_manager.click_stream,
|
audio_manager.click_stream,
|
||||||
audio_manager.ui_click_player.stream,
|
audio_manager.ui_click_player.stream,
|
||||||
"Click stream assigned to player"
|
"Click stream assigned to player"
|
||||||
@@ -292,18 +292,18 @@ func test_ui_sound_effects():
|
|||||||
# Test multiple rapid clicks (should not cause errors)
|
# Test multiple rapid clicks (should not cause errors)
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
audio_manager.play_ui_click()
|
audio_manager.play_ui_click()
|
||||||
TestHelper.assert_true(true, "Rapid click %d handled safely" % (i + 1))
|
TestHelperClass.assert_true(true, "Rapid click %d handled safely" % (i + 1))
|
||||||
|
|
||||||
# Test click with null stream
|
# Test click with null stream
|
||||||
var backup_stream = audio_manager.click_stream
|
var backup_stream = audio_manager.click_stream
|
||||||
audio_manager.click_stream = null
|
audio_manager.click_stream = null
|
||||||
audio_manager.play_ui_click() # Should not crash
|
audio_manager.play_ui_click() # Should not crash
|
||||||
TestHelper.assert_true(true, "Null click stream handled safely")
|
TestHelperClass.assert_true(true, "Null click stream handled safely")
|
||||||
audio_manager.click_stream = backup_stream
|
audio_manager.click_stream = backup_stream
|
||||||
|
|
||||||
|
|
||||||
func test_stream_loop_configuration():
|
func test_stream_loop_configuration():
|
||||||
TestHelper.print_step("Stream Loop Configuration")
|
TestHelperClass.print_step("Stream Loop Configuration")
|
||||||
|
|
||||||
# Test that music stream has loop configuration
|
# Test that music stream has loop configuration
|
||||||
var music_stream = audio_manager.music_player.stream
|
var music_stream = audio_manager.music_player.stream
|
||||||
@@ -311,9 +311,9 @@ func test_stream_loop_configuration():
|
|||||||
if music_stream is AudioStreamWAV:
|
if music_stream is AudioStreamWAV:
|
||||||
# For WAV files, check loop mode
|
# For WAV files, check loop mode
|
||||||
var has_loop_mode = "loop_mode" in music_stream
|
var has_loop_mode = "loop_mode" in music_stream
|
||||||
TestHelper.assert_true(has_loop_mode, "WAV stream has loop_mode property")
|
TestHelperClass.assert_true(has_loop_mode, "WAV stream has loop_mode property")
|
||||||
if has_loop_mode:
|
if has_loop_mode:
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
AudioStreamWAV.LOOP_FORWARD,
|
AudioStreamWAV.LOOP_FORWARD,
|
||||||
music_stream.loop_mode,
|
music_stream.loop_mode,
|
||||||
"WAV stream set to forward loop"
|
"WAV stream set to forward loop"
|
||||||
@@ -321,30 +321,30 @@ func test_stream_loop_configuration():
|
|||||||
elif music_stream is AudioStreamOggVorbis:
|
elif music_stream is AudioStreamOggVorbis:
|
||||||
# For OGG files, check loop property
|
# For OGG files, check loop property
|
||||||
var has_loop = "loop" in music_stream
|
var has_loop = "loop" in music_stream
|
||||||
TestHelper.assert_true(has_loop, "OGG stream has loop property")
|
TestHelperClass.assert_true(has_loop, "OGG stream has loop property")
|
||||||
if has_loop:
|
if has_loop:
|
||||||
TestHelper.assert_true(music_stream.loop, "OGG stream loop enabled")
|
TestHelperClass.assert_true(music_stream.loop, "OGG stream loop enabled")
|
||||||
|
|
||||||
# Test loop configuration for different stream types
|
# Test loop configuration for different stream types
|
||||||
TestHelper.assert_true(true, "Stream loop configuration tested based on type")
|
TestHelperClass.assert_true(true, "Stream loop configuration tested based on type")
|
||||||
|
|
||||||
|
|
||||||
func test_error_handling():
|
func test_error_handling():
|
||||||
TestHelper.print_step("Error Handling")
|
TestHelperClass.print_step("Error Handling")
|
||||||
|
|
||||||
# Test graceful handling of missing resources
|
# Test graceful handling of missing resources
|
||||||
# We can't actually break the resources in tests, but we can verify error handling patterns
|
# We can't actually break the resources in tests, but we can verify error handling patterns
|
||||||
|
|
||||||
# Test that AudioManager initializes even with potential issues
|
# Test that AudioManager initializes even with potential issues
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
audio_manager, "AudioManager initializes despite potential resource issues"
|
audio_manager, "AudioManager initializes despite potential resource issues"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that players are still created even if streams fail to load
|
# Test that players are still created even if streams fail to load
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
audio_manager.music_player, "Music player created regardless of stream loading"
|
audio_manager.music_player, "Music player created regardless of stream loading"
|
||||||
)
|
)
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
audio_manager.ui_click_player, "UI click player created regardless of stream loading"
|
audio_manager.ui_click_player, "UI click player created regardless of stream loading"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -354,21 +354,21 @@ func test_error_handling():
|
|||||||
|
|
||||||
# This should not crash
|
# This should not crash
|
||||||
audio_manager.play_ui_click()
|
audio_manager.play_ui_click()
|
||||||
TestHelper.assert_true(true, "play_ui_click handles null stream gracefully")
|
TestHelperClass.assert_true(true, "play_ui_click handles null stream gracefully")
|
||||||
|
|
||||||
# Restore original stream
|
# Restore original stream
|
||||||
audio_manager.click_stream = original_click_stream
|
audio_manager.click_stream = original_click_stream
|
||||||
|
|
||||||
# Test volume edge cases
|
# Test volume edge cases
|
||||||
audio_manager.update_music_volume(0.0)
|
audio_manager.update_music_volume(0.0)
|
||||||
TestHelper.assert_true(true, "Zero volume handled safely")
|
TestHelperClass.assert_true(true, "Zero volume handled safely")
|
||||||
|
|
||||||
audio_manager.update_music_volume(1.0)
|
audio_manager.update_music_volume(1.0)
|
||||||
TestHelper.assert_true(true, "Maximum volume handled safely")
|
TestHelperClass.assert_true(true, "Maximum volume handled safely")
|
||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Restore original volume settings
|
# Restore original volume settings
|
||||||
var settings_manager = root.get_node("SettingsManager")
|
var settings_manager = root.get_node("SettingsManager")
|
||||||
@@ -378,4 +378,4 @@ func cleanup_tests():
|
|||||||
# Update AudioManager to original settings
|
# Update AudioManager to original settings
|
||||||
audio_manager.update_music_volume(original_music_volume)
|
audio_manager.update_music_volume(original_music_volume)
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extends SceneTree
|
|||||||
##
|
##
|
||||||
## Tests scene transitions, input validation, and gameplay modes.
|
## Tests scene transitions, input validation, and gameplay modes.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var game_manager: Node
|
var game_manager: Node
|
||||||
var original_scene: Node
|
var original_scene: Node
|
||||||
@@ -23,13 +23,13 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("GameManager")
|
TestHelperClass.print_test_header("GameManager")
|
||||||
|
|
||||||
# Get reference to GameManager
|
# Get reference to GameManager
|
||||||
game_manager = root.get_node("GameManager")
|
game_manager = root.get_node("GameManager")
|
||||||
if not game_manager:
|
if not game_manager:
|
||||||
TestHelper.assert_true(false, "GameManager autoload not found")
|
TestHelperClass.assert_true(false, "GameManager autoload not found")
|
||||||
TestHelper.print_test_footer("GameManager")
|
TestHelperClass.print_test_footer("GameManager")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Store original scene reference
|
# Store original scene reference
|
||||||
@@ -49,14 +49,14 @@ func run_tests():
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("GameManager")
|
TestHelperClass.print_test_footer("GameManager")
|
||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
# Test that GameManager has expected properties
|
# Test that GameManager has expected properties
|
||||||
TestHelper.assert_has_properties(
|
TestHelperClass.assert_has_properties(
|
||||||
game_manager, ["pending_gameplay_mode", "is_changing_scene"], "GameManager properties"
|
game_manager, ["pending_gameplay_mode", "is_changing_scene"], "GameManager properties"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -70,83 +70,83 @@ func test_basic_functionality():
|
|||||||
"save_game",
|
"save_game",
|
||||||
"exit_to_main_menu"
|
"exit_to_main_menu"
|
||||||
]
|
]
|
||||||
TestHelper.assert_has_methods(game_manager, expected_methods, "GameManager methods")
|
TestHelperClass.assert_has_methods(game_manager, expected_methods, "GameManager methods")
|
||||||
|
|
||||||
# Test initial state
|
# Test initial state
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"match3", game_manager.pending_gameplay_mode, "Default pending gameplay mode"
|
"match3", game_manager.pending_gameplay_mode, "Default pending gameplay mode"
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(game_manager.is_changing_scene, "Initial scene change flag")
|
TestHelperClass.assert_false(game_manager.is_changing_scene, "Initial scene change flag")
|
||||||
|
|
||||||
|
|
||||||
func test_scene_constants():
|
func test_scene_constants():
|
||||||
TestHelper.print_step("Scene Path Constants")
|
TestHelperClass.print_step("Scene Path Constants")
|
||||||
|
|
||||||
# Test that scene path constants are defined and valid
|
# Test that scene path constants are defined and valid
|
||||||
TestHelper.assert_true("GAME_SCENE_PATH" in game_manager, "GAME_SCENE_PATH constant exists")
|
TestHelperClass.assert_true("GAME_SCENE_PATH" in game_manager, "GAME_SCENE_PATH constant exists")
|
||||||
TestHelper.assert_true("MAIN_SCENE_PATH" in game_manager, "MAIN_SCENE_PATH constant exists")
|
TestHelperClass.assert_true("MAIN_SCENE_PATH" in game_manager, "MAIN_SCENE_PATH constant exists")
|
||||||
|
|
||||||
# Test path format validation
|
# Test path format validation
|
||||||
var game_path = game_manager.GAME_SCENE_PATH
|
var game_path = game_manager.GAME_SCENE_PATH
|
||||||
var main_path = game_manager.MAIN_SCENE_PATH
|
var main_path = game_manager.MAIN_SCENE_PATH
|
||||||
|
|
||||||
TestHelper.assert_true(game_path.begins_with("res://"), "Game scene path uses res:// protocol")
|
TestHelperClass.assert_true(game_path.begins_with("res://"), "Game scene path uses res:// protocol")
|
||||||
TestHelper.assert_true(game_path.ends_with(".tscn"), "Game scene path has .tscn extension")
|
TestHelperClass.assert_true(game_path.ends_with(".tscn"), "Game scene path has .tscn extension")
|
||||||
TestHelper.assert_true(main_path.begins_with("res://"), "Main scene path uses res:// protocol")
|
TestHelperClass.assert_true(main_path.begins_with("res://"), "Main scene path uses res:// protocol")
|
||||||
TestHelper.assert_true(main_path.ends_with(".tscn"), "Main scene path has .tscn extension")
|
TestHelperClass.assert_true(main_path.ends_with(".tscn"), "Main scene path has .tscn extension")
|
||||||
|
|
||||||
# Test that scene files exist
|
# Test that scene files exist
|
||||||
TestHelper.assert_true(ResourceLoader.exists(game_path), "Game scene file exists at path")
|
TestHelperClass.assert_true(ResourceLoader.exists(game_path), "Game scene file exists at path")
|
||||||
TestHelper.assert_true(ResourceLoader.exists(main_path), "Main scene file exists at path")
|
TestHelperClass.assert_true(ResourceLoader.exists(main_path), "Main scene file exists at path")
|
||||||
|
|
||||||
|
|
||||||
func test_input_validation():
|
func test_input_validation():
|
||||||
TestHelper.print_step("Input Validation")
|
TestHelperClass.print_step("Input Validation")
|
||||||
|
|
||||||
# Store original state
|
# Store original state
|
||||||
var original_changing = game_manager.is_changing_scene
|
var _original_changing = game_manager.is_changing_scene
|
||||||
var original_mode = game_manager.pending_gameplay_mode
|
var original_mode = game_manager.pending_gameplay_mode
|
||||||
|
|
||||||
# Test empty string validation
|
# Test empty string validation
|
||||||
game_manager.start_game_with_mode("")
|
game_manager.start_game_with_mode("")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Empty string mode rejected"
|
original_mode, game_manager.pending_gameplay_mode, "Empty string mode rejected"
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
game_manager.is_changing_scene, "Scene change flag unchanged after empty mode"
|
game_manager.is_changing_scene, "Scene change flag unchanged after empty mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test null validation - GameManager expects String, so this tests the type safety
|
# Test null validation - GameManager expects String, so this tests the type safety
|
||||||
# Note: In Godot 4.4, passing null to String parameter causes script error as expected
|
# Note: In Godot 4.4, passing null to String parameter causes script error as expected
|
||||||
# The function properly validates empty strings instead
|
# The function properly validates empty strings instead
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after empty string test"
|
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after empty string test"
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
game_manager.is_changing_scene, "Scene change flag unchanged after validation tests"
|
game_manager.is_changing_scene, "Scene change flag unchanged after validation tests"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test invalid mode validation
|
# Test invalid mode validation
|
||||||
game_manager.start_game_with_mode("invalid_mode")
|
game_manager.start_game_with_mode("invalid_mode")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Invalid mode rejected"
|
original_mode, game_manager.pending_gameplay_mode, "Invalid mode rejected"
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
game_manager.is_changing_scene, "Scene change flag unchanged after invalid mode"
|
game_manager.is_changing_scene, "Scene change flag unchanged after invalid mode"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test case sensitivity
|
# Test case sensitivity
|
||||||
game_manager.start_game_with_mode("MATCH3")
|
game_manager.start_game_with_mode("MATCH3")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Case-sensitive mode validation"
|
original_mode, game_manager.pending_gameplay_mode, "Case-sensitive mode validation"
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
game_manager.is_changing_scene, "Scene change flag unchanged after wrong case"
|
game_manager.is_changing_scene, "Scene change flag unchanged after wrong case"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_race_condition_protection():
|
func test_race_condition_protection():
|
||||||
TestHelper.print_step("Race Condition Protection")
|
TestHelperClass.print_step("Race Condition Protection")
|
||||||
|
|
||||||
# Store original state
|
# Store original state
|
||||||
var original_mode = game_manager.pending_gameplay_mode
|
var original_mode = game_manager.pending_gameplay_mode
|
||||||
@@ -156,14 +156,14 @@ func test_race_condition_protection():
|
|||||||
game_manager.start_game_with_mode("match3")
|
game_manager.start_game_with_mode("match3")
|
||||||
|
|
||||||
# Verify second request was rejected
|
# Verify second request was rejected
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Concurrent scene change blocked"
|
original_mode, game_manager.pending_gameplay_mode, "Concurrent scene change blocked"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(game_manager.is_changing_scene, "Scene change flag preserved")
|
TestHelperClass.assert_true(game_manager.is_changing_scene, "Scene change flag preserved")
|
||||||
|
|
||||||
# Test exit to main menu during scene change
|
# Test exit to main menu during scene change
|
||||||
game_manager.exit_to_main_menu()
|
game_manager.exit_to_main_menu()
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
game_manager.is_changing_scene, "Exit request blocked during scene change"
|
game_manager.is_changing_scene, "Exit request blocked during scene change"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -172,28 +172,28 @@ func test_race_condition_protection():
|
|||||||
|
|
||||||
|
|
||||||
func test_gameplay_mode_validation():
|
func test_gameplay_mode_validation():
|
||||||
TestHelper.print_step("Gameplay Mode Validation")
|
TestHelperClass.print_step("Gameplay Mode Validation")
|
||||||
|
|
||||||
# Test valid modes
|
# Test valid modes
|
||||||
var valid_modes = ["match3", "clickomania"]
|
var valid_modes = ["match3", "clickomania"]
|
||||||
for mode in valid_modes:
|
for mode in valid_modes:
|
||||||
var original_changing = game_manager.is_changing_scene
|
var _original_changing = game_manager.is_changing_scene
|
||||||
# We'll test the validation logic without actually changing scenes
|
# We'll test the validation logic without actually changing scenes
|
||||||
# by checking if the function would accept the mode
|
# by checking if the function would accept the mode
|
||||||
|
|
||||||
# Create a temporary mock to test validation
|
# Create a temporary mock to test validation
|
||||||
var test_mode_valid = mode in ["match3", "clickomania"]
|
var test_mode_valid = mode in ["match3", "clickomania"]
|
||||||
TestHelper.assert_true(test_mode_valid, "Valid mode accepted: " + mode)
|
TestHelperClass.assert_true(test_mode_valid, "Valid mode accepted: " + mode)
|
||||||
|
|
||||||
# Test whitelist enforcement
|
# Test whitelist enforcement
|
||||||
var invalid_modes = ["puzzle", "arcade", "adventure", "rpg", "action"]
|
var invalid_modes = ["puzzle", "arcade", "adventure", "rpg", "action"]
|
||||||
for mode in invalid_modes:
|
for mode in invalid_modes:
|
||||||
var test_mode_invalid = not (mode in ["match3", "clickomania"])
|
var test_mode_invalid = not (mode in ["match3", "clickomania"])
|
||||||
TestHelper.assert_true(test_mode_invalid, "Invalid mode rejected: " + mode)
|
TestHelperClass.assert_true(test_mode_invalid, "Invalid mode rejected: " + mode)
|
||||||
|
|
||||||
|
|
||||||
func test_scene_transition_safety():
|
func test_scene_transition_safety():
|
||||||
TestHelper.print_step("Scene Transition Safety")
|
TestHelperClass.print_step("Scene Transition Safety")
|
||||||
|
|
||||||
# Test scene loading validation (without actually changing scenes)
|
# Test scene loading validation (without actually changing scenes)
|
||||||
var game_scene_path = game_manager.GAME_SCENE_PATH
|
var game_scene_path = game_manager.GAME_SCENE_PATH
|
||||||
@@ -201,19 +201,19 @@ func test_scene_transition_safety():
|
|||||||
|
|
||||||
# Test scene resource loading
|
# Test scene resource loading
|
||||||
var game_scene = load(game_scene_path)
|
var game_scene = load(game_scene_path)
|
||||||
TestHelper.assert_not_null(game_scene, "Game scene resource loads successfully")
|
TestHelperClass.assert_not_null(game_scene, "Game scene resource loads successfully")
|
||||||
TestHelper.assert_true(game_scene is PackedScene, "Game scene is PackedScene type")
|
TestHelperClass.assert_true(game_scene is PackedScene, "Game scene is PackedScene type")
|
||||||
|
|
||||||
var main_scene = load(main_scene_path)
|
var main_scene = load(main_scene_path)
|
||||||
TestHelper.assert_not_null(main_scene, "Main scene resource loads successfully")
|
TestHelperClass.assert_not_null(main_scene, "Main scene resource loads successfully")
|
||||||
TestHelper.assert_true(main_scene is PackedScene, "Main scene is PackedScene type")
|
TestHelperClass.assert_true(main_scene is PackedScene, "Main scene is PackedScene type")
|
||||||
|
|
||||||
# Test that current scene exists
|
# Test that current scene exists
|
||||||
TestHelper.assert_not_null(current_scene, "Current scene exists")
|
TestHelperClass.assert_not_null(current_scene, "Current scene exists")
|
||||||
|
|
||||||
|
|
||||||
func test_error_handling():
|
func test_error_handling():
|
||||||
TestHelper.print_step("Error Handling")
|
TestHelperClass.print_step("Error Handling")
|
||||||
|
|
||||||
# Store original state
|
# Store original state
|
||||||
var original_changing = game_manager.is_changing_scene
|
var original_changing = game_manager.is_changing_scene
|
||||||
@@ -225,26 +225,26 @@ func test_error_handling():
|
|||||||
|
|
||||||
# Verify state preservation after invalid inputs
|
# Verify state preservation after invalid inputs
|
||||||
game_manager.start_game_with_mode("")
|
game_manager.start_game_with_mode("")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_changing, game_manager.is_changing_scene, "State preserved after empty mode error"
|
original_changing, game_manager.is_changing_scene, "State preserved after empty mode error"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after empty mode error"
|
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after empty mode error"
|
||||||
)
|
)
|
||||||
|
|
||||||
game_manager.start_game_with_mode("invalid")
|
game_manager.start_game_with_mode("invalid")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_changing,
|
original_changing,
|
||||||
game_manager.is_changing_scene,
|
game_manager.is_changing_scene,
|
||||||
"State preserved after invalid mode error"
|
"State preserved after invalid mode error"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after invalid mode error"
|
original_mode, game_manager.pending_gameplay_mode, "Mode preserved after invalid mode error"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_scene_method_validation():
|
func test_scene_method_validation():
|
||||||
TestHelper.print_step("Scene Method Validation")
|
TestHelperClass.print_step("Scene Method Validation")
|
||||||
|
|
||||||
# Test that GameManager properly checks for required methods
|
# Test that GameManager properly checks for required methods
|
||||||
# We'll create a mock scene to test method validation
|
# We'll create a mock scene to test method validation
|
||||||
@@ -255,16 +255,16 @@ func test_scene_method_validation():
|
|||||||
var has_set_global_score = mock_scene.has_method("set_global_score")
|
var has_set_global_score = mock_scene.has_method("set_global_score")
|
||||||
var has_get_global_score = mock_scene.has_method("get_global_score")
|
var has_get_global_score = mock_scene.has_method("get_global_score")
|
||||||
|
|
||||||
TestHelper.assert_false(has_set_gameplay_mode, "Mock scene lacks set_gameplay_mode method")
|
TestHelperClass.assert_false(has_set_gameplay_mode, "Mock scene lacks set_gameplay_mode method")
|
||||||
TestHelper.assert_false(has_set_global_score, "Mock scene lacks set_global_score method")
|
TestHelperClass.assert_false(has_set_global_score, "Mock scene lacks set_global_score method")
|
||||||
TestHelper.assert_false(has_get_global_score, "Mock scene lacks get_global_score method")
|
TestHelperClass.assert_false(has_get_global_score, "Mock scene lacks get_global_score method")
|
||||||
|
|
||||||
# Clean up mock scene
|
# Clean up mock scene
|
||||||
mock_scene.queue_free()
|
mock_scene.queue_free()
|
||||||
|
|
||||||
|
|
||||||
func test_pending_mode_management():
|
func test_pending_mode_management():
|
||||||
TestHelper.print_step("Pending Mode Management")
|
TestHelperClass.print_step("Pending Mode Management")
|
||||||
|
|
||||||
# Store original mode
|
# Store original mode
|
||||||
var original_mode = game_manager.pending_gameplay_mode
|
var original_mode = game_manager.pending_gameplay_mode
|
||||||
@@ -275,7 +275,7 @@ func test_pending_mode_management():
|
|||||||
if test_mode in ["match3", "clickomania"]:
|
if test_mode in ["match3", "clickomania"]:
|
||||||
# This simulates what would happen in start_game_with_mode
|
# This simulates what would happen in start_game_with_mode
|
||||||
game_manager.pending_gameplay_mode = test_mode
|
game_manager.pending_gameplay_mode = test_mode
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
test_mode, game_manager.pending_gameplay_mode, "Pending mode set correctly"
|
test_mode, game_manager.pending_gameplay_mode, "Pending mode set correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -285,7 +285,7 @@ func test_pending_mode_management():
|
|||||||
|
|
||||||
# Attempt invalid operation (this should not change pending mode)
|
# Attempt invalid operation (this should not change pending mode)
|
||||||
# The actual start_game_with_mode with invalid input won't change pending_gameplay_mode
|
# The actual start_game_with_mode with invalid input won't change pending_gameplay_mode
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
preserved_mode,
|
preserved_mode,
|
||||||
game_manager.pending_gameplay_mode,
|
game_manager.pending_gameplay_mode,
|
||||||
"Mode preserved during invalid operations"
|
"Mode preserved during invalid operations"
|
||||||
@@ -296,7 +296,7 @@ func test_pending_mode_management():
|
|||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Reset GameManager state
|
# Reset GameManager state
|
||||||
game_manager.is_changing_scene = false
|
game_manager.is_changing_scene = false
|
||||||
@@ -308,4 +308,4 @@ func cleanup_tests():
|
|||||||
# Note: Can't actually delete from res:// in tests, just track for manual cleanup
|
# Note: Can't actually delete from res:// in tests, just track for manual cleanup
|
||||||
pass
|
pass
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extends SceneTree
|
|||||||
##
|
##
|
||||||
## Tests grid initialization, match detection, and scoring system.
|
## Tests grid initialization, match detection, and scoring system.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var match3_scene: PackedScene
|
var match3_scene: PackedScene
|
||||||
var match3_instance: Node2D
|
var match3_instance: Node2D
|
||||||
@@ -23,7 +23,7 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("Match3 Gameplay")
|
TestHelperClass.print_test_header("Match3 Gameplay")
|
||||||
|
|
||||||
# Setup test environment
|
# Setup test environment
|
||||||
setup_test_environment()
|
setup_test_environment()
|
||||||
@@ -43,15 +43,15 @@ func run_tests():
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("Match3 Gameplay")
|
TestHelperClass.print_test_footer("Match3 Gameplay")
|
||||||
|
|
||||||
|
|
||||||
func setup_test_environment():
|
func setup_test_environment():
|
||||||
TestHelper.print_step("Test Environment Setup")
|
TestHelperClass.print_step("Test Environment Setup")
|
||||||
|
|
||||||
# Load Match3 scene
|
# Load Match3 scene
|
||||||
match3_scene = load("res://scenes/game/gameplays/match3_gameplay.tscn")
|
match3_scene = load("res://scenes/game/gameplays/match3_gameplay.tscn")
|
||||||
TestHelper.assert_not_null(match3_scene, "Match3 scene loads successfully")
|
TestHelperClass.assert_not_null(match3_scene, "Match3 scene loads successfully")
|
||||||
|
|
||||||
# Create test viewport for isolated testing
|
# Create test viewport for isolated testing
|
||||||
test_viewport = SubViewport.new()
|
test_viewport = SubViewport.new()
|
||||||
@@ -62,7 +62,7 @@ func setup_test_environment():
|
|||||||
if match3_scene:
|
if match3_scene:
|
||||||
match3_instance = match3_scene.instantiate()
|
match3_instance = match3_scene.instantiate()
|
||||||
test_viewport.add_child(match3_instance)
|
test_viewport.add_child(match3_instance)
|
||||||
TestHelper.assert_not_null(match3_instance, "Match3 instance created successfully")
|
TestHelperClass.assert_not_null(match3_instance, "Match3 instance created successfully")
|
||||||
|
|
||||||
# Wait for initialization
|
# Wait for initialization
|
||||||
await process_frame
|
await process_frame
|
||||||
@@ -70,10 +70,10 @@ func setup_test_environment():
|
|||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
TestHelper.assert_true(false, "Match3 instance not available for testing")
|
TestHelperClass.assert_true(false, "Match3 instance not available for testing")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test that Match3 has expected properties
|
# Test that Match3 has expected properties
|
||||||
@@ -81,61 +81,61 @@ func test_basic_functionality():
|
|||||||
"GRID_SIZE", "TILE_TYPES", "grid", "current_state", "selected_tile", "cursor_position"
|
"GRID_SIZE", "TILE_TYPES", "grid", "current_state", "selected_tile", "cursor_position"
|
||||||
]
|
]
|
||||||
for prop in expected_properties:
|
for prop in expected_properties:
|
||||||
TestHelper.assert_true(prop in match3_instance, "Match3 has property: " + prop)
|
TestHelperClass.assert_true(prop in match3_instance, "Match3 has property: " + prop)
|
||||||
|
|
||||||
# Test that Match3 has expected methods
|
# Test that Match3 has expected methods
|
||||||
var expected_methods = [
|
var expected_methods = [
|
||||||
"_has_match_at", "_check_for_matches", "_get_match_line", "_clear_matches"
|
"_has_match_at", "_check_for_matches", "_get_match_line", "_clear_matches"
|
||||||
]
|
]
|
||||||
TestHelper.assert_has_methods(match3_instance, expected_methods, "Match3 gameplay methods")
|
TestHelperClass.assert_has_methods(match3_instance, expected_methods, "Match3 gameplay methods")
|
||||||
|
|
||||||
# Test signals
|
# Test signals
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_signal("score_changed"), "Match3 has score_changed signal"
|
match3_instance.has_signal("score_changed"), "Match3 has score_changed signal"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_signal("grid_state_loaded"), "Match3 has grid_state_loaded signal"
|
match3_instance.has_signal("grid_state_loaded"), "Match3 has grid_state_loaded signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_constants_and_safety_limits():
|
func test_constants_and_safety_limits():
|
||||||
TestHelper.print_step("Constants and Safety Limits")
|
TestHelperClass.print_step("Constants and Safety Limits")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test safety constants exist
|
# Test safety constants exist
|
||||||
TestHelper.assert_true("MAX_GRID_SIZE" in match3_instance, "MAX_GRID_SIZE constant exists")
|
TestHelperClass.assert_true("MAX_GRID_SIZE" in match3_instance, "MAX_GRID_SIZE constant exists")
|
||||||
TestHelper.assert_true("MAX_TILE_TYPES" in match3_instance, "MAX_TILE_TYPES constant exists")
|
TestHelperClass.assert_true("MAX_TILE_TYPES" in match3_instance, "MAX_TILE_TYPES constant exists")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"MAX_CASCADE_ITERATIONS" in match3_instance, "MAX_CASCADE_ITERATIONS constant exists"
|
"MAX_CASCADE_ITERATIONS" in match3_instance, "MAX_CASCADE_ITERATIONS constant exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true("MIN_GRID_SIZE" in match3_instance, "MIN_GRID_SIZE constant exists")
|
TestHelperClass.assert_true("MIN_GRID_SIZE" in match3_instance, "MIN_GRID_SIZE constant exists")
|
||||||
TestHelper.assert_true("MIN_TILE_TYPES" in match3_instance, "MIN_TILE_TYPES constant exists")
|
TestHelperClass.assert_true("MIN_TILE_TYPES" in match3_instance, "MIN_TILE_TYPES constant exists")
|
||||||
|
|
||||||
# Test safety limit values are reasonable
|
# Test safety limit values are reasonable
|
||||||
TestHelper.assert_equal(15, match3_instance.MAX_GRID_SIZE, "MAX_GRID_SIZE is reasonable")
|
TestHelperClass.assert_equal(15, match3_instance.MAX_GRID_SIZE, "MAX_GRID_SIZE is reasonable")
|
||||||
TestHelper.assert_equal(10, match3_instance.MAX_TILE_TYPES, "MAX_TILE_TYPES is reasonable")
|
TestHelperClass.assert_equal(10, match3_instance.MAX_TILE_TYPES, "MAX_TILE_TYPES is reasonable")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
20, match3_instance.MAX_CASCADE_ITERATIONS, "MAX_CASCADE_ITERATIONS prevents infinite loops"
|
20, match3_instance.MAX_CASCADE_ITERATIONS, "MAX_CASCADE_ITERATIONS prevents infinite loops"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(3, match3_instance.MIN_GRID_SIZE, "MIN_GRID_SIZE is reasonable")
|
TestHelperClass.assert_equal(3, match3_instance.MIN_GRID_SIZE, "MIN_GRID_SIZE is reasonable")
|
||||||
TestHelper.assert_equal(3, match3_instance.MIN_TILE_TYPES, "MIN_TILE_TYPES is reasonable")
|
TestHelperClass.assert_equal(3, match3_instance.MIN_TILE_TYPES, "MIN_TILE_TYPES is reasonable")
|
||||||
|
|
||||||
# Test current values are within safety limits
|
# Test current values are within safety limits
|
||||||
TestHelper.assert_in_range(
|
TestHelperClass.assert_in_range(
|
||||||
match3_instance.GRID_SIZE.x,
|
match3_instance.GRID_SIZE.x,
|
||||||
match3_instance.MIN_GRID_SIZE,
|
match3_instance.MIN_GRID_SIZE,
|
||||||
match3_instance.MAX_GRID_SIZE,
|
match3_instance.MAX_GRID_SIZE,
|
||||||
"Grid width within safety limits"
|
"Grid width within safety limits"
|
||||||
)
|
)
|
||||||
TestHelper.assert_in_range(
|
TestHelperClass.assert_in_range(
|
||||||
match3_instance.GRID_SIZE.y,
|
match3_instance.GRID_SIZE.y,
|
||||||
match3_instance.MIN_GRID_SIZE,
|
match3_instance.MIN_GRID_SIZE,
|
||||||
match3_instance.MAX_GRID_SIZE,
|
match3_instance.MAX_GRID_SIZE,
|
||||||
"Grid height within safety limits"
|
"Grid height within safety limits"
|
||||||
)
|
)
|
||||||
TestHelper.assert_in_range(
|
TestHelperClass.assert_in_range(
|
||||||
match3_instance.TILE_TYPES,
|
match3_instance.TILE_TYPES,
|
||||||
match3_instance.MIN_TILE_TYPES,
|
match3_instance.MIN_TILE_TYPES,
|
||||||
match3_instance.MAX_TILE_TYPES,
|
match3_instance.MAX_TILE_TYPES,
|
||||||
@@ -143,37 +143,37 @@ func test_constants_and_safety_limits():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Test timing constants
|
# Test timing constants
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"CASCADE_WAIT_TIME" in match3_instance, "CASCADE_WAIT_TIME constant exists"
|
"CASCADE_WAIT_TIME" in match3_instance, "CASCADE_WAIT_TIME constant exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"SWAP_ANIMATION_TIME" in match3_instance, "SWAP_ANIMATION_TIME constant exists"
|
"SWAP_ANIMATION_TIME" in match3_instance, "SWAP_ANIMATION_TIME constant exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"TILE_DROP_WAIT_TIME" in match3_instance, "TILE_DROP_WAIT_TIME constant exists"
|
"TILE_DROP_WAIT_TIME" in match3_instance, "TILE_DROP_WAIT_TIME constant exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_grid_initialization():
|
func test_grid_initialization():
|
||||||
TestHelper.print_step("Grid Initialization")
|
TestHelperClass.print_step("Grid Initialization")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test grid structure
|
# Test grid structure
|
||||||
TestHelper.assert_not_null(match3_instance.grid, "Grid array is initialized")
|
TestHelperClass.assert_not_null(match3_instance.grid, "Grid array is initialized")
|
||||||
TestHelper.assert_true(match3_instance.grid is Array, "Grid is Array type")
|
TestHelperClass.assert_true(match3_instance.grid is Array, "Grid is Array type")
|
||||||
|
|
||||||
# Test grid dimensions
|
# Test grid dimensions
|
||||||
var expected_height = match3_instance.GRID_SIZE.y
|
var expected_height = match3_instance.GRID_SIZE.y
|
||||||
var expected_width = match3_instance.GRID_SIZE.x
|
var expected_width = match3_instance.GRID_SIZE.x
|
||||||
|
|
||||||
TestHelper.assert_equal(expected_height, match3_instance.grid.size(), "Grid has correct height")
|
TestHelperClass.assert_equal(expected_height, match3_instance.grid.size(), "Grid has correct height")
|
||||||
|
|
||||||
# Test each row has correct width
|
# Test each row has correct width
|
||||||
for y in range(match3_instance.grid.size()):
|
for y in range(match3_instance.grid.size()):
|
||||||
if y < expected_height:
|
if y < expected_height:
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
expected_width, match3_instance.grid[y].size(), "Grid row %d has correct width" % y
|
expected_width, match3_instance.grid[y].size(), "Grid row %d has correct width" % y
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -188,89 +188,89 @@ func test_grid_initialization():
|
|||||||
|
|
||||||
if tile and is_instance_valid(tile):
|
if tile and is_instance_valid(tile):
|
||||||
valid_tile_count += 1
|
valid_tile_count += 1
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"tile_type" in tile, "Tile at (%d,%d) has tile_type property" % [x, y]
|
"tile_type" in tile, "Tile at (%d,%d) has tile_type property" % [x, y]
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"grid_position" in tile, "Tile at (%d,%d) has grid_position property" % [x, y]
|
"grid_position" in tile, "Tile at (%d,%d) has grid_position property" % [x, y]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test tile type is within valid range
|
# Test tile type is within valid range
|
||||||
if "tile_type" in tile:
|
if "tile_type" in tile:
|
||||||
TestHelper.assert_in_range(
|
TestHelperClass.assert_in_range(
|
||||||
tile.tile_type,
|
tile.tile_type,
|
||||||
0,
|
0,
|
||||||
match3_instance.TILE_TYPES - 1,
|
match3_instance.TILE_TYPES - 1,
|
||||||
"Tile type in valid range"
|
"Tile type in valid range"
|
||||||
)
|
)
|
||||||
|
|
||||||
TestHelper.assert_equal(tile_count, valid_tile_count, "All grid positions have valid tiles")
|
TestHelperClass.assert_equal(tile_count, valid_tile_count, "All grid positions have valid tiles")
|
||||||
|
|
||||||
|
|
||||||
func test_grid_layout_calculation():
|
func test_grid_layout_calculation():
|
||||||
TestHelper.print_step("Grid Layout Calculation")
|
TestHelperClass.print_step("Grid Layout Calculation")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test tile size calculation
|
# Test tile size calculation
|
||||||
TestHelper.assert_true(match3_instance.tile_size > 0, "Tile size is positive")
|
TestHelperClass.assert_true(match3_instance.tile_size > 0, "Tile size is positive")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.tile_size <= 200, "Tile size is reasonable (not too large)"
|
match3_instance.tile_size <= 200, "Tile size is reasonable (not too large)"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test grid offset
|
# Test grid offset
|
||||||
TestHelper.assert_not_null(match3_instance.grid_offset, "Grid offset is set")
|
TestHelperClass.assert_not_null(match3_instance.grid_offset, "Grid offset is set")
|
||||||
TestHelper.assert_true(match3_instance.grid_offset.x >= 0, "Grid offset X is non-negative")
|
TestHelperClass.assert_true(match3_instance.grid_offset.x >= 0, "Grid offset X is non-negative")
|
||||||
TestHelper.assert_true(match3_instance.grid_offset.y >= 0, "Grid offset Y is non-negative")
|
TestHelperClass.assert_true(match3_instance.grid_offset.y >= 0, "Grid offset Y is non-negative")
|
||||||
|
|
||||||
# Test layout constants
|
# Test layout constants
|
||||||
TestHelper.assert_equal(0.8, match3_instance.SCREEN_WIDTH_USAGE, "Screen width usage constant")
|
TestHelperClass.assert_equal(0.8, match3_instance.SCREEN_WIDTH_USAGE, "Screen width usage constant")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
0.7, match3_instance.SCREEN_HEIGHT_USAGE, "Screen height usage constant"
|
0.7, match3_instance.SCREEN_HEIGHT_USAGE, "Screen height usage constant"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(50.0, match3_instance.GRID_LEFT_MARGIN, "Grid left margin constant")
|
TestHelperClass.assert_equal(50.0, match3_instance.GRID_LEFT_MARGIN, "Grid left margin constant")
|
||||||
TestHelper.assert_equal(50.0, match3_instance.GRID_TOP_MARGIN, "Grid top margin constant")
|
TestHelperClass.assert_equal(50.0, match3_instance.GRID_TOP_MARGIN, "Grid top margin constant")
|
||||||
|
|
||||||
|
|
||||||
func test_state_management():
|
func test_state_management():
|
||||||
TestHelper.print_step("State Management")
|
TestHelperClass.print_step("State Management")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test GameState enum exists and has expected values
|
# Test GameState enum exists and has expected values
|
||||||
var game_state_class = match3_instance.get_script().get_global_class()
|
var _game_state_class = match3_instance.get_script().get_global_class()
|
||||||
TestHelper.assert_true("GameState" in match3_instance, "GameState enum accessible")
|
TestHelperClass.assert_true("GameState" in match3_instance, "GameState enum accessible")
|
||||||
|
|
||||||
# Test current state is valid
|
# Test current state is valid
|
||||||
TestHelper.assert_not_null(match3_instance.current_state, "Current state is set")
|
TestHelperClass.assert_not_null(match3_instance.current_state, "Current state is set")
|
||||||
|
|
||||||
# Test initialization flags
|
# Test initialization flags
|
||||||
TestHelper.assert_true("grid_initialized" in match3_instance, "Grid initialized flag exists")
|
TestHelperClass.assert_true("grid_initialized" in match3_instance, "Grid initialized flag exists")
|
||||||
TestHelper.assert_true(match3_instance.grid_initialized, "Grid is marked as initialized")
|
TestHelperClass.assert_true(match3_instance.grid_initialized, "Grid is marked as initialized")
|
||||||
|
|
||||||
# Test instance ID for debugging
|
# Test instance ID for debugging
|
||||||
TestHelper.assert_true("instance_id" in match3_instance, "Instance ID exists for debugging")
|
TestHelperClass.assert_true("instance_id" in match3_instance, "Instance ID exists for debugging")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.instance_id.begins_with("Match3_"), "Instance ID has correct format"
|
match3_instance.instance_id.begins_with("Match3_"), "Instance ID has correct format"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_match_detection():
|
func test_match_detection():
|
||||||
TestHelper.print_step("Match Detection Logic")
|
TestHelperClass.print_step("Match Detection Logic")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test match detection methods exist and can be called safely
|
# Test match detection methods exist and can be called safely
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_has_match_at"), "_has_match_at method exists"
|
match3_instance.has_method("_has_match_at"), "_has_match_at method exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_check_for_matches"), "_check_for_matches method exists"
|
match3_instance.has_method("_check_for_matches"), "_check_for_matches method exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_get_match_line"), "_get_match_line method exists"
|
match3_instance.has_method("_get_match_line"), "_get_match_line method exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -285,20 +285,20 @@ func test_match_detection():
|
|||||||
|
|
||||||
for pos in invalid_positions:
|
for pos in invalid_positions:
|
||||||
var result = match3_instance._has_match_at(pos)
|
var result = match3_instance._has_match_at(pos)
|
||||||
TestHelper.assert_false(result, "Invalid position (%d,%d) returns false" % [pos.x, pos.y])
|
TestHelperClass.assert_false(result, "Invalid position (%d,%d) returns false" % [pos.x, pos.y])
|
||||||
|
|
||||||
# Test valid positions don't crash
|
# Test valid positions don't crash
|
||||||
for y in range(min(3, match3_instance.GRID_SIZE.y)):
|
for y in range(min(3, match3_instance.GRID_SIZE.y)):
|
||||||
for x in range(min(3, match3_instance.GRID_SIZE.x)):
|
for x in range(min(3, match3_instance.GRID_SIZE.x)):
|
||||||
var pos = Vector2i(x, y)
|
var pos = Vector2i(x, y)
|
||||||
var result = match3_instance._has_match_at(pos)
|
var result = match3_instance._has_match_at(pos)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
result is bool, "Valid position (%d,%d) returns boolean" % [x, y]
|
result is bool, "Valid position (%d,%d) returns boolean" % [x, y]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_scoring_system():
|
func test_scoring_system():
|
||||||
TestHelper.print_step("Scoring System")
|
TestHelperClass.print_step("Scoring System")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
@@ -307,12 +307,12 @@ func test_scoring_system():
|
|||||||
# The scoring system uses: 3 gems = 3 points, 4+ gems = n + (n-2) points
|
# The scoring system uses: 3 gems = 3 points, 4+ gems = n + (n-2) points
|
||||||
|
|
||||||
# Test that the match3 instance can handle scoring (indirectly through clearing matches)
|
# Test that the match3 instance can handle scoring (indirectly through clearing matches)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_clear_matches"), "Scoring system method exists"
|
match3_instance.has_method("_clear_matches"), "Scoring system method exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that score_changed signal exists
|
# Test that score_changed signal exists
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_signal("score_changed"), "Score changed signal exists"
|
match3_instance.has_signal("score_changed"), "Score changed signal exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -327,47 +327,47 @@ func test_scoring_system():
|
|||||||
else:
|
else:
|
||||||
calculated_score = match_size + max(0, match_size - 2)
|
calculated_score = match_size + max(0, match_size - 2)
|
||||||
|
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
expected_score, calculated_score, "Scoring formula correct for %d gems" % match_size
|
expected_score, calculated_score, "Scoring formula correct for %d gems" % match_size
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_input_validation():
|
func test_input_validation():
|
||||||
TestHelper.print_step("Input Validation")
|
TestHelperClass.print_step("Input Validation")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test cursor position bounds
|
# Test cursor position bounds
|
||||||
TestHelper.assert_not_null(match3_instance.cursor_position, "Cursor position is initialized")
|
TestHelperClass.assert_not_null(match3_instance.cursor_position, "Cursor position is initialized")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.cursor_position is Vector2i, "Cursor position is Vector2i type"
|
match3_instance.cursor_position is Vector2i, "Cursor position is Vector2i type"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test keyboard navigation flag
|
# Test keyboard navigation flag
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
"keyboard_navigation_enabled" in match3_instance, "Keyboard navigation flag exists"
|
"keyboard_navigation_enabled" in match3_instance, "Keyboard navigation flag exists"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.keyboard_navigation_enabled is bool, "Keyboard navigation flag is boolean"
|
match3_instance.keyboard_navigation_enabled is bool, "Keyboard navigation flag is boolean"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test selected tile safety
|
# Test selected tile safety
|
||||||
# selected_tile can be null initially, which is valid
|
# selected_tile can be null initially, which is valid
|
||||||
if match3_instance.selected_tile:
|
if match3_instance.selected_tile:
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
is_instance_valid(match3_instance.selected_tile), "Selected tile is valid if not null"
|
is_instance_valid(match3_instance.selected_tile), "Selected tile is valid if not null"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_memory_safety():
|
func test_memory_safety():
|
||||||
TestHelper.print_step("Memory Safety")
|
TestHelperClass.print_step("Memory Safety")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test grid integrity validation
|
# Test grid integrity validation
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_validate_grid_integrity"),
|
match3_instance.has_method("_validate_grid_integrity"),
|
||||||
"Grid integrity validation method exists"
|
"Grid integrity validation method exists"
|
||||||
)
|
)
|
||||||
@@ -377,63 +377,63 @@ func test_memory_safety():
|
|||||||
for x in range(min(3, match3_instance.grid[y].size())):
|
for x in range(min(3, match3_instance.grid[y].size())):
|
||||||
var tile = match3_instance.grid[y][x]
|
var tile = match3_instance.grid[y][x]
|
||||||
if tile:
|
if tile:
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
is_instance_valid(tile), "Grid tile at (%d,%d) is valid instance" % [x, y]
|
is_instance_valid(tile), "Grid tile at (%d,%d) is valid instance" % [x, y]
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile.get_parent() == match3_instance, "Tile properly parented to Match3"
|
tile.get_parent() == match3_instance, "Tile properly parented to Match3"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test position validation
|
# Test position validation
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.has_method("_is_valid_grid_position"), "Position validation method exists"
|
match3_instance.has_method("_is_valid_grid_position"), "Position validation method exists"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test safe tile access patterns exist
|
# Test safe tile access patterns exist
|
||||||
# The Match3 code uses comprehensive bounds checking and null validation
|
# The Match3 code uses comprehensive bounds checking and null validation
|
||||||
TestHelper.assert_true(true, "Memory safety patterns implemented in Match3 code")
|
TestHelperClass.assert_true(true, "Memory safety patterns implemented in Match3 code")
|
||||||
|
|
||||||
|
|
||||||
func test_performance_requirements():
|
func test_performance_requirements():
|
||||||
TestHelper.print_step("Performance Requirements")
|
TestHelperClass.print_step("Performance Requirements")
|
||||||
|
|
||||||
if not match3_instance:
|
if not match3_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test grid size is within performance limits
|
# Test grid size is within performance limits
|
||||||
var total_tiles = match3_instance.GRID_SIZE.x * match3_instance.GRID_SIZE.y
|
var total_tiles = match3_instance.GRID_SIZE.x * match3_instance.GRID_SIZE.y
|
||||||
TestHelper.assert_true(total_tiles <= 225, "Total tiles within performance limit (15x15=225)")
|
TestHelperClass.assert_true(total_tiles <= 225, "Total tiles within performance limit (15x15=225)")
|
||||||
|
|
||||||
# Test cascade iteration limit prevents infinite loops
|
# Test cascade iteration limit prevents infinite loops
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
20,
|
20,
|
||||||
match3_instance.MAX_CASCADE_ITERATIONS,
|
match3_instance.MAX_CASCADE_ITERATIONS,
|
||||||
"Cascade iteration limit prevents infinite loops"
|
"Cascade iteration limit prevents infinite loops"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test timing constants are reasonable for 60fps gameplay
|
# Test timing constants are reasonable for 60fps gameplay
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.CASCADE_WAIT_TIME >= 0.05, "Cascade wait time allows for smooth animation"
|
match3_instance.CASCADE_WAIT_TIME >= 0.05, "Cascade wait time allows for smooth animation"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.SWAP_ANIMATION_TIME <= 0.5, "Swap animation time is responsive"
|
match3_instance.SWAP_ANIMATION_TIME <= 0.5, "Swap animation time is responsive"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
match3_instance.TILE_DROP_WAIT_TIME <= 0.3, "Tile drop wait time is responsive"
|
match3_instance.TILE_DROP_WAIT_TIME <= 0.3, "Tile drop wait time is responsive"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test grid initialization performance
|
# Test grid initialization performance
|
||||||
TestHelper.start_performance_test("grid_access")
|
TestHelperClass.start_performance_test("grid_access")
|
||||||
for y in range(min(5, match3_instance.grid.size())):
|
for y in range(min(5, match3_instance.grid.size())):
|
||||||
for x in range(min(5, match3_instance.grid[y].size())):
|
for x in range(min(5, match3_instance.grid[y].size())):
|
||||||
var tile = match3_instance.grid[y][x]
|
var tile = match3_instance.grid[y][x]
|
||||||
if tile and "tile_type" in tile:
|
if tile and "tile_type" in tile:
|
||||||
var tile_type = tile.tile_type
|
var _tile_type = tile.tile_type
|
||||||
TestHelper.end_performance_test("grid_access", 10.0, "Grid access performance within limits")
|
TestHelperClass.end_performance_test("grid_access", 10.0, "Grid access performance within limits")
|
||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Clean up Match3 instance
|
# Clean up Match3 instance
|
||||||
if match3_instance and is_instance_valid(match3_instance):
|
if match3_instance and is_instance_valid(match3_instance):
|
||||||
@@ -446,4 +446,4 @@ func cleanup_tests():
|
|||||||
# Wait for cleanup
|
# Wait for cleanup
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ extends SceneTree
|
|||||||
# Test to verify that existing save files with old checksum format can be migrated
|
# Test to verify that existing save files with old checksum format can be migrated
|
||||||
# This ensures backward compatibility with the checksum fix
|
# This ensures backward compatibility with the checksum fix
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
|
|
||||||
func _initialize():
|
func _initialize():
|
||||||
@@ -18,13 +18,13 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("Migration Compatibility")
|
TestHelperClass.print_test_header("Migration Compatibility")
|
||||||
test_migration_compatibility()
|
test_migration_compatibility()
|
||||||
TestHelper.print_test_footer("Migration Compatibility")
|
TestHelperClass.print_test_footer("Migration Compatibility")
|
||||||
|
|
||||||
|
|
||||||
func test_migration_compatibility():
|
func test_migration_compatibility():
|
||||||
TestHelper.print_step("Old Save File Compatibility")
|
TestHelperClass.print_step("Old Save File Compatibility")
|
||||||
var old_save_data = {
|
var old_save_data = {
|
||||||
"_version": 1,
|
"_version": 1,
|
||||||
"high_score": 150,
|
"high_score": 150,
|
||||||
@@ -57,13 +57,13 @@ func test_migration_compatibility():
|
|||||||
print("New checksum format: %s" % new_checksum)
|
print("New checksum format: %s" % new_checksum)
|
||||||
|
|
||||||
# The checksums should be different (old system broken)
|
# The checksums should be different (old system broken)
|
||||||
TestHelper.assert_not_equal(
|
TestHelperClass.assert_not_equal(
|
||||||
old_checksum, new_checksum, "Old and new checksum formats should be different"
|
old_checksum, new_checksum, "Old and new checksum formats should be different"
|
||||||
)
|
)
|
||||||
print("Old checksum: %s" % old_checksum)
|
print("Old checksum: %s" % old_checksum)
|
||||||
print("New checksum: %s" % new_checksum)
|
print("New checksum: %s" % new_checksum)
|
||||||
|
|
||||||
TestHelper.print_step("New System Self-Consistency")
|
TestHelperClass.print_step("New System Self-Consistency")
|
||||||
# Remove old checksum and recalculate
|
# Remove old checksum and recalculate
|
||||||
loaded_data.erase("_checksum")
|
loaded_data.erase("_checksum")
|
||||||
var first_checksum = _calculate_new_checksum(loaded_data)
|
var first_checksum = _calculate_new_checksum(loaded_data)
|
||||||
@@ -77,15 +77,15 @@ func test_migration_compatibility():
|
|||||||
|
|
||||||
var second_checksum = _calculate_new_checksum(reloaded_data)
|
var second_checksum = _calculate_new_checksum(reloaded_data)
|
||||||
|
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
first_checksum,
|
first_checksum,
|
||||||
second_checksum,
|
second_checksum,
|
||||||
"New system should be self-consistent across save/load cycles"
|
"New system should be self-consistent across save/load cycles"
|
||||||
)
|
)
|
||||||
print("Consistent checksum: %s" % first_checksum)
|
print("Consistent checksum: %s" % first_checksum)
|
||||||
|
|
||||||
TestHelper.print_step("Migration Strategy Verification")
|
TestHelperClass.print_step("Migration Strategy Verification")
|
||||||
TestHelper.assert_true(true, "Version-based checksum handling implemented")
|
TestHelperClass.assert_true(true, "Version-based checksum handling implemented")
|
||||||
print("✓ Files without _checksum: Allow (backward compatibility)")
|
print("✓ Files without _checksum: Allow (backward compatibility)")
|
||||||
print("✓ Files with version < current: Recalculate checksum after migration")
|
print("✓ Files with version < current: Recalculate checksum after migration")
|
||||||
print("✓ Files with current version: Use new checksum validation")
|
print("✓ Files with current version: Use new checksum validation")
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ extends SceneTree
|
|||||||
## Validates all .tscn files in the project for loading and instantiation errors.
|
## Validates all .tscn files in the project for loading and instantiation errors.
|
||||||
## Provides comprehensive scene validation to catch issues before runtime.
|
## Provides comprehensive scene validation to catch issues before runtime.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var discovered_scenes: Array[String] = []
|
var discovered_scenes: Array[String] = []
|
||||||
var validation_results: Dictionary = {}
|
var validation_results: Dictionary = {}
|
||||||
@@ -23,7 +23,7 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("Scene Validation")
|
TestHelperClass.print_test_header("Scene Validation")
|
||||||
|
|
||||||
# Run test suites
|
# Run test suites
|
||||||
test_scene_discovery()
|
test_scene_discovery()
|
||||||
@@ -34,11 +34,11 @@ func run_tests():
|
|||||||
# Print final summary
|
# Print final summary
|
||||||
print_validation_summary()
|
print_validation_summary()
|
||||||
|
|
||||||
TestHelper.print_test_footer("Scene Validation")
|
TestHelperClass.print_test_footer("Scene Validation")
|
||||||
|
|
||||||
|
|
||||||
func test_scene_discovery():
|
func test_scene_discovery():
|
||||||
TestHelper.print_step("Scene Discovery")
|
TestHelperClass.print_step("Scene Discovery")
|
||||||
|
|
||||||
# Discover scenes in key directories
|
# Discover scenes in key directories
|
||||||
var scene_directories = ["res://scenes/", "res://examples/"]
|
var scene_directories = ["res://scenes/", "res://examples/"]
|
||||||
@@ -46,7 +46,7 @@ func test_scene_discovery():
|
|||||||
for directory in scene_directories:
|
for directory in scene_directories:
|
||||||
discover_scenes_in_directory(directory)
|
discover_scenes_in_directory(directory)
|
||||||
|
|
||||||
TestHelper.assert_true(discovered_scenes.size() > 0, "Found scenes in project")
|
TestHelperClass.assert_true(discovered_scenes.size() > 0, "Found scenes in project")
|
||||||
print("Discovered %d scene files" % discovered_scenes.size())
|
print("Discovered %d scene files" % discovered_scenes.size())
|
||||||
|
|
||||||
# List discovered scenes for reference
|
# List discovered scenes for reference
|
||||||
@@ -77,7 +77,7 @@ func discover_scenes_in_directory(directory_path: String):
|
|||||||
|
|
||||||
|
|
||||||
func test_scene_loading():
|
func test_scene_loading():
|
||||||
TestHelper.print_step("Scene Loading Validation")
|
TestHelperClass.print_step("Scene Loading Validation")
|
||||||
|
|
||||||
for scene_path in discovered_scenes:
|
for scene_path in discovered_scenes:
|
||||||
validate_scene_loading(scene_path)
|
validate_scene_loading(scene_path)
|
||||||
@@ -89,27 +89,27 @@ func validate_scene_loading(scene_path: String):
|
|||||||
# Check if resource exists
|
# Check if resource exists
|
||||||
if not ResourceLoader.exists(scene_path):
|
if not ResourceLoader.exists(scene_path):
|
||||||
validation_results[scene_path] = "Resource does not exist"
|
validation_results[scene_path] = "Resource does not exist"
|
||||||
TestHelper.assert_false(true, "%s - Resource does not exist" % scene_name)
|
TestHelperClass.assert_false(true, "%s - Resource does not exist" % scene_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Attempt to load the scene
|
# Attempt to load the scene
|
||||||
var packed_scene = load(scene_path)
|
var packed_scene = load(scene_path)
|
||||||
if not packed_scene:
|
if not packed_scene:
|
||||||
validation_results[scene_path] = "Failed to load scene"
|
validation_results[scene_path] = "Failed to load scene"
|
||||||
TestHelper.assert_false(true, "%s - Failed to load scene" % scene_name)
|
TestHelperClass.assert_false(true, "%s - Failed to load scene" % scene_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not packed_scene is PackedScene:
|
if not packed_scene is PackedScene:
|
||||||
validation_results[scene_path] = "Resource is not a PackedScene"
|
validation_results[scene_path] = "Resource is not a PackedScene"
|
||||||
TestHelper.assert_false(true, "%s - Resource is not a PackedScene" % scene_name)
|
TestHelperClass.assert_false(true, "%s - Resource is not a PackedScene" % scene_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
validation_results[scene_path] = "Loading successful"
|
validation_results[scene_path] = "Loading successful"
|
||||||
TestHelper.assert_true(true, "%s - Scene loads successfully" % scene_name)
|
TestHelperClass.assert_true(true, "%s - Scene loads successfully" % scene_name)
|
||||||
|
|
||||||
|
|
||||||
func test_scene_instantiation():
|
func test_scene_instantiation():
|
||||||
TestHelper.print_step("Scene Instantiation Testing")
|
TestHelperClass.print_step("Scene Instantiation Testing")
|
||||||
|
|
||||||
for scene_path in discovered_scenes:
|
for scene_path in discovered_scenes:
|
||||||
# Only test instantiation for scenes that loaded successfully
|
# Only test instantiation for scenes that loaded successfully
|
||||||
@@ -127,11 +127,11 @@ func validate_scene_instantiation(scene_path: String):
|
|||||||
var scene_instance = packed_scene.instantiate()
|
var scene_instance = packed_scene.instantiate()
|
||||||
if not scene_instance:
|
if not scene_instance:
|
||||||
validation_results[scene_path] = "Failed to instantiate scene"
|
validation_results[scene_path] = "Failed to instantiate scene"
|
||||||
TestHelper.assert_false(true, "%s - Failed to instantiate scene" % scene_name)
|
TestHelperClass.assert_false(true, "%s - Failed to instantiate scene" % scene_name)
|
||||||
return
|
return
|
||||||
|
|
||||||
# Validate the instance
|
# Validate the instance
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
scene_instance, "%s - Scene instantiation creates valid node" % scene_name
|
scene_instance, "%s - Scene instantiation creates valid node" % scene_name
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ func validate_scene_instantiation(scene_path: String):
|
|||||||
|
|
||||||
|
|
||||||
func test_critical_scenes():
|
func test_critical_scenes():
|
||||||
TestHelper.print_step("Critical Scene Validation")
|
TestHelperClass.print_step("Critical Scene Validation")
|
||||||
|
|
||||||
# Define critical scenes that must work
|
# Define critical scenes that must work
|
||||||
var critical_scenes = [
|
var critical_scenes = [
|
||||||
@@ -157,13 +157,13 @@ func test_critical_scenes():
|
|||||||
for scene_path in critical_scenes:
|
for scene_path in critical_scenes:
|
||||||
if scene_path in discovered_scenes:
|
if scene_path in discovered_scenes:
|
||||||
var status = validation_results.get(scene_path, "Unknown")
|
var status = validation_results.get(scene_path, "Unknown")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"Full validation successful",
|
"Full validation successful",
|
||||||
status,
|
status,
|
||||||
"Critical scene %s must pass all validation" % scene_path.get_file()
|
"Critical scene %s must pass all validation" % scene_path.get_file()
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
TestHelper.assert_false(true, "Critical scene missing: %s" % scene_path)
|
TestHelperClass.assert_false(true, "Critical scene missing: %s" % scene_path)
|
||||||
|
|
||||||
|
|
||||||
func print_validation_summary():
|
func print_validation_summary():
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extends SceneTree
|
|||||||
##
|
##
|
||||||
## Tests input validation, file I/O, and error handling.
|
## Tests input validation, file I/O, and error handling.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var settings_manager: Node
|
var settings_manager: Node
|
||||||
var original_settings: Dictionary
|
var original_settings: Dictionary
|
||||||
@@ -23,13 +23,13 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("SettingsManager")
|
TestHelperClass.print_test_header("SettingsManager")
|
||||||
|
|
||||||
# Get reference to SettingsManager
|
# Get reference to SettingsManager
|
||||||
settings_manager = root.get_node("SettingsManager")
|
settings_manager = root.get_node("SettingsManager")
|
||||||
if not settings_manager:
|
if not settings_manager:
|
||||||
TestHelper.assert_true(false, "SettingsManager autoload not found")
|
TestHelperClass.assert_true(false, "SettingsManager autoload not found")
|
||||||
TestHelper.print_test_footer("SettingsManager")
|
TestHelperClass.print_test_footer("SettingsManager")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Store original settings for restoration
|
# Store original settings for restoration
|
||||||
@@ -49,14 +49,14 @@ func run_tests():
|
|||||||
# Cleanup and restore original state
|
# Cleanup and restore original state
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("SettingsManager")
|
TestHelperClass.print_test_footer("SettingsManager")
|
||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
# Test that SettingsManager has expected properties
|
# Test that SettingsManager has expected properties
|
||||||
TestHelper.assert_has_properties(
|
TestHelperClass.assert_has_properties(
|
||||||
settings_manager,
|
settings_manager,
|
||||||
["settings", "default_settings", "languages_data"],
|
["settings", "default_settings", "languages_data"],
|
||||||
"SettingsManager properties"
|
"SettingsManager properties"
|
||||||
@@ -66,66 +66,66 @@ func test_basic_functionality():
|
|||||||
var expected_methods = [
|
var expected_methods = [
|
||||||
"get_setting", "set_setting", "save_settings", "load_settings", "reset_settings_to_defaults"
|
"get_setting", "set_setting", "save_settings", "load_settings", "reset_settings_to_defaults"
|
||||||
]
|
]
|
||||||
TestHelper.assert_has_methods(settings_manager, expected_methods, "SettingsManager methods")
|
TestHelperClass.assert_has_methods(settings_manager, expected_methods, "SettingsManager methods")
|
||||||
|
|
||||||
# Test default settings structure
|
# Test default settings structure
|
||||||
var expected_defaults = ["master_volume", "music_volume", "sfx_volume", "language"]
|
var expected_defaults = ["master_volume", "music_volume", "sfx_volume", "language"]
|
||||||
for key in expected_defaults:
|
for key in expected_defaults:
|
||||||
TestHelper.assert_has_key(
|
TestHelperClass.assert_has_key(
|
||||||
settings_manager.default_settings, key, "Default setting key: " + key
|
settings_manager.default_settings, key, "Default setting key: " + key
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test getting settings
|
# Test getting settings
|
||||||
var master_volume = settings_manager.get_setting("master_volume")
|
var master_volume = settings_manager.get_setting("master_volume")
|
||||||
TestHelper.assert_not_null(master_volume, "Can get master_volume setting")
|
TestHelperClass.assert_not_null(master_volume, "Can get master_volume setting")
|
||||||
TestHelper.assert_true(master_volume is float, "master_volume is float type")
|
TestHelperClass.assert_true(master_volume is float, "master_volume is float type")
|
||||||
|
|
||||||
|
|
||||||
func test_input_validation_security():
|
func test_input_validation_security():
|
||||||
TestHelper.print_step("Input Validation Security")
|
TestHelperClass.print_step("Input Validation Security")
|
||||||
|
|
||||||
# Test NaN validation
|
# Test NaN validation
|
||||||
var nan_result = settings_manager.set_setting("master_volume", NAN)
|
var nan_result = settings_manager.set_setting("master_volume", NAN)
|
||||||
TestHelper.assert_false(nan_result, "NaN values rejected for volume settings")
|
TestHelperClass.assert_false(nan_result, "NaN values rejected for volume settings")
|
||||||
|
|
||||||
# Test Infinity validation
|
# Test Infinity validation
|
||||||
var inf_result = settings_manager.set_setting("master_volume", INF)
|
var inf_result = settings_manager.set_setting("master_volume", INF)
|
||||||
TestHelper.assert_false(inf_result, "Infinity values rejected for volume settings")
|
TestHelperClass.assert_false(inf_result, "Infinity values rejected for volume settings")
|
||||||
|
|
||||||
# Test negative infinity validation
|
# Test negative infinity validation
|
||||||
var neg_inf_result = settings_manager.set_setting("master_volume", -INF)
|
var neg_inf_result = settings_manager.set_setting("master_volume", -INF)
|
||||||
TestHelper.assert_false(neg_inf_result, "Negative infinity values rejected")
|
TestHelperClass.assert_false(neg_inf_result, "Negative infinity values rejected")
|
||||||
|
|
||||||
# Test range validation for volumes
|
# Test range validation for volumes
|
||||||
var negative_volume = settings_manager.set_setting("master_volume", -0.5)
|
var negative_volume = settings_manager.set_setting("master_volume", -0.5)
|
||||||
TestHelper.assert_false(negative_volume, "Negative volume values rejected")
|
TestHelperClass.assert_false(negative_volume, "Negative volume values rejected")
|
||||||
|
|
||||||
var excessive_volume = settings_manager.set_setting("master_volume", 1.5)
|
var excessive_volume = settings_manager.set_setting("master_volume", 1.5)
|
||||||
TestHelper.assert_false(excessive_volume, "Volume values > 1.0 rejected")
|
TestHelperClass.assert_false(excessive_volume, "Volume values > 1.0 rejected")
|
||||||
|
|
||||||
# Test valid volume range
|
# Test valid volume range
|
||||||
var valid_volume = settings_manager.set_setting("master_volume", 0.5)
|
var valid_volume = settings_manager.set_setting("master_volume", 0.5)
|
||||||
TestHelper.assert_true(valid_volume, "Valid volume values accepted")
|
TestHelperClass.assert_true(valid_volume, "Valid volume values accepted")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
0.5, settings_manager.get_setting("master_volume"), "Volume value set correctly"
|
0.5, settings_manager.get_setting("master_volume"), "Volume value set correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test string length validation for language
|
# Test string length validation for language
|
||||||
var long_language = "a".repeat(20) # Exceeds MAX_SETTING_STRING_LENGTH
|
var long_language = "a".repeat(20) # Exceeds MAX_SETTING_STRING_LENGTH
|
||||||
var long_lang_result = settings_manager.set_setting("language", long_language)
|
var long_lang_result = settings_manager.set_setting("language", long_language)
|
||||||
TestHelper.assert_false(long_lang_result, "Excessively long language codes rejected")
|
TestHelperClass.assert_false(long_lang_result, "Excessively long language codes rejected")
|
||||||
|
|
||||||
# Test invalid characters in language code
|
# Test invalid characters in language code
|
||||||
var invalid_chars = settings_manager.set_setting("language", "en<script>")
|
var invalid_chars = settings_manager.set_setting("language", "en<script>")
|
||||||
TestHelper.assert_false(invalid_chars, "Language codes with invalid characters rejected")
|
TestHelperClass.assert_false(invalid_chars, "Language codes with invalid characters rejected")
|
||||||
|
|
||||||
# Test valid language code
|
# Test valid language code
|
||||||
var valid_lang = settings_manager.set_setting("language", "en")
|
var valid_lang = settings_manager.set_setting("language", "en")
|
||||||
TestHelper.assert_true(valid_lang, "Valid language codes accepted")
|
TestHelperClass.assert_true(valid_lang, "Valid language codes accepted")
|
||||||
|
|
||||||
|
|
||||||
func test_file_io_security():
|
func test_file_io_security():
|
||||||
TestHelper.print_step("File I/O Security")
|
TestHelperClass.print_step("File I/O Security")
|
||||||
|
|
||||||
# Test file size limits by creating oversized config
|
# Test file size limits by creating oversized config
|
||||||
var oversized_config_path = TestHelper.create_temp_file(
|
var oversized_config_path = TestHelper.create_temp_file(
|
||||||
@@ -135,18 +135,18 @@ func test_file_io_security():
|
|||||||
|
|
||||||
# Test that normal save/load operations work
|
# Test that normal save/load operations work
|
||||||
var save_result = settings_manager.save_settings()
|
var save_result = settings_manager.save_settings()
|
||||||
TestHelper.assert_true(save_result, "Normal settings save succeeds")
|
TestHelperClass.assert_true(save_result, "Normal settings save succeeds")
|
||||||
|
|
||||||
# Test loading with backup scenario
|
# Test loading with backup scenario
|
||||||
settings_manager.load_settings()
|
settings_manager.load_settings()
|
||||||
TestHelper.assert_not_null(settings_manager.settings, "Settings loaded successfully")
|
TestHelperClass.assert_not_null(settings_manager.settings, "Settings loaded successfully")
|
||||||
|
|
||||||
# Test that settings file exists after save
|
# Test that settings file exists after save
|
||||||
TestHelper.assert_file_exists("user://settings.cfg", "Settings file created after save")
|
TestHelperClass.assert_file_exists("user://settings.cfg", "Settings file created after save")
|
||||||
|
|
||||||
|
|
||||||
func test_json_parsing_security():
|
func test_json_parsing_security():
|
||||||
TestHelper.print_step("JSON Parsing Security")
|
TestHelperClass.print_step("JSON Parsing Security")
|
||||||
|
|
||||||
# Create invalid languages.json for testing
|
# Create invalid languages.json for testing
|
||||||
var invalid_json_path = TestHelper.create_temp_file(
|
var invalid_json_path = TestHelper.create_temp_file(
|
||||||
@@ -163,101 +163,101 @@ func test_json_parsing_security():
|
|||||||
|
|
||||||
# Test that SettingsManager handles invalid JSON gracefully
|
# Test that SettingsManager handles invalid JSON gracefully
|
||||||
# This should fall back to default languages
|
# This should fall back to default languages
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
settings_manager.languages_data.has("languages"),
|
settings_manager.languages_data.has("languages"),
|
||||||
"Default languages loaded on JSON parse failure"
|
"Default languages loaded on JSON parse failure"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_language_validation():
|
func test_language_validation():
|
||||||
TestHelper.print_step("Language Validation")
|
TestHelperClass.print_step("Language Validation")
|
||||||
|
|
||||||
# Test supported languages
|
# Test supported languages
|
||||||
var supported_langs = ["en", "ru"]
|
var supported_langs = ["en", "ru"]
|
||||||
for lang in supported_langs:
|
for lang in supported_langs:
|
||||||
var result = settings_manager.set_setting("language", lang)
|
var result = settings_manager.set_setting("language", lang)
|
||||||
TestHelper.assert_true(result, "Supported language accepted: " + lang)
|
TestHelperClass.assert_true(result, "Supported language accepted: " + lang)
|
||||||
|
|
||||||
# Test unsupported language
|
# Test unsupported language
|
||||||
var unsupported_result = settings_manager.set_setting("language", "xyz")
|
var unsupported_result = settings_manager.set_setting("language", "xyz")
|
||||||
TestHelper.assert_false(unsupported_result, "Unsupported language rejected")
|
TestHelperClass.assert_false(unsupported_result, "Unsupported language rejected")
|
||||||
|
|
||||||
# Test empty language
|
# Test empty language
|
||||||
var empty_result = settings_manager.set_setting("language", "")
|
var empty_result = settings_manager.set_setting("language", "")
|
||||||
TestHelper.assert_false(empty_result, "Empty language rejected")
|
TestHelperClass.assert_false(empty_result, "Empty language rejected")
|
||||||
|
|
||||||
# Test null language
|
# Test null language
|
||||||
var null_result = settings_manager.set_setting("language", null)
|
var null_result = settings_manager.set_setting("language", null)
|
||||||
TestHelper.assert_false(null_result, "Null language rejected")
|
TestHelperClass.assert_false(null_result, "Null language rejected")
|
||||||
|
|
||||||
|
|
||||||
func test_volume_validation():
|
func test_volume_validation():
|
||||||
TestHelper.print_step("Volume Validation")
|
TestHelperClass.print_step("Volume Validation")
|
||||||
|
|
||||||
var volume_settings = ["master_volume", "music_volume", "sfx_volume"]
|
var volume_settings = ["master_volume", "music_volume", "sfx_volume"]
|
||||||
|
|
||||||
for setting in volume_settings:
|
for setting in volume_settings:
|
||||||
# Test boundary values
|
# Test boundary values
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
settings_manager.set_setting(setting, 0.0), "Volume 0.0 accepted for " + setting
|
settings_manager.set_setting(setting, 0.0), "Volume 0.0 accepted for " + setting
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
settings_manager.set_setting(setting, 1.0), "Volume 1.0 accepted for " + setting
|
settings_manager.set_setting(setting, 1.0), "Volume 1.0 accepted for " + setting
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test out of range values
|
# Test out of range values
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
settings_manager.set_setting(setting, -0.1), "Negative volume rejected for " + setting
|
settings_manager.set_setting(setting, -0.1), "Negative volume rejected for " + setting
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
settings_manager.set_setting(setting, 1.1), "Volume > 1.0 rejected for " + setting
|
settings_manager.set_setting(setting, 1.1), "Volume > 1.0 rejected for " + setting
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test invalid types
|
# Test invalid types
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
settings_manager.set_setting(setting, "0.5"), "String volume rejected for " + setting
|
settings_manager.set_setting(setting, "0.5"), "String volume rejected for " + setting
|
||||||
)
|
)
|
||||||
TestHelper.assert_false(
|
TestHelperClass.assert_false(
|
||||||
settings_manager.set_setting(setting, null), "Null volume rejected for " + setting
|
settings_manager.set_setting(setting, null), "Null volume rejected for " + setting
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_error_handling_and_recovery():
|
func test_error_handling_and_recovery():
|
||||||
TestHelper.print_step("Error Handling and Recovery")
|
TestHelperClass.print_step("Error Handling and Recovery")
|
||||||
|
|
||||||
# Test unknown setting key
|
# Test unknown setting key
|
||||||
var unknown_result = settings_manager.set_setting("unknown_setting", "value")
|
var unknown_result = settings_manager.set_setting("unknown_setting", "value")
|
||||||
TestHelper.assert_false(unknown_result, "Unknown setting keys rejected")
|
TestHelperClass.assert_false(unknown_result, "Unknown setting keys rejected")
|
||||||
|
|
||||||
# Test recovery from corrupted settings
|
# Test recovery from corrupted settings
|
||||||
# Save current state
|
# Save current state
|
||||||
var current_volume = settings_manager.get_setting("master_volume")
|
var _current_volume = settings_manager.get_setting("master_volume")
|
||||||
|
|
||||||
# Reset settings
|
# Reset settings
|
||||||
settings_manager.reset_settings_to_defaults()
|
settings_manager.reset_settings_to_defaults()
|
||||||
|
|
||||||
# Verify defaults are loaded
|
# Verify defaults are loaded
|
||||||
var default_volume = settings_manager.default_settings["master_volume"]
|
var default_volume = settings_manager.default_settings["master_volume"]
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
default_volume,
|
default_volume,
|
||||||
settings_manager.get_setting("master_volume"),
|
settings_manager.get_setting("master_volume"),
|
||||||
"Reset to defaults works correctly"
|
"Reset to defaults works correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test fallback language loading
|
# Test fallback language loading
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
settings_manager.languages_data.has("languages"), "Fallback languages loaded"
|
settings_manager.languages_data.has("languages"), "Fallback languages loaded"
|
||||||
)
|
)
|
||||||
TestHelper.assert_has_key(
|
TestHelperClass.assert_has_key(
|
||||||
settings_manager.languages_data["languages"], "en", "English fallback language available"
|
settings_manager.languages_data["languages"], "en", "English fallback language available"
|
||||||
)
|
)
|
||||||
TestHelper.assert_has_key(
|
TestHelperClass.assert_has_key(
|
||||||
settings_manager.languages_data["languages"], "ru", "Russian fallback language available"
|
settings_manager.languages_data["languages"], "ru", "Russian fallback language available"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_reset_functionality():
|
func test_reset_functionality():
|
||||||
TestHelper.print_step("Reset Functionality")
|
TestHelperClass.print_step("Reset Functionality")
|
||||||
|
|
||||||
# Modify settings
|
# Modify settings
|
||||||
settings_manager.set_setting("master_volume", 0.8)
|
settings_manager.set_setting("master_volume", 0.8)
|
||||||
@@ -267,43 +267,43 @@ func test_reset_functionality():
|
|||||||
settings_manager.reset_settings_to_defaults()
|
settings_manager.reset_settings_to_defaults()
|
||||||
|
|
||||||
# Verify reset worked
|
# Verify reset worked
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
settings_manager.default_settings["master_volume"],
|
settings_manager.default_settings["master_volume"],
|
||||||
settings_manager.get_setting("master_volume"),
|
settings_manager.get_setting("master_volume"),
|
||||||
"Volume reset to default"
|
"Volume reset to default"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
settings_manager.default_settings["language"],
|
settings_manager.default_settings["language"],
|
||||||
settings_manager.get_setting("language"),
|
settings_manager.get_setting("language"),
|
||||||
"Language reset to default"
|
"Language reset to default"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that reset saves automatically
|
# Test that reset saves automatically
|
||||||
TestHelper.assert_file_exists("user://settings.cfg", "Settings file exists after reset")
|
TestHelperClass.assert_file_exists("user://settings.cfg", "Settings file exists after reset")
|
||||||
|
|
||||||
|
|
||||||
func test_performance_benchmarks():
|
func test_performance_benchmarks():
|
||||||
TestHelper.print_step("Performance Benchmarks")
|
TestHelperClass.print_step("Performance Benchmarks")
|
||||||
|
|
||||||
# Test settings load performance
|
# Test settings load performance
|
||||||
TestHelper.start_performance_test("load_settings")
|
TestHelperClass.start_performance_test("load_settings")
|
||||||
settings_manager.load_settings()
|
settings_manager.load_settings()
|
||||||
TestHelper.end_performance_test("load_settings", 100.0, "Settings load within 100ms")
|
TestHelperClass.end_performance_test("load_settings", 100.0, "Settings load within 100ms")
|
||||||
|
|
||||||
# Test settings save performance
|
# Test settings save performance
|
||||||
TestHelper.start_performance_test("save_settings")
|
TestHelperClass.start_performance_test("save_settings")
|
||||||
settings_manager.save_settings()
|
settings_manager.save_settings()
|
||||||
TestHelper.end_performance_test("save_settings", 50.0, "Settings save within 50ms")
|
TestHelperClass.end_performance_test("save_settings", 50.0, "Settings save within 50ms")
|
||||||
|
|
||||||
# Test validation performance
|
# Test validation performance
|
||||||
TestHelper.start_performance_test("validation")
|
TestHelperClass.start_performance_test("validation")
|
||||||
for i in range(100):
|
for i in range(100):
|
||||||
settings_manager.set_setting("master_volume", 0.5)
|
settings_manager.set_setting("master_volume", 0.5)
|
||||||
TestHelper.end_performance_test("validation", 50.0, "100 validations within 50ms")
|
TestHelperClass.end_performance_test("validation", 50.0, "100 validations within 50ms")
|
||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Restore original settings
|
# Restore original settings
|
||||||
if original_settings:
|
if original_settings:
|
||||||
@@ -312,6 +312,6 @@ func cleanup_tests():
|
|||||||
|
|
||||||
# Clean up temporary files
|
# Clean up temporary files
|
||||||
for temp_file in temp_files:
|
for temp_file in temp_files:
|
||||||
TestHelper.cleanup_temp_file(temp_file)
|
TestHelperClass.cleanup_temp_file(temp_file)
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extends SceneTree
|
|||||||
##
|
##
|
||||||
## Tests tile initialization, texture management, and gem types.
|
## Tests tile initialization, texture management, and gem types.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var tile_scene: PackedScene
|
var tile_scene: PackedScene
|
||||||
var tile_instance: Node2D
|
var tile_instance: Node2D
|
||||||
@@ -23,7 +23,7 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("Tile Component")
|
TestHelperClass.print_test_header("Tile Component")
|
||||||
|
|
||||||
# Setup test environment
|
# Setup test environment
|
||||||
setup_test_environment()
|
setup_test_environment()
|
||||||
@@ -43,15 +43,15 @@ func run_tests():
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("Tile Component")
|
TestHelperClass.print_test_footer("Tile Component")
|
||||||
|
|
||||||
|
|
||||||
func setup_test_environment():
|
func setup_test_environment():
|
||||||
TestHelper.print_step("Test Environment Setup")
|
TestHelperClass.print_step("Test Environment Setup")
|
||||||
|
|
||||||
# Load Tile scene
|
# Load Tile scene
|
||||||
tile_scene = load("res://scenes/game/gameplays/tile.tscn")
|
tile_scene = load("res://scenes/game/gameplays/tile.tscn")
|
||||||
TestHelper.assert_not_null(tile_scene, "Tile scene loads successfully")
|
TestHelperClass.assert_not_null(tile_scene, "Tile scene loads successfully")
|
||||||
|
|
||||||
# Create test viewport for isolated testing
|
# Create test viewport for isolated testing
|
||||||
test_viewport = SubViewport.new()
|
test_viewport = SubViewport.new()
|
||||||
@@ -62,7 +62,7 @@ func setup_test_environment():
|
|||||||
if tile_scene:
|
if tile_scene:
|
||||||
tile_instance = tile_scene.instantiate()
|
tile_instance = tile_scene.instantiate()
|
||||||
test_viewport.add_child(tile_instance)
|
test_viewport.add_child(tile_instance)
|
||||||
TestHelper.assert_not_null(tile_instance, "Tile instance created successfully")
|
TestHelperClass.assert_not_null(tile_instance, "Tile instance created successfully")
|
||||||
|
|
||||||
# Wait for initialization
|
# Wait for initialization
|
||||||
await process_frame
|
await process_frame
|
||||||
@@ -70,10 +70,10 @@ func setup_test_environment():
|
|||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
TestHelper.assert_true(false, "Tile instance not available for testing")
|
TestHelperClass.assert_true(false, "Tile instance not available for testing")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test that Tile has expected properties
|
# Test that Tile has expected properties
|
||||||
@@ -86,7 +86,7 @@ func test_basic_functionality():
|
|||||||
"active_gem_types"
|
"active_gem_types"
|
||||||
]
|
]
|
||||||
for prop in expected_properties:
|
for prop in expected_properties:
|
||||||
TestHelper.assert_true(prop in tile_instance, "Tile has property: " + prop)
|
TestHelperClass.assert_true(prop in tile_instance, "Tile has property: " + prop)
|
||||||
|
|
||||||
# Test that Tile has expected methods
|
# Test that Tile has expected methods
|
||||||
var expected_methods = [
|
var expected_methods = [
|
||||||
@@ -96,58 +96,58 @@ func test_basic_functionality():
|
|||||||
"remove_gem_type",
|
"remove_gem_type",
|
||||||
"force_reset_visual_state"
|
"force_reset_visual_state"
|
||||||
]
|
]
|
||||||
TestHelper.assert_has_methods(tile_instance, expected_methods, "Tile component methods")
|
TestHelperClass.assert_has_methods(tile_instance, expected_methods, "Tile component methods")
|
||||||
|
|
||||||
# Test signals
|
# Test signals
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.has_signal("tile_selected"), "Tile has tile_selected signal"
|
tile_instance.has_signal("tile_selected"), "Tile has tile_selected signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test sprite reference
|
# Test sprite reference
|
||||||
TestHelper.assert_not_null(tile_instance.sprite, "Sprite node is available")
|
TestHelperClass.assert_not_null(tile_instance.sprite, "Sprite node is available")
|
||||||
TestHelper.assert_true(tile_instance.sprite is Sprite2D, "Sprite is Sprite2D type")
|
TestHelperClass.assert_true(tile_instance.sprite is Sprite2D, "Sprite is Sprite2D type")
|
||||||
|
|
||||||
# Test group membership
|
# Test group membership
|
||||||
TestHelper.assert_true(tile_instance.is_in_group("tiles"), "Tile is in 'tiles' group")
|
TestHelperClass.assert_true(tile_instance.is_in_group("tiles"), "Tile is in 'tiles' group")
|
||||||
|
|
||||||
|
|
||||||
func test_tile_constants():
|
func test_tile_constants():
|
||||||
TestHelper.print_step("Tile Constants")
|
TestHelperClass.print_step("Tile Constants")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test TILE_SIZE constant
|
# Test TILE_SIZE constant
|
||||||
TestHelper.assert_equal(48, tile_instance.TILE_SIZE, "TILE_SIZE constant is correct")
|
TestHelperClass.assert_equal(48, tile_instance.TILE_SIZE, "TILE_SIZE constant is correct")
|
||||||
|
|
||||||
# Test all_gem_textures array
|
# Test all_gem_textures array
|
||||||
TestHelper.assert_not_null(tile_instance.all_gem_textures, "All gem textures array exists")
|
TestHelperClass.assert_not_null(tile_instance.all_gem_textures, "All gem textures array exists")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.all_gem_textures is Array, "All gem textures is Array type"
|
tile_instance.all_gem_textures is Array, "All gem textures is Array type"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
8, tile_instance.all_gem_textures.size(), "All gem textures has expected count"
|
8, tile_instance.all_gem_textures.size(), "All gem textures has expected count"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that all gem textures are valid
|
# Test that all gem textures are valid
|
||||||
for i in range(tile_instance.all_gem_textures.size()):
|
for i in range(tile_instance.all_gem_textures.size()):
|
||||||
var texture = tile_instance.all_gem_textures[i]
|
var texture = tile_instance.all_gem_textures[i]
|
||||||
TestHelper.assert_not_null(texture, "Gem texture %d is not null" % i)
|
TestHelperClass.assert_not_null(texture, "Gem texture %d is not null" % i)
|
||||||
TestHelper.assert_true(texture is Texture2D, "Gem texture %d is Texture2D type" % i)
|
TestHelperClass.assert_true(texture is Texture2D, "Gem texture %d is Texture2D type" % i)
|
||||||
|
|
||||||
|
|
||||||
func test_texture_management():
|
func test_texture_management():
|
||||||
TestHelper.print_step("Texture Management")
|
TestHelperClass.print_step("Texture Management")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test default gem types initialization
|
# Test default gem types initialization
|
||||||
TestHelper.assert_not_null(tile_instance.active_gem_types, "Active gem types is initialized")
|
TestHelperClass.assert_not_null(tile_instance.active_gem_types, "Active gem types is initialized")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.active_gem_types is Array, "Active gem types is Array type"
|
tile_instance.active_gem_types is Array, "Active gem types is Array type"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.active_gem_types.size() > 0, "Active gem types has content"
|
tile_instance.active_gem_types.size() > 0, "Active gem types has content"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -156,10 +156,10 @@ func test_texture_management():
|
|||||||
|
|
||||||
for i in range(min(3, tile_instance.active_gem_types.size())):
|
for i in range(min(3, tile_instance.active_gem_types.size())):
|
||||||
tile_instance.tile_type = i
|
tile_instance.tile_type = i
|
||||||
TestHelper.assert_equal(i, tile_instance.tile_type, "Tile type set correctly to %d" % i)
|
TestHelperClass.assert_equal(i, tile_instance.tile_type, "Tile type set correctly to %d" % i)
|
||||||
|
|
||||||
if tile_instance.sprite:
|
if tile_instance.sprite:
|
||||||
TestHelper.assert_not_null(
|
TestHelperClass.assert_not_null(
|
||||||
tile_instance.sprite.texture, "Sprite texture assigned for type %d" % i
|
tile_instance.sprite.texture, "Sprite texture assigned for type %d" % i
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -168,7 +168,7 @@ func test_texture_management():
|
|||||||
|
|
||||||
|
|
||||||
func test_gem_type_management():
|
func test_gem_type_management():
|
||||||
TestHelper.print_step("Gem Type Management")
|
TestHelperClass.print_step("Gem Type Management")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
@@ -179,51 +179,51 @@ func test_gem_type_management():
|
|||||||
# Test set_active_gem_types with valid array
|
# Test set_active_gem_types with valid array
|
||||||
var test_gems = [0, 1, 2]
|
var test_gems = [0, 1, 2]
|
||||||
tile_instance.set_active_gem_types(test_gems)
|
tile_instance.set_active_gem_types(test_gems)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
3, tile_instance.get_active_gem_count(), "Active gem count set correctly"
|
3, tile_instance.get_active_gem_count(), "Active gem count set correctly"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test add_gem_type
|
# Test add_gem_type
|
||||||
var add_result = tile_instance.add_gem_type(3)
|
var add_result = tile_instance.add_gem_type(3)
|
||||||
TestHelper.assert_true(add_result, "Valid gem type added successfully")
|
TestHelperClass.assert_true(add_result, "Valid gem type added successfully")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
4, tile_instance.get_active_gem_count(), "Gem count increased after addition"
|
4, tile_instance.get_active_gem_count(), "Gem count increased after addition"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test adding duplicate gem type
|
# Test adding duplicate gem type
|
||||||
var duplicate_result = tile_instance.add_gem_type(3)
|
var duplicate_result = tile_instance.add_gem_type(3)
|
||||||
TestHelper.assert_false(duplicate_result, "Duplicate gem type addition rejected")
|
TestHelperClass.assert_false(duplicate_result, "Duplicate gem type addition rejected")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
4, tile_instance.get_active_gem_count(), "Gem count unchanged after duplicate"
|
4, tile_instance.get_active_gem_count(), "Gem count unchanged after duplicate"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test add_gem_type with invalid index
|
# Test add_gem_type with invalid index
|
||||||
var invalid_add = tile_instance.add_gem_type(99)
|
var invalid_add = tile_instance.add_gem_type(99)
|
||||||
TestHelper.assert_false(invalid_add, "Invalid gem index addition rejected")
|
TestHelperClass.assert_false(invalid_add, "Invalid gem index addition rejected")
|
||||||
|
|
||||||
# Test remove_gem_type
|
# Test remove_gem_type
|
||||||
var remove_result = tile_instance.remove_gem_type(3)
|
var remove_result = tile_instance.remove_gem_type(3)
|
||||||
TestHelper.assert_true(remove_result, "Valid gem type removed successfully")
|
TestHelperClass.assert_true(remove_result, "Valid gem type removed successfully")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
3, tile_instance.get_active_gem_count(), "Gem count decreased after removal"
|
3, tile_instance.get_active_gem_count(), "Gem count decreased after removal"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test removing non-existent gem type
|
# Test removing non-existent gem type
|
||||||
var nonexistent_remove = tile_instance.remove_gem_type(99)
|
var nonexistent_remove = tile_instance.remove_gem_type(99)
|
||||||
TestHelper.assert_false(nonexistent_remove, "Non-existent gem type removal rejected")
|
TestHelperClass.assert_false(nonexistent_remove, "Non-existent gem type removal rejected")
|
||||||
|
|
||||||
# Test minimum gem types protection
|
# Test minimum gem types protection
|
||||||
tile_instance.set_active_gem_types([0, 1]) # Set to minimum
|
tile_instance.set_active_gem_types([0, 1]) # Set to minimum
|
||||||
var protected_remove = tile_instance.remove_gem_type(0)
|
var protected_remove = tile_instance.remove_gem_type(0)
|
||||||
TestHelper.assert_false(protected_remove, "Minimum gem types protection active")
|
TestHelperClass.assert_false(protected_remove, "Minimum gem types protection active")
|
||||||
TestHelper.assert_equal(2, tile_instance.get_active_gem_count(), "Minimum gem count preserved")
|
TestHelperClass.assert_equal(2, tile_instance.get_active_gem_count(), "Minimum gem count preserved")
|
||||||
|
|
||||||
# Restore original state
|
# Restore original state
|
||||||
tile_instance.set_active_gem_types(original_gem_types)
|
tile_instance.set_active_gem_types(original_gem_types)
|
||||||
|
|
||||||
|
|
||||||
func test_visual_feedback_system():
|
func test_visual_feedback_system():
|
||||||
TestHelper.print_step("Visual Feedback System")
|
TestHelperClass.print_step("Visual Feedback System")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
@@ -234,7 +234,7 @@ func test_visual_feedback_system():
|
|||||||
|
|
||||||
# Test selection visual feedback
|
# Test selection visual feedback
|
||||||
tile_instance.is_selected = true
|
tile_instance.is_selected = true
|
||||||
TestHelper.assert_true(tile_instance.is_selected, "Selection state set correctly")
|
TestHelperClass.assert_true(tile_instance.is_selected, "Selection state set correctly")
|
||||||
|
|
||||||
# Wait for potential animation
|
# Wait for potential animation
|
||||||
await process_frame
|
await process_frame
|
||||||
@@ -242,7 +242,7 @@ func test_visual_feedback_system():
|
|||||||
if tile_instance.sprite:
|
if tile_instance.sprite:
|
||||||
# Test that modulate is brighter when selected
|
# Test that modulate is brighter when selected
|
||||||
var modulate = tile_instance.sprite.modulate
|
var modulate = tile_instance.sprite.modulate
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
modulate.r > 1.0 or modulate.g > 1.0 or modulate.b > 1.0,
|
modulate.r > 1.0 or modulate.g > 1.0 or modulate.b > 1.0,
|
||||||
"Selected tile has brighter modulate"
|
"Selected tile has brighter modulate"
|
||||||
)
|
)
|
||||||
@@ -250,21 +250,21 @@ func test_visual_feedback_system():
|
|||||||
# Test highlight visual feedback
|
# Test highlight visual feedback
|
||||||
tile_instance.is_selected = false
|
tile_instance.is_selected = false
|
||||||
tile_instance.is_highlighted = true
|
tile_instance.is_highlighted = true
|
||||||
TestHelper.assert_true(tile_instance.is_highlighted, "Highlight state set correctly")
|
TestHelperClass.assert_true(tile_instance.is_highlighted, "Highlight state set correctly")
|
||||||
|
|
||||||
# Wait for potential animation
|
# Wait for potential animation
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
# Test normal state
|
# Test normal state
|
||||||
tile_instance.is_highlighted = false
|
tile_instance.is_highlighted = false
|
||||||
TestHelper.assert_false(tile_instance.is_highlighted, "Normal state restored")
|
TestHelperClass.assert_false(tile_instance.is_highlighted, "Normal state restored")
|
||||||
|
|
||||||
# Test force reset
|
# Test force reset
|
||||||
tile_instance.is_selected = true
|
tile_instance.is_selected = true
|
||||||
tile_instance.is_highlighted = true
|
tile_instance.is_highlighted = true
|
||||||
tile_instance.force_reset_visual_state()
|
tile_instance.force_reset_visual_state()
|
||||||
TestHelper.assert_false(tile_instance.is_selected, "Force reset clears selection")
|
TestHelperClass.assert_false(tile_instance.is_selected, "Force reset clears selection")
|
||||||
TestHelper.assert_false(tile_instance.is_highlighted, "Force reset clears highlight")
|
TestHelperClass.assert_false(tile_instance.is_highlighted, "Force reset clears highlight")
|
||||||
|
|
||||||
# Restore original state
|
# Restore original state
|
||||||
tile_instance.is_selected = original_selected
|
tile_instance.is_selected = original_selected
|
||||||
@@ -272,17 +272,17 @@ func test_visual_feedback_system():
|
|||||||
|
|
||||||
|
|
||||||
func test_state_management():
|
func test_state_management():
|
||||||
TestHelper.print_step("State Management")
|
TestHelperClass.print_step("State Management")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test initial state
|
# Test initial state
|
||||||
TestHelper.assert_true(tile_instance.tile_type >= 0, "Initial tile type is non-negative")
|
TestHelperClass.assert_true(tile_instance.tile_type >= 0, "Initial tile type is non-negative")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.grid_position is Vector2i, "Grid position is Vector2i type"
|
tile_instance.grid_position is Vector2i, "Grid position is Vector2i type"
|
||||||
)
|
)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.original_scale is Vector2, "Original scale is Vector2 type"
|
tile_instance.original_scale is Vector2, "Original scale is Vector2 type"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -293,10 +293,10 @@ func test_state_management():
|
|||||||
# Test valid tile type
|
# Test valid tile type
|
||||||
if max_valid_type >= 0:
|
if max_valid_type >= 0:
|
||||||
tile_instance.tile_type = max_valid_type
|
tile_instance.tile_type = max_valid_type
|
||||||
TestHelper.assert_equal(max_valid_type, tile_instance.tile_type, "Valid tile type accepted")
|
TestHelperClass.assert_equal(max_valid_type, tile_instance.tile_type, "Valid tile type accepted")
|
||||||
|
|
||||||
# Test state consistency
|
# Test state consistency
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.tile_type < tile_instance.active_gem_types.size(),
|
tile_instance.tile_type < tile_instance.active_gem_types.size(),
|
||||||
"Tile type within active gems range"
|
"Tile type within active gems range"
|
||||||
)
|
)
|
||||||
@@ -306,7 +306,7 @@ func test_state_management():
|
|||||||
|
|
||||||
|
|
||||||
func test_input_validation():
|
func test_input_validation():
|
||||||
TestHelper.print_step("Input Validation")
|
TestHelperClass.print_step("Input Validation")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
@@ -315,52 +315,52 @@ func test_input_validation():
|
|||||||
var original_gems = tile_instance.active_gem_types.duplicate()
|
var original_gems = tile_instance.active_gem_types.duplicate()
|
||||||
tile_instance.set_active_gem_types([])
|
tile_instance.set_active_gem_types([])
|
||||||
# Should fall back to defaults or maintain previous state
|
# Should fall back to defaults or maintain previous state
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.get_active_gem_count() > 0, "Empty gem array handled gracefully"
|
tile_instance.get_active_gem_count() > 0, "Empty gem array handled gracefully"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test null gem types array
|
# Test null gem types array
|
||||||
tile_instance.set_active_gem_types(null)
|
tile_instance.set_active_gem_types(null)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.get_active_gem_count() > 0, "Null gem array handled gracefully"
|
tile_instance.get_active_gem_count() > 0, "Null gem array handled gracefully"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test invalid gem indices in array
|
# Test invalid gem indices in array
|
||||||
tile_instance.set_active_gem_types([0, 1, 99, 2]) # 99 is invalid
|
tile_instance.set_active_gem_types([0, 1, 99, 2]) # 99 is invalid
|
||||||
# Should use fallback or filter invalid indices
|
# Should use fallback or filter invalid indices
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.get_active_gem_count() > 0, "Invalid gem indices handled gracefully"
|
tile_instance.get_active_gem_count() > 0, "Invalid gem indices handled gracefully"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test negative gem indices
|
# Test negative gem indices
|
||||||
var negative_add = tile_instance.add_gem_type(-1)
|
var negative_add = tile_instance.add_gem_type(-1)
|
||||||
TestHelper.assert_false(negative_add, "Negative gem index rejected")
|
TestHelperClass.assert_false(negative_add, "Negative gem index rejected")
|
||||||
|
|
||||||
# Test out-of-bounds gem indices
|
# Test out-of-bounds gem indices
|
||||||
var oob_add = tile_instance.add_gem_type(tile_instance.all_gem_textures.size())
|
var oob_add = tile_instance.add_gem_type(tile_instance.all_gem_textures.size())
|
||||||
TestHelper.assert_false(oob_add, "Out-of-bounds gem index rejected")
|
TestHelperClass.assert_false(oob_add, "Out-of-bounds gem index rejected")
|
||||||
|
|
||||||
# Restore original state
|
# Restore original state
|
||||||
tile_instance.set_active_gem_types(original_gems)
|
tile_instance.set_active_gem_types(original_gems)
|
||||||
|
|
||||||
|
|
||||||
func test_scaling_and_sizing():
|
func test_scaling_and_sizing():
|
||||||
TestHelper.print_step("Scaling and Sizing")
|
TestHelperClass.print_step("Scaling and Sizing")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test original scale calculation
|
# Test original scale calculation
|
||||||
TestHelper.assert_not_null(tile_instance.original_scale, "Original scale is calculated")
|
TestHelperClass.assert_not_null(tile_instance.original_scale, "Original scale is calculated")
|
||||||
TestHelper.assert_true(tile_instance.original_scale.x > 0, "Original scale X is positive")
|
TestHelperClass.assert_true(tile_instance.original_scale.x > 0, "Original scale X is positive")
|
||||||
TestHelper.assert_true(tile_instance.original_scale.y > 0, "Original scale Y is positive")
|
TestHelperClass.assert_true(tile_instance.original_scale.y > 0, "Original scale Y is positive")
|
||||||
|
|
||||||
# Test that tile size is respected
|
# Test that tile size is respected
|
||||||
if tile_instance.sprite and tile_instance.sprite.texture:
|
if tile_instance.sprite and tile_instance.sprite.texture:
|
||||||
var texture_size = tile_instance.sprite.texture.get_size()
|
var texture_size = tile_instance.sprite.texture.get_size()
|
||||||
var scaled_size = texture_size * tile_instance.original_scale
|
var scaled_size = texture_size * tile_instance.original_scale
|
||||||
var max_dimension = max(scaled_size.x, scaled_size.y)
|
var max_dimension = max(scaled_size.x, scaled_size.y)
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
max_dimension <= tile_instance.TILE_SIZE + 1, "Scaled tile fits within TILE_SIZE"
|
max_dimension <= tile_instance.TILE_SIZE + 1, "Scaled tile fits within TILE_SIZE"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -374,7 +374,7 @@ func test_scaling_and_sizing():
|
|||||||
|
|
||||||
if tile_instance.sprite:
|
if tile_instance.sprite:
|
||||||
var selected_scale = tile_instance.sprite.scale
|
var selected_scale = tile_instance.sprite.scale
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
selected_scale.x >= original_scale.x, "Selected tile scale is larger or equal"
|
selected_scale.x >= original_scale.x, "Selected tile scale is larger or equal"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ func test_scaling_and_sizing():
|
|||||||
|
|
||||||
|
|
||||||
func test_memory_safety():
|
func test_memory_safety():
|
||||||
TestHelper.print_step("Memory Safety")
|
TestHelperClass.print_step("Memory Safety")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
@@ -399,31 +399,31 @@ func test_memory_safety():
|
|||||||
tile_instance._update_visual_feedback()
|
tile_instance._update_visual_feedback()
|
||||||
tile_instance.force_reset_visual_state()
|
tile_instance.force_reset_visual_state()
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Null sprite operations handled safely")
|
TestHelperClass.assert_true(true, "Null sprite operations handled safely")
|
||||||
|
|
||||||
# Restore sprite
|
# Restore sprite
|
||||||
tile_instance.sprite = original_sprite
|
tile_instance.sprite = original_sprite
|
||||||
|
|
||||||
# Test valid instance checking in visual updates
|
# Test valid instance checking in visual updates
|
||||||
if tile_instance.sprite:
|
if tile_instance.sprite:
|
||||||
TestHelper.assert_true(is_instance_valid(tile_instance.sprite), "Sprite instance is valid")
|
TestHelperClass.assert_true(is_instance_valid(tile_instance.sprite), "Sprite instance is valid")
|
||||||
|
|
||||||
# Test gem types array integrity
|
# Test gem types array integrity
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.active_gem_types is Array, "Active gem types maintains Array type"
|
tile_instance.active_gem_types is Array, "Active gem types maintains Array type"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that gem indices are within bounds
|
# Test that gem indices are within bounds
|
||||||
for gem_index in tile_instance.active_gem_types:
|
for gem_index in tile_instance.active_gem_types:
|
||||||
TestHelper.assert_true(gem_index >= 0, "Gem index is non-negative")
|
TestHelperClass.assert_true(gem_index >= 0, "Gem index is non-negative")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
gem_index < tile_instance.all_gem_textures.size(),
|
gem_index < tile_instance.all_gem_textures.size(),
|
||||||
"Gem index within texture array bounds"
|
"Gem index within texture array bounds"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func test_error_handling():
|
func test_error_handling():
|
||||||
TestHelper.print_step("Error Handling")
|
TestHelperClass.print_step("Error Handling")
|
||||||
|
|
||||||
if not tile_instance:
|
if not tile_instance:
|
||||||
return
|
return
|
||||||
@@ -434,11 +434,11 @@ func test_error_handling():
|
|||||||
|
|
||||||
# Test that _set_tile_type handles null sprite gracefully
|
# Test that _set_tile_type handles null sprite gracefully
|
||||||
tile_instance._set_tile_type(0)
|
tile_instance._set_tile_type(0)
|
||||||
TestHelper.assert_true(true, "Tile type setting handles null sprite gracefully")
|
TestHelperClass.assert_true(true, "Tile type setting handles null sprite gracefully")
|
||||||
|
|
||||||
# Test that scaling handles null sprite gracefully
|
# Test that scaling handles null sprite gracefully
|
||||||
tile_instance._scale_sprite_to_fit()
|
tile_instance._scale_sprite_to_fit()
|
||||||
TestHelper.assert_true(true, "Sprite scaling handles null sprite gracefully")
|
TestHelperClass.assert_true(true, "Sprite scaling handles null sprite gracefully")
|
||||||
|
|
||||||
# Restore sprite
|
# Restore sprite
|
||||||
tile_instance.sprite = backup_sprite
|
tile_instance.sprite = backup_sprite
|
||||||
@@ -449,7 +449,7 @@ func test_error_handling():
|
|||||||
tile_instance._set_tile_type(999) # Invalid large type
|
tile_instance._set_tile_type(999) # Invalid large type
|
||||||
|
|
||||||
# Should not crash and should maintain reasonable state
|
# Should not crash and should maintain reasonable state
|
||||||
TestHelper.assert_true(true, "Invalid tile types handled gracefully")
|
TestHelperClass.assert_true(true, "Invalid tile types handled gracefully")
|
||||||
|
|
||||||
# Restore original type
|
# Restore original type
|
||||||
tile_instance.tile_type = original_type
|
tile_instance.tile_type = original_type
|
||||||
@@ -461,14 +461,14 @@ func test_error_handling():
|
|||||||
|
|
||||||
tile_instance.set_active_gem_types(large_gem_types)
|
tile_instance.set_active_gem_types(large_gem_types)
|
||||||
# Should fall back to safe defaults
|
# Should fall back to safe defaults
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
tile_instance.get_active_gem_count() <= tile_instance.all_gem_textures.size(),
|
tile_instance.get_active_gem_count() <= tile_instance.all_gem_textures.size(),
|
||||||
"Large gem array handled safely"
|
"Large gem array handled safely"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Clean up tile instance
|
# Clean up tile instance
|
||||||
if tile_instance and is_instance_valid(tile_instance):
|
if tile_instance and is_instance_valid(tile_instance):
|
||||||
@@ -481,4 +481,4 @@ func cleanup_tests():
|
|||||||
# Wait for cleanup
|
# Wait for cleanup
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extends SceneTree
|
|||||||
##
|
##
|
||||||
## Tests data loading, value navigation, and input handling.
|
## Tests data loading, value navigation, and input handling.
|
||||||
|
|
||||||
const TestHelper = preload("res://tests/helpers/TestHelper.gd")
|
const TestHelperClass = preload("res://tests/helpers/TestHelper.gd")
|
||||||
|
|
||||||
var stepper_scene: PackedScene
|
var stepper_scene: PackedScene
|
||||||
var stepper_instance: Control
|
var stepper_instance: Control
|
||||||
@@ -24,7 +24,7 @@ func _initialize():
|
|||||||
|
|
||||||
|
|
||||||
func run_tests():
|
func run_tests():
|
||||||
TestHelper.print_test_header("ValueStepper Component")
|
TestHelperClass.print_test_header("ValueStepper Component")
|
||||||
|
|
||||||
# Store original settings
|
# Store original settings
|
||||||
var settings_manager = root.get_node("SettingsManager")
|
var settings_manager = root.get_node("SettingsManager")
|
||||||
@@ -47,15 +47,15 @@ func run_tests():
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
cleanup_tests()
|
cleanup_tests()
|
||||||
|
|
||||||
TestHelper.print_test_footer("ValueStepper Component")
|
TestHelperClass.print_test_footer("ValueStepper Component")
|
||||||
|
|
||||||
|
|
||||||
func setup_test_environment():
|
func setup_test_environment():
|
||||||
TestHelper.print_step("Test Environment Setup")
|
TestHelperClass.print_step("Test Environment Setup")
|
||||||
|
|
||||||
# Load ValueStepper scene
|
# Load ValueStepper scene
|
||||||
stepper_scene = load("res://scenes/ui/components/ValueStepper.tscn")
|
stepper_scene = load("res://scenes/ui/components/ValueStepper.tscn")
|
||||||
TestHelper.assert_not_null(stepper_scene, "ValueStepper scene loads successfully")
|
TestHelperClass.assert_not_null(stepper_scene, "ValueStepper scene loads successfully")
|
||||||
|
|
||||||
# Create test viewport for isolated testing
|
# Create test viewport for isolated testing
|
||||||
test_viewport = SubViewport.new()
|
test_viewport = SubViewport.new()
|
||||||
@@ -66,7 +66,7 @@ func setup_test_environment():
|
|||||||
if stepper_scene:
|
if stepper_scene:
|
||||||
stepper_instance = stepper_scene.instantiate()
|
stepper_instance = stepper_scene.instantiate()
|
||||||
test_viewport.add_child(stepper_instance)
|
test_viewport.add_child(stepper_instance)
|
||||||
TestHelper.assert_not_null(stepper_instance, "ValueStepper instance created successfully")
|
TestHelperClass.assert_not_null(stepper_instance, "ValueStepper instance created successfully")
|
||||||
|
|
||||||
# Wait for initialization
|
# Wait for initialization
|
||||||
await process_frame
|
await process_frame
|
||||||
@@ -74,10 +74,10 @@ func setup_test_environment():
|
|||||||
|
|
||||||
|
|
||||||
func test_basic_functionality():
|
func test_basic_functionality():
|
||||||
TestHelper.print_step("Basic Functionality")
|
TestHelperClass.print_step("Basic Functionality")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
TestHelper.assert_true(false, "ValueStepper instance not available for testing")
|
TestHelperClass.assert_true(false, "ValueStepper instance not available for testing")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test that ValueStepper has expected properties
|
# Test that ValueStepper has expected properties
|
||||||
@@ -85,7 +85,7 @@ func test_basic_functionality():
|
|||||||
"data_source", "custom_format_function", "values", "display_names", "current_index"
|
"data_source", "custom_format_function", "values", "display_names", "current_index"
|
||||||
]
|
]
|
||||||
for prop in expected_properties:
|
for prop in expected_properties:
|
||||||
TestHelper.assert_true(prop in stepper_instance, "ValueStepper has property: " + prop)
|
TestHelperClass.assert_true(prop in stepper_instance, "ValueStepper has property: " + prop)
|
||||||
|
|
||||||
# Test that ValueStepper has expected methods
|
# Test that ValueStepper has expected methods
|
||||||
var expected_methods = [
|
var expected_methods = [
|
||||||
@@ -97,50 +97,50 @@ func test_basic_functionality():
|
|||||||
"handle_input_action",
|
"handle_input_action",
|
||||||
"get_control_name"
|
"get_control_name"
|
||||||
]
|
]
|
||||||
TestHelper.assert_has_methods(
|
TestHelperClass.assert_has_methods(
|
||||||
stepper_instance, expected_methods, "ValueStepper component methods"
|
stepper_instance, expected_methods, "ValueStepper component methods"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test signals
|
# Test signals
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
stepper_instance.has_signal("value_changed"), "ValueStepper has value_changed signal"
|
stepper_instance.has_signal("value_changed"), "ValueStepper has value_changed signal"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test UI components
|
# Test UI components
|
||||||
TestHelper.assert_not_null(stepper_instance.left_button, "Left button is available")
|
TestHelperClass.assert_not_null(stepper_instance.left_button, "Left button is available")
|
||||||
TestHelper.assert_not_null(stepper_instance.right_button, "Right button is available")
|
TestHelperClass.assert_not_null(stepper_instance.right_button, "Right button is available")
|
||||||
TestHelper.assert_not_null(stepper_instance.value_display, "Value display label is available")
|
TestHelperClass.assert_not_null(stepper_instance.value_display, "Value display label is available")
|
||||||
|
|
||||||
# Test UI component types
|
# Test UI component types
|
||||||
TestHelper.assert_true(stepper_instance.left_button is Button, "Left button is Button type")
|
TestHelperClass.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")
|
TestHelperClass.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")
|
TestHelperClass.assert_true(stepper_instance.value_display is Label, "Value display is Label type")
|
||||||
|
|
||||||
|
|
||||||
func test_data_source_loading():
|
func test_data_source_loading():
|
||||||
TestHelper.print_step("Data Source Loading")
|
TestHelperClass.print_step("Data Source Loading")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Test default language data source
|
# Test default language data source
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"language", stepper_instance.data_source, "Default data source is language"
|
"language", stepper_instance.data_source, "Default data source is language"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test that values are loaded
|
# Test that values are loaded
|
||||||
TestHelper.assert_not_null(stepper_instance.values, "Values array is initialized")
|
TestHelperClass.assert_not_null(stepper_instance.values, "Values array is initialized")
|
||||||
TestHelper.assert_not_null(stepper_instance.display_names, "Display names array is initialized")
|
TestHelperClass.assert_not_null(stepper_instance.display_names, "Display names array is initialized")
|
||||||
TestHelper.assert_true(stepper_instance.values is Array, "Values is Array type")
|
TestHelperClass.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")
|
TestHelperClass.assert_true(stepper_instance.display_names is Array, "Display names is Array type")
|
||||||
|
|
||||||
# Test that language data is loaded correctly
|
# Test that language data is loaded correctly
|
||||||
if stepper_instance.data_source == "language":
|
if stepper_instance.data_source == "language":
|
||||||
TestHelper.assert_true(stepper_instance.values.size() > 0, "Language values loaded")
|
TestHelperClass.assert_true(stepper_instance.values.size() > 0, "Language values loaded")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
stepper_instance.display_names.size() > 0, "Language display names loaded"
|
stepper_instance.display_names.size() > 0, "Language display names loaded"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
stepper_instance.values.size(),
|
stepper_instance.values.size(),
|
||||||
stepper_instance.display_names.size(),
|
stepper_instance.display_names.size(),
|
||||||
"Values and display names arrays have same size"
|
"Values and display names arrays have same size"
|
||||||
@@ -150,7 +150,7 @@ func test_data_source_loading():
|
|||||||
var current_lang = root.get_node("SettingsManager").get_setting("language")
|
var current_lang = root.get_node("SettingsManager").get_setting("language")
|
||||||
var expected_index = stepper_instance.values.find(current_lang)
|
var expected_index = stepper_instance.values.find(current_lang)
|
||||||
if expected_index >= 0:
|
if expected_index >= 0:
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
expected_index,
|
expected_index,
|
||||||
stepper_instance.current_index,
|
stepper_instance.current_index,
|
||||||
"Current language index set correctly"
|
"Current language index set correctly"
|
||||||
@@ -162,8 +162,8 @@ func test_data_source_loading():
|
|||||||
test_viewport.add_child(resolution_stepper)
|
test_viewport.add_child(resolution_stepper)
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_true(resolution_stepper.values.size() > 0, "Resolution values loaded")
|
TestHelperClass.assert_true(resolution_stepper.values.size() > 0, "Resolution values loaded")
|
||||||
TestHelper.assert_contains(
|
TestHelperClass.assert_contains(
|
||||||
resolution_stepper.values, "1920x1080", "Resolution data contains expected value"
|
resolution_stepper.values, "1920x1080", "Resolution data contains expected value"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -175,35 +175,35 @@ func test_data_source_loading():
|
|||||||
test_viewport.add_child(difficulty_stepper)
|
test_viewport.add_child(difficulty_stepper)
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_true(difficulty_stepper.values.size() > 0, "Difficulty values loaded")
|
TestHelperClass.assert_true(difficulty_stepper.values.size() > 0, "Difficulty values loaded")
|
||||||
TestHelper.assert_contains(
|
TestHelperClass.assert_contains(
|
||||||
difficulty_stepper.values, "normal", "Difficulty data contains expected value"
|
difficulty_stepper.values, "normal", "Difficulty data contains expected value"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(1, difficulty_stepper.current_index, "Difficulty defaults to normal")
|
TestHelperClass.assert_equal(1, difficulty_stepper.current_index, "Difficulty defaults to normal")
|
||||||
|
|
||||||
difficulty_stepper.queue_free()
|
difficulty_stepper.queue_free()
|
||||||
|
|
||||||
|
|
||||||
func test_value_navigation():
|
func test_value_navigation():
|
||||||
TestHelper.print_step("Value Navigation")
|
TestHelperClass.print_step("Value Navigation")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Store original state
|
# Store original state
|
||||||
var original_index = stepper_instance.current_index
|
var original_index = stepper_instance.current_index
|
||||||
var original_value = stepper_instance.get_current_value()
|
var _original_value = stepper_instance.get_current_value()
|
||||||
|
|
||||||
# Test forward navigation
|
# Test forward navigation
|
||||||
var initial_value = stepper_instance.get_current_value()
|
var initial_value = stepper_instance.get_current_value()
|
||||||
stepper_instance.change_value(1)
|
stepper_instance.change_value(1)
|
||||||
var next_value = stepper_instance.get_current_value()
|
var next_value = stepper_instance.get_current_value()
|
||||||
TestHelper.assert_not_equal(initial_value, next_value, "Forward navigation changes value")
|
TestHelperClass.assert_not_equal(initial_value, next_value, "Forward navigation changes value")
|
||||||
|
|
||||||
# Test backward navigation
|
# Test backward navigation
|
||||||
stepper_instance.change_value(-1)
|
stepper_instance.change_value(-1)
|
||||||
var back_value = stepper_instance.get_current_value()
|
var back_value = stepper_instance.get_current_value()
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
initial_value, back_value, "Backward navigation returns to original value"
|
initial_value, back_value, "Backward navigation returns to original value"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -211,14 +211,14 @@ func test_value_navigation():
|
|||||||
var max_index = stepper_instance.values.size() - 1
|
var max_index = stepper_instance.values.size() - 1
|
||||||
stepper_instance.current_index = max_index
|
stepper_instance.current_index = max_index
|
||||||
stepper_instance.change_value(1)
|
stepper_instance.change_value(1)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
0, stepper_instance.current_index, "Forward navigation wraps to beginning"
|
0, stepper_instance.current_index, "Forward navigation wraps to beginning"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test wrap-around backward
|
# Test wrap-around backward
|
||||||
stepper_instance.current_index = 0
|
stepper_instance.current_index = 0
|
||||||
stepper_instance.change_value(-1)
|
stepper_instance.change_value(-1)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
max_index, stepper_instance.current_index, "Backward navigation wraps to end"
|
max_index, stepper_instance.current_index, "Backward navigation wraps to end"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ func test_value_navigation():
|
|||||||
|
|
||||||
|
|
||||||
func test_custom_values():
|
func test_custom_values():
|
||||||
TestHelper.print_step("Custom Values")
|
TestHelperClass.print_step("Custom Values")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
@@ -242,10 +242,10 @@ func test_custom_values():
|
|||||||
var custom_values = ["apple", "banana", "cherry"]
|
var custom_values = ["apple", "banana", "cherry"]
|
||||||
stepper_instance.setup_custom_values(custom_values)
|
stepper_instance.setup_custom_values(custom_values)
|
||||||
|
|
||||||
TestHelper.assert_equal(3, stepper_instance.values.size(), "Custom values set correctly")
|
TestHelperClass.assert_equal(3, stepper_instance.values.size(), "Custom values set correctly")
|
||||||
TestHelper.assert_equal("apple", stepper_instance.values[0], "First custom value correct")
|
TestHelperClass.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")
|
TestHelperClass.assert_equal(0, stepper_instance.current_index, "Index reset to 0 for custom values")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"apple", stepper_instance.get_current_value(), "Current value matches first custom value"
|
"apple", stepper_instance.get_current_value(), "Current value matches first custom value"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -253,31 +253,31 @@ func test_custom_values():
|
|||||||
var custom_display_names = ["Red Apple", "Yellow Banana", "Red Cherry"]
|
var custom_display_names = ["Red Apple", "Yellow Banana", "Red Cherry"]
|
||||||
stepper_instance.setup_custom_values(custom_values, custom_display_names)
|
stepper_instance.setup_custom_values(custom_values, custom_display_names)
|
||||||
|
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
3, stepper_instance.display_names.size(), "Custom display names set correctly"
|
3, stepper_instance.display_names.size(), "Custom display names set correctly"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"Red Apple", stepper_instance.display_names[0], "First display name correct"
|
"Red Apple", stepper_instance.display_names[0], "First display name correct"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test navigation with custom values
|
# Test navigation with custom values
|
||||||
stepper_instance.change_value(1)
|
stepper_instance.change_value(1)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"banana", stepper_instance.get_current_value(), "Navigation works with custom values"
|
"banana", stepper_instance.get_current_value(), "Navigation works with custom values"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test set_current_value
|
# Test set_current_value
|
||||||
stepper_instance.set_current_value("cherry")
|
stepper_instance.set_current_value("cherry")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"cherry", stepper_instance.get_current_value(), "set_current_value works correctly"
|
"cherry", stepper_instance.get_current_value(), "set_current_value works correctly"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
2, stepper_instance.current_index, "Index updated correctly by set_current_value"
|
2, stepper_instance.current_index, "Index updated correctly by set_current_value"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test invalid value
|
# Test invalid value
|
||||||
stepper_instance.set_current_value("grape")
|
stepper_instance.set_current_value("grape")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"cherry", stepper_instance.get_current_value(), "Invalid value doesn't change current value"
|
"cherry", stepper_instance.get_current_value(), "Invalid value doesn't change current value"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ func test_custom_values():
|
|||||||
|
|
||||||
|
|
||||||
func test_input_handling():
|
func test_input_handling():
|
||||||
TestHelper.print_step("Input Handling")
|
TestHelperClass.print_step("Input Handling")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
@@ -299,15 +299,15 @@ func test_input_handling():
|
|||||||
|
|
||||||
# Test left input action
|
# Test left input action
|
||||||
var left_handled = stepper_instance.handle_input_action("move_left")
|
var left_handled = stepper_instance.handle_input_action("move_left")
|
||||||
TestHelper.assert_true(left_handled, "Left input action handled")
|
TestHelperClass.assert_true(left_handled, "Left input action handled")
|
||||||
TestHelper.assert_not_equal(
|
TestHelperClass.assert_not_equal(
|
||||||
original_value, stepper_instance.get_current_value(), "Left action changes value"
|
original_value, stepper_instance.get_current_value(), "Left action changes value"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test right input action
|
# Test right input action
|
||||||
var right_handled = stepper_instance.handle_input_action("move_right")
|
var right_handled = stepper_instance.handle_input_action("move_right")
|
||||||
TestHelper.assert_true(right_handled, "Right input action handled")
|
TestHelperClass.assert_true(right_handled, "Right input action handled")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_value,
|
original_value,
|
||||||
stepper_instance.get_current_value(),
|
stepper_instance.get_current_value(),
|
||||||
"Right action returns to original value"
|
"Right action returns to original value"
|
||||||
@@ -315,20 +315,20 @@ func test_input_handling():
|
|||||||
|
|
||||||
# Test invalid input action
|
# Test invalid input action
|
||||||
var invalid_handled = stepper_instance.handle_input_action("invalid_action")
|
var invalid_handled = stepper_instance.handle_input_action("invalid_action")
|
||||||
TestHelper.assert_false(invalid_handled, "Invalid input action not handled")
|
TestHelperClass.assert_false(invalid_handled, "Invalid input action not handled")
|
||||||
|
|
||||||
# Test button press simulation
|
# Test button press simulation
|
||||||
if stepper_instance.left_button:
|
if stepper_instance.left_button:
|
||||||
var before_left = stepper_instance.get_current_value()
|
var before_left = stepper_instance.get_current_value()
|
||||||
stepper_instance._on_left_button_pressed()
|
stepper_instance._on_left_button_pressed()
|
||||||
TestHelper.assert_not_equal(
|
TestHelperClass.assert_not_equal(
|
||||||
before_left, stepper_instance.get_current_value(), "Left button press changes value"
|
before_left, stepper_instance.get_current_value(), "Left button press changes value"
|
||||||
)
|
)
|
||||||
|
|
||||||
if stepper_instance.right_button:
|
if stepper_instance.right_button:
|
||||||
var before_right = stepper_instance.get_current_value()
|
var _before_right = stepper_instance.get_current_value()
|
||||||
stepper_instance._on_right_button_pressed()
|
stepper_instance._on_right_button_pressed()
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_value,
|
original_value,
|
||||||
stepper_instance.get_current_value(),
|
stepper_instance.get_current_value(),
|
||||||
"Right button press returns to original"
|
"Right button press returns to original"
|
||||||
@@ -336,7 +336,7 @@ func test_input_handling():
|
|||||||
|
|
||||||
|
|
||||||
func test_visual_feedback():
|
func test_visual_feedback():
|
||||||
TestHelper.print_step("Visual Feedback")
|
TestHelperClass.print_step("Visual Feedback")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
@@ -347,30 +347,30 @@ func test_visual_feedback():
|
|||||||
|
|
||||||
# Test highlighting
|
# Test highlighting
|
||||||
stepper_instance.set_highlighted(true)
|
stepper_instance.set_highlighted(true)
|
||||||
TestHelper.assert_true(stepper_instance.is_highlighted, "Highlighted state set correctly")
|
TestHelperClass.assert_true(stepper_instance.is_highlighted, "Highlighted state set correctly")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
stepper_instance.scale.x > original_scale.x, "Scale increased when highlighted"
|
stepper_instance.scale.x > original_scale.x, "Scale increased when highlighted"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test unhighlighting
|
# Test unhighlighting
|
||||||
stepper_instance.set_highlighted(false)
|
stepper_instance.set_highlighted(false)
|
||||||
TestHelper.assert_false(stepper_instance.is_highlighted, "Highlighted state cleared correctly")
|
TestHelperClass.assert_false(stepper_instance.is_highlighted, "Highlighted state cleared correctly")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_scale, stepper_instance.scale, "Scale restored when unhighlighted"
|
original_scale, stepper_instance.scale, "Scale restored when unhighlighted"
|
||||||
)
|
)
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
original_modulate, stepper_instance.modulate, "Modulate restored when unhighlighted"
|
original_modulate, stepper_instance.modulate, "Modulate restored when unhighlighted"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test display update
|
# Test display update
|
||||||
if stepper_instance.value_display:
|
if stepper_instance.value_display:
|
||||||
var current_text = stepper_instance.value_display.text
|
var current_text = stepper_instance.value_display.text
|
||||||
TestHelper.assert_true(current_text.length() > 0, "Value display has text content")
|
TestHelperClass.assert_true(current_text.length() > 0, "Value display has text content")
|
||||||
TestHelper.assert_not_equal("N/A", current_text, "Value display shows valid content")
|
TestHelperClass.assert_not_equal("N/A", current_text, "Value display shows valid content")
|
||||||
|
|
||||||
|
|
||||||
func test_settings_integration():
|
func test_settings_integration():
|
||||||
TestHelper.print_step("Settings Integration")
|
TestHelperClass.print_step("Settings Integration")
|
||||||
|
|
||||||
if not stepper_instance or stepper_instance.data_source != "language":
|
if not stepper_instance or stepper_instance.data_source != "language":
|
||||||
return
|
return
|
||||||
@@ -394,14 +394,14 @@ func test_settings_integration():
|
|||||||
|
|
||||||
# Verify setting was updated
|
# Verify setting was updated
|
||||||
var updated_lang = root.get_node("SettingsManager").get_setting("language")
|
var updated_lang = root.get_node("SettingsManager").get_setting("language")
|
||||||
TestHelper.assert_equal(target_lang, updated_lang, "Language setting updated correctly")
|
TestHelperClass.assert_equal(target_lang, updated_lang, "Language setting updated correctly")
|
||||||
|
|
||||||
# Restore original language
|
# Restore original language
|
||||||
root.get_node("SettingsManager").set_setting("language", original_lang)
|
root.get_node("SettingsManager").set_setting("language", original_lang)
|
||||||
|
|
||||||
|
|
||||||
func test_boundary_conditions():
|
func test_boundary_conditions():
|
||||||
TestHelper.print_step("Boundary Conditions")
|
TestHelperClass.print_step("Boundary Conditions")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
@@ -412,13 +412,13 @@ func test_boundary_conditions():
|
|||||||
test_viewport.add_child(empty_stepper)
|
test_viewport.add_child(empty_stepper)
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"", empty_stepper.get_current_value(), "Empty values array returns empty string"
|
"", empty_stepper.get_current_value(), "Empty values array returns empty string"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test change_value with empty array
|
# Test change_value with empty array
|
||||||
empty_stepper.change_value(1) # Should not crash
|
empty_stepper.change_value(1) # Should not crash
|
||||||
TestHelper.assert_true(true, "change_value handles empty array gracefully")
|
TestHelperClass.assert_true(true, "change_value handles empty array gracefully")
|
||||||
|
|
||||||
empty_stepper.queue_free()
|
empty_stepper.queue_free()
|
||||||
|
|
||||||
@@ -427,14 +427,14 @@ func test_boundary_conditions():
|
|||||||
# Test negative index handling
|
# Test negative index handling
|
||||||
stepper_instance.current_index = -1
|
stepper_instance.current_index = -1
|
||||||
stepper_instance._update_display()
|
stepper_instance._update_display()
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"N/A", stepper_instance.value_display.text, "Negative index shows N/A"
|
"N/A", stepper_instance.value_display.text, "Negative index shows N/A"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test out-of-bounds index handling
|
# Test out-of-bounds index handling
|
||||||
stepper_instance.current_index = stepper_instance.values.size()
|
stepper_instance.current_index = stepper_instance.values.size()
|
||||||
stepper_instance._update_display()
|
stepper_instance._update_display()
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"N/A", stepper_instance.value_display.text, "Out-of-bounds index shows N/A"
|
"N/A", stepper_instance.value_display.text, "Out-of-bounds index shows N/A"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ func test_boundary_conditions():
|
|||||||
|
|
||||||
|
|
||||||
func test_error_handling():
|
func test_error_handling():
|
||||||
TestHelper.print_step("Error Handling")
|
TestHelperClass.print_step("Error Handling")
|
||||||
|
|
||||||
if not stepper_instance:
|
if not stepper_instance:
|
||||||
return
|
return
|
||||||
@@ -456,13 +456,13 @@ func test_error_handling():
|
|||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
# Should not crash and should handle gracefully
|
# Should not crash and should handle gracefully
|
||||||
TestHelper.assert_true(true, "Unknown data source handled gracefully")
|
TestHelperClass.assert_true(true, "Unknown data source handled gracefully")
|
||||||
unknown_stepper.queue_free()
|
unknown_stepper.queue_free()
|
||||||
|
|
||||||
# Test get_control_name
|
# Test get_control_name
|
||||||
var control_name = stepper_instance.get_control_name()
|
var control_name = stepper_instance.get_control_name()
|
||||||
TestHelper.assert_true(control_name.ends_with("_stepper"), "Control name has correct suffix")
|
TestHelperClass.assert_true(control_name.ends_with("_stepper"), "Control name has correct suffix")
|
||||||
TestHelper.assert_true(
|
TestHelperClass.assert_true(
|
||||||
control_name.begins_with(stepper_instance.data_source), "Control name includes data source"
|
control_name.begins_with(stepper_instance.data_source), "Control name includes data source"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -472,21 +472,21 @@ func test_error_handling():
|
|||||||
stepper_instance.setup_custom_values(values_3, names_2)
|
stepper_instance.setup_custom_values(values_3, names_2)
|
||||||
|
|
||||||
# Should handle gracefully - display_names should be duplicated from values
|
# Should handle gracefully - display_names should be duplicated from values
|
||||||
TestHelper.assert_equal(3, stepper_instance.values.size(), "Values array size preserved")
|
TestHelperClass.assert_equal(3, stepper_instance.values.size(), "Values array size preserved")
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
2, stepper_instance.display_names.size(), "Display names size preserved as provided"
|
2, stepper_instance.display_names.size(), "Display names size preserved as provided"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test navigation with mismatched arrays
|
# Test navigation with mismatched arrays
|
||||||
stepper_instance.current_index = 2 # Index where display_names doesn't exist
|
stepper_instance.current_index = 2 # Index where display_names doesn't exist
|
||||||
stepper_instance._update_display()
|
stepper_instance._update_display()
|
||||||
TestHelper.assert_equal(
|
TestHelperClass.assert_equal(
|
||||||
"c", stepper_instance.value_display.text, "Falls back to value when display name missing"
|
"c", stepper_instance.value_display.text, "Falls back to value when display name missing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func cleanup_tests():
|
func cleanup_tests():
|
||||||
TestHelper.print_step("Cleanup")
|
TestHelperClass.print_step("Cleanup")
|
||||||
|
|
||||||
# Restore original language setting
|
# Restore original language setting
|
||||||
root.get_node("SettingsManager").set_setting("language", original_language)
|
root.get_node("SettingsManager").set_setting("language", original_language)
|
||||||
@@ -502,4 +502,4 @@ func cleanup_tests():
|
|||||||
# Wait for cleanup
|
# Wait for cleanup
|
||||||
await process_frame
|
await process_frame
|
||||||
|
|
||||||
TestHelper.assert_true(true, "Test cleanup completed")
|
TestHelperClass.assert_true(true, "Test cleanup completed")
|
||||||
|
|||||||
Reference in New Issue
Block a user