Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include "test.h" | ||
3 | #include "buffer.h" | ||
4 | #include "editor.h" | ||
5 | #include "indent.h" | ||
6 | #include "regexp.h" | ||
7 | |||
8 | 1 | static void test_find_buffer_by_id(TestContext *ctx) | |
9 | { | ||
10 | 1 | EditorState *e = ctx->userdata; | |
11 | 1 | const Buffer *buffer = e->buffer; | |
12 | 1 | ASSERT_NONNULL(buffer); | |
13 | 1 | EXPECT_PTREQ(find_buffer_by_id(&e->buffers, buffer->id), buffer); | |
14 | |||
15 | 1 | const unsigned long large_id = 1UL << 30; | |
16 | 1 | static_assert_compatible_types(large_id, buffer->id); | |
17 | 1 | EXPECT_NULL(find_buffer_by_id(&e->buffers, large_id)); | |
18 | 1 | } | |
19 | |||
20 | 1 | static void test_buffer_mark_lines_changed(TestContext *ctx) | |
21 | { | ||
22 | 1 | Buffer b = { | |
23 | .changed_line_min = 101, | ||
24 | .changed_line_max = 399, | ||
25 | }; | ||
26 | |||
27 | 1 | buffer_mark_lines_changed(&b, 400, 12); | |
28 | 1 | EXPECT_EQ(b.changed_line_min, 12); | |
29 | 1 | EXPECT_EQ(b.changed_line_max, 400); | |
30 | |||
31 | 1 | buffer_mark_lines_changed(&b, 3, 3); | |
32 | 1 | EXPECT_EQ(b.changed_line_min, 3); | |
33 | 1 | EXPECT_EQ(b.changed_line_max, 400); | |
34 | |||
35 | 1 | buffer_mark_lines_changed(&b, 3, 990); | |
36 | 1 | EXPECT_EQ(b.changed_line_min, 3); | |
37 | 1 | EXPECT_EQ(b.changed_line_max, 990); | |
38 | |||
39 | 1 | buffer_mark_lines_changed(&b, 1234, 1); | |
40 | 1 | EXPECT_EQ(b.changed_line_min, 1); | |
41 | 1 | EXPECT_EQ(b.changed_line_max, 1234); | |
42 | 1 | } | |
43 | |||
44 | 1 | static void test_make_indent(TestContext *ctx) | |
45 | { | ||
46 | 1 | LocalOptions options = { | |
47 | .expand_tab = false, | ||
48 | .indent_width = 8, | ||
49 | .tab_width = 8, | ||
50 | }; | ||
51 | |||
52 | 1 | char *indent = make_indent(&options, 16); | |
53 | 1 | EXPECT_STREQ(indent, "\t\t"); | |
54 | 1 | free(indent); | |
55 | |||
56 | 1 | indent = make_indent(&options, 17); | |
57 | 1 | EXPECT_STREQ(indent, "\t\t "); | |
58 | 1 | free(indent); | |
59 | |||
60 | 1 | indent = make_indent(&options, 20); | |
61 | 1 | EXPECT_STREQ(indent, "\t\t "); | |
62 | 1 | free(indent); | |
63 | |||
64 | 1 | indent = make_indent(&options, 24); | |
65 | 1 | EXPECT_STREQ(indent, "\t\t\t"); | |
66 | 1 | free(indent); | |
67 | |||
68 | 1 | options.expand_tab = true; | |
69 | |||
70 | 1 | indent = make_indent(&options, 8); | |
71 | 1 | EXPECT_STREQ(indent, " "); | |
72 | 1 | free(indent); | |
73 | |||
74 | 1 | indent = make_indent(&options, 7); | |
75 | 1 | EXPECT_STREQ(indent, " "); | |
76 | 1 | free(indent); | |
77 | 1 | } | |
78 | |||
79 | 1 | static void test_get_indent_for_next_line(TestContext *ctx) | |
80 | { | ||
81 | 1 | const char *pattern = "\\{$"; | |
82 | 1 | const InternedRegexp *ir = regexp_intern(pattern); | |
83 | 1 | ASSERT_NONNULL(ir); | |
84 | |||
85 | 1 | LocalOptions options = { | |
86 | .brace_indent = false, | ||
87 | .expand_tab = true, | ||
88 | .indent_regex = ir, | ||
89 | .indent_width = 4, | ||
90 | .tab_width = 8 | ||
91 | }; | ||
92 | |||
93 | 1 | const StringView line1 = STRING_VIEW("foo {"); | |
94 | 1 | char *indent = get_indent_for_next_line(&options, &line1); | |
95 | 1 | EXPECT_STREQ(indent, " "); | |
96 | 1 | free(indent); | |
97 | |||
98 | 1 | const StringView line2 = STRING_VIEW("foo"); | |
99 | 1 | indent = get_indent_for_next_line(&options, &line2); | |
100 | 1 | EXPECT_STREQ(indent, NULL); | |
101 | 1 | free(indent); | |
102 | 1 | } | |
103 | |||
104 | 1 | static void test_buffer_insert_bytes(TestContext *ctx) | |
105 | { | ||
106 | 1 | size_t len = 600; // (> BLOCK_EDIT_SIZE) | |
107 | 1 | char *text = xmalloc(len); | |
108 | 1 | memset(text, 'a', len); | |
109 | 1 | text[len - 1] = '\n'; | |
110 |
2/2✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
|
9 | for (size_t i = 72; i < len; i += 72) { |
111 | 8 | text[i] = '\n'; | |
112 | } | ||
113 | |||
114 | 1 | EditorState *e = ctx->userdata; | |
115 | 1 | View *view = window_open_empty_buffer(e->window); | |
116 | 1 | const Buffer *buffer = view->buffer; | |
117 | 1 | uintmax_t counts[2]; | |
118 | 1 | buffer_count_blocks_and_bytes(buffer, counts); | |
119 | 1 | EXPECT_EQ(counts[0], 1); | |
120 | 1 | EXPECT_EQ(counts[1], 0); | |
121 | 1 | EXPECT_EQ(buffer->nl, 0); | |
122 | |||
123 | 1 | buffer_insert_bytes(view, text, len); | |
124 | 1 | buffer_count_blocks_and_bytes(buffer, counts); | |
125 | 1 | EXPECT_EQ(counts[0], 2); | |
126 | 1 | EXPECT_EQ(counts[1], len); | |
127 | 1 | EXPECT_EQ(buffer->nl, 9); | |
128 | |||
129 | 1 | block_iter_goto_offset(&view->cursor, len / 2); | |
130 | 1 | EXPECT_EQ(view->cursor.offset, 300); | |
131 | 1 | buffer_insert_bytes(view, text, len); | |
132 | 1 | EXPECT_EQ(view->cursor.offset, 300); | |
133 | 1 | buffer_count_blocks_and_bytes(buffer, counts); | |
134 | 1 | EXPECT_EQ(counts[0], 4); | |
135 | 1 | EXPECT_EQ(counts[1], len * 2); | |
136 | 1 | EXPECT_EQ(buffer->nl, 18); | |
137 | |||
138 | 1 | free(text); | |
139 | 1 | window_close_current_view(e->window); | |
140 | 1 | } | |
141 | |||
142 | static const TestEntry tests[] = { | ||
143 | TEST(test_find_buffer_by_id), | ||
144 | TEST(test_buffer_mark_lines_changed), | ||
145 | TEST(test_make_indent), | ||
146 | TEST(test_get_indent_for_next_line), | ||
147 | TEST(test_buffer_insert_bytes), | ||
148 | }; | ||
149 | |||
150 | const TestGroup buffer_tests = TEST_GROUP(tests); | ||
151 |