]> Pileus Git - ~andy/gtk/blob - gtk/tests/entry.c
Some more documentation fixes
[~andy/gtk] / gtk / tests / entry.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 2011 Red Hat, Inc.
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 <gtk/gtk.h>
19
20 static gint serial = 0;
21
22 typedef struct {
23   gint serial;
24   gint count;
25   gint start;
26   gint end;
27   gchar *text;
28   gchar *new_text;
29   gint position;
30   gint length;
31 } EntryData;
32
33 static void
34 notify (GtkEditable *editable, GParamSpec *pspec, EntryData *data)
35 {
36   data->serial = serial++;
37   data->count++;
38   data->text = gtk_editable_get_chars (editable, 0, -1);
39   gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
40
41 #if 0
42   g_print ("notify::%s\n", pspec->name);
43   g_print ("\ttext: %s\n", data->text);
44   g_print ("\tstart: %d\n", data->start);
45   g_print ("\tend: %d\n", data->end);
46 #endif
47 }
48
49 static void
50 insert_text (GtkEditable *editable,
51              const gchar *new_text,
52              gint         new_text_length,
53              gint        *position,
54              EntryData   *data)
55 {
56   data->serial = serial++;
57   data->count++;
58   data->text = gtk_editable_get_chars (editable, 0, -1);
59   gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
60   data->new_text = g_strdup (new_text);
61   data->position = *position;
62   data->length = new_text_length;
63
64 #if 0
65   g_print ("insert-text \"%s\", %d\n", new_text, *position);
66   g_print ("\ttext: %s\n", data->text);
67   g_print ("\tstart: %d\n", data->start);
68   g_print ("\tend: %d\n", data->end);
69 #endif
70 }
71
72 static void
73 delete_text (GtkEditable *editable,
74              gint         start_pos,
75              gint         end_pos,
76              EntryData   *data)
77 {
78   data->serial = serial++;
79   data->count++;
80   data->text = gtk_editable_get_chars (editable, 0, -1);
81   gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
82   data->position = start_pos;
83   data->length = end_pos - start_pos;
84
85 #if 0
86   g_print ("delete-text %d %d\n", start_pos, end_pos);
87   g_print ("\ttext: %s\n", data->text);
88   g_print ("\tstart: %d\n", data->start);
89   g_print ("\tend: %d\n", data->end);
90 #endif
91 }
92
93 static void
94 changed (GtkEditable *editable,
95          EntryData   *data)
96 {
97   data->serial = serial++;
98   data->count++;
99   data->text = gtk_editable_get_chars (editable, 0, -1);
100   gtk_editable_get_selection_bounds (editable, &data->start, &data->end);
101
102 #if 0
103   g_print ("changed\n");
104   g_print ("\ttext: %s\n", data->text);
105   g_print ("\tstart: %d\n", data->start);
106   g_print ("\tend: %d\n", data->end);
107 #endif
108 }
109
110 static void
111 test_insert (void)
112 {
113   GtkWidget *entry;
114   gint pos;
115   EntryData data1;
116   EntryData data2;
117   EntryData data3;
118   EntryData data4;
119   EntryData data5;
120   EntryData data6;
121
122   entry = gtk_entry_new ();
123   g_object_ref_sink (entry);
124
125   gtk_entry_set_text (GTK_ENTRY (entry), "bar");
126   gtk_editable_set_position (GTK_EDITABLE (entry), -1);
127   pos = gtk_editable_get_position (GTK_EDITABLE (entry));
128   g_assert_cmpint (pos, ==, 3);
129
130   data1.count = 0;
131   data2.count = 0;
132   data3.count = 0;
133   data4.count = 0;
134   data5.count = 0;
135   data6.count = 0;
136   g_signal_connect (entry, "notify::cursor-position",
137                     G_CALLBACK (notify), &data1);
138   g_signal_connect (entry, "notify::selection-bound",
139                     G_CALLBACK (notify), &data2);
140   g_signal_connect (entry, "notify::text",
141                     G_CALLBACK (notify), &data3);
142   g_signal_connect (entry, "insert-text",
143                     G_CALLBACK (insert_text), &data4);
144   g_signal_connect (entry, "delete-text",
145                     G_CALLBACK (delete_text), &data5);
146   g_signal_connect (entry, "changed",
147                     G_CALLBACK (changed), &data6);
148
149   pos = 0;
150   gtk_editable_insert_text (GTK_EDITABLE (entry), "foo", -1, &pos);
151   g_assert_cmpint (pos, ==, 3);
152
153   pos = gtk_editable_get_position (GTK_EDITABLE (entry));
154   g_assert_cmpint (pos, ==, 6);
155
156   /* Check that notification for ::text, ::cursor-position and
157    * ::selection-bound happens in a consistent state after the
158    * change.
159    */
160   g_assert_cmpint (data1.count, ==, 1);
161   g_assert_cmpint (data1.start, ==, 6);
162   g_assert_cmpint (data1.end, ==, 6);
163   g_assert_cmpstr (data1.text, ==, "foobar");
164   g_free (data1.text);
165
166   g_assert_cmpint (data2.count, ==, 1);
167   g_assert_cmpint (data2.start, ==, 6);
168   g_assert_cmpint (data2.end, ==, 6);
169   g_assert_cmpstr (data2.text, ==, "foobar");
170   g_free (data2.text);
171
172   g_assert_cmpint (data3.count, ==, 1);
173   g_assert_cmpint (data3.start, ==, 6);
174   g_assert_cmpint (data3.end, ==, 6);
175   g_assert_cmpstr (data3.text, ==, "foobar");
176   g_free (data3.text);
177
178   /* Check that ::insert-text sees the state _before_ the insertion */
179   g_assert_cmpint (data4.count, ==, 1);
180   g_assert_cmpint (data4.start, ==, 3);
181   g_assert_cmpint (data4.end, ==, 3);
182   g_assert_cmpstr (data4.text, ==, "bar");
183   g_assert_cmpint (data4.position, ==, 0);
184   g_assert_cmpint (data4.length, ==, 3);
185   g_assert_cmpstr (data4.new_text, ==, "foo");
186   g_free (data4.text);
187   g_free (data4.new_text);
188
189   /* no deletion here */
190   g_assert_cmpint (data5.count, ==, 0);
191
192   /* Check that ::changed sees the post-change state */
193   g_assert_cmpint (data6.count, ==, 1);
194   g_assert_cmpint (data6.start, ==, 6);
195   g_assert_cmpint (data6.end, ==, 6);
196   g_assert_cmpstr (data6.text, ==, "foobar");
197   g_free (data6.text);
198
199   /* Now check ordering: ::insert-text comes before ::notify */
200   g_assert_cmpint (data4.serial, <, data1.serial);
201   g_assert_cmpint (data4.serial, <, data2.serial);
202   g_assert_cmpint (data4.serial, <, data3.serial);
203
204   /* ... and ::changed comes after ::notify */
205   g_assert_cmpint (data6.serial, >, data1.serial);
206   g_assert_cmpint (data6.serial, >, data2.serial);
207   g_assert_cmpint (data6.serial, >, data3.serial);
208
209   g_object_unref (entry);
210 }
211
212 static void
213 test_delete (void)
214 {
215   GtkWidget *entry;
216   gint pos;
217   EntryData data1;
218   EntryData data2;
219   EntryData data3;
220   EntryData data4;
221   EntryData data5;
222   EntryData data6;
223
224   entry = gtk_entry_new ();
225   g_object_ref_sink (entry);
226
227   gtk_entry_set_text (GTK_ENTRY (entry), "foobar");
228   gtk_editable_set_position (GTK_EDITABLE (entry), -1);
229   pos = gtk_editable_get_position (GTK_EDITABLE (entry));
230   g_assert_cmpint (pos, ==, 6);
231
232   data1.count = 0;
233   data2.count = 0;
234   data3.count = 0;
235   data4.count = 0;
236   data5.count = 0;
237   data6.count = 0;
238   g_signal_connect (entry, "notify::cursor-position",
239                     G_CALLBACK (notify), &data1);
240   g_signal_connect (entry, "notify::selection-bound",
241                     G_CALLBACK (notify), &data2);
242   g_signal_connect (entry, "notify::text",
243                     G_CALLBACK (notify), &data3);
244   g_signal_connect (entry, "insert-text",
245                     G_CALLBACK (insert_text), &data4);
246   g_signal_connect (entry, "delete-text",
247                     G_CALLBACK (delete_text), &data5);
248   g_signal_connect (entry, "changed",
249                     G_CALLBACK (changed), &data6);
250
251   gtk_editable_delete_text (GTK_EDITABLE (entry), 0, 3);
252
253   pos = gtk_editable_get_position (GTK_EDITABLE (entry));
254   g_assert_cmpint (pos, ==, 3);
255
256   /* Check that notification for ::text, ::cursor-position and
257    * ::selection-bound happens in a consistent state after the
258    * change.
259    */
260   g_assert_cmpint (data1.count, ==, 1);
261   g_assert_cmpint (data1.start, ==, 3);
262   g_assert_cmpint (data1.end, ==, 3);
263   g_assert_cmpstr (data1.text, ==, "bar");
264   g_free (data1.text);
265
266   g_assert_cmpint (data2.count, ==, 1);
267   g_assert_cmpint (data2.start, ==, 3);
268   g_assert_cmpint (data2.end, ==, 3);
269   g_assert_cmpstr (data2.text, ==, "bar");
270   g_free (data2.text);
271
272   g_assert_cmpint (data3.count, ==, 1);
273   g_assert_cmpint (data3.start, ==, 3);
274   g_assert_cmpint (data3.end, ==, 3);
275   g_assert_cmpstr (data3.text, ==, "bar");
276   g_free (data3.text);
277
278   /* no insertion here */
279   g_assert_cmpint (data4.count, ==, 0);
280
281   /* Check that ::delete-text sees the state _before_ the insertion */
282   g_assert_cmpint (data5.count, ==, 1);
283   g_assert_cmpint (data5.start, ==, 6);
284   g_assert_cmpint (data5.end, ==, 6);
285   g_assert_cmpstr (data5.text, ==, "foobar");
286   g_assert_cmpint (data5.position, ==, 0);
287   g_assert_cmpint (data5.length, ==, 3);
288   g_free (data5.text);
289
290   /* Check that ::changed sees the post-change state */
291   g_assert_cmpint (data6.count, ==, 1);
292   g_assert_cmpint (data6.start, ==, 3);
293   g_assert_cmpint (data6.end, ==, 3);
294   g_assert_cmpstr (data6.text, ==, "bar");
295   g_free (data6.text);
296
297   /* Now check ordering: ::delete-text comes before ::notify */
298   g_assert_cmpint (data5.serial, <, data1.serial);
299   g_assert_cmpint (data5.serial, <, data2.serial);
300   g_assert_cmpint (data5.serial, <, data3.serial);
301
302   /* ... and ::changed comes after ::notify */
303   g_assert_cmpint (data6.serial, >, data1.serial);
304   g_assert_cmpint (data6.serial, >, data2.serial);
305   g_assert_cmpint (data6.serial, >, data3.serial);
306   g_object_unref (entry);
307 }
308
309 int
310 main (int   argc,
311       char *argv[])
312 {
313   gtk_test_init (&argc, &argv);
314
315   g_test_add_func ("/entry/delete", test_delete);
316   g_test_add_func ("/entry/insert", test_insert);
317
318   return g_test_run();
319 }