diff options
Diffstat (limited to 'Tests/Game')
| -rw-r--r-- | Tests/Game/CommandParserTestBase.gd | 29 | ||||
| -rw-r--r-- | Tests/Game/Commands/test_LookCommand.gd | 58 | ||||
| -rw-r--r-- | Tests/Game/test_CommandParser.gd | 12 | ||||
| -rw-r--r-- | Tests/Game/test_Input.gd | 86 | ||||
| -rw-r--r-- | Tests/Game/test_Output.gd | 51 | ||||
| -rw-r--r-- | Tests/Game/test_OutputBlock.gd | 32 | ||||
| -rw-r--r-- | Tests/Game/test_StatusLine.gd | 32 |
7 files changed, 300 insertions, 0 deletions
diff --git a/Tests/Game/CommandParserTestBase.gd b/Tests/Game/CommandParserTestBase.gd new file mode 100644 index 0000000..46b8b05 --- /dev/null +++ b/Tests/Game/CommandParserTestBase.gd @@ -0,0 +1,29 @@ +extends GutTest + +class_name CommandParserTestBase + +const CommandParser = preload("res://Scripts/Game/CommandParser.cs") + +var _instance: CommandParser + +func _to_bits(number: int, bits: int) -> Array: + var result = [] + for bit in bits: + result.append(number & 1) + number = number >> 1 + return result + +func before_each(): + _instance = autofree(CommandParser.new()) + +func generate_capitalization_permutations(text: String) -> Array: + var result = [] + + for permutation in pow(2, text.length()): + var mask = _to_bits(permutation, text.length()) + var copy = String(text) + for index in len(mask): + if mask[index] == 1: + copy[index] = copy[index].to_upper() + result.append(copy) + return result; diff --git a/Tests/Game/Commands/test_LookCommand.gd b/Tests/Game/Commands/test_LookCommand.gd new file mode 100644 index 0000000..558efc1 --- /dev/null +++ b/Tests/Game/Commands/test_LookCommand.gd @@ -0,0 +1,58 @@ +extends CommandParserTestBase + +const LookCommand = preload("res://Scripts/Game/Commands/LookCommand.cs") + +var _around_permutations = generate_capitalization_permutations('around') +var _at_permutations = generate_capitalization_permutations('at') +var _look_permutations = generate_capitalization_permutations('look') + +func parse(input: String) -> LookCommand: + return autofree(_instance.TryParse(input)) + +func after_all(): + assert_no_new_orphans() + +func test_parsing_look_command_without_an_argument_returns_non_null(): + assert_not_null(parse('look')) + +func test_parsing_look_command_is_case_insensitive(permutation=use_parameters(_look_permutations)): + assert_not_null(parse(permutation)) + +func test_parsing_look_command_without_an_argument_returns_look_command_with_an_emtpy_target(): + assert_eq('', parse('look').Target) + +func test_parsing_look_at_command_is_case_insensitive(permutation=use_parameters(_at_permutations)): + assert_not_null(parse('look ' + permutation)) + +func test_parsing_look_at_command_without_further_arguments_returns_look_command_with_an_emtpy_target(): + assert_eq('', parse('look at').Target) + +func test_parsing_look_at_command_without_further_arguments_returns_look_command_with_non_null_modifier(): + assert_not_null(parse('look at').Modifier) + +func test_parsing_look_at_command_without_further_arguments_returns_look_command_with_at_modifier(): + assert_eq('At', parse('look at').ModifierAsString) + +func test_parsing_look_at_command_with_more_arguments_returns_look_command_with_non_empty_target(): + assert_ne('', parse('look at door on the left').Target) + +func test_parsing_look_at_command_with_an_additional_argument_returns_look_command_with_the_additional_argument_as_the_target(): + assert_eq('window', parse('look at window').Target) + +func test_parsing_look_at_command_with_multiple_additional_arguments_returns_look_command_with_the_additional_arguments_as_the_target(): + assert_eq('table near the door', parse('look at table near the door').Target) + +func test_parsing_look_around_command_is_case_insensitive(permutation=use_parameters(_around_permutations)): + assert_not_null(parse('look ' + permutation)) + +func test_parsing_look_around_command_without_further_arguments_returns_look_command_with_an_empty_target(): + assert_eq('', parse('look around').Target) + +func test_parsing_look_around_command_without_further_arguments_returns_look_command_with_non_null_modifier(): + assert_not_null(parse('look around').Modifier) + +func test_parsing_look_around_command_without_further_arguments_returns_look_command_with_around_modifier(): + assert_eq('Around', parse('look around').ModifierAsString) + +func test_parsing_look_around_command_ignores_all_additional_arguments(): + assert_eq('', parse('look around the room').Target) diff --git a/Tests/Game/test_CommandParser.gd b/Tests/Game/test_CommandParser.gd new file mode 100644 index 0000000..659916e --- /dev/null +++ b/Tests/Game/test_CommandParser.gd @@ -0,0 +1,12 @@ +extends CommandParserTestBase + +const Command = preload("res://Scripts/Game/Command.cs") + +func parse(input: String) -> Command: + return autofree(_instance.TryParse(input)) + +func after_all(): + assert_no_new_orphans() + +func test_parsing_the_empty_string_returns_null(): + assert_null(parse('')) diff --git a/Tests/Game/test_Input.gd b/Tests/Game/test_Input.gd new file mode 100644 index 0000000..fca14e5 --- /dev/null +++ b/Tests/Game/test_Input.gd @@ -0,0 +1,86 @@ +extends GutTest + +const Scene = preload('res://Scenes/Game/Input.tscn') +const GameInput = preload('res://Scripts/Game/Input.cs') + +var _instance: GameInput = null +var _sender = InputSender.new(Input) + +const _invalid_input = 'ThisIsNotAValidCommand!' +const _valid_input = 'look at door' +const _command_submitted = 'CommandSubmitted' +const _unknown_input_submitted = 'UnknownInputSubmitted' + +func _get_input_node() -> LineEdit: + return _instance.get_node('%TextInput') as LineEdit + +func _set_input_text(text): + var textInputNode = _get_input_node() + textInputNode.text = text + textInputNode.emit_signal('text_changed', textInputNode.text) + +func before_each(): + _instance = add_child_autofree(Scene.instance()) + +func after_each(): + _sender.release_all() + _sender.clear() + +func after_all(): + assert_no_new_orphans() + +func test_can_instantiate(): + assert_not_null(_instance) + +func test_has_CommandSubmitted_signal(): + assert_has_signal(_instance, _command_submitted) + +func test_has_UnknownInputSubmitted_signal(): + assert_has_signal(_instance, _unknown_input_submitted) + +func test_TextInput_has_focus_when_scene_is_instantiated(): + assert_true(_get_input_node().has_focus()) + +func test_CommandSubmitted_signal_is_not_emitted_when_enter_is_pressed_without_text_in_TextInput(): + watch_signals(_instance) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_not_emitted(_instance, _command_submitted) + +func test_UknownInputSumbmitted_signal_is_not_emitted_when_enter_is_pressed_without_text_in_TextInput(): + watch_signals(_instance) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_not_emitted(_instance, _unknown_input_submitted) + +func test_CommandSubmitted_signal_is_emitted_when_enter_is_pressed_with_a_valid_command_in_TextInput(): + watch_signals(_instance) + _set_input_text(_valid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_emitted(_instance, _command_submitted) + +func test_UnknownInputSubmitted_signal_is_not_emitted_when_enter_is_pressed_with_an_invalid_command_in_TextInput(): + watch_signals(_instance) + _set_input_text(_valid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_not_emitted(_instance, _unknown_input_submitted) + +func test_CommandSubmitted_signal_is_not_emitted_when_enter_is_pressed_with_an_invalid_command_in_TextInput(): + watch_signals(_instance) + _set_input_text(_invalid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_not_emitted(_instance, _command_submitted) + +func test_UnknownInputSubmitted_signal_is_emitted_when_enter_is_pressed_with_a_valid_command_in_TextInput(): + watch_signals(_instance) + _set_input_text(_invalid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_signal_emitted(_instance, _unknown_input_submitted) + +func test_TextInput_is_empty_after_submitting_a_valid_command(): + _set_input_text(_valid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_true(_get_input_node().text.empty()) + +func test_TextInput_is_empty_after_submitting_an_invalid_command(): + _set_input_text(_invalid_input) + yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle') + assert_true(_get_input_node().text.empty()) diff --git a/Tests/Game/test_Output.gd b/Tests/Game/test_Output.gd new file mode 100644 index 0000000..f3793de --- /dev/null +++ b/Tests/Game/test_Output.gd @@ -0,0 +1,51 @@ +extends GutTest + +const Scene = preload('res://Scenes/Game/Output.tscn') +const GameOutput = preload('res://Scripts/Game/Output.cs') + +var _instance: GameOutput = null + +func _get_line_container() -> VBoxContainer: + return _instance.get_node('%LineContainer') as VBoxContainer + +func after_each(): + yield(yield_frames(1), YIELD) + +func before_each(): + var scene = Scene.instance() + scene.OutputBlockScene = load('res://Scenes/Game/OutputBlock.tscn') + _instance = add_child_autofree(scene) + +func after_all(): + assert_no_new_orphans() + +func test_can_be_instantiated(): + assert_not_null(_instance) + +func test_LineContainer_is_empty_after_instantiation(): + assert_true(_get_line_container().get_children().empty()) + +func test_TextBlocks_is_empty_after_instantiation(): + assert_true(_instance.TextBlocks.empty()) + +func test_LineContainer_is_not_empty_after_calling_Push_with_a_non_empty_string_as_text(): + _instance.Push('this is some test data') + assert_false(_get_line_container().get_children().empty()) + +func test_LineContainer_is_empty_after_calling_Push_with_an_empty_string_as_text(): + _instance.Push('') + assert_true(_get_line_container().get_children().empty()) + +func test_TextBlocks_is_not_empty_after_calling_Push_with_a_non_empty_string_as_text(): + _instance.Push('this is some test data') + assert_false(_instance.TextBlocks.empty()) + +func test_TextBlocks_is_empty_after_calling_Push_with_an_empty_string_as_text(): + _instance.Push('') + assert_true(_instance.TextBlocks.empty()) + +func test_TextBlocks_contains_all_pushed_texts_in_the_push_order(): + var texts = ['text block a', 'text block b'] + for text in texts: + _instance.Push(text) + assert_eq(_instance.TextBlocks, texts) diff --git a/Tests/Game/test_OutputBlock.gd b/Tests/Game/test_OutputBlock.gd new file mode 100644 index 0000000..c7addfe --- /dev/null +++ b/Tests/Game/test_OutputBlock.gd @@ -0,0 +1,32 @@ +extends GutTest + +const Scene = preload("res://Scenes/Game/OutputBlock.tscn") +const OutputBlock = preload("res://Scripts/Game/OutputBlock.cs") + +const _input_text_changed = 'InputTextChanged' +const _output_text_changed = 'OutputTextChanged' +const _test_data = 'This is some test data' +var _instance: OutputBlock = null + + +func before_each(): + _instance = add_child_autofree(Scene.instance()) + +func after_all(): + assert_no_new_orphans() + +func test_can_instantiate(): + assert_not_null(_instance) + +func test_Content_is_empty_after_instantiation(): + assert_eq(_instance.Content, '') + +func test_ContentLabel_bbcode_enabled_is_enabled_after_instantiation(): + assert_true(_instance.get_node('ContentLabel').bbcode_enabled) + +func test_ContentLabel_is_empty_after_instantiation(): + assert_eq(_instance.get_node('ContentLabel').bbcode_text, '') + +func test_setting_Content_sets_ContentLabel_bbcode_text(): + _instance.Content = 'test' + assert_eq(_instance.get_node('ContentLabel').bbcode_text, 'test') diff --git a/Tests/Game/test_StatusLine.gd b/Tests/Game/test_StatusLine.gd new file mode 100644 index 0000000..b22f624 --- /dev/null +++ b/Tests/Game/test_StatusLine.gd @@ -0,0 +1,32 @@ +extends GutTest + +const Scene = preload("res://Scenes/Game/StatusLine.tscn") +const StatusLine = preload("res://Scripts/Game/StatusLine.cs") + +var _instance: StatusLine = null + +func _get_title_label() -> RichTextLabel: + return _instance.get_node('%TitleLabel') as RichTextLabel + +func before_each(): + _instance = add_child_autofree(Scene.instance()) + +func after_all(): + assert_no_new_orphans() + +func test_can_be_instantiated(): + assert_not_null(_instance) + +func test_Title_is_empty_after_instantiation(): + assert_true(_instance.Title.empty()) + +func test_TitleLabel_is_empty_after_instantiation(): + assert_true(_get_title_label().text.empty()) + +func test_setting_Title_to_a_non_empty_string_makes_TitleLable_non_empty(): + _instance.Title = 'this is a test title' + assert_false(_get_title_label().text.empty()) + +func test_setting_Title_sets_the_bbcode_text_property_on_TitleLabel(): + _instance.Title = '[wave]this is a test title[/wave]' + assert_false(_get_title_label().bbcode_text.empty()) |
