From 1c52849ad8e31c070e8d54e473374077e5d2e23f Mon Sep 17 00:00:00 2001 From: Daehyeon Jung Date: Wed, 16 Sep 2020 16:42:28 +0900 Subject: [PATCH] Add unit tests Change-Id: I286ac76222b2d0532c57a4b17b641f8e10ccb161 Signed-off-by: Daehyeon Jung --- CMakeLists.txt | 2 + packaging/capi-appfw-preference.spec | 17 ++ unittests/CMakeLists.txt | 20 ++ unittests/mock/common_mock.cc | 23 +++ unittests/mock/common_mock.h | 30 +++ unittests/mock/mock_hook.h | 42 ++++ unittests/mock/module_mock.h | 25 +++ unittests/mock/test_fixture.cc | 21 ++ unittests/mock/test_fixture.h | 53 +++++ unittests/preference_test.cc | 296 +++++++++++++++++++++++++++ 10 files changed, 529 insertions(+) create mode 100644 unittests/CMakeLists.txt create mode 100644 unittests/mock/common_mock.cc create mode 100644 unittests/mock/common_mock.h create mode 100644 unittests/mock/mock_hook.h create mode 100644 unittests/mock/module_mock.h create mode 100644 unittests/mock/test_fixture.cc create mode 100644 unittests/mock/test_fixture.h create mode 100644 unittests/preference_test.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index dd27bc3..919c4a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,3 +10,5 @@ INSTALL( PATTERN "*_private.h" EXCLUDE PATTERN "${INC_DIR}/*.h" ) + +ADD_SUBDIRECTORY(unittests) \ No newline at end of file diff --git a/packaging/capi-appfw-preference.spec b/packaging/capi-appfw-preference.spec index 4018c41..800a9ad 100644 --- a/packaging/capi-appfw-preference.spec +++ b/packaging/capi-appfw-preference.spec @@ -10,9 +10,14 @@ BuildRequires: cmake BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gmock) BuildRequires: pkgconfig(capi-appfw-app-common) BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(libtzplatform-config) +%if 0%{?gcov:1} +BuildRequires: lcov +BuildRequires: zip +%endif %description An Application preference library in Tizen C API @@ -64,6 +69,17 @@ mkdir -p %{buildroot}%{_datadir}/gcov/obj install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj %endif +%check +cd unittests +LD_LIBRARY_PATH=../src ctest -V +%if 0%{?gcov:1} +cd ../src +lcov -c --ignore-errors graph --no-external -d . -o preference.info +genhtml preference.info -o preference.out +zip -r preference.zip preference.out +install -m 0644 preference.zip %{buildroot}%{_datadir}/gcov/ +%endif + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig @@ -85,4 +101,5 @@ install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj %if 0%{?gcov:1} %files gcov %{_datadir}/gcov/obj/* +%{_datadir}/gcov/preference.zip %endif diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt new file mode 100644 index 0000000..93444f8 --- /dev/null +++ b/unittests/CMakeLists.txt @@ -0,0 +1,20 @@ +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} TEST_SRCS) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock MOCK_SRCS) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/) + +ENABLE_TESTING() + +SET(TARGET_TEST "preference-test") +ADD_EXECUTABLE(${TARGET_TEST} ${TEST_SRCS} ${MOCK_SRCS}) +ADD_TEST(${TARGET_TEST} ${TARGET_TEST}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(test REQUIRED dlog glib-2.0 capi-appfw-app-common) +FOREACH(flag ${test_CFLAGS}) + SET(EXTRA_CXXFLAGS_test "${EXTRA_CXXFLAGS_test} ${flag}") +ENDFOREACH(flag) + +SET(${EXTRA_CXXFLAGS_test} "${EXTRA_CXXFLAGS_test} --std=c++14") +SET_TARGET_PROPERTIES(${TARGET_TEST} PROPERTIES COMPILE_FLAGS ${EXTRA_CXXFLAGS_test}) + +TARGET_LINK_LIBRARIES(${TARGET_TEST} gmock capi-appfw-preference pthread) \ No newline at end of file diff --git a/unittests/mock/common_mock.cc b/unittests/mock/common_mock.cc new file mode 100644 index 0000000..7f4a2c5 --- /dev/null +++ b/unittests/mock/common_mock.cc @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2020 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 "common_mock.h" +#include "mock_hook.h" +#include "test_fixture.h" + +extern "C" char* app_get_data_path() { + return MOCK_HOOK_P0(CommonMock, app_get_data_path); +} diff --git a/unittests/mock/common_mock.h b/unittests/mock/common_mock.h new file mode 100644 index 0000000..408a7da --- /dev/null +++ b/unittests/mock/common_mock.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020 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 MOCK_COMMON_MOCK_H_ +#define MOCK_COMMON_MOCK_H_ +#include + +#include "module_mock.h" + +class CommonMock : public virtual ModuleMock { + public: + virtual ~CommonMock() {} + + MOCK_METHOD0(app_get_data_path, char*()); +}; + +#endif // MOCK_COMMON_HOOK_H_ diff --git a/unittests/mock/mock_hook.h b/unittests/mock/mock_hook.h new file mode 100644 index 0000000..79831d7 --- /dev/null +++ b/unittests/mock/mock_hook.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2020 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 MOCK_MOCK_HOOK_H_ +#define MOCK_MOCK_HOOK_H_ + +#define MOCK_HOOK_P0(MOCK_CLASS, f) \ + TestFixture::GetMock().f() +#define MOCK_HOOK_P1(MOCK_CLASS, f, p1) \ + TestFixture::GetMock().f(p1) +#define MOCK_HOOK_P2(MOCK_CLASS, f, p1, p2) \ + TestFixture::GetMock().f(p1, p2) +#define MOCK_HOOK_P3(MOCK_CLASS, f, p1, p2, p3) \ + TestFixture::GetMock().f(p1, p2, p3) +#define MOCK_HOOK_P4(MOCK_CLASS, f, p1, p2, p3, p4) \ + TestFixture::GetMock().f(p1, p2, p3, p4) +#define MOCK_HOOK_P5(MOCK_CLASS, f, p1, p2, p3, p4, p5) \ + TestFixture::GetMock().f(p1, p2, p3, p4, p5) +#define MOCK_HOOK_P6(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6) \ + TestFixture::GetMock().f(p1, p2, p3, p4, p5, p6) +#define MOCK_HOOK_P7(MOCK_CLASS, f, p1, p2, p3, p4, p5, p6, p7) \ + TestFixture::GetMock().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().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().f( \ + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) + +#endif // MOCK_MOCK_HOOK_H_ diff --git a/unittests/mock/module_mock.h b/unittests/mock/module_mock.h new file mode 100644 index 0000000..0934014 --- /dev/null +++ b/unittests/mock/module_mock.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2020 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 MOCK_MODULE_MOCK_H_ +#define MOCK_MODULE_MOCK_H_ + +class ModuleMock { + public: + virtual ~ModuleMock() {} +}; + +#endif // MOCK_MODULE_MOCK_H_ diff --git a/unittests/mock/test_fixture.cc b/unittests/mock/test_fixture.cc new file mode 100644 index 0000000..4a77054 --- /dev/null +++ b/unittests/mock/test_fixture.cc @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 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 + +#include "test_fixture.h" + +std::unique_ptr TestFixture::mock_; diff --git a/unittests/mock/test_fixture.h b/unittests/mock/test_fixture.h new file mode 100644 index 0000000..db223f1 --- /dev/null +++ b/unittests/mock/test_fixture.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 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 MOCK_TEST_FIXTURE_H_ +#define MOCK_TEST_FIXTURE_H_ + +#include + +#include +#include +#include +#include + +#include "module_mock.h" + +class TestFixture : public ::testing::Test { + public: + explicit TestFixture(std::unique_ptr&& mock) { + mock_ = std::move(mock); + } + virtual ~TestFixture() { + mock_.reset(); + } + + virtual void SetUp() {} + virtual void TearDown() {} + + template + static T& GetMock() { + auto ptr = dynamic_cast(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 mock_; +}; + +#endif // MOCK_TEST_FIXTURE_H_ diff --git a/unittests/preference_test.cc b/unittests/preference_test.cc new file mode 100644 index 0000000..5b40e19 --- /dev/null +++ b/unittests/preference_test.cc @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2020 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 + +#include + +#include +#include +#include +#include + +#include "mock/common_mock.h" +#include "mock/test_fixture.h" + +extern "C" int __dlog_print(log_id_t log_id, int prio, const char *tag, const char *fmt, ...) { + printf("%s:", tag); + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\n"); + + return 0; +} + +namespace preference { + +class Mocks : public ::testing::NiceMock {}; + +class PreferenceTest : public TestFixture { + public: + PreferenceTest() : TestFixture(std::make_unique()) {} + virtual ~PreferenceTest() {} + + virtual void SetUp() {} + virtual void TearDown() {} +}; + +TEST_F(PreferenceTest, Basic) { + int ret; + int intval; + double doubleval; + char* strval; + bool boolval; + + ret = preference_set_int(nullptr, 0); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_set_double(nullptr, 0.1f); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_set_string(nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_set_boolean(nullptr, false); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_get_int(nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_get_double(nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_get_string(nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + ret = preference_get_boolean(nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + + EXPECT_CALL(GetMock(), app_get_data_path()) + .WillRepeatedly(testing::Invoke([&]() { + return nullptr; + })); + + ret = preference_set_int("testint", 0); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_get_int("testint", &intval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_set_double("testdouble", 0.0f); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_get_double("testdouble", &doubleval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_set_string("teststring", "test"); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_get_string("teststring", &strval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_set_boolean("testboolean", false); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + ret = preference_get_boolean("testboolean", &boolval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_IO_ERROR)); + + EXPECT_CALL(GetMock(), app_get_data_path()) + .WillRepeatedly(testing::Invoke([&]() { + return strdup("../data"); + })); + + ret = preference_set_int("testint", 1); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_int("testint", &intval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(intval, testing::Eq(1)); + ret = preference_set_double("testdouble", 0.1f); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_double("testdouble", &doubleval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(doubleval, testing::Eq(0.1f)); + ret = preference_set_string("teststring", "test"); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_string("teststring", &strval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(strval, testing::StrEq("test")); + free(strval); + ret = preference_set_boolean("testboolean", true); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_boolean("testboolean", &boolval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(boolval, testing::Eq(true)); + + // cleanup + ret = preference_remove_all(); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); +} + +TEST_F(PreferenceTest, Remove) { + EXPECT_CALL(GetMock(), app_get_data_path()) + .WillRepeatedly(testing::Invoke([&]() { + return strdup("../data"); + })); + + int ret; + bool val; + int intval; + + ret = preference_set_int("testint", 1); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_int("testint", &intval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + + ret = preference_is_existing("testint", &val); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(val, testing::Eq(true)); + ret = preference_is_existing("testint2", &val); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(val, testing::Eq(false)); + + ret = preference_remove("testint"); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_is_existing("testint", &val); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(val, testing::Eq(false)); + + ret = preference_set_int("testint", 1); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_int("testint", &intval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_int("testint2", 1); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_get_int("testint2", &intval); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_remove_all(); + ret = preference_is_existing("testint", &val); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(val, testing::Eq(false)); + ret = preference_is_existing("testint2", &val); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(val, testing::Eq(false)); +} + +TEST_F(PreferenceTest, Foreach) { + int ret; + ret = preference_set_int("1", 1); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_int("2", 2); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_int("3", 3); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_int("4", 4); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + + int test = 0; + ret = preference_foreach_item([](const char* key, void* user_data) -> bool { + int* test = reinterpret_cast(user_data); + int val; + int ret = preference_get_int(key, &val); + + if (ret != PREFERENCE_ERROR_NONE) + return false; + + if (val == (key[0] - '0')) + *test = *test + 1; + + return true; + }, reinterpret_cast(&test)); + + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(test, testing::Eq(4)); + + ret = preference_remove_all(); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); +} + +TEST_F(PreferenceTest, Type) { + int ret; + + ret = preference_set_int("int", 0); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_string("string", "string"); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_double("double", 0.0f); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + ret = preference_set_boolean("boolean", true); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + + preference_type_e type; + ret = preference_get_type("int", &type); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(type, testing::Eq(PREFERENCE_TYPE_INT)); + ret = preference_get_type("double", &type); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(type, testing::Eq(PREFERENCE_TYPE_DOUBLE)); + ret = preference_get_type("string", &type); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(type, testing::Eq(PREFERENCE_TYPE_STRING)); + ret = preference_get_type("boolean", &type); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(type, testing::Eq(PREFERENCE_TYPE_BOOLEAN)); + + ret = preference_remove_all(); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); +} + +TEST_F(PreferenceTest, Callback) { + int ret; + + ret = preference_set_int("test1", 0); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + bool called = false; + ret = preference_set_changed_cb("test1", [](const char* key, void* user_data) { + bool* called = reinterpret_cast(user_data); + *called = true; + }, reinterpret_cast(&called)); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(called, testing::Eq(false)); + + ret = preference_set_int("test1", 1); + g_main_context_iteration(g_main_context_default(), false); + + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(called, testing::Eq(true)); + + called = false; + ret = preference_unset_changed_cb("test1"); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + + ret = preference_set_int("test1", 1); + g_main_context_iteration(g_main_context_default(), false); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); + EXPECT_THAT(called, testing::Eq(false)); + + ret = preference_set_changed_cb(nullptr, nullptr, nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + + ret = preference_unset_changed_cb(nullptr); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_INVALID_PARAMETER)); + + ret = preference_remove_all(); + EXPECT_THAT(ret, testing::Eq(PREFERENCE_ERROR_NONE)); +} + +} // namespace + +int main(int argc, char* argv[]) { + int ret = 0; + try { + ::testing::InitGoogleTest(&argc, argv); + } catch(...) { + std::cout << "Exception occured" << std::endl; + return 1; + } + + try { + return RUN_ALL_TESTS(); + } catch(const ::testing::internal::GoogleTestFailureException& e) { + std::cout << "GoogleTestFailureException occured:" << e.what() << std::endl; + ret = 1; + } + + return ret; +} -- 2.34.1