Improve code coverage 24/297924/7
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 28 Aug 2023 23:34:36 +0000 (08:34 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 29 Aug 2023 02:15:40 +0000 (11:15 +0900)
- Adds unit tests
- Excludes some lines

Change-Id: I900675d55e8b4d220b3b79936bb0b8ec7e20cc7a
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
23 files changed:
CMakeLists.txt
packaging/capi-appfw-application.spec
src/app_device.cc
src/app_main.cc
src/app_main_legacy.cc
src/app_resource.cc
tests/CMakeLists.txt
tests/application_unittests/CMakeLists.txt [new file with mode: 0644]
tests/application_unittests/app_device_test.cc [new file with mode: 0644]
tests/application_unittests/app_main_legacy_test.cc [new file with mode: 0644]
tests/application_unittests/app_main_test.cc [new file with mode: 0644]
tests/application_unittests/app_resource_test.cc [new file with mode: 0644]
tests/application_unittests/main.cc [new file with mode: 0644]
tests/application_unittests/mock/app_core_efl_mock.cc [new file with mode: 0644]
tests/application_unittests/mock/app_core_efl_mock.hh [new file with mode: 0644]
tests/application_unittests/mock/app_core_mock.cc [new file with mode: 0644]
tests/application_unittests/mock/app_core_mock.hh [new file with mode: 0644]
tests/application_unittests/mock/elementary_mock.cc [new file with mode: 0644]
tests/application_unittests/mock/elementary_mock.hh [new file with mode: 0644]
tests/application_unittests/mock/mock_hook.hh [new file with mode: 0644]
tests/application_unittests/mock/module_mock.hh [new file with mode: 0644]
tests/application_unittests/mock/test_fixture.cc [new file with mode: 0644]
tests/application_unittests/mock/test_fixture.hh [new file with mode: 0644]

index 1b308a8f0ff3c48dab58312fcdd6c0bf61896fd8..8985ea01342a86cb34a3c8955e64df760c53d69c 100644 (file)
@@ -26,6 +26,11 @@ SET(TARGET_APPLICATION "capi-appfw-application")
 SET(TARGET_APPCORE_UI_APP_AMBIENT "appcore-ui-app-ambient")
 
 ENABLE_TESTING()
+SET(TARGET_APPLICATION_UNITTESTS "application_unittests")
+ADD_TEST(NAME ${TARGET_APPLICATION_UNITTESTS}
+  COMMAND ${TARGET_APPLICATION_UNITTESTS}
+  WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/tests/application_unittests)
+
 SET(TARGET_UI_APP_AMBIENT_UNITTESTS "ui-app-ambient_unittests")
 ADD_TEST(NAME ${TARGET_UI_APP_AMBIENT_UNITTESTS}
   COMMAND ${TARGET_UI_APP_AMBIENT_UNITTESTS}
index a0925c87997b1fb2afe939963d53c08e72fffd92..484d2fcd2d46d1fa67a07d459012570f2d384076 100644 (file)
@@ -75,7 +75,7 @@ MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
 %__make %{?jobs:-j%jobs}
 
 %check
-export LD_LIBRARY_PATH="../../appcore_ui_app_ambient"
+export LD_LIBRARY_PATH="../../appcore_ui_app_ambient:../../src"
 ctest --verbose %{?_smp_mflags}
 %if 0%{?gcov:1}
 lcov -c --ignore-errors graph --no-external -q -d . -o appcore_ui_app_ambient.info
@@ -116,6 +116,7 @@ setup() {
 test_main() {
     echo "test_main start"
     export "GCOV_PREFIX=/tmp"
+    /usr/bin/application_unittest
     /usr/bin/ui-app-ambient_unittest
 }
 
@@ -180,6 +181,7 @@ Header & package configuration of appcore-ui-app-ambient
 %{_libdir}/libappcore-ui-app-ambient.so.*
 
 %files unittests
+%{_bindir}/application_unittests
 %{_bindir}/ui-app-ambient_unittests
 %{_bindir}/tizen-unittests/%{name}/run-unittest.sh
 
index 5a430b3b1016a8fb72b8cfe465b0585d894c5656..88af63fdc7baad977b2304e33799896618b06e06 100644 (file)
  * limitations under the License.
  */
 
+#include "include/app_internal.h"
+
 #include <stdexcept>
 
 #include <app_core_efl_base.hh>
 
-#include "app_internal.h"
 #include "common_private.hh"
 
 using namespace tizen_cpp;
@@ -51,7 +52,7 @@ API app_device_orientation_e app_get_device_orientation(void) {
     AppCoreBase::RotationState s = AppCoreBase::GetRotationState();
     dev_orientation = AppCoreRmConvert(s);
   } catch (const std::runtime_error& e) {
-    return APP_DEVICE_ORIENTATION_0;
+    return APP_DEVICE_ORIENTATION_0;  // LCOV_EXCL_LINE
   }
 
   return dev_orientation;
index 62b000812bcd71daa35c8b0671ccb609778682b3..45b3d41da5203958dd27cd208f745227845101e8 100644 (file)
@@ -75,14 +75,18 @@ class UiAppContext : public AppCoreEflBase {
     if (b.GetHandle()) {
       int ret = app_control_create_event(b.GetHandle(), &app_control);
       if (ret != APP_ERROR_NONE) {
+        // LCOV_EXCL_START
         _E("Failed to create an app_control handle");
         return APP_ERROR_INVALID_PARAMETER;
+        // LCOV_EXCL_STOp
       }
     } else {
+      // LCOV_EXCL_START
       if (app_control_create(&app_control) != APP_ERROR_NONE) {
         _E("Failed to create an app_control handle");
         return APP_ERROR_OUT_OF_MEMORY;
       }
+      // LCOV_EXCL_STOP
     }
 
     if (callback_.app_control)
@@ -163,15 +167,19 @@ API int ui_app_main(int argc, char** argv,
   }
 
   if (callback->create == nullptr) {
+    // LCOV_EXCL_START
     _E("app_create_cb() callback MUST be registerted");
     return APP_ERROR_INVALID_PARAMETER;
+    // LCOV_EXCL_STOP
   }
 
+  // LCOV_EXCL_START
   if (__context.get() != nullptr &&
       __context->GetAppState() != UiAppContext::APP_STATE_NOT_RUNNING) {
     _E("Already running");
     return APP_ERROR_ALREADY_RUNNING;
   }
+  // LCOV_EXCL_STOP
 
   unsigned int hint = AppCoreEflBase::HINT_WINDOW_GROUP_CONTROL |
       AppCoreEflBase::HINT_WINDOW_STACK_CONTROL |
@@ -189,7 +197,7 @@ API int ui_app_main(int argc, char** argv,
 
     __context->Run(argc, argv);
   } catch (std::runtime_error& e) {
-    __context->SetAppState(UiAppContext::APP_STATE_NOT_RUNNING);
+    __context->SetAppState(UiAppContext::APP_STATE_NOT_RUNNING);  // LCOV_EXCL_LINE
   }
 
   return APP_ERROR_NONE;
@@ -218,15 +226,19 @@ API int ui_app_add_event_handler(app_event_handler_h* event_handler,
   auto* ae = new (std::nothrow) AppEvent(__app_event_converter[event_type],
       callback, user_data);
   if (ae == nullptr) {
+    // LCOV_EXCL_START
     _E("Out of memory");
     return APP_ERROR_OUT_OF_MEMORY;
+    // LCOV_EXCL_STOP
   }
 
   auto* h = new (std::nothrow) std::shared_ptr<AppEvent>(ae);
   if (h == nullptr) {
+    // LCOV_EXCL_START
     _E("Out of memory");
     delete ae;
     return APP_ERROR_OUT_OF_MEMORY;
+    // LCOV_EXCL_STOP
   }
 
   if (__context.get() &&
@@ -250,15 +262,19 @@ API int ui_app_remove_event_handler(app_event_handler_h event_handler) {
   auto type = (*eb)->GetType();
   if (type < IAppCore::IEvent::Type::LOW_MEMORY ||
       type > IAppCore::IEvent::Type::UPDATE_REQUESTED) {
+    // LCOV_EXCL_START
     _E("invalid parameter");
     return APP_ERROR_INVALID_PARAMETER;
+    // LCOV_EXCL_STOP
   }
 
   if (__context.get() &&
       __context->GetAppState() == UiAppContext::APP_STATE_RUNNING) {
     if (!__context->RemoveEvent(*eb)) {
+      // LCOV_EXCL_START
       _E("Invalid handle");
       return APP_ERROR_INVALID_PARAMETER;
+      // LCOV_EXCL_STOP
     }
   } else {
     __pending_app_events.remove(*eb);
index 5cc215842d1f54d48c8f04131b3f3e5598a800ca..0071de26ae9a9fd8d5c7111d1a64fc80913ff5e0 100644 (file)
@@ -134,6 +134,7 @@ class AppMain {
       context->cb_->app_control(app_control, context->data_);
   }
 
+  // LCOV_EXCL_START
   static void OnLowMemory(app_event_info_h event_info, void* data) {
     auto* context = static_cast<AppMain*>(data);
     if (context->cb_->low_memory)
@@ -167,6 +168,7 @@ class AppMain {
     if (context->cb_->region_format_changed)
       context->cb_->region_format_changed(context->data_);
   }
+  // LCOV_EXCL_STOP
 
  private:
   app_event_callback_s* cb_;
index 4b6d5f4fb575a0acc97c6d6da7d328ab6926c90a..8549a2681752ffc5013cefe9bcdeeb0efb1943a4 100644 (file)
  * limitations under the License.
  */
 
+#include "include/app_extension.h"
+
 #include <Elementary.h>
 
-#include "app_extension.h"
 #include "common_private.hh"
 
 API void* app_get_preinitialized_window(const char* win_name) {
index 9ed63b322561c619d60a6c4e9121cfa7edaef9bb..21027f9f0a3ae08ea18231f1f5d04b637055ebcb 100644 (file)
@@ -1 +1,2 @@
+ADD_SUBDIRECTORY(application_unittests)
 ADD_SUBDIRECTORY(ui-app-ambient_unittests)
diff --git a/tests/application_unittests/CMakeLists.txt b/tests/application_unittests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..aa815ca
--- /dev/null
@@ -0,0 +1,32 @@
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} UNIT_TEST_SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock MOCK_SRCS)
+
+ADD_EXECUTABLE(${TARGET_APPLICATION_UNITTESTS}
+  ${UNIT_TEST_SRCS}
+  ${MOCK_SRCS})
+
+TARGET_INCLUDE_DIRECTORIES(${TARGET_APPLICATION_UNITTESTS} PUBLIC
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/mock/
+  ${CMAKE_CURRENT_SOURCE_DIR}/../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../include/)
+
+APPLY_PKG_CONFIG(${TARGET_APPLICATION_UNITTESTS} PUBLIC
+  AUL_DEPS
+  BUNDLE_DEPS
+  CAPI_APPFW_APP_COMMON_DEPS
+  DLOG_DEPS
+  GLIB_DEPS
+  GMOCK_DEPS
+)
+
+TARGET_LINK_LIBRARIES(${TARGET_APPLICATION_UNITTESTS} PUBLIC
+  ${TARGET_APPLICATION})
+
+SET_TARGET_PROPERTIES(${TARGET_APPLICATION_UNITTESTS}
+  PROPERTIES COMPILE_FLAGS "-fPIE")
+SET_TARGET_PROPERTIES(${TARGET_APPLICATION_UNITTESTS}
+  PROPERTIES LINK_FLAGS "-pie")
+
+INSTALL(TARGETS ${TARGET_APPLICATION_UNITTESTS} DESTINATION bin)
diff --git a/tests/application_unittests/app_device_test.cc b/tests/application_unittests/app_device_test.cc
new file mode 100644 (file)
index 0000000..5fd866e
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <app.h>
+#include <app_extension.h>
+#include <app_internal.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "application_unittests/mock/app_core_mock.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+
+class Mocks : public ::testing::NiceMock<AppCoreMock> {};
+
+}  // namespace
+
+class AppDeviceTest : public TestFixture {
+ public:
+  AppDeviceTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~AppDeviceTest() {}
+
+  void SetUp() override {}
+  void TearDown() override {}
+};
+
+TEST_F(AppDeviceTest, app_get_device_orientation_P) {
+  EXPECT_CALL(GetMock<AppCoreMock>(), GetRotationState())
+      .WillOnce(Invoke([&]() -> tizen_cpp::AppCoreBase::RotationState {
+        return tizen_cpp::AppCoreBase::ROTATION_PORTRAIT_NORMAL;
+      }));
+
+  app_device_orientation_e orientation = app_get_device_orientation();
+  ASSERT_EQ(orientation, APP_DEVICE_ORIENTATION_0);
+
+  EXPECT_CALL(GetMock<AppCoreMock>(), GetRotationState())
+      .WillOnce(Invoke([&]() -> tizen_cpp::AppCoreBase::RotationState {
+        return tizen_cpp::AppCoreBase::ROTATION_PORTRAIT_REVERSE;
+      }));
+
+  orientation = app_get_device_orientation();
+  ASSERT_EQ(orientation, APP_DEVICE_ORIENTATION_180);
+
+  EXPECT_CALL(GetMock<AppCoreMock>(), GetRotationState())
+      .WillOnce(Invoke([&]() -> tizen_cpp::AppCoreBase::RotationState {
+        return tizen_cpp::AppCoreBase::ROTATION_LANDSCAPE_NORMAL;
+      }));
+
+  orientation = app_get_device_orientation();
+  ASSERT_EQ(orientation, APP_DEVICE_ORIENTATION_270);
+
+  EXPECT_CALL(GetMock<AppCoreMock>(), GetRotationState())
+      .WillOnce(Invoke([&]() -> tizen_cpp::AppCoreBase::RotationState {
+        return tizen_cpp::AppCoreBase::ROTATION_LANDSCAPE_REVERSE;
+      }));
+
+  orientation = app_get_device_orientation();
+  ASSERT_EQ(orientation, APP_DEVICE_ORIENTATION_90);
+}
diff --git a/tests/application_unittests/app_main_legacy_test.cc b/tests/application_unittests/app_main_legacy_test.cc
new file mode 100644 (file)
index 0000000..ea22480
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <app.h>
+#include <app_extension.h>
+#include <app_internal.h>
+#include <glib.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "application_unittests/mock/app_core_efl_mock.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+
+GMainLoop* loop_;
+
+void FakeRun(int argc, char** argv) {}
+
+void FakeAddEvent(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event) {}
+
+bool FakeRemoveEvent(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event) {
+  return true;
+}
+
+void FakeExit() {}
+
+int FakeGetWindowPosition(int* x, int* y, int* w, int* h) {
+  *x = 1920;
+  *y = 1024;
+  *w = 1920;
+  *h = 1024;
+  return 0;
+}
+
+void FakeOnLoopInit(int argc, char** argv) {
+  loop_ = g_main_loop_new(nullptr, FALSE);
+}
+
+void FakeOnLoopFinish() {
+  g_main_loop_unref(loop_);
+  loop_ = nullptr;
+}
+
+void FakeOnLoopRun() {
+  g_main_loop_run(loop_);
+}
+
+void FakeOnLoopExit() {
+  g_main_loop_quit(loop_);
+}
+
+class Mocks : public ::testing::NiceMock<AppCoreEflMock> {};
+
+bool AppCreateCb(void* user_data) { return true; }
+
+void AppPauseCb(void* user_data) {}
+
+void AppResumeCb(void* user_data) {}
+
+void AppTerminateCb(void* user_data) {}
+
+void AppControlCb(app_control_h app_control, void* user_data) {}
+
+void AppLowMemoryCb(void* user_data) {}
+
+void AppLowBatteryCb(void* user_data) {}
+
+void AppDeviceOrientationCb(app_device_orientation_e orientation,
+                            void* user_data) {}
+
+void AppLanguageChangedCb(void* user_data) {}
+
+void AppRegionFormatChangedCb(void* user_data) {}
+
+}  // namespace
+
+class AppMainLegacyTest : public TestFixture {
+ public:
+  AppMainLegacyTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~AppMainLegacyTest() {}
+
+  void SetUp() override {
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), Run(_, _))
+        .WillRepeatedly(Invoke(FakeRun));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), Exit())
+        .WillRepeatedly(Invoke(FakeExit));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), AddEvent(_))
+        .WillRepeatedly(Invoke(FakeAddEvent));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), RemoveEvent(_))
+        .WillRepeatedly(Invoke(FakeRemoveEvent));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), GetWindowPosition(_, _, _, _))
+        .WillRepeatedly(Invoke(FakeGetWindowPosition));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopInit(_, _))
+        .WillRepeatedly(Invoke(FakeOnLoopInit));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopFinish())
+        .WillRepeatedly(Invoke(FakeOnLoopFinish));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopRun())
+        .WillRepeatedly(Invoke(FakeOnLoopRun));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopExit())
+        .WillRepeatedly(Invoke(FakeOnLoopExit));
+  }
+
+  void TearDown() override {}
+};
+
+TEST_F(AppMainLegacyTest, app_main_and_app_exit_P) {
+  app_event_callback_s callback;
+  callback.create = AppCreateCb;
+  callback.terminate = AppTerminateCb;
+  callback.pause = AppPauseCb;
+  callback.resume = AppResumeCb;
+  callback.app_control = AppControlCb;
+  callback.low_memory = AppLowMemoryCb;
+  callback.low_battery = AppLowBatteryCb;
+  callback.device_orientation = AppDeviceOrientationCb;
+  callback.language_changed = AppLanguageChangedCb;
+  callback.region_format_changed = AppRegionFormatChangedCb;
+
+  int argc = 1;
+  char* args = const_cast<char*>("AppMainLegacyTest");
+  char** argv = &args;
+
+  g_timeout_add(100, [](gpointer user_data) {
+        app_exit();
+        return G_SOURCE_REMOVE;
+      }, this);
+
+  int ret = app_main(argc, argv, &callback, this);
+  EXPECT_EQ(ret, APP_ERROR_NONE);
+}
+
+TEST_F(AppMainLegacyTest, app_main_N) {
+  int ret = app_main(0, nullptr, nullptr, nullptr);
+  EXPECT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(AppMainLegacyTest, app_efl_main_and_app_efl_exit_P) {
+  app_event_callback_s callback;
+  callback.create = AppCreateCb;
+  callback.terminate = AppTerminateCb;
+  callback.pause = AppPauseCb;
+  callback.resume = AppResumeCb;
+  callback.app_control = AppControlCb;
+  callback.low_memory = AppLowMemoryCb;
+  callback.low_battery = AppLowBatteryCb;
+  callback.device_orientation = AppDeviceOrientationCb;
+  callback.language_changed = AppLanguageChangedCb;
+  callback.region_format_changed = AppRegionFormatChangedCb;
+
+  int argc = 1;
+  char* args = const_cast<char*>("AppMainLegacyTest");
+  char** argv = &args;
+
+  g_timeout_add(100, [](gpointer user_data) {
+        app_efl_exit();
+        return G_SOURCE_REMOVE;
+      }, this);
+
+  int ret = app_efl_main(&argc, &argv, &callback, this);
+  EXPECT_EQ(ret, APP_ERROR_NONE);
+}
+
+TEST_F(AppMainLegacyTest, app_efl_main_N) {
+  int ret = app_efl_main(nullptr, nullptr, nullptr, nullptr);
+  EXPECT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+}
diff --git a/tests/application_unittests/app_main_test.cc b/tests/application_unittests/app_main_test.cc
new file mode 100644 (file)
index 0000000..f4efc8e
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <app.h>
+#include <app_extension.h>
+#include <app_internal.h>
+#include <glib.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "application_unittests/mock/app_core_efl_mock.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+
+GMainLoop* loop_;
+
+void FakeRun(int argc, char** argv) {}
+
+void FakeAddEvent(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event) {}
+
+bool FakeRemoveEvent(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event) {
+  return true;
+}
+
+void FakeExit() {}
+
+int FakeGetWindowPosition(int* x, int* y, int* w, int* h) {
+  *x = 1920;
+  *y = 1024;
+  *w = 1920;
+  *h = 1024;
+  return 0;
+}
+
+void FakeOnLoopInit(int argc, char** argv) {
+  loop_ = g_main_loop_new(nullptr, FALSE);
+}
+
+void FakeOnLoopFinish() {
+  g_main_loop_unref(loop_);
+  loop_ = nullptr;
+}
+
+void FakeOnLoopRun() {
+  g_main_loop_run(loop_);
+}
+
+void FakeOnLoopExit() {
+  g_main_loop_quit(loop_);
+}
+
+class Mocks : public ::testing::NiceMock<AppCoreEflMock> {};
+
+bool AppCreateCb(void* user_data) { return true; }
+
+void AppPauseCb(void* user_data) {}
+
+void AppResumeCb(void* user_data) {}
+
+void AppTerminateCb(void* user_data) {}
+
+void AppControlCb(app_control_h app_control, void* user_data) {}
+
+void AppEventCb(app_event_info_h event_info, void* user_data) {}
+
+}  // namespace
+
+class AppMainTest : public TestFixture {
+ public:
+  AppMainTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~AppMainTest() {}
+
+  void SetUp() override {
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), Run(_, _))
+        .WillRepeatedly(Invoke(FakeRun));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), Exit())
+        .WillRepeatedly(Invoke(FakeExit));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), AddEvent(_))
+        .WillRepeatedly(Invoke(FakeAddEvent));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), RemoveEvent(_))
+        .WillRepeatedly(Invoke(FakeRemoveEvent));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), GetWindowPosition(_, _, _, _))
+        .WillRepeatedly(Invoke(FakeGetWindowPosition));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopInit(_, _))
+        .WillRepeatedly(Invoke(FakeOnLoopInit));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopFinish())
+        .WillRepeatedly(Invoke(FakeOnLoopFinish));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopRun())
+        .WillRepeatedly(Invoke(FakeOnLoopRun));
+    EXPECT_CALL(GetMock<AppCoreEflMock>(), OnLoopExit())
+        .WillRepeatedly(Invoke(FakeOnLoopExit));
+  }
+
+  void TearDown() override {}
+};
+
+TEST_F(AppMainTest, ui_app_main_and_ui_app_exit_P) {
+  ui_app_lifecycle_callback_s callback = {.create = AppCreateCb,
+                                          .terminate = AppTerminateCb,
+                                          .pause = AppPauseCb,
+                                          .resume = AppResumeCb,
+                                          .app_control = AppControlCb};
+  int argc = 1;
+  char* args = const_cast<char*>("AppMainTest");
+  char** argv = &args;
+
+  g_timeout_add(100, [](gpointer user_data) {
+        ui_app_exit();
+        return G_SOURCE_REMOVE;
+      }, this);
+
+  int ret = ui_app_main(argc, argv, &callback, this);
+  EXPECT_EQ(ret, APP_ERROR_NONE);
+}
+
+TEST_F(AppMainTest, ui_app_main_N) {
+  int ret = ui_app_main(0, nullptr, nullptr, nullptr);
+  EXPECT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(AppMainTest, ui_app_add_event_handler_P) {
+  app_event_handler_h event_handlers[7] = { nullptr, };
+  for (int i = 0; i < 7; ++i) {
+    app_event_type_e event_type = static_cast<app_event_type_e>(i);
+    int ret = ui_app_add_event_handler(&event_handlers[i], event_type,
+                                       AppEventCb, this);
+    ASSERT_EQ(ret, APP_ERROR_NONE);
+    ASSERT_NE(event_handlers[i], nullptr);
+  }
+
+  for (int i = 0; i < 7; ++i)
+    ui_app_remove_event_handler(event_handlers[i]);
+}
+
+TEST_F(AppMainTest, ui_app_add_event_handler_N) {
+  for (int i = 0; i < 7; ++i) {
+    app_event_type_e event_type = static_cast<app_event_type_e>(i);
+    int ret = ui_app_add_event_handler(nullptr, event_type, nullptr, this);
+    ASSERT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+  }
+}
+
+TEST_F(AppMainTest, ui_app_remove_event_handler_P) {
+  app_event_handler_h event_handlers[7] = { nullptr, };
+  for (int i = 0; i < 7; ++i) {
+    app_event_type_e event_type = static_cast<app_event_type_e>(i);
+    ui_app_add_event_handler(&event_handlers[i], event_type, AppEventCb, this);
+    ASSERT_NE(event_handlers[i], nullptr);
+  }
+
+  for (int i = 0; i < 7; ++i) {
+    int ret = ui_app_remove_event_handler(event_handlers[i]);
+    ASSERT_EQ(ret, APP_ERROR_NONE);
+  }
+}
+
+TEST_F(AppMainTest, ui_app_remove_event_handler_N) {
+  int ret = ui_app_remove_event_handler(nullptr);
+  ASSERT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+}
+
+TEST_F(AppMainTest, ui_app_get_window_position_P) {
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  int ret = ui_app_get_window_position(&x, &y, &w, &h);
+  ASSERT_EQ(ret, APP_ERROR_NONE);
+  ASSERT_NE(x, 0);
+  ASSERT_NE(y, 0);
+  ASSERT_NE(w, 0);
+  ASSERT_NE(h, 0);
+}
+
+TEST_F(AppMainTest, ui_app_get_window_position_N) {
+  int ret = ui_app_get_window_position(nullptr, nullptr, nullptr, nullptr);
+  ASSERT_EQ(ret, APP_ERROR_INVALID_PARAMETER);
+}
diff --git a/tests/application_unittests/app_resource_test.cc b/tests/application_unittests/app_resource_test.cc
new file mode 100644 (file)
index 0000000..e3e2d61
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <app.h>
+#include <app_extension.h>
+#include <app_internal.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "application_unittests/mock/elementary_mock.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+using ::testing::_;
+using ::testing::DoAll;
+using ::testing::Return;
+using ::testing::SetArgPointee;
+using ::testing::Invoke;
+
+namespace {
+
+int dummy_;
+Evas_Object* win_obj_ = reinterpret_cast<Evas_Object*>(&dummy_);
+Evas_Object* bg_obj_ = reinterpret_cast<Evas_Object*>(&dummy_);
+Evas_Object* conformant_obj_ = reinterpret_cast<Evas_Object*>(&dummy_);
+
+Evas_Object* fake_elm_win_precreated_object_get() {
+  return win_obj_;
+}
+
+void fake_elm_win_precreated_object_set(Evas_Object* obj) {
+  win_obj_ = obj;
+}
+
+Evas_Object* fake_elm_bg_precreated_object_get() {
+  return bg_obj_;
+}
+
+void fake_elm_bg_precreated_object_set(Evas_Object* obj) {
+  bg_obj_ = obj;
+}
+
+Evas_Object* fake_elm_conformant_precreated_object_get() {
+  return conformant_obj_;
+}
+
+void fake_elm_conformant_precreated_object_set(Evas_Object* obj) {
+  conformant_obj_ = obj;
+}
+
+Evas* fake_evas_object_evas_get(const Eo* obj) {
+  return reinterpret_cast<Evas*>(const_cast<Eo*>(obj));
+}
+
+Ecore_Evas* fake_ecore_evas_ecore_evas_get(const Evas* e) {
+  return reinterpret_cast<Ecore_Evas*>(const_cast<Evas*>(e));
+}
+
+void fake_ecore_evas_name_class_set(Ecore_Evas* ee, const char* n,
+                                    const char* c) {}
+
+class Mocks : public ::testing::NiceMock<ElementaryMock> {};
+
+}  // namespace
+
+class AppResourceTest : public TestFixture {
+ public:
+  AppResourceTest() : TestFixture(std::make_unique<Mocks>()) {}
+  virtual ~AppResourceTest() {}
+
+  void SetUp() override {
+    EXPECT_CALL(GetMock<ElementaryMock>(), elm_win_precreated_object_get())
+        .WillRepeatedly(Invoke(fake_elm_win_precreated_object_get));
+    EXPECT_CALL(GetMock<ElementaryMock>(), elm_win_precreated_object_set(_))
+        .WillRepeatedly(Invoke(fake_elm_win_precreated_object_set));
+    EXPECT_CALL(GetMock<ElementaryMock>(), elm_bg_precreated_object_get())
+        .WillRepeatedly(Invoke(fake_elm_bg_precreated_object_get));
+    EXPECT_CALL(GetMock<ElementaryMock>(), elm_bg_precreated_object_set(_))
+        .WillRepeatedly(Invoke(fake_elm_bg_precreated_object_set));
+    EXPECT_CALL(GetMock<ElementaryMock>(),
+                elm_conformant_precreated_object_get())
+        .WillRepeatedly(Invoke(fake_elm_conformant_precreated_object_get));
+    EXPECT_CALL(GetMock<ElementaryMock>(),
+                elm_conformant_precreated_object_set(_))
+        .WillRepeatedly(Invoke(fake_elm_conformant_precreated_object_set));
+    EXPECT_CALL(GetMock<ElementaryMock>(), evas_object_evas_get(_))
+        .WillRepeatedly(Invoke(fake_evas_object_evas_get));
+    EXPECT_CALL(GetMock<ElementaryMock>(), ecore_evas_ecore_evas_get(_))
+        .WillRepeatedly(Invoke(fake_ecore_evas_ecore_evas_get));
+    EXPECT_CALL(GetMock<ElementaryMock>(), ecore_evas_name_class_set(_, _, _))
+        .WillRepeatedly(Invoke(fake_ecore_evas_name_class_set));
+  }
+
+  void TearDown() override {}
+};
+
+TEST_F(AppResourceTest, app_get_preinitialized_window_P) {
+  void* win = app_get_preinitialized_window("test");
+  ASSERT_NE(win, nullptr);
+}
+
+TEST_F(AppResourceTest, app_get_preinitialized_background_P) {
+  void* win = app_get_preinitialized_background();
+  ASSERT_NE(win, nullptr);
+}
+
+TEST_F(AppResourceTest, app_get_preinitialized_conformant_P) {
+  void* win = app_get_preinitialized_conformant();
+  ASSERT_NE(win, nullptr);
+}
diff --git a/tests/application_unittests/main.cc b/tests/application_unittests/main.cc
new file mode 100644 (file)
index 0000000..f1c49aa
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+int main(int argc, char** argv) {
+  try {
+    testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+  } catch (std::exception const &e) {
+    std::cout << "test_main caught exception: " << e.what() << std::endl;
+    return -1;
+  }
+}
diff --git a/tests/application_unittests/mock/app_core_efl_mock.cc b/tests/application_unittests/mock/app_core_efl_mock.cc
new file mode 100644 (file)
index 0000000..43499e6
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "application_unittests/mock/app_core_efl_mock.hh"
+
+#include <glib.h>
+
+#include <memory>
+#include <utility>
+
+#include "application_unittests/mock/mock_hook.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+namespace tizen_cpp {
+
+void AppCoreUiBase::Run(int argc, char** argv) {
+  TestFixture::GetMock<AppCoreEflMock>().Run(argc, argv);
+  TestFixture::GetMock<AppCoreEflMock>().OnLoopInit(argc, argv);
+  OnCreate();
+
+  g_idle_add([](gpointer user_data) {
+        auto *handle = static_cast<AppCoreUiBase*>(user_data);
+        tizen_base::Bundle b;
+        handle->OnControl(b);
+        return G_SOURCE_REMOVE;
+      }, this);
+
+  g_idle_add([](gpointer user_data) {
+        auto *handle = static_cast<AppCoreUiBase*>(user_data);
+        handle->OnResume();
+        return G_SOURCE_REMOVE;
+      }, this);
+
+  TestFixture::GetMock<AppCoreEflMock>().OnLoopRun();
+  OnPause();
+  OnTerminate();
+  TestFixture::GetMock<AppCoreEflMock>().OnLoopFinish();
+}
+
+void AppCoreUiBase::Exit() {
+  TestFixture::GetMock<AppCoreEflMock>().Exit();
+  TestFixture::GetMock<AppCoreEflMock>().OnLoopExit();
+}
+
+void AppCoreBase::AddEvent(std::shared_ptr<AppCoreBase::EventBase> event) {
+  TestFixture::GetMock<AppCoreEflMock>().AddEvent(std::move(event));
+}
+
+bool AppCoreBase::RemoveEvent(
+    std::shared_ptr<AppCoreBase::EventBase> event) {
+  return TestFixture::GetMock<AppCoreEflMock>().RemoveEvent(std::move(event));
+}
+
+int AppCoreUiBase::GetWindowPosition(int* x, int* y, int* w, int* h) {
+  return TestFixture::GetMock<AppCoreEflMock>().GetWindowPosition(x, y, w, h);
+}
+
+}  // namespace tizen_cpp
diff --git a/tests/application_unittests/mock/app_core_efl_mock.hh b/tests/application_unittests/mock/app_core_efl_mock.hh
new file mode 100644 (file)
index 0000000..ce47080
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_APP_CORE_EFL_MOCK_HH_
+#define APPLICATION_UNITTESTS_MOCK_APP_CORE_EFL_MOCK_HH_
+
+#include <gmock/gmock.h>
+#include <app_core_efl_base.hh>
+
+#include "application_unittests/mock/module_mock.hh"
+
+class AppCoreEflMock : public virtual ModuleMock {
+ public:
+  virtual ~AppCoreEflMock() {}
+
+  MOCK_METHOD2(Run, void(int, char**));
+  MOCK_METHOD1(AddEvent,
+               void(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event));
+  MOCK_METHOD1(RemoveEvent,
+               bool(std::shared_ptr<tizen_cpp::AppCoreBase::EventBase> event));
+  MOCK_METHOD0(Exit, void());
+  MOCK_METHOD4(GetWindowPosition, int(int*, int*, int*, int*));
+  MOCK_METHOD2(OnLoopInit, void(int, char**));
+  MOCK_METHOD0(OnLoopFinish, void());
+  MOCK_METHOD0(OnLoopRun, void());
+  MOCK_METHOD0(OnLoopExit, void());
+};
+
+#endif  // APPLICATION_UNITTESTS_MOCK_APP_CORE_EFL_MOCK_HH_
diff --git a/tests/application_unittests/mock/app_core_mock.cc b/tests/application_unittests/mock/app_core_mock.cc
new file mode 100644 (file)
index 0000000..c99e96e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "application_unittests/mock/app_core_mock.hh"
+#include "application_unittests/mock/mock_hook.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+namespace tizen_cpp {
+
+AppCoreBase::RotationState AppCoreBase::GetRotationState() {
+  return TestFixture::GetMock<AppCoreMock>().GetRotationState();
+}
+
+}  // namespace tizen_cpp
diff --git a/tests/application_unittests/mock/app_core_mock.hh b/tests/application_unittests/mock/app_core_mock.hh
new file mode 100644 (file)
index 0000000..418a5fe
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_APP_CORE_MOCK_HH_
+#define APPLICATION_UNITTESTS_MOCK_APP_CORE_MOCK_HH_
+
+#include <gmock/gmock.h>
+#include <app_core_base.hh>
+
+#include "application_unittests/mock/module_mock.hh"
+
+class AppCoreMock : public virtual ModuleMock {
+ public:
+  virtual ~AppCoreMock() {}
+
+  MOCK_METHOD0(GetRotationState, tizen_cpp::AppCoreBase::RotationState());
+};
+
+#endif  // APPLICATION_UNITTESTS_MOCK_APP_CORE_MOCK_HH_
diff --git a/tests/application_unittests/mock/elementary_mock.cc b/tests/application_unittests/mock/elementary_mock.cc
new file mode 100644 (file)
index 0000000..6b2d205
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "application_unittests/mock/elementary_mock.hh"
+#include "application_unittests/mock/mock_hook.hh"
+#include "application_unittests/mock/test_fixture.hh"
+
+extern "C" Evas_Object* elm_win_precreated_object_get() {
+  return MOCK_HOOK_P0(ElementaryMock, elm_win_precreated_object_get);
+}
+
+extern "C" void elm_win_precreated_object_set(Evas_Object* obj) {
+  return MOCK_HOOK_P1(ElementaryMock, elm_win_precreated_object_set, obj);
+}
+
+extern "C" Evas_Object* elm_bg_precreated_object_get() {
+  return MOCK_HOOK_P0(ElementaryMock, elm_bg_precreated_object_get);
+}
+
+extern "C" void elm_bg_precreated_object_set(Evas_Object* obj) {
+  return MOCK_HOOK_P1(ElementaryMock, elm_bg_precreated_object_set, obj);
+}
+
+extern "C" Evas_Object* elm_conformant_precreated_object_get() {
+  return MOCK_HOOK_P0(ElementaryMock, elm_conformant_precreated_object_get);
+}
+
+extern "C" void elm_conformant_precreated_object_set(Evas_Object* obj) {
+  return MOCK_HOOK_P1(ElementaryMock, elm_conformant_precreated_object_set,
+                      obj);
+}
+
+extern "C" Evas* evas_object_evas_get(const Eo* obj) {
+  return MOCK_HOOK_P1(ElementaryMock, evas_object_evas_get, obj);
+}
+
+extern "C" Ecore_Evas* ecore_evas_ecore_evas_get(const Evas* e) {
+  return MOCK_HOOK_P1(ElementaryMock, ecore_evas_ecore_evas_get, e);
+}
+
+extern "C" void ecore_evas_name_class_set(Ecore_Evas* ee, const char* n,
+                                          const char* c) {
+  return MOCK_HOOK_P3(ElementaryMock, ecore_evas_name_class_set, ee, n, c);
+}
\ No newline at end of file
diff --git a/tests/application_unittests/mock/elementary_mock.hh b/tests/application_unittests/mock/elementary_mock.hh
new file mode 100644 (file)
index 0000000..2e5dfa9
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_ELEMENTARY_MOCK_HH_
+#define APPLICATION_UNITTESTS_MOCK_ELEMENTARY_MOCK_HH_
+
+#include <Elementary.h>
+
+#include <gmock/gmock.h>
+
+#include "application_unittests/mock/module_mock.hh"
+
+class ElementaryMock : public virtual ModuleMock {
+ public:
+  virtual ~ElementaryMock() {}
+
+  MOCK_METHOD0(elm_win_precreated_object_get, Evas_Object*());
+  MOCK_METHOD1(elm_win_precreated_object_set, void(Evas_Object*));
+  MOCK_METHOD0(elm_bg_precreated_object_get, Evas_Object*());
+  MOCK_METHOD1(elm_bg_precreated_object_set, void(Evas_Object*));
+  MOCK_METHOD0(elm_conformant_precreated_object_get, Evas_Object*());
+  MOCK_METHOD1(elm_conformant_precreated_object_set, void(Evas_Object*));
+
+  MOCK_METHOD1(evas_object_evas_get, Evas*(const Eo*));
+  MOCK_METHOD1(ecore_evas_ecore_evas_get, Ecore_Evas*(const Evas*));
+  MOCK_METHOD3(ecore_evas_name_class_set,
+               void(Ecore_Evas*, const char*, const char*));
+};
+
+#endif  // APPLICATION_UNITTESTS_MOCK_ELEMENTARY_MOCK_HH_
diff --git a/tests/application_unittests/mock/mock_hook.hh b/tests/application_unittests/mock/mock_hook.hh
new file mode 100644 (file)
index 0000000..b70f48e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_MOCK_HOOK_HH_
+#define APPLICATION_UNITTESTS_MOCK_MOCK_HOOK_HH_
+
+#define MOCK_HOOK_P0(MOCK_CLASS, f)                                            \
+    TestFixture::GetMock<MOCK_CLASS>().f()
+#define MOCK_HOOK_P1(MOCK_CLASS, f, p1)                                        \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1)
+#define MOCK_HOOK_P2(MOCK_CLASS, f, p1, p2)                                    \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2)
+#define MOCK_HOOK_P3(MOCK_CLASS, f, p1, p2, p3)                                \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3)
+#define MOCK_HOOK_P4(MOCK_CLASS, f, p1, p2, p3, p4)                            \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4)
+#define MOCK_HOOK_P5(MOCK_CLASS, f, p1, p2, p3, p4, p5)                        \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5)
+#define MOCK_HOOK_P6(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6)                    \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6)
+#define MOCK_HOOK_P7(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7)                \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7)
+#define MOCK_HOOK_P8(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8)            \
+    TestFixture::GetMock<MOCK_CLASS>().f(p1, p2, p3, p4, p5, p6, p7, p8)
+#define MOCK_HOOK_P10(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)  \
+    TestFixture::GetMock<MOCK_CLASS>().f(                                      \
+        p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+
+#endif  // APPLICATION_UNITTESTS_MOCK_MOCK_HOOK_HH_
diff --git a/tests/application_unittests/mock/module_mock.hh b/tests/application_unittests/mock/module_mock.hh
new file mode 100644 (file)
index 0000000..ca90fb9
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_MODULE_MOCK_HH_
+#define APPLICATION_UNITTESTS_MOCK_MODULE_MOCK_HH_
+
+class ModuleMock {
+ public:
+  virtual ~ModuleMock() {}
+};
+
+#endif  // APPLICATION_UNITTESTS_MOCK_MODULE_MOCK_HH_
diff --git a/tests/application_unittests/mock/test_fixture.cc b/tests/application_unittests/mock/test_fixture.cc
new file mode 100644 (file)
index 0000000..9deebb9
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "application_unittests/mock/test_fixture.hh"
+
+#include <memory>
+
+std::unique_ptr<ModuleMock> TestFixture::mock_;
diff --git a/tests/application_unittests/mock/test_fixture.hh b/tests/application_unittests/mock/test_fixture.hh
new file mode 100644 (file)
index 0000000..0b1a1bc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPLICATION_UNITTESTS_MOCK_TEST_FIXTURE_HH_
+#define APPLICATION_UNITTESTS_MOCK_TEST_FIXTURE_HH_
+
+#include <gtest/gtest.h>
+
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+
+#include "application_unittests/mock/module_mock.hh"
+
+class TestFixture : public ::testing::Test {
+ public:
+  explicit TestFixture(std::unique_ptr<ModuleMock>&& mock) {
+    mock_ = std::move(mock);
+  }
+  virtual ~TestFixture() {
+    mock_.reset();
+  }
+
+  virtual void SetUp() {}
+  virtual void TearDown() {}
+
+  template <typename T>
+  static T& GetMock() {
+    auto ptr = dynamic_cast<T*>(mock_.get());
+    if (!ptr)
+      throw std::invalid_argument("The test does not provide mock of \"" +
+          std::string(typeid(T).name()) + "\"");
+    return *ptr;
+  }
+
+  static std::unique_ptr<ModuleMock> mock_;
+};
+
+#endif  // APPLICATION_UNITTESTS_MOCK_TEST_FIXTURE_HH_