Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
using System.Linq;
using System.Threading.Tasks;
using Godot;
using GodotTestDriver.Drivers;
using GodotXUnitApi;
using Xunit;
namespace OpenScadGraphEditor.Tests
{
public class ModuleTests : MainWindowTest
{
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task AddingAModuleWorks()
{
// when
// press the add module button
await MainWindow.AddModuleButton.ClickCenter();
// and enter a module name in the invokable refactoring dialog
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
// and press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// then
// we have a tab with the module and this tab is selected
Assert.Equal("test_module", MainWindow.TabContainer.SelectedTabTitle);
// a single node is shown in the graph editor
Assert.Single(MainWindow.GraphEditor.Nodes);
var node = MainWindow.GraphEditor.Nodes.First();
// and the node has the correct title
Assert.Equal("test_module", node.NodeTitle);
// and the node has no output ports
Assert.Equal(0, node.OutputPortCount);
// and the node has no input ports
Assert.Equal(0, node.InputPortCount);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task AddingAModuleWithParametersWorks()
{
// when
// press the add module button
await MainWindow.AddModuleButton.ClickCenter();
// and enter a module name in the invokable refactoring dialog
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
// and i add a parameter
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
var parameterLine = MainWindow.InvokableRefactorDialog.ParameterLines.First();
// and i set the parameter name to "foo"
await parameterLine.NameEdit.Type("foo");
// and i select the type to be "boolean"
await parameterLine.Type.SelectItemWithText("boolean");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// then
// a single node is shown in the graph editor
Assert.Single(MainWindow.GraphEditor.Nodes);
var node = MainWindow.GraphEditor.Nodes.First();
// and the node has the correct title
Assert.Equal("test_module", node.NodeTitle);
// and the node has no input ports
Assert.Equal(0, node.InputPortCount);
// and the node has one output port
Assert.Equal(1, node.OutputPortCount);
// and the node has a toggle button to enable a literal for the output port
Assert.True(node.ToggleButton(Port.Output(0)).IsVisible);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task RenamingAModuleWorks()
{
// when
// i add a module
await MainWindow.AddModuleButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// and i create a call to this module in main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
await MainWindow.AddNode("test_module");
// and i then go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i right-click the module entrypoint
await MainWindow.GraphEditor.Nodes.First().ClickAtSelectionSpot(ButtonList.Right);
// and i select the "Refactor test_module" menu item
await MainWindow.PopupMenu.SelectItemWithText("Refactor test_module");
// and i enter a new name in the invokable refactoring dialog
await MainWindow.InvokableRefactorDialog.NameEdit.Type("renamed_module");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// then
// the module is renamed
Assert.Equal("renamed_module", MainWindow.GraphEditor.Nodes.First().NodeTitle);
// the tab title is also renamed
Assert.Equal("renamed_module", MainWindow.TabContainer.SelectedTabTitle);
// and when i get back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// and the call to the module is renamed as well
Assert.Equal("renamed_module", MainWindow.GraphEditor.Nodes.First().NodeTitle);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task MakingAParameterOptionalWorks()
{
// when
// i add a module
await MainWindow.AddModuleButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
// and i add a parameter
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
var parameterLine = MainWindow.InvokableRefactorDialog.ParameterLines.First();
// and i set the parameter name to "foo"
await parameterLine.NameEdit.Type("foo");
// and i select the type to be "boolean"
await parameterLine.Type.SelectItemWithText("boolean");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// and i create a call to this module in main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
await MainWindow.AddNode("test_module");
var moduleInvocation = MainWindow.GraphEditor.Nodes.First();
// then
// the module has no toggle button for the parameter, because it is mandatory
Assert.False(moduleInvocation.ToggleButton(Port.Input(0)).IsVisible);
// and i then go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i click the toggle button on the entrypoint parameter
// so it is now optional
var entrypointNode = MainWindow.GraphEditor.Nodes.First();
await entrypointNode.ToggleButton(Port.Output(0)).ClickCenter();
// then
// the entrypoint now shows a checkbox for the parameter default value
Assert.True(entrypointNode.CheckBoxLiteral(Port.Output(0)).IsVisible);
// and when i get back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// the module invocation now has a toggle button for setting the parameter value
Assert.True(moduleInvocation.ToggleButton(Port.Input(0)).IsVisible);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task ReorderingParametersWorks()
{
// when
// i add a module
await MainWindow.AddModuleButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
// and i add two parameters
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
var lines = MainWindow.InvokableRefactorDialog.ParameterLines.ToList();
var firstLine = lines[0];
var secondLine = lines[1];
// and i set the first parameter name to "foo"
await firstLine.NameEdit.Type("foo");
// and i select the type to be "vector3"
await firstLine.Type.SelectItemWithText("vector3");
// and i set the second parameter name to "bar"
await secondLine.NameEdit.Type("bar");
// and i select the type to be "boolean"
await secondLine.Type.SelectItemWithText("boolean");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
var moduleEntryPoint = MainWindow.GraphEditor.Nodes.First();
// and i add a cube node
await MainWindow.AddNode("cube");
var cubeNode = MainWindow.GraphEditor.Nodes.Last();
// and i connect the first output of the module entrypoint to the first input of the cube node
await moduleEntryPoint.DragConnection(Port.Output(0), cubeNode, Port.Input(0));
// and i connect the second output of the module entrypoint to the second input of the cube node
await moduleEntryPoint.DragConnection(Port.Output(1), cubeNode, Port.Input(1));
// and i create a call to this module in main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
await MainWindow.AddNode("test_module");
var moduleInvocation = MainWindow.GraphEditor.Nodes.First();
// and i move this a bit to the right
await moduleInvocation.DragByOwnSize(2, 0);
// and i add a construct vector3
await MainWindow.AddNode("Construct Vector3");
var constructVector3 = MainWindow.GraphEditor.Nodes.Last();
// and i move it a bit to the left and up
await constructVector3.DragByOwnSize(-2, -1);
// and i add a boolean "AND"
await MainWindow.AddNode("Boolean And");
var booleanAnd = MainWindow.GraphEditor.Nodes.Last();
// and i move it a bit to the left and down
await booleanAnd.DragByOwnSize(-2, 1);
// and i connect the output of the construct vector3 to the first input of the module invocation
await constructVector3.DragConnection(Port.Output(0), moduleInvocation, Port.Input(0));
// and i connect the output of the boolean and to the second input of the module invocation
await booleanAnd.DragConnection(Port.Output(0), moduleInvocation, Port.Input(1));
// and i go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i right-click the module entry point
await moduleEntryPoint.ClickAtSelectionSpot(ButtonList.Right);
// and i select the "Refactor test_module" menu item
await MainWindow.PopupMenu.SelectItemWithText("Refactor test_module");
// and i click the "move up" button in the second parameter row
await MainWindow.InvokableRefactorDialog.ParameterLines.Skip(1).First().UpButton.ClickCenter();
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// then
// the name of the first parameter is now "bar"
Assert.Equal("bar", moduleEntryPoint.PortLabel(Port.Output(0)).Text);
// the name of the second parameter is now "foo"
Assert.Equal("foo", moduleEntryPoint.PortLabel(Port.Output(1)).Text);
// the first output of the module entry point is now connected to the second input of the cube node
Assert.True(
MainWindow.GraphEditor.HasConnection(moduleEntryPoint, Port.Output(0), cubeNode, Port.Input(1))
);
// the second output of the module entry point is now connected to the first input of the cube node
Assert.True(
MainWindow.GraphEditor.HasConnection(moduleEntryPoint, Port.Output(1), cubeNode, Port.Input(0))
);
// and when i go back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// the output of the "construct vector3" is now connected to the second input of the module invocation
Assert.True(
MainWindow.GraphEditor.HasConnection(constructVector3, Port.Output(0), moduleInvocation, Port.Input(1))
);
// the output of the "boolean and" is now connected to the first input of the module invocation
Assert.True(
MainWindow.GraphEditor.HasConnection(booleanAnd, Port.Output(0), moduleInvocation, Port.Input(0))
);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task AddingAParameterWorks()
{
// when
// i add a module
await MainWindow.AddModuleButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
var moduleEntryPoint = MainWindow.GraphEditor.Nodes.First();
// and i add an instance of this to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
await MainWindow.AddNode("test_module");
var moduleInvocation = MainWindow.GraphEditor.Nodes.First();
// and i go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i right-click the module entry point
await moduleEntryPoint.ClickAtSelectionSpot(ButtonList.Right);
// and i select the "Refactor test_module" menu item
await MainWindow.PopupMenu.SelectItemWithText("Refactor test_module");
// and i add a parameter
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
var line = MainWindow.InvokableRefactorDialog.ParameterLines.First();
await line.Type.SelectItemWithText("boolean");
// and i press OK
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// then
// the module entry point has a new parameter
Assert.Equal(1, moduleEntryPoint.OutputPortCount);
// and there is a toggle button at the new parameter
Assert.True(moduleEntryPoint.ToggleButton(Port.Output(0)).IsVisible);
// and when i go back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// the module invocation has a new parameter
Assert.Equal(1, moduleInvocation.InputPortCount);
// and there is a checkbox where the new parameter value can be set
Assert.True(moduleInvocation.CheckBoxLiteral(Port.Input(0)).IsVisible);
}
[GodotFact(Frame = GodotFactFrame.Process)]
public async Task OperatorModulesWork()
{
// setup
// i add a module with two number parameters
await MainWindow.AddModuleButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.NameEdit.Type("test_module");
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
await MainWindow.InvokableRefactorDialog.AddParameterButton.ClickCenter();
var firstParameter = MainWindow.InvokableRefactorDialog.ParameterLines.First();
await firstParameter.NameEdit.Type("param1");
await firstParameter.Type.SelectItemWithText("number");
var secondParameter = MainWindow.InvokableRefactorDialog.ParameterLines.Last();
await secondParameter.NameEdit.Type("param2");
await secondParameter.Type.SelectItemWithText("number");
await MainWindow.InvokableRefactorDialog.OkButton.ClickCenter();
// and i go back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// and i add an instance of this to the main module
await MainWindow.AddNode("test_module");
var moduleInvocation = MainWindow.GraphEditor.Nodes.First();
// and i move this a bit to the right
await moduleInvocation.DragByOwnSize(2, 0);
// and I add a `+` operation
await MainWindow.AddNode("++");
var operatorModule1 = MainWindow.GraphEditor.Nodes.Last();
// and i move this a bit left and up
await operatorModule1.DragByOwnSize(-2, -2);
// and I add a `-` operation
await MainWindow.AddNode("--");
var operatorModule2 = MainWindow.GraphEditor.Nodes.Last();
// and i move this a bit left and down
await operatorModule2.DragByOwnSize(-2, 2);
// and i connect the output port of the first operator module into first input port of the module invocation
await operatorModule1.DragConnection(Port.Output(0), moduleInvocation, Port.Input(0));
// and i connect the output port of the second operator module into second input port of the module invocation
await operatorModule2.DragConnection(Port.Output(0), moduleInvocation, Port.Input(1));
// when
// i go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i add a children node
await MainWindow.AddNode("[MCld]");
var childrenNode = MainWindow.GraphEditor.Nodes.Last();
// then
// when i go back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// the module invocation has a new input
Assert.Equal(3, moduleInvocation.InputPortCount);
// there is no connection to the first input of the module invocation
Assert.False( MainWindow.GraphEditor.HasConnectionTo(moduleInvocation, Port.Input(0)));
// and the operator1 module is now connected to the second input of the module invocation
Assert.True(MainWindow.GraphEditor.HasConnection(operatorModule1, Port.Output(0), moduleInvocation, Port.Input(1)));
// and the operator2 module is now connected to the third input of the module invocation
Assert.True(MainWindow.GraphEditor.HasConnection(operatorModule2, Port.Output(0), moduleInvocation, Port.Input(2)));
// now when i add cube node
await MainWindow.AddNode("[Cbe]");
var cube = MainWindow.GraphEditor.Nodes.Last();
// and i move this up and left
await cube.DragByOwnSize(-2, -4);
// and i connect the output port of the cube node into the first input port of the module invocation
await cube.DragConnection(Port.Output(0), moduleInvocation, Port.Input(0));
// and if i now go back to the module editor
await MainWindow.TabContainer.SelectTabWithTitle("test_module");
// and i remove the children node
await childrenNode.Delete();
// and if i now go back to the main module
await MainWindow.TabContainer.SelectTabWithTitle("<main>");
// then
// them module invocation has only two inputs now
Assert.Equal(2, moduleInvocation.InputPortCount);
// there is no more connection coming from the cube node
Assert.False(MainWindow.GraphEditor.HasConnectionFrom(cube, Port.Output(0)));
// the operator 1 module is now connected to the first input of the module invocation
Assert.True(MainWindow.GraphEditor.HasConnection(operatorModule1, Port.Output(0), moduleInvocation, Port.Input(0)));
// the operator 2 module is now connected to the second input of the module invocation
Assert.True(MainWindow.GraphEditor.HasConnection(operatorModule2, Port.Output(0), moduleInvocation, Port.Input(1)));
}
}
}3ee9813f7This file is pinned to the selected release. Download the original to open it in your design tool.