1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | #include <stdio.h> |
20 | #include <string.h> |
21 | |
22 | #include <gtk/gtk.h> |
23 | |
24 | static void |
25 | test_empty_search (void) |
26 | { |
27 | GtkTextBuffer *buffer; |
28 | GtkTextIter it, s, e; |
29 | gboolean res; |
30 | |
31 | buffer = gtk_text_buffer_new (NULL); |
32 | gtk_text_buffer_set_text (buffer, text: "This is some foo text" , len: -1); |
33 | |
34 | /* search from start forward */ |
35 | gtk_text_buffer_get_start_iter (buffer, iter: &it); |
36 | res = gtk_text_iter_forward_search (iter: &it, str: "" , flags: 0, match_start: &s, match_end: &e, NULL); |
37 | g_assert_true (res); |
38 | g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e)); |
39 | g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 1); |
40 | |
41 | /* search from end backward */ |
42 | gtk_text_buffer_get_end_iter (buffer, iter: &it); |
43 | res = gtk_text_iter_backward_search (iter: &it, str: "" , flags: 0, match_start: &s, match_end: &e, NULL); |
44 | g_assert_true (res); |
45 | g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, gtk_text_iter_get_offset (&e)); |
46 | g_assert_cmpint (gtk_text_iter_get_offset (&s), ==, 20); |
47 | } |
48 | |
49 | static void |
50 | check_found_forward (const char *haystack, |
51 | const char *needle, |
52 | GtkTextSearchFlags flags, |
53 | int expected_start, |
54 | int expected_end, |
55 | const char *expected_string) |
56 | { |
57 | GtkTextBuffer *buffer; |
58 | GtkTextIter i, s, e; |
59 | gboolean res; |
60 | char *text; |
61 | |
62 | buffer = gtk_text_buffer_new (NULL); |
63 | |
64 | gtk_text_buffer_set_text (buffer, text: haystack, len: -1); |
65 | |
66 | /* TODO: add test with limit before, after and in the middle |
67 | of expected start and end */ |
68 | |
69 | /* search from start forward */ |
70 | gtk_text_buffer_get_start_iter (buffer, iter: &i); |
71 | res = gtk_text_iter_forward_search (iter: &i, str: needle, flags, match_start: &s, match_end: &e, NULL); |
72 | g_assert_true (res); |
73 | g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s)); |
74 | g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e)); |
75 | text = gtk_text_iter_get_text (start: &s, end: &e); |
76 | g_assert_cmpstr (expected_string, ==, text); |
77 | g_free (mem: text); |
78 | |
79 | g_object_unref (object: buffer); |
80 | } |
81 | |
82 | static void |
83 | check_found_backward (const char *haystack, |
84 | const char *needle, |
85 | GtkTextSearchFlags flags, |
86 | int expected_start, |
87 | int expected_end, |
88 | const char *expected_string) |
89 | { |
90 | GtkTextBuffer *buffer; |
91 | GtkTextIter i, s, e; |
92 | gboolean res; |
93 | char *text; |
94 | |
95 | buffer = gtk_text_buffer_new (NULL); |
96 | |
97 | gtk_text_buffer_set_text (buffer, text: haystack, len: -1); |
98 | |
99 | /* search from end backward */ |
100 | gtk_text_buffer_get_end_iter (buffer, iter: &i); |
101 | res = gtk_text_iter_backward_search (iter: &i, str: needle, flags, match_start: &s, match_end: &e, NULL); |
102 | g_assert_true (res); |
103 | g_assert_cmpint (expected_start, ==, gtk_text_iter_get_offset (&s)); |
104 | g_assert_cmpint (expected_end, ==, gtk_text_iter_get_offset (&e)); |
105 | text = gtk_text_iter_get_text (start: &s, end: &e); |
106 | g_assert_cmpstr (expected_string, ==, text); |
107 | g_free (mem: text); |
108 | |
109 | g_object_unref (object: buffer); |
110 | } |
111 | |
112 | static void |
113 | check_not_found (const char *haystack, |
114 | const char *needle, |
115 | GtkTextSearchFlags flags) |
116 | { |
117 | GtkTextBuffer *buffer; |
118 | GtkTextIter i, s, e; |
119 | gboolean res; |
120 | |
121 | buffer = gtk_text_buffer_new (NULL); |
122 | |
123 | gtk_text_buffer_set_text (buffer, text: haystack, len: -1); |
124 | |
125 | /* search from start forward */ |
126 | gtk_text_buffer_get_start_iter (buffer, iter: &i); |
127 | res = gtk_text_iter_forward_search (iter: &i, str: needle, flags, match_start: &s, match_end: &e, NULL); |
128 | g_assert_false (res); |
129 | |
130 | /* search from end backward */ |
131 | gtk_text_buffer_get_end_iter (buffer, iter: &i); |
132 | res = gtk_text_iter_backward_search (iter: &i, str: needle, flags, match_start: &s, match_end: &e, NULL); |
133 | g_assert_false (res); |
134 | |
135 | g_object_unref (object: buffer); |
136 | } |
137 | |
138 | static void |
139 | test_search_full_buffer (void) |
140 | { |
141 | check_found_forward (haystack: "foo" , needle: "foo" , flags: 0, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
142 | check_found_backward (haystack: "foo" , needle: "foo" , flags: 0, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
143 | check_found_forward (haystack: "foo" , needle: "foo" , flags: GTK_TEXT_SEARCH_CASE_INSENSITIVE, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
144 | check_found_backward (haystack: "foo" , needle: "foo" , flags: GTK_TEXT_SEARCH_CASE_INSENSITIVE, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
145 | check_found_forward (haystack: "foo" , needle: "Foo" , flags: GTK_TEXT_SEARCH_CASE_INSENSITIVE, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
146 | check_found_backward (haystack: "foo" , needle: "Foo" , flags: GTK_TEXT_SEARCH_CASE_INSENSITIVE, expected_start: 0, expected_end: 3, expected_string: "foo" ); |
147 | } |
148 | |
149 | static void |
150 | test_search (void) |
151 | { |
152 | /* simple match */ |
153 | check_found_forward (haystack: "This is some foo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
154 | check_found_backward (haystack: "This is some foo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
155 | check_not_found (haystack: "This is some foo text" , needle: "Foo" , flags: 0); |
156 | |
157 | /* different matches for forward and backward */ |
158 | check_found_forward (haystack: "This is some foo foo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
159 | check_found_backward (haystack: "This is some foo foo text" , needle: "foo" , flags: 0, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
160 | |
161 | /* new lines in the haystack */ |
162 | check_found_forward (haystack: "This is some\nfoo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
163 | check_found_backward (haystack: "This is some\nfoo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
164 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "foo" , flags: 0, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
165 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "foo" , flags: 0, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
166 | check_not_found (haystack: "This is some\nfoo text" , needle: "Foo" , flags: 0); |
167 | |
168 | /* end of buffer */ |
169 | check_found_forward (haystack: "This is some\ntext foo" , needle: "foo" , flags: 0, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
170 | check_found_backward (haystack: "This is some\ntext foo" , needle: "foo" , flags: 0, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
171 | check_not_found (haystack: "This is some\ntext foo" , needle: "Foo" , flags: 0); |
172 | |
173 | /* multiple lines in the needle */ |
174 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "foo\nfoo" , flags: 0, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
175 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "foo\nfoo" , flags: 0, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
176 | check_not_found (haystack: "This is some foo\nfoo text" , needle: "Foo\nfoo" , flags: 0); |
177 | |
178 | /* check also that different composition of utf8 characters |
179 | (e.g. accented letters) match */ |
180 | |
181 | check_found_forward (haystack: "This is some \303\200 text" , needle: "\303\200" , flags: 0, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
182 | check_found_forward (haystack: "This is some \303\200 text" , needle: "some \303\200" , flags: 0, expected_start: 8, expected_end: 14, expected_string: "some \303\200" ); |
183 | check_found_forward (haystack: "This is some \303\200 text" , needle: "\303\200 text" , flags: 0, expected_start: 13, expected_end: 19, expected_string: "\303\200 text" ); |
184 | check_found_forward (haystack: "This is some \303\200 text" , needle: "some \303\200 text" , flags: 0, expected_start: 8, expected_end: 19, expected_string: "some \303\200 text" ); |
185 | check_found_backward (haystack: "This is some \303\240 text" , needle: "\303\240" , flags: 0, expected_start: 13, expected_end: 14, expected_string: "\303\240" ); |
186 | check_found_backward (haystack: "This is some \303\240 text" , needle: "some \303\240" , flags: 0, expected_start: 8, expected_end: 14, expected_string: "some \303\240" ); |
187 | check_found_backward (haystack: "This is some \303\240 text" , needle: "\303\240 text" , flags: 0, expected_start: 13, expected_end: 19, expected_string: "\303\240 text" ); |
188 | check_found_backward (haystack: "This is some \303\240 text" , needle: "some \303\240 text" , flags: 0, expected_start: 8, expected_end: 19, expected_string: "some \303\240 text" ); |
189 | |
190 | /* multi-byte characters outside the needle */ |
191 | check_found_forward (haystack: "\303\200 aa" , needle: "aa" , flags: 0, expected_start: 2, expected_end: 4, expected_string: "aa" ); |
192 | check_found_forward (haystack: "aa \303\200" , needle: "aa" , flags: 0, expected_start: 0, expected_end: 2, expected_string: "aa" ); |
193 | check_found_backward (haystack: "\303\200 aa" , needle: "aa" , flags: 0, expected_start: 2, expected_end: 4, expected_string: "aa" ); |
194 | check_found_backward (haystack: "aa \303\200" , needle: "aa" , flags: 0, expected_start: 0, expected_end: 2, expected_string: "aa" ); |
195 | } |
196 | |
197 | static void |
198 | test_search_caseless (void) |
199 | { |
200 | GtkTextSearchFlags flags; |
201 | |
202 | flags = GTK_TEXT_SEARCH_CASE_INSENSITIVE; |
203 | |
204 | /* simple match */ |
205 | check_found_forward (haystack: "This is some foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
206 | check_found_forward (haystack: "This is some foo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
207 | check_found_forward (haystack: "This is some Foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
208 | check_found_backward (haystack: "This is some foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
209 | check_found_backward (haystack: "This is some foo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
210 | check_found_backward (haystack: "This is some Foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
211 | |
212 | /* check also that different composition of utf8 characters |
213 | (e.g. accented letters) match */ |
214 | |
215 | /* different matches for forward and backward */ |
216 | check_found_forward (haystack: "This is some foo foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
217 | check_found_forward (haystack: "This is some foo foo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
218 | check_found_forward (haystack: "This is some Foo foo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
219 | check_found_forward (haystack: "This is some \303\200 \303\240 text" , needle: "\303\240" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
220 | check_found_forward (haystack: "This is some \303\200 \303\240 text" , needle: "\303\200" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
221 | check_found_forward (haystack: "This is some \303\200 \303\240 text" , needle: "a\314\200" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
222 | check_found_backward (haystack: "This is some foo foo text" , needle: "foo" , flags, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
223 | check_found_backward (haystack: "This is some foo foo text" , needle: "Foo" , flags, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
224 | check_found_backward (haystack: "This is some foo Foo text" , needle: "foo" , flags, expected_start: 17, expected_end: 20, expected_string: "Foo" ); |
225 | check_found_backward (haystack: "This is some \303\200 \303\240 text" , needle: "\303\240" , flags, expected_start: 15, expected_end: 16, expected_string: "\303\240" ); |
226 | check_found_backward (haystack: "This is some \303\200 \303\240 text" , needle: "\303\200" , flags, expected_start: 15, expected_end: 16, expected_string: "\303\240" ); |
227 | check_found_backward (haystack: "This is some \303\200 \303\240 text" , needle: "a\314\200" , flags, expected_start: 15, expected_end: 16, expected_string: "\303\240" ); |
228 | |
229 | /* new lines in the haystack */ |
230 | check_found_forward (haystack: "This is some\nfoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
231 | check_found_forward (haystack: "This is some\nfoo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
232 | check_found_forward (haystack: "This is some\nFoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
233 | check_found_forward (haystack: "This is some\n\303\200 text" , needle: "\303\240" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
234 | check_found_forward (haystack: "This is some\n\303\200 text" , needle: "a\314\200" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
235 | check_found_backward (haystack: "This is some\nfoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
236 | check_found_backward (haystack: "This is some\nfoo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
237 | check_found_backward (haystack: "This is some\nFoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
238 | check_found_backward (haystack: "This is some\n\303\200 text" , needle: "\303\240" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
239 | check_found_backward (haystack: "This is some\n\303\200 text" , needle: "a\314\200" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
240 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
241 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "Foo" , flags, expected_start: 13, expected_end: 16, expected_string: "foo" ); |
242 | check_found_forward (haystack: "This is some Foo\nfoo text" , needle: "foo" , flags, expected_start: 13, expected_end: 16, expected_string: "Foo" ); |
243 | check_found_forward (haystack: "This is some \303\200\n\303\200 text" , needle: "\303\240" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
244 | check_found_forward (haystack: "This is some \303\200\n\303\200 text" , needle: "a\314\200" , flags, expected_start: 13, expected_end: 14, expected_string: "\303\200" ); |
245 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "foo" , flags, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
246 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "Foo" , flags, expected_start: 17, expected_end: 20, expected_string: "foo" ); |
247 | check_found_backward (haystack: "This is some foo\nFoo text" , needle: "foo" , flags, expected_start: 17, expected_end: 20, expected_string: "Foo" ); |
248 | check_found_backward (haystack: "This is some \303\200\n\303\200 text" , needle: "\303\240" , flags, expected_start: 15, expected_end: 16, expected_string: "\303\200" ); |
249 | check_found_backward (haystack: "This is some \303\200\n\303\200 text" , needle: "a\314\200" , flags, expected_start: 15, expected_end: 16, expected_string: "\303\200" ); |
250 | |
251 | /* end of buffer */ |
252 | check_found_forward (haystack: "This is some\ntext foo" , needle: "foo" , flags, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
253 | check_found_forward (haystack: "This is some\ntext foo" , needle: "Foo" , flags, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
254 | check_found_forward (haystack: "This is some\ntext Foo" , needle: "foo" , flags, expected_start: 18, expected_end: 21, expected_string: "Foo" ); |
255 | check_found_forward (haystack: "This is some\ntext \303\200" , needle: "\303\240" , flags, expected_start: 18, expected_end: 19, expected_string: "\303\200" ); |
256 | check_found_forward (haystack: "This is some\ntext \303\200" , needle: "a\314\200" , flags, expected_start: 18, expected_end: 19, expected_string: "\303\200" ); |
257 | check_found_backward (haystack: "This is some\ntext foo" , needle: "foo" , flags, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
258 | check_found_backward (haystack: "This is some\ntext foo" , needle: "Foo" , flags, expected_start: 18, expected_end: 21, expected_string: "foo" ); |
259 | check_found_backward (haystack: "This is some\ntext Foo" , needle: "foo" , flags, expected_start: 18, expected_end: 21, expected_string: "Foo" ); |
260 | check_found_backward (haystack: "This is some\ntext \303\200" , needle: "\303\240" , flags, expected_start: 18, expected_end: 19, expected_string: "\303\200" ); |
261 | check_found_backward (haystack: "This is some\ntext \303\200" , needle: "a\314\200" , flags, expected_start: 18, expected_end: 19, expected_string: "\303\200" ); |
262 | |
263 | /* multiple lines in the needle */ |
264 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "foo\nfoo" , flags, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
265 | check_found_forward (haystack: "This is some foo\nfoo text" , needle: "Foo\nFoo" , flags, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
266 | check_found_forward (haystack: "This is some Foo\nFoo text" , needle: "foo\nfoo" , flags, expected_start: 13, expected_end: 20, expected_string: "Foo\nFoo" ); |
267 | check_found_forward (haystack: "This is some \303\200\n\303\200 text" , needle: "\303\240\n\303\240" , flags, expected_start: 13, expected_end: 16, expected_string: "\303\200\n\303\200" ); |
268 | check_found_forward (haystack: "This is some \303\200\n\303\200 text" , needle: "a\314\200\na\314\200" , flags, expected_start: 13, expected_end: 16, expected_string: "\303\200\n\303\200" ); |
269 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "foo\nfoo" , flags, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
270 | check_found_backward (haystack: "This is some foo\nfoo text" , needle: "Foo\nFoo" , flags, expected_start: 13, expected_end: 20, expected_string: "foo\nfoo" ); |
271 | check_found_backward (haystack: "This is some Foo\nFoo text" , needle: "foo\nfoo" , flags, expected_start: 13, expected_end: 20, expected_string: "Foo\nFoo" ); |
272 | check_found_backward (haystack: "This is some \303\200\n\303\200 text" , needle: "\303\240\n\303\240" , flags, expected_start: 13, expected_end: 16, expected_string: "\303\200\n\303\200" ); |
273 | check_found_backward (haystack: "This is some \303\200\n\303\200 text" , needle: "a\314\200\na\314\200" , flags, expected_start: 13, expected_end: 16, expected_string: "\303\200\n\303\200" ); |
274 | |
275 | /* multi-byte characters outside the needle */ |
276 | check_found_forward (haystack: "\303\200 aa" , needle: "aa" , flags, expected_start: 2, expected_end: 4, expected_string: "aa" ); |
277 | check_found_forward (haystack: "aa \303\200" , needle: "aa" , flags, expected_start: 0, expected_end: 2, expected_string: "aa" ); |
278 | check_found_backward (haystack: "\303\200 aa" , needle: "aa" , flags, expected_start: 2, expected_end: 4, expected_string: "aa" ); |
279 | check_found_backward (haystack: "aa \303\200" , needle: "aa" , flags, expected_start: 0, expected_end: 2, expected_string: "aa" ); |
280 | } |
281 | |
282 | static void |
283 | test_forward_to_tag_toggle (void) |
284 | { |
285 | GtkTextBuffer *buffer; |
286 | GtkTextTag *bold_tag; |
287 | GtkTextTag *editable_tag; |
288 | GtkTextIter iter; |
289 | int offset; |
290 | gboolean ret; |
291 | |
292 | buffer = gtk_text_buffer_new (NULL); |
293 | |
294 | bold_tag = gtk_text_buffer_create_tag (buffer, tag_name: "bold" , |
295 | first_property_name: "weight" , PANGO_WEIGHT_BOLD, |
296 | NULL); |
297 | |
298 | editable_tag = gtk_text_buffer_create_tag (buffer, tag_name: "not-editable" , |
299 | first_property_name: "editable" , FALSE, |
300 | NULL); |
301 | |
302 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
303 | |
304 | gtk_text_buffer_insert (buffer, iter: &iter, text: "a" , len: -1); |
305 | gtk_text_buffer_insert_with_tags (buffer, iter: &iter, text: "b" , len: -1, first_tag: bold_tag, NULL); |
306 | gtk_text_buffer_insert_with_tags (buffer, iter: &iter, text: "c" , len: -1, first_tag: editable_tag, NULL); |
307 | |
308 | /* Go to the first "on" toggle */ |
309 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
310 | ret = gtk_text_iter_forward_to_tag_toggle (iter: &iter, NULL); |
311 | g_assert_true (ret); |
312 | offset = gtk_text_iter_get_offset (iter: &iter); |
313 | g_assert_cmpint (offset, ==, 1); |
314 | |
315 | /* Go to the last "off" toggle for the bold tag */ |
316 | ret = gtk_text_iter_forward_to_tag_toggle (iter: &iter, tag: bold_tag); |
317 | g_assert_true (ret); |
318 | offset = gtk_text_iter_get_offset (iter: &iter); |
319 | g_assert_cmpint (offset, ==, 2); |
320 | |
321 | ret = gtk_text_iter_forward_to_tag_toggle (iter: &iter, tag: bold_tag); |
322 | g_assert_false (ret); |
323 | |
324 | /* Go to the first "on" toggle for the editable tag */ |
325 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
326 | ret = gtk_text_iter_forward_to_tag_toggle (iter: &iter, tag: editable_tag); |
327 | g_assert_true (ret); |
328 | offset = gtk_text_iter_get_offset (iter: &iter); |
329 | g_assert_cmpint (offset, ==, 2); |
330 | |
331 | /* Test with the end iter */ |
332 | gtk_text_buffer_get_end_iter (buffer, iter: &iter); |
333 | ret = gtk_text_iter_forward_to_tag_toggle (iter: &iter, tag: editable_tag); |
334 | g_assert_false (ret); |
335 | |
336 | g_object_unref (object: buffer); |
337 | } |
338 | |
339 | static void |
340 | check_forward_line_end (const char *buffer_text, |
341 | int initial_offset, |
342 | int result_offset, |
343 | gboolean ret) |
344 | { |
345 | GtkTextBuffer *buffer; |
346 | GtkTextIter iter; |
347 | |
348 | buffer = gtk_text_buffer_new (NULL); |
349 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
350 | |
351 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
352 | |
353 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_to_line_end (&iter)); |
354 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
355 | |
356 | g_object_unref (object: buffer); |
357 | } |
358 | |
359 | static void |
360 | test_forward_to_line_end (void) |
361 | { |
362 | check_forward_line_end(buffer_text: "a" , initial_offset: 0, result_offset: 1, FALSE); |
363 | check_forward_line_end(buffer_text: "a\n" , initial_offset: 0, result_offset: 1, TRUE); |
364 | check_forward_line_end(buffer_text: "a\r\n" , initial_offset: 0, result_offset: 1, TRUE); |
365 | check_forward_line_end(buffer_text: "a\na\n" , initial_offset: 1, result_offset: 3, TRUE); |
366 | check_forward_line_end(buffer_text: "a\na\n\n" , initial_offset: 1, result_offset: 3, TRUE); |
367 | check_forward_line_end(buffer_text: "a\r\na\n" , initial_offset: 1, result_offset: 4, TRUE); |
368 | check_forward_line_end(buffer_text: "a\r\na\r\n\r\n" , initial_offset: 1, result_offset: 4, TRUE); |
369 | } |
370 | |
371 | static void |
372 | check_word_boundaries (const char *buffer_text, |
373 | int offset, |
374 | gboolean starts_word, |
375 | gboolean ends_word, |
376 | gboolean inside_word) |
377 | { |
378 | GtkTextBuffer *buffer; |
379 | GtkTextIter iter; |
380 | |
381 | buffer = gtk_text_buffer_new (NULL); |
382 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
383 | |
384 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: offset); |
385 | |
386 | g_assert_cmpint (starts_word, ==, gtk_text_iter_starts_word (&iter)); |
387 | g_assert_cmpint (ends_word, ==, gtk_text_iter_ends_word (&iter)); |
388 | g_assert_cmpint (inside_word, ==, gtk_text_iter_inside_word (&iter)); |
389 | |
390 | g_object_unref (object: buffer); |
391 | } |
392 | |
393 | static void |
394 | check_forward_word_end (const char *buffer_text, |
395 | int initial_offset, |
396 | int result_offset, |
397 | gboolean ret) |
398 | { |
399 | GtkTextBuffer *buffer; |
400 | GtkTextIter iter; |
401 | |
402 | buffer = gtk_text_buffer_new (NULL); |
403 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
404 | |
405 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
406 | |
407 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_word_end (&iter)); |
408 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
409 | |
410 | g_object_unref (object: buffer); |
411 | } |
412 | |
413 | static void |
414 | check_backward_word_start (const char *buffer_text, |
415 | int initial_offset, |
416 | int result_offset, |
417 | gboolean ret) |
418 | { |
419 | GtkTextBuffer *buffer; |
420 | GtkTextIter iter; |
421 | |
422 | buffer = gtk_text_buffer_new (NULL); |
423 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
424 | |
425 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
426 | |
427 | g_assert_cmpint (ret, ==, gtk_text_iter_backward_word_start (&iter)); |
428 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
429 | |
430 | g_object_unref (object: buffer); |
431 | } |
432 | |
433 | static void |
434 | test_word_boundaries (void) |
435 | { |
436 | /* Test with trivial content. The word boundaries are anyway determined by |
437 | * Pango and can change in the future for corner cases. |
438 | */ |
439 | |
440 | check_word_boundaries (buffer_text: "ab " , offset: 0, TRUE, FALSE, TRUE); |
441 | check_word_boundaries (buffer_text: "ab " , offset: 1, FALSE, FALSE, TRUE); |
442 | check_word_boundaries (buffer_text: "ab " , offset: 2, FALSE, TRUE, FALSE); |
443 | check_word_boundaries (buffer_text: "ab " , offset: 3, FALSE, FALSE, FALSE); |
444 | check_word_boundaries (buffer_text: "" , offset: 0, FALSE, FALSE, FALSE); |
445 | |
446 | check_forward_word_end (buffer_text: "ab " , initial_offset: 0, result_offset: 2, TRUE); |
447 | check_forward_word_end (buffer_text: "ab " , initial_offset: 1, result_offset: 2, TRUE); |
448 | check_forward_word_end (buffer_text: "ab " , initial_offset: 2, result_offset: 2, FALSE); |
449 | check_forward_word_end (buffer_text: "ab " , initial_offset: 3, result_offset: 3, FALSE); |
450 | check_forward_word_end (buffer_text: "ab" , initial_offset: 0, result_offset: 2, FALSE); |
451 | check_forward_word_end (buffer_text: "ab\n" , initial_offset: 2, result_offset: 2, FALSE); |
452 | |
453 | check_backward_word_start (buffer_text: " ab" , initial_offset: 3, result_offset: 1, TRUE); |
454 | check_backward_word_start (buffer_text: " ab" , initial_offset: 2, result_offset: 1, TRUE); |
455 | check_backward_word_start (buffer_text: " ab" , initial_offset: 1, result_offset: 1, FALSE); |
456 | check_backward_word_start (buffer_text: " ab" , initial_offset: 0, result_offset: 0, FALSE); |
457 | check_backward_word_start (buffer_text: "ab" , initial_offset: 2, result_offset: 0, TRUE); |
458 | } |
459 | |
460 | static void |
461 | check_forward_visible_word_end (GtkTextBuffer *buffer, |
462 | int initial_offset, |
463 | int result_offset, |
464 | gboolean ret) |
465 | { |
466 | GtkTextIter iter; |
467 | |
468 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
469 | |
470 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_visible_word_end (&iter)); |
471 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
472 | } |
473 | |
474 | static void |
475 | check_backward_visible_word_start (GtkTextBuffer *buffer, |
476 | int initial_offset, |
477 | int result_offset, |
478 | gboolean ret) |
479 | { |
480 | GtkTextIter iter; |
481 | |
482 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
483 | |
484 | g_assert_cmpint (ret, ==, gtk_text_iter_backward_visible_word_start (&iter)); |
485 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
486 | } |
487 | |
488 | static void |
489 | test_visible_word_boundaries (void) |
490 | { |
491 | /* Test with trivial content. The word boundaries are anyway determined by |
492 | * Pango and can change in the future for corner cases. |
493 | */ |
494 | |
495 | GtkTextBuffer *buffer; |
496 | GtkTextTag *invisible_tag; |
497 | GtkTextIter iter; |
498 | |
499 | buffer = gtk_text_buffer_new (NULL); |
500 | |
501 | invisible_tag = gtk_text_buffer_create_tag (buffer, NULL, |
502 | first_property_name: "invisible" , TRUE, |
503 | NULL); |
504 | |
505 | /* Buffer contents: " a b c " with " b " invisible */ |
506 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
507 | gtk_text_buffer_insert (buffer, iter: &iter, text: " a" , len: -1); |
508 | gtk_text_buffer_insert_with_tags (buffer, iter: &iter, text: " b " , len: -1, first_tag: invisible_tag, NULL); |
509 | gtk_text_buffer_insert (buffer, iter: &iter, text: "c " , len: -1); |
510 | |
511 | check_forward_visible_word_end (buffer, initial_offset: 0, result_offset: 6, TRUE); |
512 | check_forward_visible_word_end (buffer, initial_offset: 1, result_offset: 6, TRUE); |
513 | check_forward_visible_word_end (buffer, initial_offset: 2, result_offset: 6, TRUE); |
514 | check_forward_visible_word_end (buffer, initial_offset: 3, result_offset: 6, TRUE); |
515 | check_forward_visible_word_end (buffer, initial_offset: 4, result_offset: 6, TRUE); |
516 | check_forward_visible_word_end (buffer, initial_offset: 5, result_offset: 6, TRUE); |
517 | check_forward_visible_word_end (buffer, initial_offset: 6, result_offset: 6, FALSE); |
518 | check_forward_visible_word_end (buffer, initial_offset: 7, result_offset: 7, FALSE); |
519 | |
520 | check_backward_visible_word_start (buffer, initial_offset: 7, result_offset: 5, TRUE); /* FIXME result_offset should be 1 */ |
521 | check_backward_visible_word_start (buffer, initial_offset: 6, result_offset: 5, TRUE); /* FIXME result_offset should be 1 */ |
522 | check_backward_visible_word_start (buffer, initial_offset: 5, result_offset: 1, TRUE); |
523 | check_backward_visible_word_start (buffer, initial_offset: 4, result_offset: 1, TRUE); |
524 | check_backward_visible_word_start (buffer, initial_offset: 3, result_offset: 1, TRUE); |
525 | check_backward_visible_word_start (buffer, initial_offset: 2, result_offset: 1, TRUE); |
526 | check_backward_visible_word_start (buffer, initial_offset: 1, result_offset: 1, FALSE); |
527 | check_backward_visible_word_start (buffer, initial_offset: 0, result_offset: 0, FALSE); |
528 | |
529 | gtk_text_buffer_set_text (buffer, text: "ab" , len: -1); |
530 | check_forward_visible_word_end (buffer, initial_offset: 0, result_offset: 2, FALSE); |
531 | |
532 | /* Buffer contents: "b c " with "b" invisible */ |
533 | gtk_text_buffer_set_text (buffer, text: "" , len: -1); |
534 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
535 | gtk_text_buffer_insert_with_tags (buffer, iter: &iter, text: "b" , len: -1, first_tag: invisible_tag, NULL); |
536 | gtk_text_buffer_insert (buffer, iter: &iter, text: " c " , len: -1); |
537 | |
538 | check_forward_visible_word_end (buffer, initial_offset: 0, result_offset: 1, TRUE); /* FIXME result_offset should be 3 */ |
539 | |
540 | g_object_unref (object: buffer); |
541 | } |
542 | |
543 | static void |
544 | check_is_cursor_position (const char *buffer_text, |
545 | int offset, |
546 | gboolean ret) |
547 | { |
548 | GtkTextBuffer *buffer; |
549 | GtkTextIter iter; |
550 | |
551 | buffer = gtk_text_buffer_new (NULL); |
552 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
553 | |
554 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: offset); |
555 | g_assert_cmpint (ret, ==, gtk_text_iter_is_cursor_position (&iter)); |
556 | |
557 | g_object_unref (object: buffer); |
558 | } |
559 | |
560 | static void |
561 | check_cursor_position (const char *buffer_text, |
562 | gboolean forward, |
563 | int initial_offset, |
564 | int result_offset, |
565 | gboolean ret) |
566 | { |
567 | GtkTextBuffer *buffer; |
568 | GtkTextIter iter; |
569 | |
570 | buffer = gtk_text_buffer_new (NULL); |
571 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
572 | |
573 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
574 | |
575 | if (forward) |
576 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_cursor_position (&iter)); |
577 | else |
578 | g_assert_cmpint (ret, ==, gtk_text_iter_backward_cursor_position (&iter)); |
579 | |
580 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
581 | |
582 | g_object_unref (object: buffer); |
583 | } |
584 | |
585 | static void |
586 | test_cursor_positions (void) |
587 | { |
588 | check_is_cursor_position (buffer_text: "a\r\n" , offset: 0, TRUE); |
589 | check_is_cursor_position (buffer_text: "a\r\n" , offset: 1, TRUE); |
590 | check_is_cursor_position (buffer_text: "a\r\n" , offset: 2, FALSE); |
591 | check_is_cursor_position (buffer_text: "a\r\n" , offset: 3, TRUE); |
592 | check_is_cursor_position (buffer_text: "" , offset: 0, TRUE); |
593 | |
594 | /* forward */ |
595 | check_cursor_position (buffer_text: "a\r\nb" , TRUE, initial_offset: 0, result_offset: 1, TRUE); |
596 | check_cursor_position (buffer_text: "a\r\nb" , TRUE, initial_offset: 1, result_offset: 3, TRUE); |
597 | check_cursor_position (buffer_text: "a\r\nb" , TRUE, initial_offset: 2, result_offset: 3, TRUE); |
598 | check_cursor_position (buffer_text: "a\r\nb" , TRUE, initial_offset: 3, result_offset: 4, FALSE); |
599 | check_cursor_position (buffer_text: "a\r\nb" , TRUE, initial_offset: 4, result_offset: 4, FALSE); |
600 | check_cursor_position (buffer_text: "a\n" , TRUE, initial_offset: 1, result_offset: 2, FALSE); |
601 | |
602 | /* backward */ |
603 | check_cursor_position (buffer_text: "a\r\nb" , FALSE, initial_offset: 4, result_offset: 3, TRUE); |
604 | check_cursor_position (buffer_text: "a\r\nb" , FALSE, initial_offset: 3, result_offset: 1, TRUE); |
605 | check_cursor_position (buffer_text: "a\r\nb" , FALSE, initial_offset: 2, result_offset: 1, TRUE); |
606 | check_cursor_position (buffer_text: "a\r\nb" , FALSE, initial_offset: 1, result_offset: 0, TRUE); |
607 | check_cursor_position (buffer_text: "a\r\nb" , FALSE, initial_offset: 0, result_offset: 0, FALSE); |
608 | } |
609 | |
610 | static void |
611 | check_visible_cursor_position (GtkTextBuffer *buffer, |
612 | gboolean forward, |
613 | int initial_offset, |
614 | int result_offset, |
615 | gboolean ret) |
616 | { |
617 | GtkTextIter iter; |
618 | |
619 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
620 | |
621 | if (forward) |
622 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_visible_cursor_position (&iter)); |
623 | else |
624 | g_assert_cmpint (ret, ==, gtk_text_iter_backward_visible_cursor_position (&iter)); |
625 | |
626 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
627 | } |
628 | |
629 | static void |
630 | test_visible_cursor_positions (void) |
631 | { |
632 | GtkTextBuffer *buffer; |
633 | GtkTextTag *invisible_tag; |
634 | GtkTextIter iter; |
635 | |
636 | buffer = gtk_text_buffer_new (NULL); |
637 | |
638 | invisible_tag = gtk_text_buffer_create_tag (buffer, NULL, |
639 | first_property_name: "invisible" , TRUE, |
640 | NULL); |
641 | |
642 | /* Buffer contents: "abcd" with 'bc' invisible */ |
643 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
644 | gtk_text_buffer_insert (buffer, iter: &iter, text: "a" , len: -1); |
645 | gtk_text_buffer_insert_with_tags (buffer, iter: &iter, text: "bc" , len: -1, first_tag: invisible_tag, NULL); |
646 | gtk_text_buffer_insert (buffer, iter: &iter, text: "d" , len: -1); |
647 | |
648 | /* forward */ |
649 | check_visible_cursor_position (buffer, TRUE, initial_offset: 0, result_offset: 3, TRUE); |
650 | check_visible_cursor_position (buffer, TRUE, initial_offset: 1, result_offset: 3, TRUE); |
651 | check_visible_cursor_position (buffer, TRUE, initial_offset: 2, result_offset: 3, TRUE); |
652 | check_visible_cursor_position (buffer, TRUE, initial_offset: 3, result_offset: 4, FALSE); |
653 | check_visible_cursor_position (buffer, TRUE, initial_offset: 4, result_offset: 4, FALSE); |
654 | |
655 | /* backward */ |
656 | check_visible_cursor_position (buffer, FALSE, initial_offset: 4, result_offset: 3, TRUE); |
657 | check_visible_cursor_position (buffer, FALSE, initial_offset: 3, result_offset: 0, TRUE); |
658 | check_visible_cursor_position (buffer, FALSE, initial_offset: 2, result_offset: 0, TRUE); |
659 | check_visible_cursor_position (buffer, FALSE, initial_offset: 1, result_offset: 0, TRUE); |
660 | check_visible_cursor_position (buffer, FALSE, initial_offset: 0, result_offset: 0, FALSE); |
661 | |
662 | g_object_unref (object: buffer); |
663 | } |
664 | |
665 | static void |
666 | check_sentence_boundaries (const char *buffer_text, |
667 | int offset, |
668 | gboolean starts_sentence, |
669 | gboolean ends_sentence, |
670 | gboolean inside_sentence) |
671 | { |
672 | GtkTextBuffer *buffer; |
673 | GtkTextIter iter; |
674 | |
675 | buffer = gtk_text_buffer_new (NULL); |
676 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
677 | |
678 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: offset); |
679 | |
680 | g_assert_cmpint (starts_sentence, ==, gtk_text_iter_starts_sentence (&iter)); |
681 | g_assert_cmpint (ends_sentence, ==, gtk_text_iter_ends_sentence (&iter)); |
682 | g_assert_cmpint (inside_sentence, ==, gtk_text_iter_inside_sentence (&iter)); |
683 | |
684 | g_object_unref (object: buffer); |
685 | } |
686 | |
687 | static void |
688 | check_forward_sentence_end (const char *buffer_text, |
689 | int initial_offset, |
690 | int result_offset, |
691 | gboolean ret) |
692 | { |
693 | GtkTextBuffer *buffer; |
694 | GtkTextIter iter; |
695 | |
696 | buffer = gtk_text_buffer_new (NULL); |
697 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
698 | |
699 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
700 | |
701 | g_assert_cmpint (ret, ==, gtk_text_iter_forward_sentence_end (&iter)); |
702 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
703 | |
704 | g_object_unref (object: buffer); |
705 | } |
706 | |
707 | static void |
708 | check_backward_sentence_start (const char *buffer_text, |
709 | int initial_offset, |
710 | int result_offset, |
711 | gboolean ret) |
712 | { |
713 | GtkTextBuffer *buffer; |
714 | GtkTextIter iter; |
715 | |
716 | buffer = gtk_text_buffer_new (NULL); |
717 | gtk_text_buffer_set_text (buffer, text: buffer_text, len: -1); |
718 | |
719 | gtk_text_buffer_get_iter_at_offset (buffer, iter: &iter, char_offset: initial_offset); |
720 | |
721 | g_assert_cmpint (ret, ==, gtk_text_iter_backward_sentence_start (&iter)); |
722 | g_assert_cmpint (result_offset, ==, gtk_text_iter_get_offset (&iter)); |
723 | |
724 | g_object_unref (object: buffer); |
725 | } |
726 | |
727 | static void |
728 | test_sentence_boundaries (void) |
729 | { |
730 | check_sentence_boundaries (buffer_text: "Hi. " , offset: 0, TRUE, FALSE, TRUE); |
731 | check_sentence_boundaries (buffer_text: "Hi. " , offset: 1, FALSE, FALSE, TRUE); |
732 | check_sentence_boundaries (buffer_text: "Hi. " , offset: 2, FALSE, FALSE, TRUE); |
733 | check_sentence_boundaries (buffer_text: "Hi. " , offset: 3, FALSE, TRUE, FALSE); |
734 | check_sentence_boundaries (buffer_text: "Hi. " , offset: 4, FALSE, FALSE, FALSE); |
735 | check_sentence_boundaries (buffer_text: "" , offset: 0, FALSE, FALSE, FALSE); |
736 | |
737 | check_forward_sentence_end (buffer_text: "Hi. " , initial_offset: 0, result_offset: 3, TRUE); |
738 | check_forward_sentence_end (buffer_text: "Hi. " , initial_offset: 1, result_offset: 3, TRUE); |
739 | check_forward_sentence_end (buffer_text: "Hi. " , initial_offset: 2, result_offset: 3, TRUE); |
740 | check_forward_sentence_end (buffer_text: "Hi. " , initial_offset: 3, result_offset: 3, FALSE); |
741 | check_forward_sentence_end (buffer_text: "Hi. " , initial_offset: 4, result_offset: 4, FALSE); |
742 | check_forward_sentence_end (buffer_text: "Hi." , initial_offset: 0, result_offset: 3, FALSE); |
743 | check_forward_sentence_end (buffer_text: "Hi.\n" , initial_offset: 3, result_offset: 3, FALSE); |
744 | |
745 | check_backward_sentence_start (buffer_text: " Hi." , initial_offset: 4, result_offset: 1, TRUE); |
746 | check_backward_sentence_start (buffer_text: " Hi." , initial_offset: 3, result_offset: 1, TRUE); |
747 | check_backward_sentence_start (buffer_text: " Hi." , initial_offset: 2, result_offset: 1, TRUE); |
748 | check_backward_sentence_start (buffer_text: " Hi." , initial_offset: 1, result_offset: 1, FALSE); |
749 | check_backward_sentence_start (buffer_text: " Hi." , initial_offset: 0, result_offset: 0, FALSE); |
750 | } |
751 | |
752 | static void |
753 | test_backward_line (void) |
754 | { |
755 | GtkTextBuffer *buffer; |
756 | GtkTextIter iter, start, end; |
757 | gboolean ret; |
758 | int offset; |
759 | |
760 | buffer = gtk_text_buffer_new (NULL); |
761 | gtk_text_buffer_get_start_iter (buffer, iter: &iter); |
762 | gtk_text_buffer_insert (buffer, iter: &iter, text: "Hi line 1\nHi line 2" , len: -1); |
763 | |
764 | /* Go to middle of first line */ |
765 | gtk_text_iter_backward_line (iter: &iter); |
766 | gtk_text_iter_set_line_offset (iter: &iter, char_on_line: 4); |
767 | |
768 | /* Now insert some chars with gtk_text_buffer_insert_range() */ |
769 | gtk_text_buffer_get_end_iter (buffer, iter: &end); |
770 | start = end; |
771 | gtk_text_iter_backward_cursor_positions (iter: &start, count: 5); |
772 | gtk_text_buffer_insert_range (buffer, iter: &iter, start: &start, end: &end); |
773 | |
774 | /* Check we are still at the first line */ |
775 | g_assert_cmpint (gtk_text_iter_get_line (&iter), ==, 0); |
776 | |
777 | /* Now a call to gtk_text_iter_backward_line() should return TRUE |
778 | and move &iter to start of the line, or return FALSE if &iter |
779 | was already at start of the line, so in both cases &iter should |
780 | be at the start of the line, so check that */ |
781 | ret = gtk_text_iter_backward_line (iter: &iter); |
782 | g_assert_true (ret); |
783 | offset = gtk_text_iter_get_line_offset (iter: &iter); |
784 | g_assert_cmpint (offset, ==, 0); |
785 | |
786 | g_object_unref (object: buffer); |
787 | } |
788 | |
789 | int |
790 | main (int argc, char** argv) |
791 | { |
792 | gtk_test_init (argcp: &argc, argvp: &argv); |
793 | |
794 | g_test_add_func (testpath: "/TextIter/Search Empty" , test_func: test_empty_search); |
795 | g_test_add_func (testpath: "/TextIter/Search Full Buffer" , test_func: test_search_full_buffer); |
796 | g_test_add_func (testpath: "/TextIter/Search" , test_func: test_search); |
797 | g_test_add_func (testpath: "/TextIter/Search Caseless" , test_func: test_search_caseless); |
798 | g_test_add_func (testpath: "/TextIter/Forward To Tag Toggle" , test_func: test_forward_to_tag_toggle); |
799 | g_test_add_func (testpath: "/TextIter/Forward To Line End" , test_func: test_forward_to_line_end); |
800 | g_test_add_func (testpath: "/TextIter/Word Boundaries" , test_func: test_word_boundaries); |
801 | g_test_add_func (testpath: "/TextIter/Visible Word Boundaries" , test_func: test_visible_word_boundaries); |
802 | g_test_add_func (testpath: "/TextIter/Cursor Positions" , test_func: test_cursor_positions); |
803 | g_test_add_func (testpath: "/TextIter/Visible Cursor Positions" , test_func: test_visible_cursor_positions); |
804 | g_test_add_func (testpath: "/TextIter/Sentence Boundaries" , test_func: test_sentence_boundaries); |
805 | g_test_add_func (testpath: "/TextIter/Backward line" , test_func: test_backward_line); |
806 | |
807 | return g_test_run(); |
808 | } |
809 | |