test_editor_core.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #include "gtest/gtest.h"
  2. #include "lumacs/editor_core.hpp"
  3. #include "lumacs/buffer_manager.hpp"
  4. #include "lumacs/window_manager.hpp"
  5. #include "lumacs/kill_ring_manager.hpp"
  6. #include "lumacs/register_manager.hpp"
  7. #include "lumacs/macro_manager.hpp"
  8. #include "lumacs/rectangle_manager.hpp"
  9. #include <string>
  10. // Test fixture for EditorCore, initializing core subsystems
  11. struct EditorCoreTest : public ::testing::Test {
  12. lumacs::EditorCore core;
  13. void SetUp() override {
  14. // EditorCore's constructor already initializes most things.
  15. // We might want to mock some dependencies for more isolated tests later.
  16. }
  17. void TearDown() override {
  18. // Clean up
  19. }
  20. };
  21. TEST_F(EditorCoreTest, InitialSetup) {
  22. ASSERT_NE(core.buffer_manager().active_buffer(), nullptr);
  23. ASSERT_NE(core.window_manager().active_window(), nullptr);
  24. ASSERT_EQ(core.buffer().name(), "*scratch*");
  25. ASSERT_EQ(core.cursor().line, 0);
  26. ASSERT_EQ(core.cursor().column, 0);
  27. }
  28. TEST_F(EditorCoreTest, MoveCursorRight) {
  29. core.buffer_manager().active_buffer()->insert({0,0}, "hello");
  30. core.move_right();
  31. ASSERT_EQ(core.cursor().column, 1);
  32. }
  33. TEST_F(EditorCoreTest, NewBufferCommand) {
  34. core.new_buffer("test_new");
  35. ASSERT_EQ(core.buffer().name(), "test_new");
  36. ASSERT_EQ(core.cursor().line, 0);
  37. ASSERT_EQ(core.cursor().column, 0);
  38. }
  39. TEST_F(EditorCoreTest, SetMessage) {
  40. std::string test_message = "Hello, Lumacs!";
  41. core.set_message(test_message);
  42. ASSERT_EQ(core.last_message(), test_message);
  43. }
  44. TEST_F(EditorCoreTest, SplitWindowHorizontally) {
  45. core.split_horizontally();
  46. // After split, there should be 2 windows in the layout.
  47. std::vector<std::shared_ptr<lumacs::Window>> windows;
  48. core.window_manager().collect_windows(core.root_layout().get(), windows);
  49. ASSERT_EQ(windows.size(), 2);
  50. // The newly created window should be the active one.
  51. ASSERT_EQ(core.active_window(), windows[1]);
  52. }
  53. TEST_F(EditorCoreTest, KillLine) {
  54. core.buffer_manager().active_buffer()->insert({0,0}, "Line 1\nLine 2");
  55. core.set_cursor({0,0});
  56. core.kill_line();
  57. ASSERT_EQ(core.buffer().line(0), "Line 2");
  58. ASSERT_FALSE(core.kill_ring_manager().empty());
  59. ASSERT_EQ(core.kill_ring_manager().current(), "Line 1\n");
  60. }
  61. TEST_F(EditorCoreTest, Yank) {
  62. core.buffer_manager().active_buffer()->insert({0,0}, "some text");
  63. core.set_cursor({0,5}); // at ' '
  64. core.kill_line(); // Kills " text"
  65. core.yank(); // Yanks " text"
  66. ASSERT_EQ(core.buffer().line(0), "some text"); // Should be "some" + " text" from kill ring
  67. ASSERT_EQ(core.cursor().column, 9); // Cursor should be at end of yanked text
  68. }
  69. TEST_F(EditorCoreTest, CopyToRegisterAndInsert) {
  70. char reg_name = 'a';
  71. std::string reg_content = "Register content";
  72. core.copy_to_register(reg_name, reg_content);
  73. core.buffer_manager().active_buffer()->insert({0,0}, "Original ");
  74. core.set_cursor({0,9});
  75. core.insert_register(reg_name);
  76. ASSERT_EQ(core.buffer().line(0), "Original Register content");
  77. }
  78. TEST_F(EditorCoreTest, StartAndEndMacro) {
  79. ASSERT_FALSE(core.macro_manager().is_recording_macro());
  80. core.start_kbd_macro();
  81. ASSERT_TRUE(core.macro_manager().is_recording_macro());
  82. core.record_key_sequence("a");
  83. core.end_kbd_macro_or_call();
  84. ASSERT_FALSE(core.macro_manager().is_recording_macro());
  85. // Executing the macro will depend on process_key being called
  86. // which is hard to test without mocking keybinding_manager directly.
  87. // For now, just test recording state.
  88. }
  89. TEST_F(EditorCoreTest, KillRectangle) {
  90. core.buffer_manager().active_buffer()->insert({0,0}, "Line1\nLine2\nLine3");
  91. core.buffer_manager().active_buffer()->set_mark({0,1}); // Mark 'i'
  92. core.set_cursor({2,3}); // Cursor 'e' in Line3
  93. core.kill_rectangle();
  94. // Expected buffer state after killing rectangle from (0,1) to (2,3)
  95. // "Lne1"
  96. // "Lne2"
  97. // "Lne3"
  98. ASSERT_EQ(core.buffer().line(0), "Le1");
  99. ASSERT_EQ(core.buffer().line(1), "Le2");
  100. ASSERT_EQ(core.buffer().line(2), "Le3"); // Check if rectangle was killed by verifying we can yank it back or check if it's not empty
  101. // Since we can't access private members, we'll check side effects or public API
  102. // For now, let's just assert that the buffer changed as expected.
  103. // A more robust test would verify the content of the rectangle_manager's kill ring
  104. // or through `yank_rectangle`.
  105. // For this test, we expect the buffer to be modified
  106. ASSERT_NE(core.buffer().content(), "Line1\nLine2\nLine3");
  107. }