소스 검색

test(core): Migrate existing tests to Google Test

This commit completes Subtask 2.2 of the development plan by migrating existing tests ( and ) to the Google Test framework.

Key changes include:
- Converted  and  to use Google Test syntax and assertion macros.
- Updated  to correctly build these new Google Test-based test files.
- Ensured previously existing test logic is retained in the new Google Test format.
Bernardo Magri 1 개월 전
부모
커밋
0e9cdacf14
4개의 변경된 파일173개의 추가작업 그리고 3개의 파일을 삭제
  1. 4 2
      documentation/PLAN.md
  2. 1 1
      tests/CMakeLists.txt
  3. 50 0
      tests/test_buffer.cpp
  4. 118 0
      tests/test_editor_core.cpp

+ 4 - 2
documentation/PLAN.md

@@ -86,8 +86,8 @@ Lumacs/
 *   **Subtask 2.1: Select and Integrate a Standard Testing Framework:** ✅ Completed
     *   **Recommendation:** Google Test. Integrated into the CMake build system.
     *   Removed the custom `test_framework.hpp`.
-*   **Subtask 2.2: Migrate Existing Tests:**
-    *   Rewrite `test_buffer.cpp` and `test_editor_core.cpp` tests using the new framework's syntax and features.
+*   **Subtask 2.2: Migrate Existing Tests:** ✅ Completed
+    *   `test_buffer.cpp` and `test_editor_core.cpp` have been converted to Google Test format.
 *   **Subtask 2.3: Expand Test Coverage:**
     *   Write unit tests for all new manager classes created in Phase 1. Focus on testing their individual functionalities in isolation.
     *   Increase test coverage for existing components, especially `LuaApi`, `CommandSystem`, and `Window`.
@@ -193,6 +193,8 @@ This phase aimed to enhance the Command System to support robust, type-safe, and
 - ✅ **EditorCore Decomposition (Registers Management)**: Extracted registers management into a dedicated `RegisterManager` class.
 - ✅ **EditorCore Decomposition (Keyboard Macro Management)**: Extracted keyboard macro management into a dedicated `MacroManager` class.
 - ✅ **EditorCore Decomposition (Rectangle Operations Management)**: Extracted rectangle operations management into a dedicated `RectangleManager` class.
+- ✅ **Testing Infrastructure (Framework Integration)**: Integrated Google Test and removed custom test framework.
+- ✅ **Testing Infrastructure (Migrate Existing Tests)**: Converted `test_buffer.cpp` and `test_editor_core.cpp` to Google Test format.
 
 ## Technical Debt/Notes
 

+ 1 - 1
tests/CMakeLists.txt

@@ -24,4 +24,4 @@ target_link_libraries(test_runner PRIVATE
 
 # Automatically discover and register tests
 include(GoogleTest)
-gtest_discover_tests(test_runner)
+gtest_discover_tests(test_runner)

+ 50 - 0
tests/test_buffer.cpp

@@ -0,0 +1,50 @@
+#include "gtest/gtest.h"
+#include "lumacs/buffer.hpp" // Assuming this path is correct based on include setup
+
+// Test fixture for Buffer
+struct BufferTest : public ::testing::Test {
+    lumacs::Buffer buffer;
+
+    void SetUp() override {
+        // Initialize buffer before each test
+        buffer = lumacs::Buffer("test-buffer");
+    }
+
+    void TearDown() override {
+        // Clean up after each test (if necessary)
+    }
+};
+
+TEST_F(BufferTest, NewBufferIsEmpty) {
+    ASSERT_EQ(buffer.line_count(), 1);
+    ASSERT_TRUE(buffer.line(0).empty());
+}
+
+TEST_F(BufferTest, InsertText) {
+    buffer.insert({0, 0}, "hello");
+    ASSERT_EQ(buffer.line(0), "hello");
+    ASSERT_EQ(buffer.line_count(), 1);
+}
+
+TEST_F(BufferTest, InsertNewline) {
+    buffer.insert({0, 0}, "hello");
+    buffer.insert_newline({0, 5});
+    ASSERT_EQ(buffer.line(0), "hello");
+    ASSERT_EQ(buffer.line(1), "");
+    ASSERT_EQ(buffer.line_count(), 2);
+}
+
+TEST_F(BufferTest, EraseText) {
+    buffer.insert({0, 0}, "world");
+    buffer.erase({0, 0}, {0, 5});
+    ASSERT_TRUE(buffer.line(0).empty());
+}
+
+TEST_F(BufferTest, IsModified) {
+    ASSERT_FALSE(buffer.is_modified());
+    buffer.insert({0, 0}, "change");
+    ASSERT_TRUE(buffer.is_modified());
+    // Saving should clear modified flag
+    // buffer.save("/tmp/test.txt"); // Requires mock filesystem or actual file write
+    // ASSERT_FALSE(buffer.is_modified());
+}

+ 118 - 0
tests/test_editor_core.cpp

@@ -0,0 +1,118 @@
+#include "gtest/gtest.h"
+#include "lumacs/editor_core.hpp"
+#include "lumacs/buffer_manager.hpp"
+#include "lumacs/window_manager.hpp"
+#include "lumacs/kill_ring_manager.hpp"
+#include "lumacs/register_manager.hpp"
+#include "lumacs/macro_manager.hpp"
+#include "lumacs/rectangle_manager.hpp"
+#include <string>
+
+// Test fixture for EditorCore, initializing core subsystems
+struct EditorCoreTest : public ::testing::Test {
+    lumacs::EditorCore core;
+
+    void SetUp() override {
+        // EditorCore's constructor already initializes most things.
+        // We might want to mock some dependencies for more isolated tests later.
+    }
+
+    void TearDown() override {
+        // Clean up
+    }
+};
+
+TEST_F(EditorCoreTest, InitialSetup) {
+    ASSERT_NE(core.buffer_manager().active_buffer(), nullptr);
+    ASSERT_NE(core.window_manager().active_window(), nullptr);
+    ASSERT_EQ(core.buffer().name(), "*scratch*");
+    ASSERT_EQ(core.cursor().line, 0);
+    ASSERT_EQ(core.cursor().column, 0);
+}
+
+TEST_F(EditorCoreTest, MoveCursorRight) {
+    core.buffer_manager().active_buffer()->insert({0,0}, "hello");
+    core.move_right();
+    ASSERT_EQ(core.cursor().column, 1);
+}
+
+TEST_F(EditorCoreTest, NewBufferCommand) {
+    core.new_buffer("test_new");
+    ASSERT_EQ(core.buffer().name(), "test_new");
+    ASSERT_EQ(core.cursor().line, 0);
+    ASSERT_EQ(core.cursor().column, 0);
+}
+
+TEST_F(EditorCoreTest, SetMessage) {
+    std::string test_message = "Hello, Lumacs!";
+    core.set_message(test_message);
+    ASSERT_EQ(core.last_message(), test_message);
+}
+
+TEST_F(EditorCoreTest, SplitWindowHorizontally) {
+    core.split_horizontally();
+    // After split, there should be 2 windows in the layout.
+    std::vector<std::shared_ptr<lumacs::Window>> windows;
+    core.window_manager().collect_windows(core.root_layout(), windows);
+    ASSERT_EQ(windows.size(), 2);
+    // The newly created window should be the active one.
+    ASSERT_EQ(core.active_window(), windows[1]); 
+}
+
+TEST_F(EditorCoreTest, KillLine) {
+    core.buffer_manager().active_buffer()->insert({0,0}, "Line 1\nLine 2");
+    core.set_cursor({0,0});
+    core.kill_line();
+    ASSERT_EQ(core.buffer().line(0), "Line 2");
+    ASSERT_FALSE(core.kill_ring_manager().empty());
+    ASSERT_EQ(core.kill_ring_manager().current(), "Line 1\n");
+}
+
+TEST_F(EditorCoreTest, Yank) {
+    core.buffer_manager().active_buffer()->insert({0,0}, "some text");
+    core.set_cursor({0,5}); // at ' '
+    core.kill_line(); // Kills " text"
+    core.yank(); // Yanks " text"
+    ASSERT_EQ(core.buffer().line(0), "some text text"); // Should be "some text" + " text"
+    ASSERT_EQ(core.cursor().column, 14); // Cursor should be at end of yanked text
+}
+
+TEST_F(EditorCoreTest, CopyToRegisterAndInsert) {
+    char reg_name = 'a';
+    std::string reg_content = "Register content";
+    core.copy_to_register(reg_name, reg_content);
+    
+    core.buffer_manager().active_buffer()->insert({0,0}, "Original ");
+    core.set_cursor({0,9});
+    core.insert_register(reg_name);
+    
+    ASSERT_EQ(core.buffer().line(0), "Original Register content");
+}
+
+TEST_F(EditorCoreTest, StartAndEndMacro) {
+    ASSERT_FALSE(core.macro_manager().is_recording_macro());
+    core.start_kbd_macro();
+    ASSERT_TRUE(core.macro_manager().is_recording_macro());
+    core.record_key_sequence("a");
+    core.end_kbd_macro_or_call();
+    ASSERT_FALSE(core.macro_manager().is_recording_macro());
+    // Executing the macro will depend on process_key being called
+    // which is hard to test without mocking keybinding_manager directly.
+    // For now, just test recording state.
+}
+
+TEST_F(EditorCoreTest, KillRectangle) {
+    core.buffer_manager().active_buffer()->insert({0,0}, "Line1\nLine2\nLine3");
+    core.buffer_manager().active_buffer()->set_mark({0,1}); // Mark 'i'
+    core.set_cursor({2,3}); // Cursor 'e' in Line3
+    core.kill_rectangle();
+    
+    // Expected buffer state after killing rectangle from (0,1) to (2,3)
+    // "Lne1"
+    // "Lne2"
+    // "Lne3"
+    ASSERT_EQ(core.buffer().line(0), "Lne1");
+    ASSERT_EQ(core.buffer().line(1), "Lne2");
+    ASSERT_EQ(core.buffer().line(2), "Lne3");
+    ASSERT_FALSE(core.rectangle_manager().rectangle_kill_ring_.empty()); // Check internal state
+}