summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Scenes/Game/Game.tscn8
-rw-r--r--Scenes/Game/Input.tscn6
-rw-r--r--Scenes/Game/Output.tscn16
-rw-r--r--Scenes/Game/OutputBlock.tscn5
-rw-r--r--Scenes/Game/StatusLine.tscn3
-rw-r--r--Scripts/Game/Input.cs11
-rw-r--r--Scripts/Game/Output.cs2
-rw-r--r--Scripts/Game/StatusLine.cs4
-rw-r--r--Tests/ComponentTests/test_InputContainer.gd80
-rw-r--r--Tests/ComponentTests/test_OutputRow.gd46
-rw-r--r--Tests/ComponentTests/test_StartMenu.gd60
-rw-r--r--Tests/Game/CommandParserTestBase.gd (renamed from Tests/ComponentTests/ParserTests/CommandParserTestBase.gd)2
-rw-r--r--Tests/Game/Commands/test_LookCommand.gd (renamed from Tests/ComponentTests/ParserTests/test_LookCommand.gd)5
-rw-r--r--Tests/Game/test_CommandParser.gd (renamed from Tests/ComponentTests/ParserTests/test_CommandParser.gd)5
-rw-r--r--Tests/Game/test_Input.gd86
-rw-r--r--Tests/Game/test_Output.gd51
-rw-r--r--Tests/Game/test_OutputBlock.gd32
-rw-r--r--Tests/Game/test_StatusLine.gd32
-rw-r--r--project.godot2
19 files changed, 242 insertions, 214 deletions
diff --git a/Scenes/Game/Game.tscn b/Scenes/Game/Game.tscn
index e51a434..7ea6324 100644
--- a/Scenes/Game/Game.tscn
+++ b/Scenes/Game/Game.tscn
@@ -14,9 +14,17 @@ script = ExtResource( 4 )
[node name="StatusLine" parent="." instance=ExtResource( 1 )]
unique_name_in_owner = true
+Title = "Adventure Title"
[node name="Output" parent="." instance=ExtResource( 2 )]
unique_name_in_owner = true
+anchor_right = 0.0
+anchor_bottom = 0.0
+margin_top = 31.0
+margin_right = 640.0
+margin_bottom = 451.0
+size_flags_horizontal = 3
+size_flags_vertical = 3
OutputBlockScene = ExtResource( 5 )
[node name="Input" parent="." instance=ExtResource( 3 )]
diff --git a/Scenes/Game/Input.tscn b/Scenes/Game/Input.tscn
index 627a0ac..baf5315 100644
--- a/Scenes/Game/Input.tscn
+++ b/Scenes/Game/Input.tscn
@@ -14,14 +14,14 @@ margin_top = 2.0
margin_right = 632.0
margin_bottom = 27.0
-[node name="Prompt" type="Label" parent="Container"]
+[node name="PromptLabel" type="Label" parent="Container"]
unique_name_in_owner = true
margin_right = 20.0
margin_bottom = 25.0
theme_type_variation = "InvertedLabel"
text = "?>"
-[node name="Text" type="LineEdit" parent="Container"]
+[node name="TextInput" type="LineEdit" parent="Container"]
unique_name_in_owner = true
margin_left = 28.0
margin_right = 624.0
@@ -35,4 +35,4 @@ caret_blink = true
unique_name_in_owner = true
script = ExtResource( 2 )
-[connection signal="text_entered" from="Container/Text" to="." method="OnTextEntered"]
+[connection signal="text_entered" from="Container/TextInput" to="." method="OnTextEntered"]
diff --git a/Scenes/Game/Output.tscn b/Scenes/Game/Output.tscn
index 68f36f4..70ca6c3 100644
--- a/Scenes/Game/Output.tscn
+++ b/Scenes/Game/Output.tscn
@@ -4,30 +4,26 @@
[ext_resource path="res://Scripts/Game/Output.cs" type="Script" id=2]
[node name="Output" type="PanelContainer"]
-margin_top = 31.0
-margin_right = 640.0
-margin_bottom = 451.0
-size_flags_horizontal = 3
-size_flags_vertical = 3
+anchor_right = 1.0
+anchor_bottom = 1.0
script = ExtResource( 2 )
[node name="ScrollContainer" type="ScrollContainer" parent="."]
margin_left = 8.0
margin_top = 2.0
margin_right = 632.0
-margin_bottom = 418.0
+margin_bottom = 478.0
mouse_filter = 1
-size_flags_horizontal = 3
-size_flags_vertical = 3
scroll_horizontal_enabled = false
[node name="LineContainer" type="VBoxContainer" parent="ScrollContainer"]
unique_name_in_owner = true
margin_right = 624.0
-margin_bottom = 54.0
+margin_bottom = 476.0
size_flags_horizontal = 3
+size_flags_vertical = 3
[node name="OutputBlock" parent="ScrollContainer/LineContainer" instance=ExtResource( 1 )]
anchor_right = 0.0
margin_right = 624.0
-margin_bottom = 54.0
+margin_bottom = 27.0
diff --git a/Scenes/Game/OutputBlock.tscn b/Scenes/Game/OutputBlock.tscn
index aa1d60f..f4fc1dd 100644
--- a/Scenes/Game/OutputBlock.tscn
+++ b/Scenes/Game/OutputBlock.tscn
@@ -5,12 +5,11 @@
[node name="OutputBlock" type="MarginContainer"]
anchor_right = 1.0
script = ExtResource( 1 )
-Content = "This is where the output goes."
[node name="ContentLabel" type="RichTextLabel" parent="."]
unique_name_in_owner = true
margin_right = 640.0
-margin_bottom = 54.0
-text = "This is where the output goes and it should wrap correctly if it goes beyond the screen width."
+margin_bottom = 27.0
+bbcode_enabled = true
fit_content_height = true
scroll_active = false
diff --git a/Scenes/Game/StatusLine.tscn b/Scenes/Game/StatusLine.tscn
index 1392507..fc167ec 100644
--- a/Scenes/Game/StatusLine.tscn
+++ b/Scenes/Game/StatusLine.tscn
@@ -7,7 +7,6 @@ margin_right = 640.0
margin_bottom = 31.0
theme_type_variation = "InvertedPanelContainer"
script = ExtResource( 1 )
-Title = "Adventure Title"
[node name="Container" type="HBoxContainer" parent="."]
margin_left = 8.0
@@ -24,6 +23,6 @@ size_flags_horizontal = 3
size_flags_vertical = 6
theme_type_variation = "InvertedRichTextLabel"
bbcode_enabled = true
-text = "This is where the title goes."
+text = "This is where the title goes"
fit_content_height = true
scroll_active = false
diff --git a/Scripts/Game/Input.cs b/Scripts/Game/Input.cs
index 2342ac2..90a9962 100644
--- a/Scripts/Game/Input.cs
+++ b/Scripts/Game/Input.cs
@@ -8,17 +8,20 @@ namespace Texty.Scripts.Game
[Signal] public delegate void UnknownInputSubmitted(string text);
private CommandParser CommandParser => GetNodeOrNull<CommandParser>($"%{nameof(CommandParser)}");
- private Label Prompt => GetNodeOrNull<Label>($"%{nameof(Prompt)}");
- private LineEdit Text => GetNodeOrNull<LineEdit>($"%{nameof(Text)}");
+ private Label PromptLabel => GetNodeOrNull<Label>($"%{nameof(PromptLabel)}");
+ private LineEdit TextInput => GetNodeOrNull<LineEdit>($"%{nameof(TextInput)}");
public override void _Ready()
{
- Text.GrabFocus();
+ TextInput.GrabFocus();
}
public void OnTextEntered(string text)
{
- Text.Clear();
+ if (text.Empty())
+ return;
+
+ TextInput.Clear();
var command = CommandParser.TryParse(text);
if (command != null)
EmitSignal(nameof(CommandSubmitted), command);
diff --git a/Scripts/Game/Output.cs b/Scripts/Game/Output.cs
index be943f7..abd3328 100644
--- a/Scripts/Game/Output.cs
+++ b/Scripts/Game/Output.cs
@@ -22,6 +22,7 @@ namespace Texty.Scripts.Game
{
Debug.Assert(OutputBlockScene != null, "OutputBlockScene has not been configured!");
Debug.Assert(OutputBlockScene.CanInstance(), "OutputBlockScene can not be instanced!");
+ Clear();
}
public void Clear()
@@ -35,6 +36,7 @@ namespace Texty.Scripts.Game
public void Push(string text)
{
+ if (text.Empty()) return;
var block = OutputBlockScene.Instance<OutputBlock>();
block.Content = text;
LineContainer.AddChild(block);
diff --git a/Scripts/Game/StatusLine.cs b/Scripts/Game/StatusLine.cs
index ef98a0a..8e19cb4 100644
--- a/Scripts/Game/StatusLine.cs
+++ b/Scripts/Game/StatusLine.cs
@@ -4,7 +4,7 @@ namespace Texty.Scripts.Game
{
public class StatusLine : PanelContainer
{
- private string _titleText = "Title Text";
+ private string _titleText = "";
private RichTextLabel TitleLabel => GetNodeOrNull<RichTextLabel>($"%{nameof(TitleLabel)}");
[Export]
@@ -15,7 +15,7 @@ namespace Texty.Scripts.Game
{
_titleText = value;
if (TitleLabel != null)
- TitleLabel.Text = GodotSharp.Singleton.Tr(value);
+ TitleLabel.BbcodeText = GodotSharp.Singleton.Tr(value);
}
}
diff --git a/Tests/ComponentTests/test_InputContainer.gd b/Tests/ComponentTests/test_InputContainer.gd
deleted file mode 100644
index 5289903..0000000
--- a/Tests/ComponentTests/test_InputContainer.gd
+++ /dev/null
@@ -1,80 +0,0 @@
-extends GutTest
-
-const Scene = preload('res://Scenes/InputContainer.tscn')
-const InputContainer = preload('res://Scripts/InputContainer.cs')
-
-var _instance: InputContainer = null
-var _sender = InputSender.new(Input)
-const _test_data = 'This is some test data'
-const _input_submitted = 'InputSubmitted'
-
-func _set_input_text(text):
- _instance.InputField.text = text
- _instance.InputField.emit_signal('text_changed', _instance.InputField.text)
-
-func before_each():
- _instance = add_child_autofree(Scene.instance())
- yield(yield_frames(1), YIELD)
-
-func after_each():
- _sender.release_all()
- _sender.clear()
-
-func test_can_instantiate():
- assert_not_null(_instance)
-
-func test_has_InputSubmitted_signal():
- assert_has_signal(_instance, _input_submitted)
-
-func test_has_InputField():
- assert_not_null(_instance.InputField)
-
-func test_InputField_has_focus_when_scene_is_instantiated():
- assert_true(_instance.InputField.has_focus())
-
-func test_InputSubmitted_signal_is_not_emitted_when_enter_is_pressed_without_text_in_InputField():
- watch_signals(_instance)
- yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle')
- assert_signal_not_emitted(_instance, _input_submitted)
-
-func test_InputSubmitted_signal_is_emitted_when_enter_is_pressed_with_text_in_InputField():
- watch_signals(_instance)
- _set_input_text(_test_data)
- yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle')
- assert_signal_emitted(_instance, _input_submitted)
-
-func test_InputField_is_empty_after_text_is_submitted():
- _set_input_text(_test_data)
- yield(UiHelpers.press_key(_sender, KEY_ENTER), 'idle')
- assert_eq(_instance.InputField.text, '')
-
-func test_has_SubmitButton():
- assert_not_null(_instance.SubmitButton)
-
-func test_SubmitButton_is_disable_after_scene_was_instantiated():
- assert_true(_instance.SubmitButton.disabled)
-
-func test_SubmitButton_is_disabled_when_InputField_is_set_to_empty():
- _set_input_text('')
- assert_true(_instance.SubmitButton.disabled)
-
-func test_SubmitButton_is_enabled_when_InputField_is_set_to_some_text():
- _set_input_text(_test_data)
- assert_false(_instance.SubmitButton.disabled)
-
-func test_InputSubmitted_signal_is_not_emitted_when_SubmitButton_is_clicked_without_text_in_InputField():
- watch_signals(_instance)
- _set_input_text('')
- yield(UiHelpers.click_control(_sender, _instance.SubmitButton), 'idle')
- assert_signal_not_emitted(_instance, _input_submitted)
-
-func test_InputSubmitted_signal_is_emitted_when_SubmitButton_is_clicked_with_text_in_InputField():
- watch_signals(_instance)
- _set_input_text(_test_data)
- yield(UiHelpers.click_control(_sender, _instance.SubmitButton), 'idle')
- assert_signal_emitted(_instance, _input_submitted)
-
-func test_InputField_is_empty_after_text_is_submitted_via_SubmitButton():
- _set_input_text(_test_data)
- yield(UiHelpers.click_control(_sender, _instance.SubmitButton), 'idle')
- assert_eq(_instance.InputField.text, '')
diff --git a/Tests/ComponentTests/test_OutputRow.gd b/Tests/ComponentTests/test_OutputRow.gd
deleted file mode 100644
index 6e782de..0000000
--- a/Tests/ComponentTests/test_OutputRow.gd
+++ /dev/null
@@ -1,46 +0,0 @@
-extends GutTest
-
-const Scene = preload("res://Scenes/OutputRow.tscn")
-const OutputRow = preload("res://Scripts/OutputRow.cs")
-
-const _input_text_changed = 'InputTextChanged'
-const _output_text_changed = 'OutputTextChanged'
-const _test_data = 'This is some test data'
-var _instance: OutputRow = null
-
-
-func before_each():
- _instance = add_child_autofree(Scene.instance())
-
-func test_can_instantiate():
- assert_not_null(_instance)
-
-func test_InputText_is_empty_after_instantiation():
- assert_eq(_instance.InputText, '')
-
-func test_OutputText_is_empty_after_instantiation():
- assert_eq(_instance.OutputText, '')
-
-func test_Input_contains_text_assigned_to_InputText():
- _instance.InputText = _test_data
- assert_eq(_instance.Input.text, _test_data)
-
-func test_Output_contains_text_assigned_to_OutputText():
- _instance.OutputText = _test_data
- assert_eq(_instance.Output.text, _test_data)
-
-func test_has_InputTextChanged_signal():
- assert_has_signal(_instance, _input_text_changed)
-
-func test_has_OutputTextChanged_signal():
- assert_has_signal(_instance, _output_text_changed)
-
-func test_InputTextChanged_signal_is_emitted_when_setting_InputText():
- watch_signals(_instance)
- _instance.InputText = _test_data
- assert_signal_emitted(_instance, _input_text_changed)
-
-func test_OutputTextChanged_signal_is_emitted_when_setting_OutputText():
- watch_signals(_instance)
- _instance.OutputText = _test_data
- assert_signal_emitted(_instance, _output_text_changed)
diff --git a/Tests/ComponentTests/test_StartMenu.gd b/Tests/ComponentTests/test_StartMenu.gd
deleted file mode 100644
index 8563a67..0000000
--- a/Tests/ComponentTests/test_StartMenu.gd
+++ /dev/null
@@ -1,60 +0,0 @@
-extends GutTest
-
-const Scene = preload('res://Scenes/StartMenu.tscn')
-const StartMenu = preload('res://Scripts/StartMenu.cs')
-
-var _instance: StartMenu = null
-var _sender = InputSender.new(Input)
-const _quit_game = 'QuitGame'
-const _show_credits = 'ShowCredits'
-const _start_game = 'StartGame'
-
-func before_each():
- _instance = add_child_autofree(Scene.instance())
- yield(_instance, 'visibility_changed')
-
-func after_each():
- _sender.release_all()
- _sender.clear()
-
-func test_can_instantiate():
- assert_not_null(_instance)
-
-func test_StartButton_is_focused_when_scene_becomes_visible():
- assert_true(_instance.StartButton.has_focus())
-
-func test_has_QuitGame_signal():
- assert_has_signal(_instance, _quit_game)
-
-func test_has_ShowCredits_signal():
- assert_has_signal(_instance, _show_credits)
-
-func test_has_StartGame_signal():
- assert_has_signal(_instance, _start_game)
-
-func test_clicking_the_Credits_button_emits_ShowCredits_signal():
- watch_signals(_instance)
- yield(UiHelpers.click_control(_sender, _instance.CreditsButton), 'idle')
- assert_signal_emitted(_instance, _show_credits)
-
-func test_clicking_the_Quit_button_emits_QuitGame_signal():
- watch_signals(_instance)
- yield(UiHelpers.click_control(_sender, _instance.QuitButton), 'idle')
- assert_signal_emitted(_instance, _quit_game)
-
-func test_clicking_the_Start_button_emits_StartGame_signal():
- watch_signals(_instance)
- yield(UiHelpers.click_control(_sender, _instance.StartButton), 'idle')
- assert_signal_emitted(_instance, _start_game)
-
-func test_Credits_button_label_is_localized():
- var label = _instance.CreditsButton.text
- assert_ne(label, tr(label))
-
-func test_Quit_button_label_is_localized():
- var label = _instance.QuitButton.text
- assert_ne(label, tr(label))
-
-func test_Start_button_label_is_localize():
- var label = _instance.StartButton.text
- assert_ne(label, tr(label))
diff --git a/Tests/ComponentTests/ParserTests/CommandParserTestBase.gd b/Tests/Game/CommandParserTestBase.gd
index 6e452cb..46b8b05 100644
--- a/Tests/ComponentTests/ParserTests/CommandParserTestBase.gd
+++ b/Tests/Game/CommandParserTestBase.gd
@@ -2,7 +2,7 @@ extends GutTest
class_name CommandParserTestBase
-const CommandParser = preload("res://Scripts/CommandParser.cs")
+const CommandParser = preload("res://Scripts/Game/CommandParser.cs")
var _instance: CommandParser
diff --git a/Tests/ComponentTests/ParserTests/test_LookCommand.gd b/Tests/Game/Commands/test_LookCommand.gd
index 32268b0..558efc1 100644
--- a/Tests/ComponentTests/ParserTests/test_LookCommand.gd
+++ b/Tests/Game/Commands/test_LookCommand.gd
@@ -1,6 +1,6 @@
extends CommandParserTestBase
-const LookCommand = preload("res://Scripts/Commands/LookCommand.cs")
+const LookCommand = preload("res://Scripts/Game/Commands/LookCommand.cs")
var _around_permutations = generate_capitalization_permutations('around')
var _at_permutations = generate_capitalization_permutations('at')
@@ -9,6 +9,9 @@ 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'))
diff --git a/Tests/ComponentTests/ParserTests/test_CommandParser.gd b/Tests/Game/test_CommandParser.gd
index bdb14a6..659916e 100644
--- a/Tests/ComponentTests/ParserTests/test_CommandParser.gd
+++ b/Tests/Game/test_CommandParser.gd
@@ -1,9 +1,12 @@
extends CommandParserTestBase
-const Command = preload("res://Scripts/Command.cs")
+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())
diff --git a/project.godot b/project.godot
index 6b4fafa..3f00c81 100644
--- a/project.godot
+++ b/project.godot
@@ -12,7 +12,7 @@ _global_script_classes=[ {
"base": "GutTest",
"class": "CommandParserTestBase",
"language": "GDScript",
-"path": "res://Tests/ComponentTests/ParserTests/CommandParserTestBase.gd"
+"path": "res://Tests/Game/CommandParserTestBase.gd"
}, {
"base": "Reference",
"class": "GutHookScript",