#include "stdafx.h" #include "xtr/core/PyCore.h" #pragma warning( push ) #pragma warning( disable : 4100 ) #include "Python.h" #pragma warning( pop ) using cxxpython::PyCore; using cxxpython::Object; class UTPyCore : public ::testing::Test { protected: inline static const std::string sampleModule = "sample_module"; inline static const std::string moduleKey = "sample"; PyCore& python{ PyCore::Instance() }; void SetUp() override { python.Start(); } void TearDown() override { python.Stop(); } }; TEST_F(UTPyCore, Start) { python.Stop(); EXPECT_FALSE(python.IsRunning()); ASSERT_TRUE(python.Start()); EXPECT_FALSE(python.Start()); EXPECT_TRUE(python.IsRunning()); python.Stop(); } TEST_F(UTPyCore, Stop) { python.Stop(); EXPECT_FALSE(python.IsRunning()); EXPECT_NO_THROW(python.Stop()); } TEST_F(UTPyCore, ObjectNullptr) { EXPECT_TRUE(Object(nullptr) == nullptr); EXPECT_TRUE(Object::FromNew(nullptr) == nullptr); EXPECT_TRUE(Object::FromBorrowed(nullptr) == nullptr); } TEST_F(UTPyCore, ObjectHandles) { auto newTuple = Object::FromNew(PyTuple_New(1)); ASSERT_TRUE(newTuple != nullptr); EXPECT_EQ(Py_REFCNT(newTuple.get()), 1); const auto borrowed = Object::FromBorrowed(newTuple.get()); EXPECT_EQ(Py_REFCNT(borrowed.get()), 2); newTuple = nullptr; EXPECT_EQ(Py_REFCNT(borrowed.get()), 1); auto copy = borrowed; EXPECT_EQ(Py_REFCNT(copy.get()), 2); } TEST_F(UTPyCore, ObjectTypes) { const auto boolObj = Object::FromNew(PyBool_FromLong(0)); const auto longObj = Object::FromNew(PyLong_FromLong(42)); const auto strObj = Object::FromNew(PyUnicode_FromString("test")); const auto tupleObj = Object::FromNew(Py_BuildValue("(i, u)", 43, L"second")); EXPECT_FALSE(cxxpython::ToBool(boolObj)); EXPECT_EQ(cxxpython::ToLong(longObj), 42); EXPECT_EQ(cxxpython::ToString(strObj), "test"); EXPECT_EQ(cxxpython::ToLong(tupleObj.at(0)), 43); EXPECT_EQ(cxxpython::ToString(tupleObj.at(1)), "second"); } TEST_F(UTPyCore, LoadModule) { EXPECT_TRUE(python.LoadModule(moduleKey, sampleModule)); EXPECT_TRUE(python.LoadModule(moduleKey, sampleModule)); EXPECT_FALSE(python.LoadModule({}, {})); EXPECT_FALSE(python.LoadModule("42", "42")); EXPECT_TRUE(python.LoadModule(moduleKey + "42", sampleModule)); EXPECT_FALSE(python.LoadModule({}, sampleModule)); } TEST_F(UTPyCore, PyFunction) { EXPECT_TRUE(python.PyFunction({}, {}) == nullptr); EXPECT_TRUE(python.PyFunction(moduleKey, {}) == nullptr); python.LoadModule(moduleKey, sampleModule); EXPECT_TRUE(python.PyFunction(moduleKey, "invalid_func") == nullptr); EXPECT_FALSE(python.PyFunction(moduleKey, "get_state") == nullptr); } TEST_F(UTPyCore, CallFunction) { python.LoadModule(moduleKey, sampleModule); const auto get_state = python.PyFunction(moduleKey, "get_state"); const auto increment = python.PyFunction(moduleKey, "increment"); const auto add_abc = python.PyFunction(moduleKey, "add_abc"); EXPECT_EQ(cxxpython::ToLong(get_state()), 42); EXPECT_EQ(cxxpython::ToLong(increment("(i)", 42)), 43); EXPECT_EQ(cxxpython::ToString(add_abc("(s)", "123")), "123abc"); }