/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and 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 #include #include #include "PythonTraceMessageSink.h" #include "PythonTestingUtility.h" #include #include #include #include #include #include #include namespace UnitTest { struct PythonReflectUnorderedSet { AZ_TYPE_INFO(PythonReflectUnorderedSet, "{A596466F-2F29-4479-A721-0E50FA704962}"); AZStd::unordered_set m_u8Set {1,2}; AZStd::unordered_set m_u16Set {4,8}; AZStd::unordered_set m_u32Set {16,32}; AZStd::unordered_set m_u64Set {64,128}; AZStd::unordered_set m_s8Set {-1,-2}; AZStd::unordered_set m_s16Set {-4,-8}; AZStd::unordered_set m_s32Set {-16,-32}; AZStd::unordered_set m_s64Set {-64,-128}; AZStd::unordered_set m_floatSet {1.0f, 2.0f}; AZStd::unordered_set m_doubleSet {0.1, 0.2}; AZStd::unordered_set m_stringSet {"one", "two"}; void Reflect(AZ::ReflectContext* context) { if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); serializeContext->RegisterGenericType(); } if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->Class() ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Module, "test.set") ->Property("u8Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_u8Set) ) ->Property("u16Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_u16Set)) ->Property("u32Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_u32Set)) ->Property("u64Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_u64Set)) ->Property("s8Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_s8Set)) ->Property("s16Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_s16Set)) ->Property("s32Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_s32Set)) ->Property("s64Set", BehaviorValueProperty(&PythonReflectUnorderedSet::m_s64Set)) ->Property("floatSet", BehaviorValueProperty(&PythonReflectUnorderedSet::m_floatSet)) ->Property("doubleSet", BehaviorValueProperty(&PythonReflectUnorderedSet::m_doubleSet)) ->Property("stringSet", BehaviorValueProperty(&PythonReflectUnorderedSet::m_stringSet)) ; } } }; ////////////////////////////////////////////////////////////////////////// // fixtures struct PythonAssociativeTest : public PythonTestingFixture { PythonTraceMessageSink m_testSink; void SetUp() override { PythonTestingFixture::SetUp(); PythonTestingFixture::RegisterComponentDescriptors(); } void TearDown() override { // clearing up memory m_testSink = PythonTraceMessageSink(); PythonTestingFixture::TearDown(); } }; TEST_F(PythonAssociativeTest, SimpleUnorderedSet_Assignment) { enum class LogTypes { Skip = 0, Update, }; m_testSink.m_evaluateMessage = [](const char* window, const char* message) -> int { if (AZ::StringFunc::Equal(window, "python")) { if (AZ::StringFunc::StartsWith(message, "Update")) { return aznumeric_cast(LogTypes::Update); } } return aznumeric_cast(LogTypes::Skip); }; PythonReflectUnorderedSet pythonReflectUnorderedSet; pythonReflectUnorderedSet.Reflect(m_app.GetSerializeContext()); pythonReflectUnorderedSet.Reflect(m_app.GetBehaviorContext()); AZ::Entity e; Activate(e); SimulateEditorBecomingInitialized(); try { pybind11::exec(R"( import azlmbr.test.set tester = azlmbr.test.set.PythonReflectUnorderedSet() def updateNumberDataSet(memberSet, dataSet): memberSet = dataSet for value in memberSet: if (value in dataSet): print ('Update_worked_{}'.format(memberSet)) updateNumberDataSet(tester.u8Set, {2, 1}) updateNumberDataSet(tester.u16Set, {8, 4}) updateNumberDataSet(tester.u32Set, {32, 16}) updateNumberDataSet(tester.u64Set, {128, 64}) updateNumberDataSet(tester.s8Set, {-2, -1}) updateNumberDataSet(tester.s16Set, {-8, -4}) updateNumberDataSet(tester.s32Set, {-32, -16}) updateNumberDataSet(tester.s64Set, {-128, -64}) from azlmbr.math import Math_IsClose def updateFloatDataSet(memberFloatSet, dataSet): memberFloatSet = dataSet for dataItem in dataSet: for memberItem in memberFloatSet: if (Math_IsClose(dataItem, memberItem)): print ('Update_float_worked_{}'.format(memberFloatSet)) updateFloatDataSet(tester.floatSet, {4.0, 8.0}) updateFloatDataSet(tester.doubleSet, {0.4, 0.8}) stringDataSet = {'three','four'} tester.stringSet = stringDataSet for dataItem in stringDataSet: for memberItem in tester.stringSet: if (dataItem == memberItem): print ('Update_string_worked') )"); } catch (const std::exception& e) { AZ_Error("UnitTest", false, "Failed with Python exception of %s", e.what()); } e.Deactivate(); EXPECT_EQ(22, m_testSink.m_evaluationMap[aznumeric_cast(LogTypes::Update)]); } TEST_F(PythonAssociativeTest, SimpleUnorderedSet_Creation) { enum class LogTypes { Skip = 0, Create, }; m_testSink.m_evaluateMessage = [](const char* window, const char* message) -> int { if (AZ::StringFunc::Equal(window, "python")) { if (AZ::StringFunc::StartsWith(message, "Create")) { return aznumeric_cast(LogTypes::Create); } } return aznumeric_cast(LogTypes::Skip); }; PythonReflectUnorderedSet pythonReflectUnorderedSet; pythonReflectUnorderedSet.Reflect(m_app.GetSerializeContext()); pythonReflectUnorderedSet.Reflect(m_app.GetBehaviorContext()); AZ::Entity e; Activate(e); SimulateEditorBecomingInitialized(); try { pybind11::exec(R"( import azlmbr.test.set tester = azlmbr.test.set.PythonReflectUnorderedSet() if (tester.u8Set == {1, 2}): print ('Create_Works_u8Set') if (tester.u16Set == {4, 8}): print ('Create_Works_u16Set') if (tester.u32Set == {16, 32}): print ('Create_Works_u32Set') if (tester.u64Set == {64, 128}): print ('Create_Works_u64Set') if (tester.s8Set == {-1, -2}): print ('Create_Works_s8Set') if (tester.s16Set == {-4, -8}): print ('Create_Works_s16Set') if (tester.s32Set == {-16, -32}): print ('Create_Works_s32Set') if (tester.s64Set == {-64, -128}): print ('Create_Works_s64Set') from azlmbr.math import Math_IsClose for value in tester.floatSet: if (Math_IsClose(value, 1.0) or Math_IsClose(value, 2.0)): print ('Create_Works_floatSet') for value in tester.doubleSet: if (Math_IsClose(value, 0.1) or Math_IsClose(value, 0.2)): print ('Create_Works_doubleSet') for value in tester.stringSet: if ((value == 'one') or (value == 'two')): print ('Create_Works_stringSet') )"); } catch (const std::exception& e) { AZ_Error("UnitTest", false, "Failed with Python exception of %s", e.what()); } e.Deactivate(); EXPECT_EQ(14, m_testSink.m_evaluationMap[aznumeric_cast(LogTypes::Create)]); } }