1 /*
2  * Copyright (C) 2010 Canonical Ltd
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 3 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by
17  *              Neil Jagdish Patel <neil.patel@canonical.com>
18  *              Mikkel Kamstrup Erlandsen <mikkel.kamstrup@canonical.com>
19  *              Michal Hruby <michal.hruby@canonical.com>
20  *
21  */
22 
23 #include <glib.h>
24 #include <glib-object.h>
25 #include <dee.h>
26 #include <stdlib.h>
27 
28 typedef struct
29 {
30   DeeModel *model;
31 
32 } RowsFixture;
33 
34 static void seq_rows_setup    (RowsFixture *fix, gconstpointer data);
35 static void seq_rows_teardown (RowsFixture *fix, gconstpointer data);
36 static void proxy_rows_setup    (RowsFixture *fix, gconstpointer data);
37 static void proxy_rows_teardown (RowsFixture *fix, gconstpointer data);
38 static void txn_rows_setup    (RowsFixture *fix, gconstpointer data);
39 static void txn_rows_teardown (RowsFixture *fix, gconstpointer data);
40 
41 static void seq_rows_asv_setup   (RowsFixture *fix, gconstpointer data);
42 static void proxy_rows_asv_setup (RowsFixture *fix, gconstpointer data);
43 static void txn_rows_asv_setup   (RowsFixture *fix, gconstpointer data);
44 
45 static void test_rows_allocation (RowsFixture *fix, gconstpointer data);
46 static void test_rows_clear      (RowsFixture *fix, gconstpointer data);
47 static void test_insert_at_pos   (RowsFixture *fix, gconstpointer data);
48 static void test_insert_at_iter  (RowsFixture *fix, gconstpointer data);
49 static void test_prepend         (RowsFixture *fix, gconstpointer data);
50 static void test_append          (RowsFixture *fix, gconstpointer data);
51 static void test_get_value       (RowsFixture *fix, gconstpointer data);
52 static void test_no_transfer     (RowsFixture *fix, gconstpointer data);
53 static void test_iter_backwards  (RowsFixture *fix, gconstpointer data);
54 static void test_illegal_access  (RowsFixture *fix, gconstpointer data);
55 static void test_sorted          (RowsFixture *fix, gconstpointer data);
56 static void test_sort_stable     (RowsFixture *fix, gconstpointer data);
57 static void test_sorted_with_sizes (RowsFixture *fix, gconstpointer data);
58 static void test_named_cols_append (RowsFixture *fix, gconstpointer data);
59 static void test_named_cols_fields (RowsFixture *fix, gconstpointer data);
60 static void test_named_cols_duplicated_fields (RowsFixture *fix, gconstpointer data);
61 static void test_named_cols_error  (RowsFixture *fix, gconstpointer data);
62 
63 static void test_model_iter_copy (RowsFixture *fix, gconstpointer data);
64 static void test_model_iter_free (RowsFixture *fix, gconstpointer data);
65 
66 void
test_model_rows_create_suite(void)67 test_model_rows_create_suite (void)
68 {
69 #define ITER_DOMAIN "/ModelIter/Boxing"
70 #define SEQ_DOMAIN "/Model/Sequence/Rows"
71 #define PROXY_DOMAIN "/Model/Proxy/Rows"
72 #define TXN_DOMAIN "/Model/Transaction/Rows"
73 
74   g_test_add (ITER_DOMAIN"/Copy", RowsFixture, 0,
75               seq_rows_setup, test_model_iter_copy, seq_rows_teardown);
76   g_test_add (ITER_DOMAIN"/Free", RowsFixture, 0,
77               seq_rows_setup, test_model_iter_free, seq_rows_teardown);
78 
79   g_test_add (SEQ_DOMAIN"/Allocation", RowsFixture, 0,
80               seq_rows_setup, test_rows_allocation, seq_rows_teardown);
81   g_test_add (PROXY_DOMAIN"/Allocation", RowsFixture, 0,
82               proxy_rows_setup, test_rows_allocation, proxy_rows_teardown);
83   g_test_add (TXN_DOMAIN"/Allocation", RowsFixture, 0,
84               txn_rows_setup, test_rows_allocation, txn_rows_teardown);
85 
86   g_test_add (SEQ_DOMAIN"/Clear", RowsFixture, 0,
87               seq_rows_setup, test_rows_clear, seq_rows_teardown);
88   g_test_add (PROXY_DOMAIN"/Clear", RowsFixture, 0,
89               proxy_rows_setup, test_rows_clear, proxy_rows_teardown);
90   g_test_add (TXN_DOMAIN"/Clear", RowsFixture, 0,
91               txn_rows_setup, test_rows_clear, txn_rows_teardown);
92 
93   g_test_add (SEQ_DOMAIN"/InsertAtPos", RowsFixture, 0,
94               seq_rows_setup, test_insert_at_pos, seq_rows_teardown);
95   g_test_add (PROXY_DOMAIN"/InsertAtPos", RowsFixture, 0,
96               proxy_rows_setup, test_insert_at_pos, proxy_rows_teardown);
97   g_test_add (TXN_DOMAIN"/InsertAtPos", RowsFixture, 0,
98               txn_rows_setup, test_insert_at_pos, txn_rows_teardown);
99 
100   g_test_add (SEQ_DOMAIN"/InsertAtIter", RowsFixture, 0,
101               seq_rows_setup, test_insert_at_iter, seq_rows_teardown);
102   g_test_add (PROXY_DOMAIN"/InsertAtIter", RowsFixture, 0,
103               proxy_rows_setup, test_insert_at_iter, proxy_rows_teardown);
104   g_test_add (TXN_DOMAIN"/InsertAtIter", RowsFixture, 0,
105               txn_rows_setup, test_insert_at_iter, txn_rows_teardown);
106 
107   g_test_add (SEQ_DOMAIN"/Prepend", RowsFixture, 0,
108               seq_rows_setup, test_prepend, seq_rows_teardown);
109   g_test_add (PROXY_DOMAIN"/Prepend", RowsFixture, 0,
110               proxy_rows_setup, test_prepend, proxy_rows_teardown);
111   g_test_add (TXN_DOMAIN"/Prepend", RowsFixture, 0,
112               txn_rows_setup, test_prepend, txn_rows_teardown);
113 
114   g_test_add (SEQ_DOMAIN"/Append", RowsFixture, 0,
115               seq_rows_setup, test_append, seq_rows_teardown);
116   g_test_add (PROXY_DOMAIN"/Append", RowsFixture, 0,
117               proxy_rows_setup, test_append, proxy_rows_teardown);
118   g_test_add (TXN_DOMAIN"/Append", RowsFixture, 0,
119               txn_rows_setup, test_append, txn_rows_teardown);
120 
121   g_test_add (SEQ_DOMAIN"/GetValue", RowsFixture, 0,
122               seq_rows_setup, test_get_value, seq_rows_teardown);
123   g_test_add (PROXY_DOMAIN"/GetValue", RowsFixture, 0,
124               proxy_rows_setup, test_get_value, proxy_rows_teardown);
125   g_test_add (TXN_DOMAIN"/GetValue", RowsFixture, 0,
126               txn_rows_setup, test_get_value, txn_rows_teardown);
127 
128   g_test_add (SEQ_DOMAIN"/NoTransfer", RowsFixture, 0,
129               seq_rows_setup, test_no_transfer, seq_rows_teardown);
130   g_test_add (PROXY_DOMAIN"/NoTransfer", RowsFixture, 0,
131               proxy_rows_setup, test_no_transfer, proxy_rows_teardown);
132   g_test_add (TXN_DOMAIN"/NoTransfer", RowsFixture, 0,
133               txn_rows_setup, test_no_transfer, txn_rows_teardown);
134 
135   g_test_add (SEQ_DOMAIN"/IterBackwards", RowsFixture, 0,
136               seq_rows_setup, test_iter_backwards, seq_rows_teardown);
137   g_test_add (PROXY_DOMAIN"/IterBackwards", RowsFixture, 0,
138               proxy_rows_setup, test_iter_backwards, proxy_rows_teardown);
139   g_test_add (TXN_DOMAIN"/IterBackwards", RowsFixture, 0,
140               txn_rows_setup, test_iter_backwards, txn_rows_teardown);
141 
142   g_test_add (SEQ_DOMAIN"/IllegalAccess", RowsFixture, 0,
143               seq_rows_setup, test_illegal_access, seq_rows_teardown);
144   g_test_add (PROXY_DOMAIN"/IllegalAccess", RowsFixture, 0,
145               proxy_rows_setup, test_illegal_access, proxy_rows_teardown);
146   g_test_add (TXN_DOMAIN"/IllegalAccess", RowsFixture, 0,
147               txn_rows_setup, test_illegal_access, txn_rows_teardown);
148 
149   g_test_add (SEQ_DOMAIN"/Sorted", RowsFixture, 0,
150               seq_rows_setup, test_sorted, seq_rows_teardown);
151   g_test_add (PROXY_DOMAIN"/Sorted", RowsFixture, 0,
152               proxy_rows_setup, test_sorted, proxy_rows_teardown);
153   g_test_add (TXN_DOMAIN"/Sorted", RowsFixture, 0,
154               txn_rows_setup, test_sorted, txn_rows_teardown);
155 
156   g_test_add (SEQ_DOMAIN"/Sorted/WithSizes", RowsFixture, 0,
157               seq_rows_setup, test_sorted_with_sizes, seq_rows_teardown);
158   g_test_add (PROXY_DOMAIN"/Sorted/WithSizes", RowsFixture, 0,
159               proxy_rows_setup, test_sorted_with_sizes, proxy_rows_teardown);
160   g_test_add (TXN_DOMAIN"/Sorted/WithSizes", RowsFixture, 0,
161               txn_rows_setup, test_sorted_with_sizes, txn_rows_teardown);
162 
163   g_test_add (SEQ_DOMAIN"/StableSorted", RowsFixture, 0,
164               seq_rows_setup, test_sort_stable, seq_rows_teardown);
165   g_test_add (PROXY_DOMAIN"/StableSorted", RowsFixture, 0,
166               proxy_rows_setup, test_sort_stable, proxy_rows_teardown);
167   g_test_add (TXN_DOMAIN"/StableSorted", RowsFixture, 0,
168               txn_rows_setup, test_sort_stable, txn_rows_teardown);
169 
170   g_test_add (SEQ_DOMAIN"/NamedColumns/Append", RowsFixture, 0,
171               seq_rows_setup, test_named_cols_append, seq_rows_teardown);
172   g_test_add (PROXY_DOMAIN"/NamedColumns/Append", RowsFixture, 0,
173               proxy_rows_setup, test_named_cols_append, proxy_rows_teardown);
174   g_test_add (TXN_DOMAIN"/NamedColumns/Append", RowsFixture, 0,
175               txn_rows_setup, test_named_cols_append, txn_rows_teardown);
176 
177   g_test_add (SEQ_DOMAIN"/NamedColumns/Fields", RowsFixture, 0,
178               seq_rows_asv_setup, test_named_cols_fields, seq_rows_teardown);
179   g_test_add (PROXY_DOMAIN"/NamedColumns/Fields", RowsFixture, 0,
180               proxy_rows_asv_setup, test_named_cols_fields, proxy_rows_teardown);
181   g_test_add (TXN_DOMAIN"/NamedColumns/Fields", RowsFixture, 0,
182               txn_rows_asv_setup, test_named_cols_fields, txn_rows_teardown);
183 
184   g_test_add (SEQ_DOMAIN"/NamedColumns/DuplicatedFields", RowsFixture, 0,
185               seq_rows_asv_setup, test_named_cols_duplicated_fields, seq_rows_teardown);
186   g_test_add (PROXY_DOMAIN"/NamedColumns/DuplicatedFields", RowsFixture, 0,
187               proxy_rows_asv_setup, test_named_cols_duplicated_fields, proxy_rows_teardown);
188   g_test_add (TXN_DOMAIN"/NamedColumns/DuplicatedFields", RowsFixture, 0,
189               txn_rows_asv_setup, test_named_cols_duplicated_fields, txn_rows_teardown);
190 
191   g_test_add (SEQ_DOMAIN"/NamedColumns/Invalid", RowsFixture, 0,
192               seq_rows_setup, test_named_cols_error, seq_rows_teardown);
193   g_test_add (PROXY_DOMAIN"/NamedColumns/Invalid", RowsFixture, 0,
194               proxy_rows_setup, test_named_cols_error, proxy_rows_teardown);
195   g_test_add (TXN_DOMAIN"/NamedColumns/Invalid", RowsFixture, 0,
196               txn_rows_setup, test_named_cols_error, txn_rows_teardown);
197 }
198 
199 /* setup & teardown functions */
200 static void
seq_rows_setup(RowsFixture * fix,gconstpointer data)201 seq_rows_setup (RowsFixture *fix, gconstpointer data)
202 {
203   fix->model = dee_sequence_model_new ();
204   dee_model_set_schema (fix->model, "i", "s", NULL);
205 
206   g_assert (DEE_IS_SEQUENCE_MODEL (fix->model));
207 }
208 
209 static void
seq_rows_teardown(RowsFixture * fix,gconstpointer data)210 seq_rows_teardown (RowsFixture *fix, gconstpointer data)
211 {
212   g_object_unref (fix->model);
213   fix->model = NULL;
214 }
215 
216 static void
proxy_rows_setup(RowsFixture * fix,gconstpointer data)217 proxy_rows_setup (RowsFixture *fix, gconstpointer data)
218 {
219   seq_rows_setup (fix, data);
220   fix->model = g_object_new (DEE_TYPE_PROXY_MODEL,
221                              "back-end", fix->model,
222                              NULL);
223 
224   g_assert (DEE_IS_PROXY_MODEL (fix->model));
225 }
226 
227 static void
proxy_rows_teardown(RowsFixture * fix,gconstpointer data)228 proxy_rows_teardown (RowsFixture *fix, gconstpointer data)
229 {
230   g_object_unref (fix->model);
231   fix->model = NULL;
232 }
233 
234 static void
txn_rows_setup(RowsFixture * fix,gconstpointer data)235 txn_rows_setup (RowsFixture *fix, gconstpointer data)
236 {
237   seq_rows_setup (fix, data);
238   fix->model = dee_transaction_new (fix->model);
239 
240   g_assert (DEE_IS_TRANSACTION (fix->model));
241 }
242 
243 static void
txn_rows_teardown(RowsFixture * fix,gconstpointer data)244 txn_rows_teardown (RowsFixture *fix, gconstpointer data)
245 {
246   g_object_unref (fix->model);
247   fix->model = NULL;
248 }
249 
250 static void
seq_rows_asv_setup(RowsFixture * fix,gconstpointer data)251 seq_rows_asv_setup (RowsFixture *fix, gconstpointer data)
252 {
253   fix->model = dee_sequence_model_new ();
254   dee_model_set_schema (fix->model, "i", "s", "a{sv}", "a{sv}", NULL);
255   dee_model_set_column_names (fix->model, "count", "name",
256                               "hints", "hints2", NULL);
257 
258   g_assert (DEE_IS_SEQUENCE_MODEL (fix->model));
259 }
260 
261 static void
proxy_rows_asv_setup(RowsFixture * fix,gconstpointer data)262 proxy_rows_asv_setup (RowsFixture *fix, gconstpointer data)
263 {
264   seq_rows_asv_setup (fix, data);
265   fix->model = g_object_new (DEE_TYPE_PROXY_MODEL,
266                              "back-end", fix->model,
267                              NULL);
268 
269   g_assert (DEE_IS_PROXY_MODEL (fix->model));
270 }
271 
272 static void
txn_rows_asv_setup(RowsFixture * fix,gconstpointer data)273 txn_rows_asv_setup (RowsFixture *fix, gconstpointer data)
274 {
275   seq_rows_asv_setup (fix, data);
276   fix->model = dee_transaction_new (fix->model);
277 
278   g_assert (DEE_IS_TRANSACTION (fix->model));
279 }
280 
281 /* test cases */
test_model_iter_copy(RowsFixture * fix,gconstpointer data)282 static void test_model_iter_copy (RowsFixture *fix, gconstpointer data)
283 {
284   DeeModelIter *iter, *copied;
285 
286   iter = dee_model_append (fix->model, 10, "Rooney");
287 
288   copied = g_boxed_copy (DEE_TYPE_MODEL_ITER, iter);
289 
290   g_assert (iter == copied);
291 }
292 
test_model_iter_free(RowsFixture * fix,gconstpointer data)293 static void test_model_iter_free (RowsFixture *fix, gconstpointer data)
294 {
295   DeeModelIter *iter;
296   gint i;
297 
298   iter = dee_model_append (fix->model, 10, "Rooney");
299 
300   g_boxed_free (DEE_TYPE_MODEL_ITER, iter);
301 
302   /* And since it's supposed to be a no-op we can do this */
303   for (i = 0; i < 100; i++)
304     g_boxed_free (DEE_TYPE_MODEL_ITER, iter);
305 
306   /* Didn't crash? Good! */
307 }
308 
309 static void
test_rows_allocation(RowsFixture * fix,gconstpointer data)310 test_rows_allocation (RowsFixture *fix, gconstpointer data)
311 {
312   g_assert (DEE_IS_MODEL (fix->model));
313 }
314 
315 static gint n_clear_sigs = 0;
316 
317 static void
on_clear_row_removed(DeeModel * model,DeeModelIter * iter)318 on_clear_row_removed (DeeModel *model, DeeModelIter *iter)
319 {
320   n_clear_sigs++;
321 }
322 
323 static void
test_rows_clear(RowsFixture * fix,gconstpointer data)324 test_rows_clear (RowsFixture *fix, gconstpointer data)
325 {
326   gint i;
327 
328   for (i = 0; i < 1000; i++)
329     {
330       dee_model_append (fix->model, 10, "Rooney");
331     }
332 
333   g_assert_cmpint (1000, ==, dee_model_get_n_rows (fix->model));
334 
335   g_signal_connect (fix->model, "row-removed",
336                     G_CALLBACK (on_clear_row_removed), NULL);
337 
338   n_clear_sigs = 0;
339   dee_model_clear (fix->model);
340 
341   g_assert_cmpint (0, ==, dee_model_get_n_rows (fix->model));
342   g_assert_cmpint (1000, ==, n_clear_sigs);
343 }
344 
345 static void
test_insert_at_pos(RowsFixture * fix,gconstpointer data)346 test_insert_at_pos (RowsFixture *fix, gconstpointer data)
347 {
348   DeeModelIter *iter;
349   gint           i;
350   gchar         *str;
351 
352   dee_model_append (fix->model, 10, "Rooney");
353   dee_model_append (fix->model, 10, "Rooney");
354   g_assert_cmpint (2, ==, dee_model_get_n_rows (fix->model));
355 
356   dee_model_insert (fix->model, 1, 27, "Not Rooney");
357   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
358 
359   iter = dee_model_get_first_iter (fix->model);
360   g_assert (dee_model_is_first (fix->model, iter));
361 
362   dee_model_get (fix->model, iter, &i, &str);
363   g_assert_cmpint (10, ==, i);
364   g_assert_cmpstr (str, ==, "Rooney");
365 
366   iter = dee_model_next (fix->model, iter);
367   dee_model_get (fix->model, iter, &i, &str);
368   g_assert_cmpint (27, ==, i);
369   g_assert_cmpstr (str, ==, "Not Rooney");
370 
371   iter = dee_model_next (fix->model, iter);
372   dee_model_get (fix->model, iter, &i, &str);
373   g_assert_cmpint (10, ==, i);
374   g_assert_cmpstr (str, ==, "Rooney");
375 
376   iter = dee_model_next (fix->model, iter);
377   g_assert (dee_model_is_last (fix->model, iter));
378 }
379 
380 static void
test_insert_at_iter(RowsFixture * fix,gconstpointer data)381 test_insert_at_iter (RowsFixture *fix, gconstpointer data)
382 {
383   DeeModelIter *iter;
384   gint           i;
385   gchar         *str;
386 
387   dee_model_append (fix->model, 10, "Rooney");
388   dee_model_append (fix->model, 10, "Rooney");
389   g_assert_cmpint (2, ==, dee_model_get_n_rows (fix->model));
390 
391   iter = dee_model_get_first_iter (fix->model);
392   iter = dee_model_next (fix->model, iter);
393   dee_model_insert_before (fix->model, iter, 27, "Not Rooney");
394   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
395 
396   iter = dee_model_get_first_iter (fix->model);
397   dee_model_get (fix->model, iter, &i, &str);
398   g_assert_cmpint (10, ==, i);
399   g_assert_cmpstr (str, ==, "Rooney");
400 
401   iter = dee_model_next (fix->model, iter);
402   dee_model_get (fix->model, iter, &i, &str);
403   g_assert_cmpint (27, ==, i);
404   g_assert_cmpstr (str, ==, "Not Rooney");
405 
406   iter = dee_model_next (fix->model, iter);
407   dee_model_get (fix->model, iter, &i, &str);
408   g_assert_cmpint (10, ==, i);
409   g_assert_cmpstr (str, ==, "Rooney");
410 
411   iter = dee_model_next (fix->model, iter);
412   g_assert (dee_model_is_last (fix->model, iter));
413 }
414 
415 static void
test_prepend(RowsFixture * fix,gconstpointer data)416 test_prepend (RowsFixture *fix, gconstpointer data)
417 {
418   DeeModelIter *iter;
419   gint           i;
420   gchar         *str;
421 
422   dee_model_prepend (fix->model, 11, "Mid");
423   dee_model_append (fix->model, 12, "Last");
424   dee_model_prepend (fix->model, 10, "First");
425   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
426 
427   iter = dee_model_get_first_iter (fix->model);
428   dee_model_get (fix->model, iter, &i, &str);
429   g_assert_cmpint (10, ==, i);
430   g_assert_cmpstr (str, ==, "First");
431 
432   iter = dee_model_next (fix->model, iter);
433   dee_model_get (fix->model, iter, &i, &str);
434   g_assert_cmpint (11, ==, i);
435   g_assert_cmpstr (str, ==, "Mid");
436 
437   iter = dee_model_next (fix->model, iter);
438   dee_model_get (fix->model, iter, &i, &str);
439   g_assert_cmpint (12, ==, i);
440   g_assert_cmpstr (str, ==, "Last");
441 
442   iter = dee_model_next (fix->model, iter);
443   g_assert (dee_model_is_last (fix->model, iter));
444 }
445 
446 static void
test_append(RowsFixture * fix,gconstpointer data)447 test_append (RowsFixture *fix, gconstpointer data)
448 {
449   DeeModelIter *iter;
450   gint           i;
451   gchar         *str;
452 
453   dee_model_append (fix->model, 11, "First");
454   dee_model_append (fix->model, 12, "Mid");
455   dee_model_append (fix->model, 10, "Last");
456   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
457 
458   iter = dee_model_get_first_iter (fix->model);
459   dee_model_get (fix->model, iter, &i, &str);
460   g_assert_cmpint (11, ==, i);
461   g_assert_cmpstr (str, ==, "First");
462 
463   iter = dee_model_next (fix->model, iter);
464   dee_model_get (fix->model, iter, &i, &str);
465   g_assert_cmpint (12, ==, i);
466   g_assert_cmpstr (str, ==, "Mid");
467 
468   iter = dee_model_next (fix->model, iter);
469   dee_model_get (fix->model, iter, &i, &str);
470   g_assert_cmpint (10, ==, i);
471   g_assert_cmpstr (str, ==, "Last");
472 
473   iter = dee_model_next (fix->model, iter);
474   g_assert (dee_model_is_last (fix->model, iter));
475 }
476 
477 static void
test_get_value(RowsFixture * fix,gconstpointer data)478 test_get_value (RowsFixture *fix, gconstpointer data)
479 {
480   DeeModelIter *iter;
481   GVariant     *variant;
482 
483   dee_model_set_column_names (fix->model, "count", "name", NULL);
484 
485   dee_model_append (fix->model, 11, "First");
486   dee_model_append (fix->model, 12, "Mid");
487   dee_model_append (fix->model, 10, "Last");
488   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
489 
490   iter = dee_model_get_first_iter (fix->model);
491   variant = dee_model_get_value (fix->model, iter, 0);
492   g_assert_cmpint (g_variant_get_int32 (variant), ==, 11);
493   g_variant_unref (variant);
494 
495   iter = dee_model_next (fix->model, iter);
496   variant = dee_model_get_value (fix->model, iter, 1);
497   g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "Mid");
498   g_variant_unref (variant);
499 
500   iter = dee_model_next (fix->model, iter);
501   variant = dee_model_get_value_by_name (fix->model, iter, "count");
502   g_assert_cmpint (g_variant_get_int32 (variant), ==, 10);
503   g_variant_unref (variant);
504 
505   iter = dee_model_next (fix->model, iter);
506   g_assert (dee_model_is_last (fix->model, iter));
507 }
508 
509 static void
test_iter_backwards(RowsFixture * fix,gconstpointer data)510 test_iter_backwards (RowsFixture *fix, gconstpointer data)
511 {
512   DeeModelIter *iter;
513   gint           i;
514   gchar         *str;
515 
516   dee_model_append (fix->model, 11, "First");
517   dee_model_append (fix->model, 12, "Mid");
518   dee_model_append (fix->model, 10, "Last");
519   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
520 
521   iter = dee_model_get_last_iter (fix->model);
522   g_assert (dee_model_is_last (fix->model, iter));
523 
524   iter = dee_model_prev (fix->model, iter);
525   dee_model_get (fix->model, iter, &i, &str);
526   g_assert_cmpint (10, ==, i);
527   g_assert_cmpstr (str, ==, "Last");
528 
529   iter = dee_model_prev (fix->model, iter);
530   dee_model_get (fix->model, iter, &i, &str);
531   g_assert_cmpint (12, ==, i);
532   g_assert_cmpstr (str, ==, "Mid");
533 
534   iter = dee_model_prev (fix->model, iter);
535   dee_model_get (fix->model, iter, &i, &str);
536   g_assert_cmpint (11, ==, i);
537   g_assert_cmpstr (str, ==, "First");
538 
539   g_assert (dee_model_is_first (fix->model,   iter));
540 }
541 
542 /* Make sure the the memory allocated for strings is not reffed inside
543  * the model. Also checks that strings are returned as const pointers */
544 static void
test_no_transfer(RowsFixture * fix,gconstpointer data)545 test_no_transfer (RowsFixture *fix, gconstpointer data)
546 {
547   DeeModelIter *iter;
548   gchar         *orig, *str1, *str2;
549 
550   orig = g_strdup ("test");
551 
552   dee_model_append (fix->model, 1, orig);
553   g_assert_cmpint (1, ==, dee_model_get_n_rows (fix->model));
554 
555   /* This should work, of course */
556   iter = dee_model_get_first_iter (fix->model);
557   dee_model_get (fix->model, iter, NULL, &str1);
558   g_assert_cmpstr (str1, ==, "test");
559 
560   /* Assert that we get a const pointer to the string back.
561    * Strings should behave like that */
562   dee_model_get (fix->model, iter, NULL, &str2);
563   g_assert (str1 == str2);
564 
565   /* Modify orig in place and assert it doesn't affect the model */
566   orig[0] = 'P';
567   dee_model_get (fix->model, iter, NULL, &str1, -1);
568   g_assert_cmpstr (str1, ==, "test");
569 
570   /* Now free orig and make sure we can still read from the model */
571   g_free (orig);
572   dee_model_get (fix->model, iter, NULL, &str1, -1);
573   g_assert_cmpstr (str1, ==, "test");
574 }
575 
576 /* Try to get and set values from a removed row */
577 static void
test_illegal_access(RowsFixture * fix,gconstpointer data)578 test_illegal_access (RowsFixture *fix, gconstpointer data)
579 {
580   DeeModelIter *iter;
581 
582   dee_model_append (fix->model, 1, "Hello");
583   iter = dee_model_append (fix->model, 1, "Mary");
584   dee_model_append (fix->model, 1, "Lou");
585 
586   dee_model_remove (fix->model, iter);
587 
588   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
589     {
590       g_assert_cmpstr (dee_model_get_string (fix->model, iter, 1), ==, "Mary");
591       exit (0); /* successful test run */
592     }
593   g_test_trap_assert_failed ();
594 
595   if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
596     {
597       dee_model_set (fix->model, iter, 27, "Marie");
598       exit (0); /* successful test run */
599     }
600   g_test_trap_assert_failed ();
601 }
602 
603 static gint
cmp_constant(GVariant ** row1,GVariant ** row2,gpointer user_data)604 cmp_constant (GVariant **row1, GVariant **row2, gpointer user_data)
605 {
606   g_assert_cmpstr (user_data, ==, "test-user-data");
607   return 0;
608 }
609 
610 static gint
cmp_col_0(GVariant ** row1,GVariant ** row2,gpointer user_data)611 cmp_col_0 (GVariant **row1, GVariant **row2, gpointer user_data)
612 {
613   g_assert_cmpstr (user_data, ==, "test-user-data");
614   //g_debug ("CMP %i %i", g_variant_get_int32 (row1[0]), g_variant_get_int32 (row2[0]));
615   return g_variant_get_int32 (row2[0]) - g_variant_get_int32 (row1[0]);
616 }
617 
618 static void
test_sorted(RowsFixture * fix,gconstpointer data)619 test_sorted (RowsFixture *fix, gconstpointer data)
620 {
621   DeeModelIter *hter, *iter, *jter, *kter;
622   gboolean      was_found;
623 
624   /* FINAL MODEL: [(28,s), (27,s), (26,s), (25,s)]
625    *           ~= [hter, iter, jter, kter] */
626 
627   /* Test find() with an empty model. With NULL was_found arg */
628   iter = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", NULL,
629                                 0, "");
630   g_assert (iter == dee_model_get_last_iter (fix->model));
631 
632   /* Test find() with an empty model. With non-NULL was_found arg */
633   was_found = TRUE;
634   iter = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", &was_found,
635                                 0, "");
636   g_assert (!was_found);
637   g_assert (iter == dee_model_get_last_iter (fix->model));
638 
639   /* Insert the first row */
640   iter = dee_model_insert_sorted (fix->model, cmp_col_0, "test-user-data",
641                                   27, "Sorta sorted");
642   g_assert (iter != dee_model_get_last_iter (fix->model));
643   g_assert (iter == dee_model_get_first_iter (fix->model));
644 
645   /* Test append */
646   kter = dee_model_insert_sorted (fix->model, cmp_col_0, "test-user-data",
647                                   25, "Sorta sorted");
648   g_assert (kter != dee_model_get_last_iter (fix->model));
649   g_assert (kter != dee_model_get_first_iter (fix->model));
650   g_assert (iter == dee_model_get_first_iter (fix->model));
651   g_assert (kter != iter);
652 
653   g_assert_cmpint (2, ==, dee_model_get_n_rows (fix->model));
654   g_assert (kter == dee_model_next (fix->model, iter));
655 
656   /* Test insert in between rows */
657   jter = dee_model_insert_sorted (fix->model, cmp_col_0, "test-user-data",
658                                   26, "Sorta sorted");
659   g_assert (jter != dee_model_get_last_iter (fix->model));
660   g_assert (jter != dee_model_get_first_iter (fix->model));
661   g_assert (iter == dee_model_get_first_iter (fix->model));
662   g_assert (jter != iter);
663   g_assert (jter != kter);
664 
665   g_assert (jter == dee_model_next (fix->model, iter));
666   g_assert (kter == dee_model_next (fix->model, jter));
667   g_assert (dee_model_get_last_iter (fix->model) == dee_model_next (fix->model, kter));
668 
669   /* Test prepend */
670   hter = dee_model_insert_sorted (fix->model, cmp_col_0, "test-user-data",
671                                   28, "Sorta sorted");
672   g_assert (hter == dee_model_get_first_iter (fix->model));
673   g_assert (iter == dee_model_next (fix->model, hter));
674 
675   g_assert_cmpint (4, ==, dee_model_get_n_rows (fix->model));
676 
677   /* Test find() again now that we have data in the model */
678   DeeModelIter *result;
679   result = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", NULL,
680                                   24, "");
681   g_assert (result == dee_model_get_last_iter (fix->model));
682   result = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", NULL,
683                                   28, "");
684   g_assert (result == hter);
685 
686   /* Test find(). With non-NULL was_found arg */
687   was_found = TRUE;
688   result = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", &was_found,
689                                   24, "");
690   g_assert (result == dee_model_get_last_iter (fix->model));
691   result = dee_model_find_sorted (fix->model, cmp_col_0, "test-user-data", &was_found,
692                                   28, "");
693   g_assert (was_found);
694   g_assert (result == hter);
695 }
696 
697 static void
test_sort_stable(RowsFixture * fix,gconstpointer data)698 test_sort_stable (RowsFixture *fix, gconstpointer data)
699 {
700   DeeModelIter *hter, *iter, *jter, *kter;
701 
702   /* FINAL MODEL: [(25,s), (26,s), (27,s), (28,s)]
703    *           ~= [hter, iter, jter, kter] */
704 
705   /* Insert the first row */
706   iter = dee_model_insert_sorted (fix->model, cmp_constant, "test-user-data",
707                                   25, "Stable");
708   g_assert (iter != dee_model_get_last_iter (fix->model));
709   g_assert (iter == dee_model_get_first_iter (fix->model));
710 
711   /* Second row */
712   kter = dee_model_insert_sorted (fix->model, cmp_constant, "test-user-data",
713                                   26, "Stable");
714   g_assert (kter != dee_model_get_last_iter (fix->model));
715   g_assert (kter != dee_model_get_first_iter (fix->model));
716   g_assert (iter == dee_model_get_first_iter (fix->model));
717   g_assert (kter != iter);
718 
719   g_assert_cmpint (2, ==, dee_model_get_n_rows (fix->model));
720   g_assert (kter == dee_model_next (fix->model, iter));
721 
722   /* Third row */
723   jter = dee_model_insert_sorted (fix->model, cmp_constant, "test-user-data",
724                                   27, "Stable");
725   g_assert (jter != dee_model_get_last_iter (fix->model));
726   g_assert (jter != dee_model_get_first_iter (fix->model));
727   g_assert (iter == dee_model_get_first_iter (fix->model));
728   g_assert (jter != iter);
729   g_assert (jter != kter);
730 
731   g_assert (jter == dee_model_next (fix->model, kter));
732   g_assert (dee_model_get_last_iter (fix->model) == dee_model_next (fix->model, jter));
733 
734   /* Fourth row */
735   hter = dee_model_insert_sorted (fix->model, cmp_constant, "test-user-data",
736                                   28, "Stable");
737   g_assert (hter == dee_model_next (fix->model, jter));
738 
739   g_assert_cmpint (4, ==, dee_model_get_n_rows (fix->model));
740 }
741 
742 static gint
sized_cmp_col_0(GVariant ** row1,guint row1_length,GVariant ** row2,guint row2_length,gpointer user_data)743 sized_cmp_col_0 (GVariant **row1, guint row1_length,
744                  GVariant **row2, guint row2_length, gpointer user_data)
745 {
746   g_assert_cmpstr (user_data, ==, "test-user-data");
747   g_assert_cmpuint (row1_length, ==, 2);
748   g_assert_cmpuint (row2_length, ==, 2);
749   g_assert_cmpuint (row1_length, ==, row2_length);
750   return g_variant_get_int32 (row2[0]) - g_variant_get_int32 (row1[0]);
751 }
752 
753 static void
test_sorted_with_sizes(RowsFixture * fix,gconstpointer data)754 test_sorted_with_sizes (RowsFixture *fix, gconstpointer data)
755 {
756   DeeModelIter *hter, *iter, *jter, *kter;
757   gboolean      was_found;
758   GVariant     *row_spec[2];
759 
760   /* FINAL MODEL: [(28,s), (27,s), (26,s), (25,s)]
761    *           ~= [hter, iter, jter, kter] */
762 
763   row_spec[0] = g_variant_new_int32 (0);
764   row_spec[1] = g_variant_new_string ("");
765   /* Test find() with an empty model. With NULL was_found arg */
766   iter = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
767                                                sized_cmp_col_0,
768                                                "test-user-data",
769                                                NULL);
770   g_assert (iter == dee_model_get_last_iter (fix->model));
771 
772   /* Test find() with an empty model. With non-NULL was_found arg */
773   was_found = TRUE;
774   iter = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
775                                                sized_cmp_col_0,
776                                                "test-user-data",
777                                                &was_found);
778   g_assert (!was_found);
779   g_assert (iter == dee_model_get_last_iter (fix->model));
780 
781   /* Insert the first row */
782   row_spec[0] = g_variant_new_int32 (27);
783   row_spec[1] = g_variant_new_string ("Sorta sorted");
784   iter = dee_model_insert_row_sorted_with_sizes (fix->model, row_spec,
785                                                  sized_cmp_col_0,
786                                                  "test-user-data");
787   g_assert (iter != dee_model_get_last_iter (fix->model));
788   g_assert (iter == dee_model_get_first_iter (fix->model));
789 
790   /* Test append */
791   row_spec[0] = g_variant_new_int32 (25);
792   row_spec[1] = g_variant_new_string ("Sorta sorted");
793   kter = dee_model_insert_row_sorted_with_sizes (fix->model, row_spec,
794                                                  sized_cmp_col_0,
795                                                  "test-user-data");
796   g_assert (kter != dee_model_get_last_iter (fix->model));
797   g_assert (kter != dee_model_get_first_iter (fix->model));
798   g_assert (iter == dee_model_get_first_iter (fix->model));
799   g_assert (kter != iter);
800 
801   g_assert_cmpint (2, ==, dee_model_get_n_rows (fix->model));
802   g_assert (kter == dee_model_next (fix->model, iter));
803 
804   /* Test insert in between rows */
805   row_spec[0] = g_variant_new_int32 (26);
806   row_spec[1] = g_variant_new_string ("Sorta sorted");
807   jter = dee_model_insert_row_sorted_with_sizes (fix->model, row_spec,
808                                                  sized_cmp_col_0,
809                                                  "test-user-data");
810   g_assert (jter != dee_model_get_last_iter (fix->model));
811   g_assert (jter != dee_model_get_first_iter (fix->model));
812   g_assert (iter == dee_model_get_first_iter (fix->model));
813   g_assert (jter != iter);
814   g_assert (jter != kter);
815 
816   g_assert (jter == dee_model_next (fix->model, iter));
817   g_assert (kter == dee_model_next (fix->model, jter));
818   g_assert (dee_model_get_last_iter (fix->model) == dee_model_next (fix->model, kter));
819 
820   /* Test prepend */
821   row_spec[0] = g_variant_new_int32 (28);
822   row_spec[1] = g_variant_new_string ("Sorta sorted");
823   hter = dee_model_insert_row_sorted_with_sizes (fix->model, row_spec,
824                                                  sized_cmp_col_0,
825                                                  "test-user-data");
826   g_assert (hter == dee_model_get_first_iter (fix->model));
827   g_assert (iter == dee_model_next (fix->model, hter));
828 
829   g_assert_cmpint (4, ==, dee_model_get_n_rows (fix->model));
830 
831   /* Test find() again now that we have data in the model */
832   DeeModelIter *result;
833   row_spec[0] = g_variant_new_int32 (24);
834   row_spec[1] = g_variant_new_string ("");
835   result = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
836                                                  sized_cmp_col_0,
837                                                  "test-user-data", NULL);
838   g_assert (result == dee_model_get_last_iter (fix->model));
839   row_spec[0] = g_variant_new_int32 (28);
840   row_spec[1] = g_variant_new_string ("");
841   result = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
842                                                  sized_cmp_col_0,
843                                                  "test-user-data", NULL);
844   g_assert (result == hter);
845 
846   /* Test find(). With non-NULL was_found arg */
847   was_found = FALSE;
848   row_spec[0] = g_variant_new_int32 (24);
849   row_spec[1] = g_variant_new_string ("");
850   result = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
851                                                  sized_cmp_col_0,
852                                                  "test-user-data", &was_found);
853   g_assert (result == dee_model_get_last_iter (fix->model));
854   row_spec[0] = g_variant_new_int32 (28);
855   row_spec[1] = g_variant_new_string ("");
856   result = dee_model_find_row_sorted_with_sizes (fix->model, row_spec,
857                                                  sized_cmp_col_0,
858                                                  "test-user-data", &was_found);
859   g_assert (was_found);
860   g_assert (result == hter);
861 }
862 
863 static void
test_named_cols_append(RowsFixture * fix,gconstpointer data)864 test_named_cols_append (RowsFixture *fix, gconstpointer data)
865 {
866   DeeModelIter *iter;
867   gint          i;
868   gchar        *str;
869   GVariant     *row_members[2];
870 
871   dee_model_set_column_names (fix->model, "count", "name", NULL);
872 
873   dee_model_build_named_row (fix->model, row_members,
874                              "count", 11, "name", "First", NULL);
875   dee_model_append_row (fix->model, row_members);
876   dee_model_build_named_row (fix->model, row_members,
877                              "name", "Mid", "count", 12, NULL);
878   dee_model_append_row (fix->model, row_members);
879   dee_model_build_named_row (fix->model, row_members,
880                              "count", 10, "name", "Last", NULL);
881   dee_model_append_row (fix->model, row_members);
882   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
883 
884   iter = dee_model_get_first_iter (fix->model);
885   dee_model_get (fix->model, iter, &i, &str);
886   g_assert_cmpint (11, ==, i);
887   g_assert_cmpstr (str, ==, "First");
888 
889   iter = dee_model_next (fix->model, iter);
890   dee_model_get (fix->model, iter, &i, &str);
891   g_assert_cmpint (12, ==, i);
892   g_assert_cmpstr (str, ==, "Mid");
893 
894   iter = dee_model_next (fix->model, iter);
895   dee_model_get (fix->model, iter, &i, &str);
896   g_assert_cmpint (10, ==, i);
897   g_assert_cmpstr (str, ==, "Last");
898 
899   iter = dee_model_next (fix->model, iter);
900   g_assert (dee_model_is_last (fix->model, iter));
901 }
902 
903 static void
test_named_cols_fields(RowsFixture * fix,gconstpointer data)904 test_named_cols_fields (RowsFixture *fix, gconstpointer data)
905 {
906   DeeModelIter *iter;
907   gint          i;
908   gchar        *str;
909   GVariant     *row_members[4];
910   GVariant     *dict, *dummy;
911   GHashTable   *fields_schemas;
912 
913   fields_schemas = g_hash_table_new (g_str_hash, g_str_equal);
914   g_hash_table_insert (fields_schemas, "object-path", "o");
915   g_hash_table_insert (fields_schemas, "id", "i");
916 
917   dee_model_register_vardict_schema (fix->model, 2, fields_schemas);
918   g_hash_table_unref (fields_schemas);
919 
920   dee_model_build_named_row (fix->model, row_members,
921                              "count", 11, "name", "First", NULL);
922   dee_model_append_row (fix->model, row_members);
923   dee_model_build_named_row (fix->model, row_members,
924                              "name", "Mid", "count", 12,
925                              "object-path", "/org/example",
926                              "hints::id", 8123, NULL);
927   dee_model_append_row (fix->model, row_members);
928   dee_model_build_named_row (fix->model, row_members,
929                              "count", 10, "name", "Last", "id", 90, NULL);
930   dee_model_append_row (fix->model, row_members);
931 
932   /* Commence checks */
933   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
934 
935   iter = dee_model_get_first_iter (fix->model);
936   dee_model_get (fix->model, iter, &i, &str, &dict, &dummy);
937   g_assert_cmpint (11, ==, i);
938   g_assert_cmpstr (str, ==, "First");
939   g_assert_cmpuint (0, ==, g_variant_n_children (dict));
940   g_assert (dee_model_get_value_by_name (fix->model, iter, "object-path") == NULL);
941 
942   iter = dee_model_next (fix->model, iter);
943   dee_model_get (fix->model, iter, &i, &str, &dict, &dummy);
944   g_assert_cmpint (12, ==, i);
945   g_assert_cmpstr (str, ==, "Mid");
946   g_assert_cmpuint (2, ==, g_variant_n_children (dict));
947   g_assert_cmpstr ("/org/example", ==, g_variant_get_string (g_variant_lookup_value (dict, "object-path", G_VARIANT_TYPE_OBJECT_PATH), NULL));
948   g_assert_cmpint (8123, ==, g_variant_get_int32 (dee_model_get_value_by_name (fix->model, iter, "id")));
949 
950   iter = dee_model_next (fix->model, iter);
951   dee_model_get (fix->model, iter, &i, &str, &dict, &dummy);
952   g_assert_cmpint (10, ==, i);
953   g_assert_cmpstr (str, ==, "Last");
954   g_assert_cmpuint (1, ==, g_variant_n_children (dict));
955   g_assert_cmpint (90, ==, g_variant_get_int32 (dee_model_get_value_by_name (fix->model, iter, "id")));
956 
957   iter = dee_model_next (fix->model, iter);
958   g_assert (dee_model_is_last (fix->model, iter));
959 }
960 
961 static gboolean
expected_error_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * msg,gpointer user_data)962 expected_error_handler (const gchar *log_domain, GLogLevelFlags log_level,
963                         const gchar *msg, gpointer user_data)
964 {
965   return FALSE;
966 }
967 
968 static void
ignore_error_handler(const gchar * log_domain,GLogLevelFlags log_level,const gchar * msg,gpointer user_data)969 ignore_error_handler (const gchar *log_domain, GLogLevelFlags log_level,
970                       const gchar *msg, gpointer user_data)
971 {
972 }
973 
974 static void
test_named_cols_duplicated_fields(RowsFixture * fix,gconstpointer data)975 test_named_cols_duplicated_fields (RowsFixture *fix, gconstpointer data)
976 {
977   DeeModelIter *iter;
978   gint          i;
979   guint         handler_id;
980   gchar        *str;
981   GVariant     *row_members[4];
982   GVariant     *dict1, *dict2;
983   GHashTable   *fields_schemas;
984 
985   g_test_log_set_fatal_handler (expected_error_handler, NULL);
986   handler_id = g_log_set_handler ("dee", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
987                                   ignore_error_handler, NULL);
988 
989   fields_schemas = g_hash_table_new (g_str_hash, g_str_equal);
990   g_hash_table_insert (fields_schemas, "id", "i");
991 
992   dee_model_register_vardict_schema (fix->model, 2, fields_schemas);
993 
994   g_hash_table_insert (fields_schemas, "id", "s");
995   g_hash_table_insert (fields_schemas, "extra-id", "i");
996   dee_model_register_vardict_schema (fix->model, 3, fields_schemas);
997   g_hash_table_unref (fields_schemas);
998 
999   dee_model_build_named_row (fix->model, row_members,
1000                              "count", 11, "name", "First", NULL);
1001   dee_model_append_row (fix->model, row_members);
1002   dee_model_build_named_row (fix->model, row_members,
1003                              "name", "Mid", "count", 12,
1004                              "hints::id", 8123,
1005                              "hints2::id", "8123", NULL);
1006   dee_model_append_row (fix->model, row_members);
1007   dee_model_build_named_row (fix->model, row_members,
1008                              "count", 10, "name", "Last",
1009                              "hints2::id", "foo", NULL);
1010   dee_model_append_row (fix->model, row_members);
1011 
1012   /* Commence checks */
1013   g_assert_cmpint (3, ==, dee_model_get_n_rows (fix->model));
1014 
1015   iter = dee_model_get_first_iter (fix->model);
1016   dee_model_get (fix->model, iter, &i, &str, &dict1, &dict2);
1017   g_assert_cmpint (11, ==, i);
1018   g_assert_cmpstr (str, ==, "First");
1019   g_assert_cmpuint (0, ==, g_variant_n_children (dict1));
1020   g_assert_cmpuint (0, ==, g_variant_n_children (dict2));
1021   g_assert (dee_model_get_value_by_name (fix->model, iter, "hints::id") == NULL);
1022 
1023   iter = dee_model_next (fix->model, iter);
1024   dee_model_get (fix->model, iter, &i, &str, &dict1, &dict2);
1025   g_assert_cmpint (12, ==, i);
1026   g_assert_cmpstr (str, ==, "Mid");
1027   g_assert_cmpuint (1, ==, g_variant_n_children (dict1));
1028   g_assert_cmpuint (1, ==, g_variant_n_children (dict2));
1029   g_assert_cmpint (8123, ==, g_variant_get_int32 (dee_model_get_value_by_name (fix->model, iter, "hints::id")));
1030   g_assert_cmpstr ("8123", ==, g_variant_get_string (dee_model_get_value_by_name (fix->model, iter, "hints2::id"), NULL));
1031 
1032   iter = dee_model_next (fix->model, iter);
1033   dee_model_get (fix->model, iter, &i, &str, &dict1, &dict2);
1034   g_assert_cmpint (10, ==, i);
1035   g_assert_cmpstr (str, ==, "Last");
1036   g_assert_cmpuint (0, ==, g_variant_n_children (dict1));
1037   g_assert_cmpuint (1, ==, g_variant_n_children (dict2));
1038   g_assert_cmpstr ("foo", ==, g_variant_get_string (dee_model_get_value_by_name (fix->model, iter, "hints2::id"), NULL));
1039 
1040   iter = dee_model_next (fix->model, iter);
1041   g_assert (dee_model_is_last (fix->model, iter));
1042 
1043   g_log_remove_handler ("dee", handler_id);
1044 }
1045 
1046 static void
test_named_cols_error(RowsFixture * fix,gconstpointer data)1047 test_named_cols_error (RowsFixture *fix, gconstpointer data)
1048 {
1049   GVariant     *row_members[2];
1050   GVariant    **result;
1051   guint         handler_id;
1052 
1053   dee_model_set_column_names (fix->model, "count", "name", NULL);
1054 
1055   g_test_log_set_fatal_handler (expected_error_handler, NULL);
1056   handler_id = g_log_set_handler ("dee", G_LOG_LEVEL_CRITICAL |
1057                                   G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL,
1058                                   ignore_error_handler, NULL);
1059 
1060   /* Only first col set */
1061   result = dee_model_build_named_row (fix->model, row_members,
1062                                       "name", "First", NULL);
1063   g_assert (result == NULL);
1064 
1065   /* Only second col set */
1066   result = dee_model_build_named_row (fix->model, row_members,
1067                                       "count", 12, NULL);
1068   g_assert (result == NULL);
1069 
1070   /* Unregistered cols set */
1071   result = dee_model_build_named_row (fix->model, row_members,
1072                                       "nm", "Foo", "cnt", 12, NULL);
1073   g_assert (result == NULL);
1074 
1075   g_log_remove_handler ("dee", handler_id);
1076 }
1077 
1078