diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..daa9d9b --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10.0) +project(test_plan_execute) +include(FetchContent) +if (MSVC) + add_compile_options(/utf-8) +endif() +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include) + +include(CTest) +enable_testing() + +add_executable(test_plan_execute test_app.cpp ../src/app.cpp) + +target_link_libraries(test_plan_execute gtest gmock gtest_main) +include(GoogleTest) +gtest_discover_tests(test_plan_execute) \ No newline at end of file diff --git a/tests/test_app.cpp b/tests/test_app.cpp new file mode 100644 index 0000000..65935da --- /dev/null +++ b/tests/test_app.cpp @@ -0,0 +1,120 @@ +#include +#include "app.hpp" +#include +#include + +namespace fs = std::filesystem; + +class TodoServiceTest : public ::testing::Test { +protected: + void SetUp() override { + test_file_ = "test_todo.json"; + if (fs::exists(test_file_)) fs::remove(test_file_); + } + + void TearDown() override { + if (fs::exists(test_file_)) fs::remove(test_file_); + } + + std::string test_file_; +}; + +TEST_F(TodoServiceTest, testLoadValidJsonFile) { + std::ofstream ofs(test_file_); + ofs << R"({ + "items": [ + {"id": 1, "title": "Task1", "description": "Desc1", "completed": false}, + {"id": 2, "title": "Task2", "description": "Desc2", "completed": true} + ], + "next_id": 3 + })"; + ofs.close(); + + TodoService service(test_file_); + auto items = service.get_all(); + ASSERT_EQ(items.size(), 2); + EXPECT_EQ(items[0].id, 1); + EXPECT_EQ(items[1].id, 2); + EXPECT_EQ(items[1].completed, true); + + auto new_item = service.create("Task3", "Desc3"); + EXPECT_EQ(new_item.id, 3); +} + +TEST_F(TodoServiceTest, testLoadEmptyFile) { + std::ofstream ofs(test_file_); + ofs.close(); + + TodoService service(test_file_); + auto items = service.get_all(); + EXPECT_TRUE(items.empty()); + + auto new_item = service.create("Task", "Desc"); + EXPECT_EQ(new_item.id, 1); +} + +TEST_F(TodoServiceTest, testLoadNonExistentFile) { + TodoService service("nonexistent.json"); + auto items = service.get_all(); + EXPECT_TRUE(items.empty()); + + auto new_item = service.create("Task", "Desc"); + EXPECT_EQ(new_item.id, 1); +} + +TEST_F(TodoServiceTest, testLoadInvalidJson) { + std::ofstream ofs(test_file_); + ofs << "invalid json content"; + ofs.close(); + + TodoService service(test_file_); + auto items = service.get_all(); + EXPECT_TRUE(items.empty()); + + auto new_item = service.create("Task", "Desc"); + EXPECT_EQ(new_item.id, 1); +} + +TEST_F(TodoServiceTest, testLoadNextIdAdjustment) { + std::ofstream ofs(test_file_); + ofs << R"({ + "items": [ + {"id": 5, "title": "Task", "description": "Desc", "completed": false} + ], + "next_id": 3 + })"; + ofs.close(); + + TodoService service(test_file_); + auto new_item = service.create("NewTask", "NewDesc"); + EXPECT_EQ(new_item.id, 6); +} + +TEST_F(TodoServiceTest, testSaveValidData) { + TodoService service(test_file_); + service.create("Task1", "Desc1"); + service.create("Task2", "Desc2"); + + std::ifstream ifs(test_file_); + std::string content((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + EXPECT_NE(content.find("\"id\": 1"), std::string::npos); + EXPECT_NE(content.find("\"id\": 2"), std::string::npos); + EXPECT_NE(content.find("\"next_id\": 3"), std::string::npos); +} + +TEST_F(TodoServiceTest, testSaveEmptyItems) { + TodoService service(test_file_); + auto item = service.create("Temp", "Desc"); + service.delete_item(item.id); + + std::ifstream ifs(test_file_); + std::string content((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + EXPECT_NE(content.find("\"items\": []"), std::string::npos); + EXPECT_NE(content.find("\"next_id\": 2"), std::string::npos); +} + +TEST_F(TodoServiceTest, testSaveInvalidPath) { + TodoService service("/invalid/path/test.json"); + EXPECT_NO_THROW(service.create("Task", "Desc")); + EXPECT_FALSE(fs::exists("/invalid/path/test.json")); +}