2039 lines
78 KiB
C++
2039 lines
78 KiB
C++
/*
|
|
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
|
* its licensors.
|
|
*
|
|
* For complete copyright EntityRef license terms please see the LICENSE at the root of this
|
|
* distribution (the "License"). All use of this software is governed by the License,
|
|
* or, if provided, by the license below or the license accompanying this file. Do not
|
|
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#include <Source/Framework/ScriptCanvasTestFixture.h>
|
|
#include <Source/Framework/ScriptCanvasTestUtilities.h>
|
|
#include <Source/Framework/ScriptCanvasTestNodes.h>
|
|
|
|
#include <AzCore/Serialization/IdUtils.h>
|
|
#include <AzCore/std/smart_ptr/make_shared.h>
|
|
|
|
#include <ScriptCanvas/Asset/RuntimeAsset.h>
|
|
#include <ScriptCanvas/Asset/RuntimeAssetHandler.h>
|
|
#include <ScriptCanvas/Execution/RuntimeComponent.h>
|
|
#include <ScriptCanvas/Variable/GraphVariableManagerComponent.h>
|
|
|
|
using namespace ScriptCanvasTests;
|
|
using namespace TestNodes;
|
|
|
|
TEST_F(ScriptCanvasTestFixture, CoreNodeFunction_OwningGraphCheck)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
Graph* graph = CreateGraph();
|
|
ConfigurableUnitTestNode* groupedNode = CreateConfigurableNode();
|
|
|
|
EXPECT_EQ(graph, groupedNode->GetGraph());
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, AddRemoveSlot)
|
|
{
|
|
|
|
|
|
RegisterComponentDescriptor<AddNodeWithRemoveSlot>();
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity = AZStd::make_unique<AZ::Entity>("RemoveSlotGraph");
|
|
graphEntity->Init();
|
|
Graph* graph{};
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::CreateGraphOnEntity, graphEntity.get());
|
|
|
|
ScriptCanvasId graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId outID;
|
|
auto startNode = CreateTestNode<Nodes::Core::Start>(graphUniqueId, outID);
|
|
auto numberAddNode = CreateTestNode<AddNodeWithRemoveSlot>(graphUniqueId, outID);
|
|
|
|
auto number1Node = CreateDataNode<Data::NumberType>(graphUniqueId, 1.0, outID);
|
|
auto number2Node = CreateDataNode<Data::NumberType>(graphUniqueId, 2.0, outID);
|
|
auto number3Node = CreateDataNode<Data::NumberType>(graphUniqueId, 4.0, outID);
|
|
auto numberResultNode = CreateDataNode<Data::NumberType>(graphUniqueId, 0.0, outID);
|
|
|
|
// data
|
|
EXPECT_TRUE(Connect(*graph, number1Node->GetEntityId(), "Get", numberAddNode->GetEntityId(), "A"));
|
|
EXPECT_TRUE(Connect(*graph, number2Node->GetEntityId(), "Get", numberAddNode->GetEntityId(), "B"));
|
|
EXPECT_TRUE(Connect(*graph, number3Node->GetEntityId(), "Get", numberAddNode->GetEntityId(), "C"));
|
|
EXPECT_TRUE(Connect(*graph, numberAddNode->GetEntityId(), "Result", numberResultNode->GetEntityId(), "Set"));
|
|
|
|
// logic
|
|
EXPECT_TRUE(Connect(*graph, startNode->GetEntityId(), "Out", numberAddNode->GetEntityId(), "In"));
|
|
|
|
// execute pre remove
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode, "Set"))
|
|
{
|
|
SC_EXPECT_DOUBLE_EQ(7.0, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
// Remove the second number slot from the AddNodeWithRemoveSlot node(the one that contains value = 2.0)
|
|
numberAddNode->RemoveSlot(numberAddNode->GetSlotId("B"));
|
|
EXPECT_FALSE(numberAddNode->GetSlotId("B").IsValid());
|
|
|
|
// execute post-remove
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode, "Set"))
|
|
{
|
|
SC_EXPECT_DOUBLE_EQ(5.0, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
// Add two more slots and set there values to 8.0 and 16.0
|
|
EXPECT_TRUE(numberAddNode->AddSlot("D").IsValid());
|
|
EXPECT_TRUE(numberAddNode->AddSlot("B").IsValid());
|
|
auto number4Node = CreateDataNode<Data::NumberType>(graphUniqueId, 8.0, outID);
|
|
auto number5Node = CreateDataNode<Data::NumberType>(graphUniqueId, 16.0, outID);
|
|
EXPECT_TRUE(Connect(*graph, number4Node->GetEntityId(), "Get", numberAddNode->GetEntityId(), "D"));
|
|
EXPECT_TRUE(Connect(*graph, number5Node->GetEntityId(), "Get", numberAddNode->GetEntityId(), "B"));
|
|
|
|
// execute post-add of slot "D" and re-add of slot "A"
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode, "Set"))
|
|
{
|
|
SC_EXPECT_DOUBLE_EQ(1.0 + 4.0 + 8.0 + 16.0, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
// Remove the first number slot from the AddNodeWithRemoveSlot node(the one that contains value = 1.0
|
|
numberAddNode->RemoveSlot(numberAddNode->GetSlotId("A"));
|
|
EXPECT_FALSE(numberAddNode->GetSlotId("A").IsValid());
|
|
|
|
// execute post-remove of "A" slot
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode, "Set"))
|
|
{
|
|
SC_EXPECT_DOUBLE_EQ(4.0 + 8.0 + 16.0, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
graphEntity.reset();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, AddRemoveSlotNotifications)
|
|
{
|
|
RegisterComponentDescriptor<AddNodeWithRemoveSlot>();
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> numberAddEntity = AZStd::make_unique<AZ::Entity>("numberAddEntity");
|
|
auto numberAddNode = numberAddEntity->CreateComponent<AddNodeWithRemoveSlot>();
|
|
numberAddEntity->Init();
|
|
|
|
ScriptUnitTestNodeNotificationHandler nodeNotifications(numberAddNode->GetEntityId());
|
|
|
|
SlotId testSlotId = numberAddNode->AddSlot("test");
|
|
EXPECT_EQ(1U, nodeNotifications.GetSlotsAdded());
|
|
numberAddNode->RemoveSlot(testSlotId);
|
|
EXPECT_EQ(1U, nodeNotifications.GetSlotsRemoved());
|
|
|
|
testSlotId = numberAddNode->AddSlot("duplicate");
|
|
EXPECT_EQ(2U, nodeNotifications.GetSlotsAdded());
|
|
// This should not signal the NodeNotification::OnSlotAdded event as the slot already exist on the node
|
|
SlotId duplicateSlotId = numberAddNode->AddSlot("duplicate");
|
|
EXPECT_EQ(2U, nodeNotifications.GetSlotsAdded());
|
|
EXPECT_EQ(testSlotId, duplicateSlotId);
|
|
|
|
numberAddNode->RemoveSlot(testSlotId);
|
|
EXPECT_EQ(2U, nodeNotifications.GetSlotsRemoved());
|
|
// This should not signal the NodeNotification::OnSlotRemoved event as the slot no longer exist on the node
|
|
numberAddNode->RemoveSlot(testSlotId);
|
|
EXPECT_EQ(2U, nodeNotifications.GetSlotsRemoved());
|
|
|
|
numberAddEntity.reset();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, InsertSlot_Basic)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
Graph* graph = CreateGraph();
|
|
ConfigurableUnitTestNode* basicNode = CreateConfigurableNode();
|
|
|
|
SlotId firstSlotAdded;
|
|
SlotId secondSlotAdded;
|
|
SlotId thirdSlotAdded;
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "A";
|
|
slotConfiguration.SetDefaultValue(0);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
Slot* slot = basicNode->AddTestingSlot(slotConfiguration);
|
|
|
|
firstSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "C";
|
|
slotConfiguration.SetDefaultValue(2);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
Slot* slot = basicNode->AddTestingSlot(slotConfiguration);
|
|
|
|
secondSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "B";
|
|
slotConfiguration.SetDefaultValue(1);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
auto index = basicNode->FindSlotIndex(secondSlotAdded);
|
|
EXPECT_EQ(index, 1);
|
|
|
|
Slot* slot = basicNode->InsertTestingSlot(index, slotConfiguration);
|
|
|
|
thirdSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->GetAllSlots();
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
|
|
graph->Activate();
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->GetAllSlots();
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
|
|
graph->Deactivate();
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->GetAllSlots();
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, InsertSlot_FrontPadded)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
Graph* graph = CreateGraph();
|
|
ConfigurableUnitTestNode* basicNode = CreateConfigurableNode();
|
|
|
|
basicNode->AddTestingSlot(ExecutionSlotConfiguration("Input", ConnectionType::Input));
|
|
basicNode->AddTestingSlot(ExecutionSlotConfiguration("Input-1", ConnectionType::Input));
|
|
basicNode->AddTestingSlot(ExecutionSlotConfiguration("Input-2", ConnectionType::Input));
|
|
basicNode->AddTestingSlot(ExecutionSlotConfiguration("Input-3", ConnectionType::Input));
|
|
|
|
SlotId firstSlotAdded;
|
|
SlotId secondSlotAdded;
|
|
SlotId thirdSlotAdded;
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "A";
|
|
slotConfiguration.SetDefaultValue(0);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
Slot* slot = basicNode->AddTestingSlot(slotConfiguration);
|
|
|
|
firstSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "C";
|
|
slotConfiguration.SetDefaultValue(2);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
Slot* slot = basicNode->AddTestingSlot(slotConfiguration);
|
|
|
|
secondSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
DataSlotConfiguration slotConfiguration;
|
|
|
|
slotConfiguration.m_name = "B";
|
|
slotConfiguration.SetDefaultValue(1);
|
|
slotConfiguration.SetConnectionType(ConnectionType::Input);
|
|
|
|
auto index = basicNode->FindSlotIndex(secondSlotAdded);
|
|
|
|
Slot* slot = basicNode->InsertTestingSlot(index, slotConfiguration);
|
|
|
|
thirdSlotAdded = slot->GetId();
|
|
}
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->FindSlotsByDescriptor(SlotDescriptors::DataIn());
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
|
|
graph->Activate();
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->FindSlotsByDescriptor(SlotDescriptors::DataIn());
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
|
|
graph->Deactivate();
|
|
|
|
{
|
|
AZStd::vector< const Slot* > slotList = basicNode->FindSlotsByDescriptor(SlotDescriptors::DataIn());
|
|
|
|
EXPECT_EQ(slotList.size(), 3);
|
|
|
|
{
|
|
const Slot* firstSlot = slotList[0];
|
|
EXPECT_EQ(firstSlot->GetId(), firstSlotAdded);
|
|
EXPECT_EQ(firstSlot->GetName(), "A");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*firstSlot->FindDatum()->GetAs<Data::NumberType>())), 0.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* secondSlot = slotList[1];
|
|
EXPECT_EQ(secondSlot->GetId(), thirdSlotAdded);
|
|
EXPECT_EQ(secondSlot->GetName(), "B");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*secondSlot->FindDatum()->GetAs<Data::NumberType>())), 1.0f);
|
|
}
|
|
|
|
{
|
|
const Slot* thirdSlot = slotList[2];
|
|
EXPECT_EQ(thirdSlot->GetId(), secondSlotAdded);
|
|
EXPECT_EQ(thirdSlot->GetName(), "C");
|
|
EXPECT_FLOAT_EQ(static_cast<float>((*thirdSlot->FindDatum()->GetAs<Data::NumberType>())), 2.0f);
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, InsertSlot)
|
|
{
|
|
RegisterComponentDescriptor<InsertSlotConcatNode>();
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity = AZStd::make_unique<AZ::Entity>("RemoveSlotGraph");
|
|
graphEntity->Init();
|
|
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateEngineComponentsOnEntity, graphEntity.get());
|
|
Graph* graph = AZ::EntityUtils::FindFirstDerivedComponent<Graph>(graphEntity.get());
|
|
|
|
ScriptCanvasId graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId outId;
|
|
auto startNode = CreateTestNode<Nodes::Core::Start>(graphUniqueId, outId);
|
|
auto insertSlotConcatNode = CreateTestNode<InsertSlotConcatNode>(graphUniqueId, outId);
|
|
auto setVariableNode = CreateTestNode<Nodes::Core::SetVariableNode>(graphUniqueId, outId);
|
|
VariableId resultVarId = CreateVariable(graphUniqueId, Data::StringType(), "result");
|
|
setVariableNode->SetId(resultVarId);
|
|
|
|
EXPECT_TRUE(setVariableNode->GetDataInSlotId().IsValid());
|
|
|
|
//logic connections
|
|
EXPECT_TRUE(Connect(*graph, startNode->GetEntityId(), "Out", insertSlotConcatNode->GetEntityId(), "In"));
|
|
EXPECT_TRUE(Connect(*graph, insertSlotConcatNode->GetEntityId(), "Out", setVariableNode->GetEntityId(), "In"));
|
|
|
|
// insert slots
|
|
auto concatSlotId = insertSlotConcatNode->InsertSlot(-1, "A");
|
|
auto slotAId = concatSlotId;
|
|
SetInput_UNIT_TEST(insertSlotConcatNode, concatSlotId, Data::StringType("Hello"));
|
|
concatSlotId = insertSlotConcatNode->InsertSlot(-1, "B");
|
|
auto slotBId = concatSlotId;
|
|
SetInput_UNIT_TEST(insertSlotConcatNode, concatSlotId, Data::StringType(" World"));
|
|
|
|
// data connections
|
|
EXPECT_TRUE(graph->Connect(insertSlotConcatNode->GetEntityId(), insertSlotConcatNode->GetSlotId("Result"), setVariableNode->GetEntityId(), setVariableNode->GetDataInSlotId()));
|
|
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
const GraphVariable* resultDatum{};
|
|
VariableRequestBus::EventResult(resultDatum, GraphScopedVariableId(graphUniqueId, resultVarId), &VariableRequests::GetVariableConst);
|
|
ASSERT_NE(nullptr, resultDatum);
|
|
EXPECT_EQ("Hello World", resultDatum->GetDatum()->ToString());
|
|
|
|
// insert additional slot between A and B
|
|
auto slotIndex = insertSlotConcatNode->FindSlotIndex(slotBId);
|
|
EXPECT_GE(slotIndex, 0);
|
|
concatSlotId = insertSlotConcatNode->InsertSlot(slotIndex, "Alpha");
|
|
SetInput_UNIT_TEST(insertSlotConcatNode, concatSlotId, Data::StringType(" Ice Cream"));
|
|
|
|
// re-execute the graph
|
|
graphEntity->Activate();
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
// the new concatenated string should be in the middle
|
|
EXPECT_EQ("Hello Ice Cream World", resultDatum->GetDatum()->ToString());
|
|
|
|
graphEntity.reset();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, NativeProperties)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZ::Entity* graphEntity = aznew AZ::Entity("Graph");
|
|
graphEntity->Init();
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateGraphOnEntity, graphEntity);
|
|
auto graph = graphEntity->FindComponent<Graph>();
|
|
EXPECT_NE(nullptr, graph);
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZ::EntityId addId;
|
|
CreateTestNode<Vector3Nodes::AddNode>(graphUniqueId, addId);
|
|
|
|
AZ::EntityId vector3IdA, vector3IdB, vector3IdC;
|
|
auto vector3NodeA = CreateTestNode<Nodes::Math::Vector3>(graphUniqueId, vector3IdA);
|
|
auto vector3NodeB = CreateTestNode<Nodes::Math::Vector3>(graphUniqueId, vector3IdB);
|
|
auto vector3NodeC = CreateTestNode<Nodes::Math::Vector3>(graphUniqueId, vector3IdC);
|
|
|
|
AZ::EntityId number1Id, number2Id, number3Id, number4Id, number5Id, number6Id, number7Id, number8Id, number9Id;
|
|
Node* number1Node = CreateDataNode<Data::NumberType>(graphUniqueId, 1, number1Id);
|
|
Node* number2Node = CreateDataNode<Data::NumberType>(graphUniqueId, 2, number2Id);
|
|
Node* number3Node = CreateDataNode<Data::NumberType>(graphUniqueId, 3, number3Id);
|
|
Node* number4Node = CreateDataNode<Data::NumberType>(graphUniqueId, 4, number4Id);
|
|
Node* number5Node = CreateDataNode<Data::NumberType>(graphUniqueId, 5, number5Id);
|
|
Node* number6Node = CreateDataNode<Data::NumberType>(graphUniqueId, 6, number6Id);
|
|
Node* number7Node = CreateDataNode<Data::NumberType>(graphUniqueId, 7, number7Id);
|
|
Node* number8Node = CreateDataNode<Data::NumberType>(graphUniqueId, 8, number8Id);
|
|
Node* number9Node = CreateDataNode<Data::NumberType>(graphUniqueId, 0, number9Id);
|
|
|
|
// data
|
|
EXPECT_TRUE(Connect(*graph, number1Id, "Get", vector3IdA, "Number: x"));
|
|
EXPECT_TRUE(Connect(*graph, number2Id, "Get", vector3IdA, "Number: y"));
|
|
EXPECT_TRUE(Connect(*graph, number3Id, "Get", vector3IdA, "Number: z"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, number4Id, "Get", vector3IdB, "Number: x"));
|
|
EXPECT_TRUE(Connect(*graph, number5Id, "Get", vector3IdB, "Number: y"));
|
|
EXPECT_TRUE(Connect(*graph, number6Id, "Get", vector3IdB, "Number: z"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, vector3IdA, "Get", addId, "Vector3: A"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdB, "Get", addId, "Vector3: B"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, addId, "Result: Vector3", vector3IdC, "Set"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, vector3IdC, "x: Number", number7Id, "Set"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdC, "y: Number", number8Id, "Set"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdC, "z: Number", number9Id, "Set"));
|
|
|
|
// code
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", addId, "In"));
|
|
|
|
graphEntity->Activate();
|
|
|
|
ReportErrors(graph);
|
|
|
|
if (auto result = GetInput_UNIT_TEST<AZ::Vector3>(vector3NodeC, "Set"))
|
|
{
|
|
EXPECT_EQ(AZ::Vector3(5, 7, 9), *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(number7Node, "Set"))
|
|
{
|
|
EXPECT_EQ(5, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(number8Node, "Set"))
|
|
{
|
|
EXPECT_EQ(7, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
if (auto result = GetInput_UNIT_TEST<Data::NumberType>(number9Node, "Set"))
|
|
{
|
|
EXPECT_EQ(9, *result);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
graphEntity->Deactivate();
|
|
delete graphEntity;
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, ExtractPropertiesNativeType)
|
|
{
|
|
// TODO: Add Extract test for all Native Types
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity = AZStd::make_unique<AZ::Entity>("PropertyGraph");
|
|
Graph* graph{};
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::CreateGraphOnEntity, graphEntity.get());
|
|
ASSERT_NE(nullptr, graph);
|
|
|
|
AZ::EntityId propertyEntityId = graphEntity->GetId();
|
|
ScriptCanvasId graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
graphEntity->Init();
|
|
|
|
// Create Extract Property Node
|
|
AZ::EntityId outID;
|
|
auto startNode = CreateTestNode<Nodes::Core::Start>(graphUniqueId, outID);
|
|
auto extractPropertyNode = CreateTestNode<Nodes::Core::ExtractProperty>(graphUniqueId, outID);
|
|
auto printNode = CreateTestNode<TestResult>(graphUniqueId, outID);
|
|
|
|
// Test Native Vector3 Properties
|
|
auto vector3Node = CreateDataNode(graphUniqueId, Data::Vector3Type(10.0f, 23.3f, 77.45f), outID);
|
|
|
|
auto numberResultNode1 = CreateDataNode(graphUniqueId, 0.0f, outID);
|
|
auto numberResultNode2 = CreateDataNode(graphUniqueId, 0.0f, outID);
|
|
auto numberResultNode3 = CreateDataNode(graphUniqueId, 0.0f, outID);
|
|
|
|
// data
|
|
EXPECT_EQ(0, extractPropertyNode->GetPropertyFields().size());
|
|
EXPECT_FALSE(extractPropertyNode->GetSourceSlotDataType().IsValid());
|
|
|
|
EXPECT_TRUE(Connect(*graph, vector3Node->GetEntityId(), "Get", extractPropertyNode->GetEntityId(), "Source"));
|
|
|
|
auto propertyFields = extractPropertyNode->GetPropertyFields();
|
|
EXPECT_EQ(3, propertyFields.size());
|
|
EXPECT_TRUE(extractPropertyNode->GetSourceSlotDataType().IS_A(Data::Type::Vector3()));
|
|
|
|
// Vector3::x
|
|
auto propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "x";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, numberResultNode1->GetEntityId(), numberResultNode1->GetSlotId("Set")));
|
|
|
|
// Vector3::y
|
|
propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "y";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, numberResultNode2->GetEntityId(), numberResultNode2->GetSlotId("Set")));
|
|
|
|
// Vector3::z
|
|
propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "z";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, numberResultNode3->GetEntityId(), numberResultNode3->GetSlotId("Set")));
|
|
|
|
// Print the z value to console
|
|
EXPECT_TRUE(graph->Connect(numberResultNode3->GetEntityId(), numberResultNode3->GetSlotId("Get"), printNode->GetEntityId(), printNode->GetSlotId("Value")));
|
|
|
|
// logic
|
|
EXPECT_TRUE(Connect(*graph, startNode->GetEntityId(), "Out", extractPropertyNode->GetEntityId(), "In"));
|
|
EXPECT_TRUE(Connect(*graph, extractPropertyNode->GetEntityId(), "Out", printNode->GetEntityId(), "In"));
|
|
|
|
// execute
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graphEntity->Activate();
|
|
}
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
AZ::Entity* connectionEntity{};
|
|
EXPECT_TRUE(graph->FindConnection(connectionEntity, { vector3Node->GetEntityId(), vector3Node->GetSlotId("Get") }, { extractPropertyNode->GetEntityId(), extractPropertyNode->GetSlotId("Source") }));
|
|
EXPECT_TRUE(graph->DisconnectById(connectionEntity->GetId()));
|
|
|
|
const float tolerance = 0.001f;
|
|
// x result
|
|
auto vectorElementResult = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode1, "Set");
|
|
ASSERT_NE(nullptr, vectorElementResult);
|
|
EXPECT_NEAR(10.0f, *vectorElementResult, tolerance);
|
|
|
|
// y result
|
|
vectorElementResult = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode2, "Set");
|
|
ASSERT_NE(nullptr, vectorElementResult);
|
|
EXPECT_NEAR(23.3f, *vectorElementResult, tolerance);
|
|
|
|
// z result
|
|
vectorElementResult = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode3, "Set");
|
|
ASSERT_NE(nullptr, vectorElementResult);
|
|
EXPECT_NEAR(77.45f, *vectorElementResult, tolerance);
|
|
|
|
graphEntity.reset();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, ExtractPropertiesBehaviorType)
|
|
{
|
|
TestBehaviorContextProperties::Reflect(m_serializeContext);
|
|
TestBehaviorContextProperties::Reflect(m_behaviorContext);
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace Nodes;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity = AZStd::make_unique<AZ::Entity>("PropertyGraph");
|
|
Graph* graph{};
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::CreateGraphOnEntity, graphEntity.get());
|
|
ASSERT_NE(nullptr, graph);
|
|
|
|
AZ::EntityId propertyEntityId = graphEntity->GetId();
|
|
ScriptCanvasId graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
graphEntity->Init();
|
|
|
|
// Create Extract Property Node
|
|
AZ::EntityId outID;
|
|
auto startNode = CreateTestNode<Nodes::Core::Start>(graphUniqueId, outID);
|
|
auto extractPropertyNode = CreateTestNode<Nodes::Core::ExtractProperty>(graphUniqueId, outID);
|
|
auto printNode = CreateTestNode<TestResult>(graphUniqueId, outID);
|
|
|
|
// Test BehaviorContext Properties
|
|
|
|
TestBehaviorContextProperties behaviorContextProperties;
|
|
behaviorContextProperties.m_booleanProp = true;
|
|
behaviorContextProperties.m_numberProp = 11.90f;
|
|
behaviorContextProperties.m_stringProp = "String Property";
|
|
auto behaviorContextPropertyNode = CreateDataNode(graphUniqueId, behaviorContextProperties, outID);
|
|
|
|
auto booleanResultNode = CreateDataNode(graphUniqueId, false, outID);
|
|
auto numberResultNode = CreateDataNode(graphUniqueId, 0.0f, outID);
|
|
auto stringResultNode = CreateDataNode(graphUniqueId, Data::StringType("Uninitialized"), outID);
|
|
|
|
// data
|
|
EXPECT_EQ(0, extractPropertyNode->GetPropertyFields().size());
|
|
EXPECT_FALSE(extractPropertyNode->GetSourceSlotDataType().IsValid());
|
|
|
|
EXPECT_TRUE(Connect(*graph, behaviorContextPropertyNode->GetEntityId(), "Get", extractPropertyNode->GetEntityId(), "Source"));
|
|
|
|
auto propertyFields = extractPropertyNode->GetPropertyFields();
|
|
EXPECT_EQ(4, propertyFields.size());
|
|
EXPECT_TRUE(extractPropertyNode->GetSourceSlotDataType().IS_A(Data::FromAZType<TestBehaviorContextProperties>()));
|
|
|
|
// TestBehaviorContextProperties::boolean
|
|
auto propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "boolean";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, booleanResultNode->GetEntityId(), booleanResultNode->GetSlotId("Set")));
|
|
|
|
// TestBehaviorContextProperties::number
|
|
propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "number";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, numberResultNode->GetEntityId(), numberResultNode->GetSlotId("Set")));
|
|
|
|
// TestBehaviorContextProperties::string
|
|
propIt = AZStd::find_if(propertyFields.begin(), propertyFields.end(), [](const AZStd::pair<AZStd::string_view, SlotId> propertyField)
|
|
{
|
|
return propertyField.first == "string";
|
|
});
|
|
|
|
ASSERT_NE(propIt, propertyFields.end());
|
|
EXPECT_TRUE(graph->Connect(extractPropertyNode->GetEntityId(), propIt->second, stringResultNode->GetEntityId(), stringResultNode->GetSlotId("Set")));
|
|
|
|
// Print the string value to console
|
|
EXPECT_TRUE(graph->Connect(stringResultNode->GetEntityId(), stringResultNode->GetSlotId("Get"), printNode->GetEntityId(), printNode->GetSlotId("Value")));
|
|
|
|
// logic
|
|
EXPECT_TRUE(Connect(*graph, startNode->GetEntityId(), "Out", extractPropertyNode->GetEntityId(), "In"));
|
|
EXPECT_TRUE(Connect(*graph, extractPropertyNode->GetEntityId(), "Out", printNode->GetEntityId(), "In"));
|
|
|
|
// execute
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graphEntity->Activate();
|
|
}
|
|
|
|
ReportErrors(graph);
|
|
graphEntity->Deactivate();
|
|
|
|
AZ::Entity* connectionEntity{};
|
|
EXPECT_TRUE(graph->FindConnection(connectionEntity, { behaviorContextPropertyNode->GetEntityId(), behaviorContextPropertyNode->GetSlotId("Get") }, { extractPropertyNode->GetEntityId(), extractPropertyNode->GetSlotId("Source") }));
|
|
EXPECT_TRUE(graph->DisconnectById(connectionEntity->GetId()));
|
|
|
|
// boolean result
|
|
auto booleanResult = GetInput_UNIT_TEST<Data::BooleanType>(booleanResultNode, "Set");
|
|
ASSERT_NE(nullptr, booleanResult);
|
|
EXPECT_TRUE(booleanResult);
|
|
|
|
// number result
|
|
const float tolerance = 0.001f;
|
|
auto numberResult = GetInput_UNIT_TEST<Data::NumberType>(numberResultNode, "Set");
|
|
ASSERT_NE(nullptr, numberResult);
|
|
EXPECT_NEAR(11.90f, *numberResult, tolerance);
|
|
|
|
// string result
|
|
auto stringResult = GetInput_UNIT_TEST<Data::StringType>(stringResultNode, "Set");
|
|
ASSERT_NE(nullptr, stringResult);
|
|
EXPECT_EQ("String Property", *stringResult);
|
|
|
|
graphEntity.reset();
|
|
|
|
m_serializeContext->EnableRemoveReflection();
|
|
TestBehaviorContextProperties::Reflect(m_serializeContext);
|
|
m_serializeContext->DisableRemoveReflection();
|
|
m_behaviorContext->EnableRemoveReflection();
|
|
TestBehaviorContextProperties::Reflect(m_behaviorContext);
|
|
m_behaviorContext->DisableRemoveReflection();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, IsNullCheck)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
EventTestHandler::Reflect(m_serializeContext);
|
|
EventTestHandler::Reflect(m_behaviorContext);
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
|
|
Graph* graph(nullptr);
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityID = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZ::EntityId isNullFalseID;
|
|
CreateTestNode<Nodes::Logic::IsNull>(graphUniqueId, isNullFalseID);
|
|
|
|
AZ::EntityId isNullTrueID;
|
|
CreateTestNode<Nodes::Logic::IsNull>(graphUniqueId, isNullTrueID);
|
|
|
|
AZ::EntityId isNullResultFalseID;
|
|
auto isNullResultFalse = CreateDataNode(graphUniqueId, true, isNullResultFalseID);
|
|
AZ::EntityId isNullResultTrueID;
|
|
auto isNullResultTrue = CreateDataNode(graphUniqueId, false, isNullResultTrueID);
|
|
|
|
AZ::EntityId normalizeID;
|
|
Nodes::Core::Method* normalize = CreateTestNode<Nodes::Core::Method>(graphUniqueId, normalizeID);
|
|
Namespaces empty;
|
|
normalize->InitializeClass(empty, "TestBehaviorContextObject", "Normalize");
|
|
|
|
AZ::EntityId vectorID;
|
|
Nodes::Core::BehaviorContextObjectNode* vector = CreateTestNode<Nodes::Core::BehaviorContextObjectNode>(graphUniqueId, vectorID);
|
|
const AZStd::string vector3("TestBehaviorContextObject");
|
|
vector->InitializeObject(vector3);
|
|
if (auto vector3_2 = ModInput_UNIT_TEST<TestBehaviorContextObject>(vector, "Set"))
|
|
{
|
|
EXPECT_FALSE(vector3_2->IsNormalized());
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
// test the reference type contract
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
EXPECT_FALSE(Connect(*graph, isNullResultFalseID, "Get", isNullTrueID, "Reference"));
|
|
}
|
|
|
|
// data
|
|
EXPECT_TRUE(Connect(*graph, vectorID, "Get", normalizeID, "TestBehaviorContextObject: 0"));
|
|
EXPECT_TRUE(Connect(*graph, vectorID, "Get", isNullFalseID, "Reference"));
|
|
EXPECT_TRUE(Connect(*graph, isNullTrueID, "Is Null", isNullResultTrueID, "Set"));
|
|
EXPECT_TRUE(Connect(*graph, isNullFalseID, "Is Null", isNullResultFalseID, "Set"));
|
|
// execution
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", isNullTrueID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, isNullTrueID, "True", isNullFalseID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, isNullFalseID, "False", normalizeID, "In"));
|
|
|
|
AZ::Entity* graphEntity = graph->GetEntity();
|
|
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graphEntity->Activate();
|
|
}
|
|
|
|
ReportErrors(graph);
|
|
|
|
if (auto vector3_2 = GetInput_UNIT_TEST<TestBehaviorContextObject>(vector, "Set"))
|
|
{
|
|
EXPECT_TRUE(vector3_2->IsNormalized());
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
if (auto shouldBeFalse = GetInput_UNIT_TEST<bool>(isNullResultFalse, "Set"))
|
|
{
|
|
EXPECT_FALSE(*shouldBeFalse);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
if (auto shouldBeTrue = GetInput_UNIT_TEST<bool>(isNullResultTrue, "Set"))
|
|
{
|
|
EXPECT_TRUE(*shouldBeTrue);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
graphEntity->Deactivate();
|
|
delete graphEntity;
|
|
|
|
m_serializeContext->EnableRemoveReflection();
|
|
m_behaviorContext->EnableRemoveReflection();
|
|
EventTestHandler::Reflect(m_serializeContext);
|
|
EventTestHandler::Reflect(m_behaviorContext);
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
m_serializeContext->DisableRemoveReflection();
|
|
m_behaviorContext->DisableRemoveReflection();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, NullThisPointerDoesNotCrash)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
EventTestHandler::Reflect(m_serializeContext);
|
|
EventTestHandler::Reflect(m_behaviorContext);
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
|
|
Graph* graph(nullptr);
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityID = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZ::EntityId normalizeID;
|
|
Nodes::Core::Method* normalize = CreateTestNode<Nodes::Core::Method>(graphUniqueId, normalizeID);
|
|
Namespaces empty;
|
|
normalize->InitializeClass(empty, "TestBehaviorContextObject", "Normalize");
|
|
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", normalizeID, "In"));
|
|
|
|
AZ::Entity* graphEntity = graph->GetEntity();
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graphEntity->Activate();
|
|
}
|
|
// just don't crash, but be in error
|
|
const bool expectError = true;
|
|
const bool expectIrrecoverableError = true;
|
|
ReportErrors(graph, expectError, expectIrrecoverableError);
|
|
|
|
graphEntity->Deactivate();
|
|
delete graphEntity;
|
|
|
|
m_serializeContext->EnableRemoveReflection();
|
|
m_behaviorContext->EnableRemoveReflection();
|
|
EventTestHandler::Reflect(m_serializeContext);
|
|
EventTestHandler::Reflect(m_behaviorContext);
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
m_serializeContext->DisableRemoveReflection();
|
|
m_behaviorContext->DisableRemoveReflection();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, ValueTypes)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
Datum number0(Datum(0));
|
|
int number0Value = *number0.GetAs<int>();
|
|
|
|
Datum number1(Datum(1));
|
|
int number1Value = *number1.GetAs<int>();
|
|
|
|
Datum numberFloat(Datum(2.f));
|
|
float numberFloatValue = *numberFloat.GetAs<float>();
|
|
|
|
Datum numberDouble(Datum(3.0));
|
|
double numberDoubleValue = *numberDouble.GetAs<double>();
|
|
|
|
Datum numberHex(Datum(0xff));
|
|
int numberHexValue = *numberHex.GetAs<int>();
|
|
|
|
Datum numberPi(Datum(3.14f));
|
|
float numberPiValue = *numberPi.GetAs<float>();
|
|
|
|
Datum numberSigned(Datum(-100));
|
|
int numberSignedValue = *numberSigned.GetAs<int>();
|
|
|
|
Datum numberUnsigned(Datum(100u));
|
|
unsigned int numberUnsignedValue = *numberUnsigned.GetAs<unsigned int>();
|
|
|
|
Datum numberDoublePi(Datum(6.28));
|
|
double numberDoublePiValue = *numberDoublePi.GetAs<double>();
|
|
|
|
EXPECT_EQ(number0Value, 0);
|
|
EXPECT_EQ(number1Value, 1);
|
|
|
|
EXPECT_TRUE(AZ::IsClose(numberFloatValue, 2.f, std::numeric_limits<float>::epsilon()));
|
|
EXPECT_TRUE(AZ::IsClose(numberDoubleValue, 3.0, std::numeric_limits<double>::epsilon()));
|
|
|
|
EXPECT_NE(number0Value, number1Value);
|
|
SC_EXPECT_FLOAT_EQ(numberPiValue, 3.14f);
|
|
|
|
EXPECT_NE(number0Value, numberPiValue);
|
|
EXPECT_NE(numberPiValue, numberDoublePiValue);
|
|
|
|
Datum boolTrue(Datum(true));
|
|
EXPECT_TRUE(*boolTrue.GetAs<bool>());
|
|
Datum boolFalse(Datum(false));
|
|
EXPECT_FALSE(*boolFalse.GetAs<bool>());
|
|
boolFalse = boolTrue;
|
|
EXPECT_TRUE(*boolFalse.GetAs<bool>());
|
|
Datum boolFalse2(Datum(false));
|
|
boolTrue = boolFalse2;
|
|
EXPECT_FALSE(*boolTrue.GetAs<bool>());
|
|
|
|
{
|
|
const int k_count(10000);
|
|
AZStd::vector<Datum> objects;
|
|
for (int i = 0; i < k_count; ++i)
|
|
{
|
|
objects.push_back(Datum("Vector3", Datum::eOriginality::Original));
|
|
}
|
|
}
|
|
|
|
GTEST_SUCCEED();
|
|
}
|
|
|
|
|
|
namespace
|
|
{
|
|
using namespace ScriptCanvas;
|
|
using namespace ScriptCanvas::Nodes;
|
|
|
|
bool GraphHasVectorWithValue(const Graph& graph, const AZ::Vector3& vector)
|
|
{
|
|
for (auto nodeId : graph.GetNodes())
|
|
{
|
|
AZ::Entity* entity{};
|
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, nodeId);
|
|
|
|
if (entity)
|
|
{
|
|
if (auto node = AZ::EntityUtils::FindFirstDerivedComponent<Core::BehaviorContextObjectNode>(entity))
|
|
{
|
|
if (auto candidate = NodeAccessor::GetInput_UNIT_TEST<AZ::Vector3>(node, "Set"))
|
|
{
|
|
if (*candidate == vector)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, SerializationSaveTest)
|
|
{
|
|
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace ScriptCanvas::Nodes;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Make the graph.
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
// Make the nodes.
|
|
|
|
// Start
|
|
AZ::Entity* startEntity{ aznew AZ::Entity };
|
|
startEntity->Init();
|
|
AZ::EntityId startNode{ startEntity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, startNode, graphUniqueId, Nodes::Core::Start::TYPEINFO_Uuid());
|
|
|
|
// Constant 0
|
|
AZ::Entity* constant0Entity{ aznew AZ::Entity };
|
|
constant0Entity->Init();
|
|
AZ::EntityId constant0Node{ constant0Entity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, constant0Node, graphUniqueId, Nodes::Math::Number::TYPEINFO_Uuid());
|
|
|
|
// Get the node and set the value
|
|
Nodes::Math::Number* constant0NodePtr = nullptr;
|
|
SystemRequestBus::BroadcastResult(constant0NodePtr, &SystemRequests::GetNode<Nodes::Math::Number>, constant0Node);
|
|
EXPECT_TRUE(constant0NodePtr != nullptr);
|
|
if (constant0NodePtr)
|
|
{
|
|
SetInput_UNIT_TEST(constant0NodePtr, "Set", 4);
|
|
}
|
|
|
|
// Constant 1
|
|
AZ::Entity* constant1Entity{ aznew AZ::Entity };
|
|
constant1Entity->Init();
|
|
AZ::EntityId constant1Node{ constant1Entity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, constant1Node, graphUniqueId, Nodes::Math::Number::TYPEINFO_Uuid());
|
|
// Get the node and set the value
|
|
Nodes::Math::Number* constant1NodePtr = nullptr;
|
|
SystemRequestBus::BroadcastResult(constant1NodePtr, &SystemRequests::GetNode<Nodes::Math::Number>, constant1Node);
|
|
EXPECT_TRUE(constant1NodePtr != nullptr);
|
|
if (constant1NodePtr)
|
|
{
|
|
SetInput_UNIT_TEST(constant1NodePtr, "Set", 12);
|
|
}
|
|
|
|
// Sum
|
|
AZ::Entity* sumEntity{ aznew AZ::Entity };
|
|
sumEntity->Init();
|
|
AZ::EntityId sumNode{ sumEntity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, sumNode, graphUniqueId, Nodes::Math::Sum::TYPEINFO_Uuid());
|
|
|
|
AZ::EntityId printID;
|
|
auto printNode = CreateTestNode<TestResult>(graphUniqueId, printID);
|
|
|
|
// Connect, disconnect and reconnect to validate disconnection
|
|
graph->Connect(sumNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(sumEntity)->GetSlotId(BinaryOperator::k_lhsName), constant0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(constant0Entity)->GetSlotId("Get"));
|
|
graph->Disconnect(sumNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(sumEntity)->GetSlotId(BinaryOperator::k_lhsName), constant0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(constant0Entity)->GetSlotId("Get"));
|
|
graph->Connect(sumNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(sumEntity)->GetSlotId(BinaryOperator::k_lhsName), constant0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(constant0Entity)->GetSlotId("Get"));
|
|
{
|
|
auto* sumNodePtr = AZ::EntityUtils::FindFirstDerivedComponent<Nodes::Math::Sum>(sumEntity);
|
|
EXPECT_NE(nullptr, sumNodePtr);
|
|
EXPECT_EQ(1, graph->GetConnectedEndpoints({ sumNode, sumNodePtr->GetSlotId(BinaryOperator::k_lhsName) }).size());
|
|
}
|
|
|
|
graph->Connect(sumNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(sumEntity)->GetSlotId(BinaryOperator::k_rhsName), constant1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(constant1Entity)->GetSlotId("Get"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, sumNode, "Result", printID, "Value"));
|
|
EXPECT_TRUE(Connect(*graph, startNode, "Out", sumNode, Nodes::BinaryOperator::k_evaluateName));
|
|
EXPECT_TRUE(Connect(*graph, sumNode, Nodes::BinaryOperator::k_outName, printID, "In"));
|
|
|
|
AZ::EntityId vector3IdA, vector3IdB, vector3IdC;
|
|
const AZ::Vector3 allOne(1, 1, 1);
|
|
const AZ::Vector3 allTwo(2, 2, 2);
|
|
const AZ::Vector3 allThree(3, 3, 3);
|
|
const AZ::Vector3 allFour(4, 4, 4);
|
|
|
|
Core::BehaviorContextObjectNode* vector3NodeA = CreateTestNode<Core::BehaviorContextObjectNode>(graphUniqueId, vector3IdA);
|
|
vector3NodeA->InitializeObject(azrtti_typeid<AZ::Vector3>());
|
|
*ModInput_UNIT_TEST<AZ::Vector3>(vector3NodeA, "Set") = allOne;
|
|
Core::BehaviorContextObjectNode* vector3NodeB = CreateTestNode<Core::BehaviorContextObjectNode>(graphUniqueId, vector3IdB);
|
|
vector3NodeB->InitializeObject(azrtti_typeid<AZ::Vector3>());
|
|
*ModInput_UNIT_TEST<AZ::Vector3>(vector3NodeB, "Set") = allTwo;
|
|
Core::BehaviorContextObjectNode* vector3NodeC = CreateTestNode<Core::BehaviorContextObjectNode>(graphUniqueId, vector3IdC);
|
|
vector3NodeC->InitializeObject(azrtti_typeid<AZ::Vector3>());
|
|
*ModInput_UNIT_TEST<AZ::Vector3>(vector3NodeC, "Set") = allFour;
|
|
|
|
AZ::EntityId add3IdA;
|
|
CreateTestNode<Vector3Nodes::AddNode>(graphUniqueId, add3IdA);
|
|
|
|
EXPECT_TRUE(Connect(*graph, printID, "Out", add3IdA, "In"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdA, "Get", add3IdA, "Vector3: A"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdB, "Get", add3IdA, "Vector3: B"));
|
|
EXPECT_TRUE(Connect(*graph, vector3IdC, "Set", add3IdA, "Result: Vector3"));
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity{ graph->GetEntity() };
|
|
|
|
EXPECT_EQ(allOne, *GetInput_UNIT_TEST<AZ::Vector3>(vector3NodeA, "Set"));
|
|
EXPECT_EQ(allTwo, *GetInput_UNIT_TEST<AZ::Vector3>(vector3NodeB, "Set"));
|
|
auto vector3C = *GetInput_UNIT_TEST<AZ::Vector3>(vector3NodeC, "Set");
|
|
EXPECT_EQ(allFour, vector3C);
|
|
|
|
auto nodeIDs = graph->GetNodes();
|
|
EXPECT_EQ(9, nodeIDs.size());
|
|
|
|
ScriptCanvasEditor::TraceSuppressionBus::Broadcast(&ScriptCanvasEditor::TraceSuppressionRequests::SuppressPrintf, true);
|
|
graphEntity->Activate();
|
|
ScriptCanvasEditor::TraceSuppressionBus::Broadcast(&ScriptCanvasEditor::TraceSuppressionRequests::SuppressPrintf, false);
|
|
ReportErrors(graph);
|
|
|
|
vector3C = *GetInput_UNIT_TEST<AZ::Vector3>(vector3NodeC, "Set");
|
|
EXPECT_EQ(allThree, vector3C);
|
|
|
|
if (auto result = GetInput_UNIT_TEST<float>(printNode, "Value"))
|
|
{
|
|
SC_EXPECT_FLOAT_EQ(*result, 16.0f);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
graphEntity->Deactivate();
|
|
|
|
auto* fileIO = AZ::IO::LocalFileIO::GetInstance();
|
|
EXPECT_TRUE(fileIO != nullptr);
|
|
|
|
auto pathResult = fileIO->CreatePath(k_tempCoreAssetDir);;
|
|
EXPECT_EQ(pathResult.GetResultCode(), AZ::IO::ResultCode::Success) << "Path failed to create";
|
|
|
|
// Save it
|
|
bool result = false;
|
|
AZ::IO::FileIOStream outFileStream(k_tempCoreAssetPath, AZ::IO::OpenMode::ModeWrite);
|
|
if (outFileStream.IsOpen())
|
|
{
|
|
RuntimeAssetHandler runtimeAssetHandler;
|
|
AZ::Data::Asset<RuntimeAsset> runtimeAsset = CreateRuntimeAsset(graph);
|
|
EXPECT_TRUE(runtimeAssetHandler.SaveAssetData(runtimeAsset, &outFileStream)) << "Asset failed to save";
|
|
|
|
EXPECT_TRUE(fileIO->Exists(k_tempCoreAssetPath));
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE() << "File stream not open";
|
|
}
|
|
|
|
outFileStream.Close();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, SerializationLoadTest_Graph)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Make the graph.
|
|
Graph* graph = nullptr;
|
|
|
|
AZStd::unique_ptr<AZ::Entity> graphEntity = AZStd::make_unique<AZ::Entity>("Loaded Graph");
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::CreateGraphOnEntity, graphEntity.get());
|
|
|
|
auto* fileIO = AZ::IO::LocalFileIO::GetInstance();
|
|
ASSERT_NE(nullptr, fileIO);
|
|
EXPECT_TRUE(fileIO->Exists(k_tempCoreAssetPath));
|
|
|
|
// Load it
|
|
AZ::Data::Asset<RuntimeAsset> runtimeAsset;
|
|
runtimeAsset.Create(AZ::Uuid::CreateRandom());
|
|
AZ::u64 fileLength = 0;
|
|
AZ::IO::FileIOBase::GetInstance()->Size(k_tempCoreAssetPath, fileLength);
|
|
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream = AZStd::make_shared<AZ::Data::AssetDataStream>();
|
|
stream->Open(k_tempCoreAssetPath, 0, fileLength);
|
|
stream->BlockUntilLoadComplete();
|
|
|
|
// Serialize the graph entity back in.
|
|
RuntimeAssetHandler runtimeAssetHandler;
|
|
EXPECT_EQ(runtimeAssetHandler.LoadAssetData(runtimeAsset, stream, {}), AZ::Data::AssetHandler::LoadResult::LoadComplete);
|
|
|
|
GraphData& assetGraphData = runtimeAsset.Get()->GetData().m_graphData;
|
|
AZStd::unordered_map<AZ::EntityId, AZ::EntityId> idRemap;
|
|
AZ::IdUtils::Remapper<AZ::EntityId>::GenerateNewIdsAndFixRefs(&assetGraphData, idRemap, m_serializeContext);
|
|
graph->AddGraphData(assetGraphData);
|
|
// Clear GraphData on asset to prevent it from deleting the graph data, the Graph component takes care of cleaning it up
|
|
assetGraphData.Clear();
|
|
|
|
// Initialize the entity
|
|
graphEntity->Init();
|
|
ScriptCanvasEditor::TraceSuppressionBus::Broadcast(&ScriptCanvasEditor::TraceSuppressionRequests::SuppressPrintf, true);
|
|
graphEntity->Activate();
|
|
ScriptCanvasEditor::TraceSuppressionBus::Broadcast(&ScriptCanvasEditor::TraceSuppressionRequests::SuppressPrintf, false);
|
|
|
|
// Run the graph component
|
|
graph = graphEntity->FindComponent<Graph>();
|
|
EXPECT_TRUE(graph != nullptr); // "Graph entity did not have the graph component.");
|
|
ReportErrors(graph);
|
|
|
|
const AZ::Vector3 allOne(1, 1, 1);
|
|
const AZ::Vector3 allTwo(2, 2, 2);
|
|
const AZ::Vector3 allThree(3, 3, 3);
|
|
const AZ::Vector3 allFour(4, 4, 4);
|
|
|
|
auto nodeIDs = graph->GetNodes();
|
|
EXPECT_EQ(9, nodeIDs.size());
|
|
|
|
// Graph result should be still 16
|
|
// Serialized graph has new remapped entity ids
|
|
auto nodes = graph->GetNodes();
|
|
auto sumNodeIt = AZStd::find_if(nodes.begin(), nodes.end(), [](const AZ::EntityId& nodeId) -> bool
|
|
{
|
|
AZ::Entity* entity{};
|
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, nodeId);
|
|
return entity ? AZ::EntityUtils::FindFirstDerivedComponent<TestResult>(entity) ? true : false : false;
|
|
});
|
|
EXPECT_NE(nodes.end(), sumNodeIt);
|
|
|
|
TestResult* printNode = nullptr;
|
|
SystemRequestBus::BroadcastResult(printNode, &SystemRequests::GetNode<TestResult>, *sumNodeIt);
|
|
EXPECT_TRUE(printNode != nullptr);
|
|
|
|
if (auto result = GetInput_UNIT_TEST<float>(printNode, "Value"))
|
|
{
|
|
SC_EXPECT_FLOAT_EQ(*result, 16.0f);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
EXPECT_TRUE(GraphHasVectorWithValue(*graph, allOne));
|
|
EXPECT_TRUE(GraphHasVectorWithValue(*graph, allTwo));
|
|
EXPECT_TRUE(GraphHasVectorWithValue(*graph, allThree));
|
|
EXPECT_FALSE(GraphHasVectorWithValue(*graph, allFour));
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, SerializationLoadTest_RuntimeComponent)
|
|
{
|
|
|
|
using namespace ScriptCanvas;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// Make the graph.
|
|
AZStd::unique_ptr<AZ::Entity> executionEntity = AZStd::make_unique<AZ::Entity>("Loaded Graph");
|
|
auto executionComponent = executionEntity->CreateComponent<ScriptCanvas::RuntimeComponent>();
|
|
|
|
auto* fileIO = AZ::IO::LocalFileIO::GetInstance();
|
|
EXPECT_NE(nullptr, fileIO);
|
|
EXPECT_TRUE(fileIO->Exists(k_tempCoreAssetPath));
|
|
|
|
// Load it
|
|
AZ::Data::Asset<ScriptCanvas::RuntimeAsset> runtimeAsset;
|
|
runtimeAsset.Create(AZ::Uuid::CreateRandom());
|
|
AZ::u64 fileLength = 0;
|
|
AZ::IO::FileIOBase::GetInstance()->Size(k_tempCoreAssetPath, fileLength);
|
|
AZStd::shared_ptr<AZ::Data::AssetDataStream> stream = AZStd::make_shared<AZ::Data::AssetDataStream>();
|
|
stream->Open(k_tempCoreAssetPath, 0, fileLength);
|
|
stream->BlockUntilLoadComplete();
|
|
|
|
// Serialize the runtime asset back in.
|
|
RuntimeAssetHandler runtimeAssetHandler;
|
|
EXPECT_EQ(runtimeAssetHandler.LoadAssetData(runtimeAsset, stream, {}), AZ::Data::AssetHandler::LoadResult::LoadComplete);
|
|
runtimeAssetHandler.InitAsset(runtimeAsset, true, false);
|
|
|
|
// Initialize the entity
|
|
executionComponent->SetRuntimeAsset(runtimeAsset);
|
|
executionEntity->Init();
|
|
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
executionEntity->Activate();
|
|
// Dispatch the AssetBus events to force onAssetReady event
|
|
AZ::Data::AssetManager::Instance().DispatchEvents();
|
|
}
|
|
|
|
EXPECT_FALSE(executionComponent->IsInErrorState());
|
|
|
|
const AZ::Vector3 allOne(1, 1, 1);
|
|
const AZ::Vector3 allTwo(2, 2, 2);
|
|
const AZ::Vector3 allThree(3, 3, 3);
|
|
const AZ::Vector3 allFour(4, 4, 4);
|
|
|
|
auto nodeIds = executionComponent->GetNodes();
|
|
EXPECT_EQ(9, nodeIds.size());
|
|
|
|
// Graph result should be still 16
|
|
// Serialized graph has new remapped entity ids
|
|
|
|
auto sumNodeIt = AZStd::find_if(nodeIds.begin(), nodeIds.end(), [](const AZ::EntityId& nodeId) -> bool
|
|
{
|
|
AZ::Entity* entity{};
|
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, nodeId);
|
|
return entity ? AZ::EntityUtils::FindFirstDerivedComponent<TestResult>(entity) ? true : false : false;
|
|
});
|
|
EXPECT_NE(nodeIds.end(), sumNodeIt);
|
|
|
|
TestResult* printNode = nullptr;
|
|
SystemRequestBus::BroadcastResult(printNode, &SystemRequests::GetNode<TestResult>, *sumNodeIt);
|
|
EXPECT_TRUE(printNode != nullptr);
|
|
|
|
if (auto result = GetInput_UNIT_TEST<float>(printNode, "Value"))
|
|
{
|
|
SC_EXPECT_FLOAT_EQ(*result, 16.0f);
|
|
}
|
|
else
|
|
{
|
|
ADD_FAILURE();
|
|
}
|
|
|
|
AZStd::vector<AZ::Vector3> vector3Results;
|
|
for (auto nodeId : nodeIds)
|
|
{
|
|
AZ::Entity* entity{};
|
|
AZ::ComponentApplicationBus::BroadcastResult(entity, &AZ::ComponentApplicationRequests::FindEntity, nodeId);
|
|
auto behaviorContextNode = entity ? AZ::EntityUtils::FindFirstDerivedComponent<Core::BehaviorContextObjectNode>(entity) : nullptr;
|
|
auto rawVector3 = behaviorContextNode ? GetInput_UNIT_TEST<AZ::Vector3>(behaviorContextNode, PureData::k_setThis) : nullptr;
|
|
if (rawVector3)
|
|
{
|
|
vector3Results.push_back(*rawVector3);
|
|
}
|
|
}
|
|
|
|
auto allOneFound = AZStd::any_of(vector3Results.begin(), vector3Results.end(), [allOne](const AZ::Vector3& vector3Result)
|
|
{
|
|
return allOne == vector3Result;
|
|
});
|
|
auto allTwoFound = AZStd::any_of(vector3Results.begin(), vector3Results.end(), [allTwo](const AZ::Vector3& vector3Result)
|
|
{
|
|
return allTwo == vector3Result;
|
|
});
|
|
auto allThreeFound = AZStd::any_of(vector3Results.begin(), vector3Results.end(), [allThree](const AZ::Vector3& vector3Result)
|
|
{
|
|
return allThree == vector3Result;
|
|
});
|
|
auto allFourFound = AZStd::any_of(vector3Results.begin(), vector3Results.end(), [allFour](const AZ::Vector3& vector3Result)
|
|
{
|
|
return allFour == vector3Result;
|
|
});
|
|
|
|
EXPECT_TRUE(allOneFound);
|
|
EXPECT_TRUE(allTwoFound);
|
|
EXPECT_TRUE(allThreeFound);
|
|
EXPECT_FALSE(allFourFound);
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, Contracts)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
RegisterComponentDescriptor<ContractNode>();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Make the graph.
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
// Make the nodes.
|
|
|
|
// Start
|
|
AZ::Entity* startEntity{ aznew AZ::Entity("Start") };
|
|
startEntity->Init();
|
|
AZ::EntityId startNode{ startEntity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, startNode, graphUniqueId, Nodes::Core::Start::TYPEINFO_Uuid());
|
|
|
|
// ContractNode 0
|
|
AZ::Entity* contract0Entity{ aznew AZ::Entity("Contract 0") };
|
|
contract0Entity->Init();
|
|
AZ::EntityId contract0Node{ contract0Entity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, contract0Node, graphUniqueId, ContractNode::TYPEINFO_Uuid());
|
|
|
|
// ContractNode 1
|
|
AZ::Entity* contract1Entity{ aznew AZ::Entity("Contract 1") };
|
|
contract1Entity->Init();
|
|
AZ::EntityId contract1Node{ contract1Entity->GetId() };
|
|
SystemRequestBus::Broadcast(&SystemRequests::CreateNodeOnEntity, contract1Node, graphUniqueId, ContractNode::TYPEINFO_Uuid());
|
|
|
|
// invalid
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("Out"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Out")));
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("In"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("In")));
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("In"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Get String")));
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("Out"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Get String")));
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("In"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String")));
|
|
EXPECT_FALSE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("Out"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String")));
|
|
EXPECT_FALSE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Set String")));
|
|
EXPECT_FALSE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Set Number")));
|
|
EXPECT_FALSE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Get Number")));
|
|
EXPECT_FALSE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Set String")));
|
|
|
|
EXPECT_FALSE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Out"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("In")));
|
|
}
|
|
|
|
// valid
|
|
EXPECT_TRUE(graph->Connect(startNode, AZ::EntityUtils::FindFirstDerivedComponent<Node>(startEntity)->GetSlotId("Out"), contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("In")));
|
|
EXPECT_TRUE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set String"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Get String")));
|
|
EXPECT_TRUE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("In"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Out")));
|
|
EXPECT_TRUE(graph->Connect(contract0Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract0Entity)->GetSlotId("Set Number"), contract1Node, AZ::EntityUtils::FindFirstDerivedComponent<Node>(contract1Entity)->GetSlotId("Get Number")));
|
|
|
|
// Execute it
|
|
graph->GetEntity()->Activate();
|
|
ReportErrors(graph);
|
|
graph->GetEntity()->Deactivate();
|
|
delete graph->GetEntity();
|
|
}
|
|
|
|
#if defined (SCRIPTCANVAS_ERRORS_ENABLED)
|
|
|
|
TEST_F(ScriptCanvasTestFixture, Error)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
RegisterComponentDescriptor<UnitTestErrorNode>();
|
|
RegisterComponentDescriptor<InfiniteLoopNode>();
|
|
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
UnitTestEventsHandler unitTestHandler;
|
|
unitTestHandler.BusConnect();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZStd::string description = "Unit test error!";
|
|
AZ::EntityId stringNodeID;
|
|
CreateDataNode(graphUniqueId, description, stringNodeID);
|
|
|
|
AZStd::string sideFX1 = "Side FX 1";
|
|
AZ::EntityId sideFX1NodeID;
|
|
CreateDataNode(graphUniqueId, sideFX1, sideFX1NodeID);
|
|
|
|
AZ::EntityId errorNodeID;
|
|
CreateTestNode<UnitTestErrorNode>(graphUniqueId, errorNodeID);
|
|
|
|
AZ::EntityId sideEffectID = CreateClassFunctionNode(graphUniqueId, "UnitTestEventsBus", "SideEffect");
|
|
|
|
EXPECT_TRUE(Connect(*graph, sideFX1NodeID, "Get", sideEffectID, "String: 0"));
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", errorNodeID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, errorNodeID, "Out", sideEffectID, "In"));
|
|
|
|
// test to make sure the graph received an error
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graph->GetEntity()->Activate();
|
|
}
|
|
|
|
const bool expectErrors = true;
|
|
const bool expectIrrecoverableErrors = true;
|
|
ReportErrors(graph, expectErrors, expectIrrecoverableErrors);
|
|
|
|
EXPECT_EQ(unitTestHandler.SideEffectCount(sideFX1), 0);
|
|
|
|
graph->GetEntity()->Deactivate();
|
|
delete graph->GetEntity();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, ErrorNode)
|
|
{
|
|
|
|
using namespace ScriptCanvas;
|
|
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
UnitTestEventsHandler unitTestHandler;
|
|
unitTestHandler.BusConnect();
|
|
|
|
// Start
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZStd::string description = "Test Error Report";
|
|
AZ::EntityId stringNodeID;
|
|
CreateDataNode(graphUniqueId, description, stringNodeID);
|
|
|
|
AZStd::string sideFX1 = "Side FX 1";
|
|
AZ::EntityId sideFX1NodeID;
|
|
CreateDataNode(graphUniqueId, sideFX1, sideFX1NodeID);
|
|
|
|
AZ::EntityId errorNodeID;
|
|
CreateTestNode<Nodes::Core::Error>(graphUniqueId, errorNodeID);
|
|
|
|
AZ::EntityId sideEffectID = CreateClassFunctionNode(graphUniqueId, "UnitTestEventsBus", "SideEffect");
|
|
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", sideEffectID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, sideFX1NodeID, "Get", sideEffectID, "String: 0"));
|
|
EXPECT_TRUE(Connect(*graph, sideEffectID, "Out", errorNodeID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, stringNodeID, "Get", errorNodeID, "Description"));
|
|
|
|
// test to make sure the graph received an error
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graph->GetEntity()->Activate();
|
|
}
|
|
|
|
const bool expectErrors = true;
|
|
const bool expectIrrecoverableErrors = true;
|
|
ReportErrors(graph, expectErrors, expectIrrecoverableErrors);
|
|
|
|
EXPECT_EQ(unitTestHandler.SideEffectCount(sideFX1), 1);
|
|
|
|
graph->GetEntity()->Deactivate();
|
|
|
|
// test to make sure the graph did to retry execution
|
|
graph->GetEntity()->Activate();
|
|
ReportErrors(graph, expectErrors, expectIrrecoverableErrors);
|
|
|
|
// if the graph was allowed to execute, the side effect counter should be higher
|
|
EXPECT_EQ(unitTestHandler.SideEffectCount(sideFX1), 1);
|
|
|
|
delete graph->GetEntity();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, InfiniteLoopDetected)
|
|
{
|
|
using namespace ScriptCanvas;
|
|
|
|
RegisterComponentDescriptor<InfiniteLoopNode>();
|
|
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
UnitTestEventsHandler unitTestHandler;
|
|
unitTestHandler.BusConnect();
|
|
|
|
AZStd::string sideFXpass = "Side FX Infinite Loop Error Handled";
|
|
AZ::EntityId sideFXpassNodeID;
|
|
CreateDataNode(graphUniqueId, sideFXpass, sideFXpassNodeID);
|
|
|
|
AZStd::string sideFXfail = "Side FX Infinite Loop Node Failed";
|
|
AZ::EntityId sideFXfailNodeID;
|
|
CreateDataNode(graphUniqueId, sideFXfail, sideFXfailNodeID);
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
AZ::EntityId infiniteLoopNodeID;
|
|
CreateTestNode<InfiniteLoopNode>(graphUniqueId, infiniteLoopNodeID);
|
|
AZ::EntityId errorHandlerID;
|
|
CreateTestNode<Nodes::Core::ErrorHandler>(graphUniqueId, errorHandlerID);
|
|
|
|
AZ::EntityId sideEffectPassID = CreateClassFunctionNode(graphUniqueId, "UnitTestEventsBus", "SideEffect");
|
|
AZ::EntityId sideEffectFailID = CreateClassFunctionNode(graphUniqueId, "UnitTestEventsBus", "SideEffect");
|
|
|
|
EXPECT_TRUE(Connect(*graph, sideFXpassNodeID, "Get", sideEffectPassID, "String: 0"));
|
|
EXPECT_TRUE(Connect(*graph, sideFXfailNodeID, "Get", sideEffectFailID, "String: 0"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", infiniteLoopNodeID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, infiniteLoopNodeID, "In", infiniteLoopNodeID, "Before Infinity"));
|
|
|
|
EXPECT_TRUE(Connect(*graph, infiniteLoopNodeID, "After Infinity", sideEffectFailID, "In"));
|
|
EXPECT_TRUE(Connect(*graph, errorHandlerID, "Out", sideEffectPassID, "In"));
|
|
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graph->GetEntity()->Activate();
|
|
}
|
|
|
|
const bool expectError = true;
|
|
const bool expectIrrecoverableError = true;
|
|
ReportErrors(graph, expectError, expectIrrecoverableError);
|
|
EXPECT_EQ(0, unitTestHandler.SideEffectCount(sideFXpass));
|
|
EXPECT_EQ(0, unitTestHandler.SideEffectCount(sideFXfail));
|
|
|
|
graph->GetEntity()->Deactivate();
|
|
graph->GetEntity()->Activate();
|
|
|
|
ReportErrors(graph, expectError, expectIrrecoverableError);
|
|
EXPECT_EQ(0, unitTestHandler.SideEffectCount(sideFXpass));
|
|
EXPECT_EQ(0, unitTestHandler.SideEffectCount(sideFXfail));
|
|
|
|
delete graph->GetEntity();
|
|
}
|
|
|
|
#endif // SCRIPTCANAS_ERRORS_ENABLED
|
|
|
|
|
|
TEST_F(ScriptCanvasTestFixture, BinaryOperationTest)
|
|
{
|
|
|
|
using namespace ScriptCanvas::Nodes;
|
|
using namespace ScriptCanvas::Nodes::Comparison;
|
|
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
|
|
BinaryOpTest<EqualTo>(1, 1, true);
|
|
BinaryOpTest<EqualTo>(1, 0, false);
|
|
BinaryOpTest<EqualTo>(0, 1, false);
|
|
BinaryOpTest<EqualTo>(0, 0, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(1, 1, false);
|
|
BinaryOpTest<NotEqualTo>(1, 0, true);
|
|
BinaryOpTest<NotEqualTo>(0, 1, true);
|
|
BinaryOpTest<NotEqualTo>(0, 0, false);
|
|
|
|
BinaryOpTest<Greater>(1, 1, false);
|
|
BinaryOpTest<Greater>(1, 0, true);
|
|
BinaryOpTest<Greater>(0, 1, false);
|
|
BinaryOpTest<Greater>(0, 0, false);
|
|
|
|
BinaryOpTest<GreaterEqual>(1, 1, true);
|
|
BinaryOpTest<GreaterEqual>(1, 0, true);
|
|
BinaryOpTest<GreaterEqual>(0, 1, false);
|
|
BinaryOpTest<GreaterEqual>(0, 0, true);
|
|
|
|
BinaryOpTest<Less>(1, 1, false);
|
|
BinaryOpTest<Less>(1, 0, false);
|
|
BinaryOpTest<Less>(0, 1, true);
|
|
BinaryOpTest<Less>(0, 0, false);
|
|
|
|
BinaryOpTest<LessEqual>(1, 1, true);
|
|
BinaryOpTest<LessEqual>(1, 0, false);
|
|
BinaryOpTest<LessEqual>(0, 1, true);
|
|
BinaryOpTest<LessEqual>(0, 0, true);
|
|
|
|
BinaryOpTest<EqualTo>(true, true, true);
|
|
BinaryOpTest<EqualTo>(true, false, false);
|
|
BinaryOpTest<EqualTo>(false, true, false);
|
|
BinaryOpTest<EqualTo>(false, false, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(true, true, false);
|
|
BinaryOpTest<NotEqualTo>(true, false, true);
|
|
BinaryOpTest<NotEqualTo>(false, true, true);
|
|
BinaryOpTest<NotEqualTo>(false, false, false);
|
|
|
|
AZStd::string string0("a string");
|
|
AZStd::string string1("b string");
|
|
|
|
BinaryOpTest<EqualTo>(string1, string1, true);
|
|
BinaryOpTest<EqualTo>(string1, string0, false);
|
|
BinaryOpTest<EqualTo>(string0, string1, false);
|
|
BinaryOpTest<EqualTo>(string0, string0, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(string1, string1, false);
|
|
BinaryOpTest<NotEqualTo>(string1, string0, true);
|
|
BinaryOpTest<NotEqualTo>(string0, string1, true);
|
|
BinaryOpTest<NotEqualTo>(string0, string0, false);
|
|
|
|
BinaryOpTest<Greater>(string1, string1, false);
|
|
BinaryOpTest<Greater>(string1, string0, true);
|
|
BinaryOpTest<Greater>(string0, string1, false);
|
|
BinaryOpTest<Greater>(string0, string0, false);
|
|
|
|
BinaryOpTest<GreaterEqual>(string1, string1, true);
|
|
BinaryOpTest<GreaterEqual>(string1, string0, true);
|
|
BinaryOpTest<GreaterEqual>(string0, string1, false);
|
|
BinaryOpTest<GreaterEqual>(string0, string0, true);
|
|
|
|
BinaryOpTest<Less>(string1, string1, false);
|
|
BinaryOpTest<Less>(string1, string0, false);
|
|
BinaryOpTest<Less>(string0, string1, true);
|
|
BinaryOpTest<Less>(string0, string0, false);
|
|
|
|
BinaryOpTest<LessEqual>(string1, string1, true);
|
|
BinaryOpTest<LessEqual>(string1, string0, false);
|
|
BinaryOpTest<LessEqual>(string0, string1, true);
|
|
BinaryOpTest<LessEqual>(string0, string0, true);
|
|
|
|
const AZ::Vector3 vectorOne(1.0f, 1.0f, 1.0f);
|
|
const AZ::Vector3 vectorZero(0.0f, 0.0f, 0.0f);
|
|
|
|
BinaryOpTest<EqualTo>(vectorOne, vectorOne, true);
|
|
BinaryOpTest<EqualTo>(vectorOne, vectorZero, false);
|
|
BinaryOpTest<EqualTo>(vectorZero, vectorOne, false);
|
|
BinaryOpTest<EqualTo>(vectorZero, vectorZero, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(vectorOne, vectorOne, false);
|
|
BinaryOpTest<NotEqualTo>(vectorOne, vectorZero, true);
|
|
BinaryOpTest<NotEqualTo>(vectorZero, vectorOne, true);
|
|
BinaryOpTest<NotEqualTo>(vectorZero, vectorZero, false);
|
|
|
|
const TestBehaviorContextObject zero(0);
|
|
const TestBehaviorContextObject one(1);
|
|
const TestBehaviorContextObject otherOne(1);
|
|
|
|
BinaryOpTest<EqualTo>(one, one, true);
|
|
BinaryOpTest<EqualTo>(one, zero, false);
|
|
BinaryOpTest<EqualTo>(zero, one, false);
|
|
BinaryOpTest<EqualTo>(zero, zero, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(one, one, false);
|
|
BinaryOpTest<NotEqualTo>(one, zero, true);
|
|
BinaryOpTest<NotEqualTo>(zero, one, true);
|
|
BinaryOpTest<NotEqualTo>(zero, zero, false);
|
|
|
|
BinaryOpTest<Greater>(one, one, false);
|
|
BinaryOpTest<Greater>(one, zero, true);
|
|
BinaryOpTest<Greater>(zero, one, false);
|
|
BinaryOpTest<Greater>(zero, zero, false);
|
|
|
|
BinaryOpTest<GreaterEqual>(one, one, true);
|
|
BinaryOpTest<GreaterEqual>(one, zero, true);
|
|
BinaryOpTest<GreaterEqual>(zero, one, false);
|
|
BinaryOpTest<GreaterEqual>(zero, zero, true);
|
|
|
|
BinaryOpTest<Less>(one, one, false);
|
|
BinaryOpTest<Less>(one, zero, false);
|
|
BinaryOpTest<Less>(zero, one, true);
|
|
BinaryOpTest<Less>(zero, zero, false);
|
|
|
|
BinaryOpTest<LessEqual>(one, one, true);
|
|
BinaryOpTest<LessEqual>(one, zero, false);
|
|
BinaryOpTest<LessEqual>(zero, one, true);
|
|
BinaryOpTest<LessEqual>(zero, zero, true);
|
|
|
|
BinaryOpTest<EqualTo>(one, otherOne, true);
|
|
BinaryOpTest<EqualTo>(otherOne, one, true);
|
|
|
|
BinaryOpTest<NotEqualTo>(one, otherOne, false);
|
|
BinaryOpTest<NotEqualTo>(otherOne, one, false);
|
|
|
|
BinaryOpTest<Greater>(one, otherOne, false);
|
|
BinaryOpTest<Greater>(otherOne, one, false);
|
|
|
|
BinaryOpTest<GreaterEqual>(one, otherOne, true);
|
|
BinaryOpTest<GreaterEqual>(otherOne, one, true);
|
|
|
|
BinaryOpTest<Less>(one, otherOne, false);
|
|
BinaryOpTest<Less>(otherOne, one, false);
|
|
|
|
BinaryOpTest<LessEqual>(one, otherOne, true);
|
|
BinaryOpTest<LessEqual>(otherOne, one, true);
|
|
|
|
// force failures, to verify crash proofiness
|
|
BinaryOpTest<EqualTo>(one, zero, false, true);
|
|
BinaryOpTest<NotEqualTo>(one, zero, true, true);
|
|
BinaryOpTest<Greater>(one, zero, true, true);
|
|
BinaryOpTest<GreaterEqual>(one, zero, true, true);
|
|
BinaryOpTest<Less>(one, zero, false, true);
|
|
BinaryOpTest<LessEqual>(one, zero, false, true);
|
|
|
|
m_serializeContext->EnableRemoveReflection();
|
|
m_behaviorContext->EnableRemoveReflection();
|
|
TestBehaviorContextObject::Reflect(m_serializeContext);
|
|
TestBehaviorContextObject::Reflect(m_behaviorContext);
|
|
m_serializeContext->DisableRemoveReflection();
|
|
m_behaviorContext->DisableRemoveReflection();
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, EntityRefTest)
|
|
{
|
|
|
|
|
|
using namespace ScriptCanvas;
|
|
using namespace ScriptCanvas::Nodes;
|
|
|
|
// Fake "world" entities
|
|
AZ::Entity first("First");
|
|
first.CreateComponent<ScriptCanvasTests::TestComponent>();
|
|
first.Init();
|
|
first.Activate();
|
|
|
|
AZ::Entity second("Second");
|
|
second.CreateComponent<ScriptCanvasTests::TestComponent>();
|
|
second.Init();
|
|
second.Activate();
|
|
|
|
// Script Canvas Graph
|
|
Graph* graph = nullptr;
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
|
|
m_entityContext.AddEntity(first.GetId());
|
|
m_entityContext.AddEntity(second.GetId());
|
|
m_entityContext.AddEntity(graph->GetEntityId());
|
|
|
|
graph->GetEntity()->SetName("Graph Owner Entity");
|
|
|
|
graph->GetEntity()->CreateComponent<ScriptCanvasTests::TestComponent>();
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityId = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
// EntityRef node to some specific entity #1
|
|
AZ::EntityId selfEntityIdNode;
|
|
auto selfEntityRef = CreateTestNode<Nodes::Entity::EntityRef>(graphUniqueId, selfEntityIdNode);
|
|
selfEntityRef->SetEntityRef(first.GetId());
|
|
|
|
// EntityRef node to some specific entity #2
|
|
AZ::EntityId otherEntityIdNode;
|
|
auto otherEntityRef = CreateTestNode<Nodes::Entity::EntityRef>(graphUniqueId, otherEntityIdNode);
|
|
otherEntityRef->SetEntityRef(second.GetId());
|
|
|
|
// Explicitly set an EntityRef node with this graph's entity Id.
|
|
AZ::EntityId graphEntityIdNode;
|
|
auto graphEntityRef = CreateTestNode<Nodes::Entity::EntityRef>(graphUniqueId, graphEntityIdNode);
|
|
graphEntityRef->SetEntityRef(graph->GetEntity()->GetId());
|
|
|
|
// First test: directly set an entity Id on the EntityID: 0 slot
|
|
AZ::EntityId eventAid;
|
|
Nodes::Core::Method* nodeA = CreateTestNode<Nodes::Core::Method>(graphUniqueId, eventAid);
|
|
nodeA->InitializeEvent({ {} }, "EntityRefTestEventBus", "TestEvent");
|
|
if (auto entityId = ModInput_UNIT_TEST<AZ::EntityId>(nodeA, "EntityID: 0"))
|
|
{
|
|
*entityId = first.GetId();
|
|
}
|
|
|
|
// Second test: Will connect the slot to an EntityRef node
|
|
AZ::EntityId eventBid;
|
|
Nodes::Core::Method* nodeB = CreateTestNode<Nodes::Core::Method>(graphUniqueId, eventBid);
|
|
nodeB->InitializeEvent({ {} }, "EntityRefTestEventBus", "TestEvent");
|
|
|
|
// Third test: Set the slot's EntityId: 0 to GraphOwnerId, this should result in the same Id as graph->GetEntityId()
|
|
AZ::EntityId eventCid;
|
|
Nodes::Core::Method* nodeC = CreateTestNode<Nodes::Core::Method>(graphUniqueId, eventCid);
|
|
nodeC->InitializeEvent({ {} }, "EntityRefTestEventBus", "TestEvent");
|
|
if (auto entityId = ModInput_UNIT_TEST<AZ::EntityId>(nodeC, "EntityID: 0"))
|
|
{
|
|
*entityId = ScriptCanvas::GraphOwnerId;
|
|
}
|
|
|
|
// True
|
|
AZ::EntityId trueNodeId;
|
|
CreateDataNode<Data::BooleanType>(graphUniqueId, true, trueNodeId);
|
|
|
|
// False
|
|
AZ::EntityId falseNodeId;
|
|
CreateDataNode<Data::BooleanType>(graphUniqueId, false, falseNodeId);
|
|
|
|
// Start -> TestEvent
|
|
// O EntityId: 0 (not connected, it was set directly on the slot)
|
|
// EntityRef: first -O EntityId: 1
|
|
// False -O Boolean: 2
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", eventAid, "In"));
|
|
EXPECT_TRUE(Connect(*graph, eventAid, "EntityID: 1", selfEntityIdNode, "Get"));
|
|
EXPECT_TRUE(Connect(*graph, eventAid, "Boolean: 2", falseNodeId, "Get"));
|
|
|
|
// Start -> TestEvent
|
|
// EntityRef: second -O EntityId: 0
|
|
// EntityRef: second -O EntityId: 1
|
|
// False -O Boolean: 2
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", eventBid, "In"));
|
|
EXPECT_TRUE(Connect(*graph, eventBid, "EntityID: 0", otherEntityIdNode, "Get"));
|
|
EXPECT_TRUE(Connect(*graph, eventBid, "EntityID: 1", otherEntityIdNode, "Get"));
|
|
EXPECT_TRUE(Connect(*graph, eventBid, "Boolean: 2", falseNodeId, "Get"));
|
|
|
|
// Start -> TestEvent
|
|
// -O EntityId: 0 (not connected, slot is set to GraphOwnerId)
|
|
// graphEntityIdNode -O EntityId: 1
|
|
// True -O Boolean: 2
|
|
EXPECT_TRUE(Connect(*graph, startID, "Out", eventCid, "In"));
|
|
EXPECT_TRUE(Connect(*graph, eventCid, "EntityID: 1", graphEntityIdNode, "Get"));
|
|
EXPECT_TRUE(Connect(*graph, eventCid, "Boolean: 2", trueNodeId, "Get"));
|
|
|
|
// Execute the graph
|
|
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graph->GetEntity()->Activate();
|
|
}
|
|
|
|
ReportErrors(graph);
|
|
delete graph->GetEntity();
|
|
|
|
}
|
|
|
|
const int k_executionCount = 998;
|
|
|
|
TEST_F(ScriptCanvasTestFixture, ExecutionLength)
|
|
{
|
|
|
|
using namespace ScriptCanvas;
|
|
|
|
Graph* graph(nullptr);
|
|
SystemRequestBus::BroadcastResult(graph, &SystemRequests::MakeGraph);
|
|
EXPECT_TRUE(graph != nullptr);
|
|
graph->GetEntity()->Init();
|
|
|
|
const AZ::EntityId& graphEntityID = graph->GetEntityId();
|
|
const ScriptCanvasId& graphUniqueId = graph->GetScriptCanvasId();
|
|
|
|
AZ::EntityId startID;
|
|
CreateTestNode<Nodes::Core::Start>(graphUniqueId, startID);
|
|
|
|
AZ::EntityId previousID = startID;
|
|
|
|
for (int i = 0; i < k_executionCount; ++i)
|
|
{
|
|
AZ::EntityId printNodeID;
|
|
TestResult* printNode = CreateTestNode<TestResult>(graphUniqueId, printNodeID);
|
|
SetInput_UNIT_TEST<int>(printNode, "Value", i);
|
|
EXPECT_TRUE(Connect(*graph, previousID, "Out", printNodeID, "In"));
|
|
previousID = printNodeID;
|
|
}
|
|
|
|
AZ::Entity* graphEntity = graph->GetEntity();
|
|
{
|
|
ScriptCanvasEditor::ScopedOutputSuppression suppressOutput;
|
|
graphEntity->Activate();
|
|
}
|
|
|
|
ReportErrors(graph);
|
|
|
|
graphEntity->Deactivate();
|
|
delete graphEntity;
|
|
}
|
|
|
|
TEST_F(ScriptCanvasTestFixture, AnyNode)
|
|
{
|
|
RunUnitTestGraph("LY_SC_UnitTest_Any");
|
|
}
|