#include "gtest/gtest.h" #include "lumacs/window.hpp" #include "lumacs/buffer.hpp" using namespace lumacs; class WindowTest : public ::testing::Test { protected: std::shared_ptr buffer; std::unique_ptr window; void SetUp() override { buffer = std::make_shared("test_buffer"); window = std::make_unique(buffer); // Set a viewport large enough to avoid scroll margin conflicts // Margin is 3 (vertical) and 5 (horizontal). // Need height > 2*3 = 6, width > 2*5 = 10. window->set_viewport_size(20, 10); } }; TEST_F(WindowTest, InitialState) { ASSERT_EQ(window->cursor().line, 0); ASSERT_EQ(window->cursor().column, 0); const auto& vp = window->viewport(); ASSERT_EQ(vp.scroll_offset, 0); ASSERT_EQ(vp.horizontal_offset, 0); ASSERT_EQ(vp.width, 20); ASSERT_EQ(vp.height, 10); } TEST_F(WindowTest, VerticalScrolling) { // Fill buffer with enough lines for (int i = 0; i < 30; ++i) { size_t last_line = buffer->line_count() - 1; size_t last_col = buffer->line(last_line).size(); buffer->insert_newline({last_line, last_col}); } // Viewport height 10, Margin 3. // Trigger point for scroll down: scroll + height - margin // 0 + 10 - 3 = 7. // So line 6 should not scroll. Line 7 should scroll. window->set_cursor({6, 0}); ASSERT_EQ(window->viewport().scroll_offset, 0); window->set_cursor({7, 0}); // New scroll = cursor - height + margin + 1 // 7 - 10 + 3 + 1 = 1. ASSERT_EQ(window->viewport().scroll_offset, 1); // Verify visible range: [1, 11) (10 lines) auto range = window->visible_line_range(); ASSERT_EQ(range.first, 1); ASSERT_EQ(range.second, 11); } TEST_F(WindowTest, HorizontalScrolling) { // Fill line 0 with text std::string long_text = "012345678901234567890123456789"; // 30 chars buffer->insert({0,0}, long_text); // Viewport width 20, Margin 5. // Trigger point for scroll right: scroll + width - margin // 0 + 20 - 5 = 15. // Col 14 -> no scroll. Col 15 -> scroll. window->set_cursor({0, 14}); ASSERT_EQ(window->viewport().horizontal_offset, 0); window->set_cursor({0, 15}); // New scroll = col - width + margin + 1 // 15 - 20 + 5 + 1 = 1. ASSERT_EQ(window->viewport().horizontal_offset, 1); } TEST_F(WindowTest, ScrollLinesExplicitly) { for (int i = 0; i < 30; ++i) { size_t last_line = buffer->line_count() - 1; size_t last_col = buffer->line(last_line).size(); buffer->insert_newline({last_line, last_col}); } // Scroll down 2 lines window->scroll_lines(2); ASSERT_EQ(window->viewport().scroll_offset, 2); // Cursor was at 0. Top of view is 2. // Cursor should be moved to 2. ASSERT_EQ(window->cursor().line, 2); // Scroll up 1 line window->scroll_lines(-1); ASSERT_EQ(window->viewport().scroll_offset, 1); } TEST_F(WindowTest, VisibleLineRange) { for (int i = 0; i < 20; ++i) { size_t last_line = buffer->line_count() - 1; size_t last_col = buffer->line(last_line).size(); buffer->insert_newline({last_line, last_col}); } window->scroll_lines(2); // Viewport height 10, offset 2. Range: [2, 12) auto range = window->visible_line_range(); ASSERT_EQ(range.first, 2); ASSERT_EQ(range.second, 12); }