|
|
@@ -0,0 +1,111 @@
|
|
|
+#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> buffer;
|
|
|
+ std::unique_ptr<Window> window;
|
|
|
+
|
|
|
+ void SetUp() override {
|
|
|
+ buffer = std::make_shared<Buffer>("test_buffer");
|
|
|
+ window = std::make_unique<Window>(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);
|
|
|
+}
|