No issues found
Tool | Failure ID | Location | Function | Message | Data |
---|---|---|---|---|---|
clang-analyzer | no-output-found | test-rhythmdb-property-model.c | Message(text='Unable to locate XML output from invoke-clang-analyzer') | None |
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * The Rhythmbox authors hereby grant permission for non-GPL compatible
9 * GStreamer plugins to be used and distributed together with GStreamer
10 * and Rhythmbox. This permission is above and beyond the permissions granted
11 * by the GPL license by which Rhythmbox is covered. If you modify this code
12 * you may extend this exception to your version of the code, but you are not
13 * obligated to do so. If you do not wish to do so, delete this exception
14 * statement from your version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24 *
25 */
26
27
28 #include "config.h"
29
30 #include <check.h>
31 #include <gtk/gtk.h>
32 #include <locale.h>
33 #include "test-utils.h"
34 #include "rhythmdb-query-model.h"
35 #include "rhythmdb-property-model.h"
36
37 #include "rb-debug.h"
38 #include "rb-file-helpers.h"
39 #include "rb-util.h"
40
41 static int
42 _get_property_count (RhythmDBPropertyModel *model, const char *artist)
43 {
44 GtkTreeIter iter;
45 int count;
46
47 if (rhythmdb_property_model_iter_from_string (model, artist, &iter) == FALSE) {
48 return 0;
49 }
50
51 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
52 RHYTHMDB_PROPERTY_MODEL_COLUMN_NUMBER, &count, -1);
53 return count;
54 }
55
56 /* tests property models attached to static query models */
57 START_TEST (test_rhythmdb_property_model_static)
58 {
59 RhythmDBQueryModel *model;
60 RhythmDBQueryModel *model2;
61 RhythmDBPropertyModel *propmodel;
62 RhythmDBEntry *a, *b;
63 GtkTreeIter iter;
64
65 start_test_case ();
66
67 /* setup */
68 model = rhythmdb_query_model_new_empty (db);
69 g_object_set (model, "show-hidden", FALSE, NULL);
70 propmodel = rhythmdb_property_model_new (db, RHYTHMDB_PROP_ARTIST);
71 g_object_set (propmodel, "query-model", model, NULL);
72
73 /* create test entries */
74 a = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///a.ogg");
75 b = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///b.ogg");
76 rhythmdb_commit (db);
77
78 /* set artist values */
79 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "x");
80 set_entry_string (db, b, RHYTHMDB_PROP_ARTIST, "y");
81 rhythmdb_commit (db);
82
83 end_step ();
84
85 /* add to model */
86 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
87 rhythmdb_query_model_add_entry (model, a, -1);
88 wait_for_signal ();
89 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
90 rhythmdb_query_model_add_entry (model, b, -1);
91 wait_for_signal ();
92 fail_unless (rhythmdb_query_model_entry_to_iter (model, a, &iter));
93 fail_unless (rhythmdb_query_model_entry_to_iter (model, b, &iter));
94 /*fail_unless (_get_property_count (propmodel, _("All")) == 2);*/
95 fail_unless (_get_property_count (propmodel, "x") == 1);
96 fail_unless (_get_property_count (propmodel, "y") == 1);
97
98 end_step ();
99
100 /* change one */
101 set_waiting_signal (G_OBJECT (propmodel), "row-deleted");
102 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "y");
103 rhythmdb_commit (db);
104 wait_for_signal ();
105 fail_unless (_get_property_count (propmodel, "x") == 0);
106 fail_unless (_get_property_count (propmodel, "y") == 2);
107
108 end_step ();
109
110 /* hide it */
111 set_waiting_signal (G_OBJECT (model), "entry-prop-changed");
112 set_entry_hidden (db, a, TRUE);
113 rhythmdb_commit (db);
114 wait_for_signal ();
115 /*fail_unless (_get_property_count (propmodel, _("All")) == 1);*/
116 fail_unless (_get_property_count (propmodel, "x") == 0);
117 fail_unless (_get_property_count (propmodel, "y") == 1);
118
119 end_step ();
120
121 /* change back */
122 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "x");
123 rhythmdb_commit (db);
124 fail_unless (_get_property_count (propmodel, "x") == 0);
125 fail_unless (_get_property_count (propmodel, "y") == 1);
126
127 end_step ();
128
129 /* unhide */
130 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
131 set_entry_hidden (db, a, FALSE);
132 rhythmdb_commit (db);
133 wait_for_signal ();
134
135 /*fail_unless (_get_property_count (propmodel, _("All")) == 2);*/
136 fail_unless (_get_property_count (propmodel, "x") == 1);
137 fail_unless (_get_property_count (propmodel, "y") == 1);
138
139 end_step ();
140
141 /* remove one */
142 set_waiting_signal (G_OBJECT (propmodel), "pre-row-deletion");
143 rhythmdb_query_model_remove_entry (model, a);
144 wait_for_signal ();
145 /*fail_unless (_get_property_count (propmodel, _("All")) == 1);*/
146 fail_unless (_get_property_count (propmodel, "x") == 0);
147 fail_unless (_get_property_count (propmodel, "y") == 1);
148
149 end_step ();
150
151 /* switch model */
152 model2 = rhythmdb_query_model_new_empty (db);
153 g_object_set (model2, "show-hidden", FALSE, NULL);
154 rhythmdb_query_model_add_entry (model2, a, -1);
155 rhythmdb_query_model_add_entry (model2, b, -1);
156 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
157 g_object_set (propmodel, "query-model", model2, NULL);
158 wait_for_signal ();
159
160 fail_unless (_get_property_count (propmodel, "x") == 1);
161 fail_unless (_get_property_count (propmodel, "y") == 1);
162
163 end_step ();
164
165 /* delete an entry */
166 set_waiting_signal (G_OBJECT (db), "entry_deleted");
167 rhythmdb_entry_delete (db, a);
168 rhythmdb_commit (db);
169 wait_for_signal ();
170 fail_unless (_get_property_count (propmodel, "x") == 0);
171 fail_unless (_get_property_count (propmodel, "y") == 1);
172
173 end_step ();
174
175 /* and the other */
176 set_waiting_signal (G_OBJECT (propmodel), "row-deleted");
177 rhythmdb_entry_delete (db, b);
178 rhythmdb_commit (db);
179 wait_for_signal ();
180 fail_unless (_get_property_count (propmodel, "x") == 0);
181 fail_unless (_get_property_count (propmodel, "y") == 0);
182
183 end_test_case ();
184
185 g_object_unref (model);
186 g_object_unref (model2);
187 g_object_unref (propmodel);
188 }
189 END_TEST
190
191 /* tests property models attached to query models with an actual query */
192 START_TEST (test_rhythmdb_property_model_query)
193 {
194 RhythmDBQueryModel *model;
195 RhythmDBQueryModel *model2;
196 RhythmDBPropertyModel *propmodel;
197 RhythmDBEntry *a, *b;
198 GPtrArray *query;
199
200 start_test_case ();
201
202 /* setup */
203 query = rhythmdb_query_parse (db,
204 RHYTHMDB_QUERY_PROP_EQUALS,
205 RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
206 RHYTHMDB_QUERY_PROP_LIKE,
207 RHYTHMDB_PROP_ARTIST, "x",
208 RHYTHMDB_QUERY_END);
209
210 model = rhythmdb_query_model_new (db, query, (GCompareDataFunc)rhythmdb_query_model_location_sort_func, NULL, NULL, FALSE);
211 rhythmdb_query_free (query);
212
213 query = rhythmdb_query_parse (db,
214 RHYTHMDB_QUERY_PROP_EQUALS,
215 RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
216 RHYTHMDB_QUERY_PROP_LIKE,
217 RHYTHMDB_PROP_ARTIST, "y",
218 RHYTHMDB_QUERY_END);
219 model2 = rhythmdb_query_model_new (db, query, (GCompareDataFunc)rhythmdb_query_model_location_sort_func, NULL, NULL, FALSE);
220 rhythmdb_query_free (query);
221
222
223 propmodel = rhythmdb_property_model_new (db, RHYTHMDB_PROP_ARTIST);
224 g_object_set (propmodel, "query-model", model, NULL);
225
226 end_step ();
227
228 /* create test entries */
229 set_waiting_signal (G_OBJECT (db), "entry_added");
230 a = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///a.ogg");
231 b = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///b.ogg");
232 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "x");
233 set_entry_string (db, b, RHYTHMDB_PROP_ARTIST, "y");
234 rhythmdb_commit (db);
235 wait_for_signal ();
236
237 fail_unless (_get_property_count (propmodel, "x") == 1);
238 fail_unless (_get_property_count (propmodel, "y") == 0);
239
240 end_step ();
241
242 /* change b so it matches the query */
243 set_waiting_signal (G_OBJECT (db), "entry-changed");
244 set_entry_string (db, b, RHYTHMDB_PROP_ARTIST, "x");
245 rhythmdb_commit (db);
246 wait_for_signal ();
247 fail_unless (_get_property_count (propmodel, "x") == 2);
248 fail_unless (_get_property_count (propmodel, "y") == 0);
249
250 end_step ();
251
252 /* change b again */
253 set_waiting_signal (G_OBJECT (db), "entry-changed");
254 set_entry_string (db, b, RHYTHMDB_PROP_ARTIST, "xx");
255 rhythmdb_commit (db);
256 wait_for_signal ();
257 fail_unless (_get_property_count (propmodel, "x") == 1);
258 fail_unless (_get_property_count (propmodel, "xx") == 1);
259 fail_unless (_get_property_count (propmodel, "y") == 0);
260
261 end_step ();
262
263 /* hide a */
264 set_waiting_signal (G_OBJECT (db), "entry-changed");
265 set_entry_hidden (db, a, TRUE);
266 rhythmdb_commit (db);
267 wait_for_signal ();
268 fail_unless (_get_property_count (propmodel, "x") == 0);
269 fail_unless (_get_property_count (propmodel, "xx") == 1);
270
271 end_step ();
272
273 /* change a */
274 set_waiting_signal (G_OBJECT (db), "entry-changed");
275 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "xx");
276 rhythmdb_commit (db);
277 wait_for_signal ();
278 fail_unless (_get_property_count (propmodel, "x") == 0);
279 fail_unless (_get_property_count (propmodel, "xx") == 1);
280
281 end_step ();
282
283 /* unhide a */
284 set_waiting_signal (G_OBJECT (db), "entry-changed");
285 set_entry_hidden (db, a, FALSE);
286 rhythmdb_commit (db);
287 wait_for_signal ();
288 fail_unless (_get_property_count (propmodel, "x") == 0);
289 fail_unless (_get_property_count (propmodel, "xx") == 2);
290
291 end_step ();
292
293 /* change a -> y */
294 set_waiting_signal (G_OBJECT (db), "entry-changed");
295 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "y");
296 rhythmdb_commit (db);
297 wait_for_signal ();
298 fail_unless (_get_property_count (propmodel, "x") == 0);
299 fail_unless (_get_property_count (propmodel, "xx") == 1);
300 fail_unless (_get_property_count (propmodel, "y") == 0);
301
302 end_step ();
303
304 /* switch to model2 */
305 g_object_set (propmodel, "query-model", model2, NULL);
306 fail_unless (_get_property_count (propmodel, "x") == 0);
307 fail_unless (_get_property_count (propmodel, "y") == 1);
308 fail_unless (_get_property_count (propmodel, "xx") == 0);
309
310 end_step ();
311
312 /* change a -> x */
313 set_waiting_signal (G_OBJECT (db), "entry-changed");
314 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "x");
315 rhythmdb_commit (db);
316 wait_for_signal ();
317 fail_unless (_get_property_count (propmodel, "x") == 0);
318 fail_unless (_get_property_count (propmodel, "xx") == 0);
319 fail_unless (_get_property_count (propmodel, "y") == 0);
320
321 end_step ();
322
323 rhythmdb_entry_delete (db, a);
324 rhythmdb_entry_delete (db, b);
325 rhythmdb_commit (db);
326
327 end_test_case ();
328
329 g_object_unref (model);
330 g_object_unref (model2);
331 g_object_unref (propmodel);
332 }
333 END_TEST
334
335 /* tests property models attached to chained query models */
336 START_TEST (test_rhythmdb_property_model_query_chain)
337 {
338 RhythmDBQueryModel *base_model;
339 RhythmDBQueryModel *model;
340 RhythmDBPropertyModel *propmodel;
341 RhythmDBQuery *query;
342 RhythmDBEntry *a, *b;
343
344 start_test_case ();
345
346 /* setup */
347 query = rhythmdb_query_parse (db,
348 RHYTHMDB_QUERY_PROP_EQUALS,
349 RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
350 RHYTHMDB_QUERY_PROP_LIKE,
351 RHYTHMDB_PROP_SEARCH_MATCH, "y",
352 RHYTHMDB_QUERY_END);
353
354 base_model = rhythmdb_query_model_new (db, query, (GCompareDataFunc)rhythmdb_query_model_location_sort_func, NULL, NULL, FALSE);
355 rhythmdb_query_free (query);
356
357 query = rhythmdb_query_parse (db,
358 RHYTHMDB_QUERY_PROP_EQUALS,
359 RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
360 RHYTHMDB_QUERY_PROP_EQUALS,
361 RHYTHMDB_PROP_TRACK_NUMBER, 1,
362 RHYTHMDB_QUERY_END);
363 model = rhythmdb_query_model_new (db, query, (GCompareDataFunc)rhythmdb_query_model_location_sort_func, NULL, NULL, FALSE);
364 rhythmdb_query_free (query);
365
366 rhythmdb_query_model_chain (model, base_model, TRUE);
367
368 propmodel = rhythmdb_property_model_new (db, RHYTHMDB_PROP_ALBUM);
369 g_object_set (propmodel, "query-model", model, NULL);
370
371 /* create test entries */
372 set_waiting_signal (G_OBJECT (db), "entry_added");
373 a = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///a.ogg");
374 set_entry_string (db, a, RHYTHMDB_PROP_ALBUM, "x");
375 set_entry_ulong (db, a, RHYTHMDB_PROP_TRACK_NUMBER, 1);
376 rhythmdb_commit (db);
377 wait_for_signal ();
378
379 set_waiting_signal (G_OBJECT (db), "entry_added");
380 b = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///b.ogg");
381 set_entry_string (db, b, RHYTHMDB_PROP_ALBUM, "y");
382 set_entry_ulong (db, b, RHYTHMDB_PROP_TRACK_NUMBER, 1);
383 rhythmdb_commit (db);
384 wait_for_signal ();
385
386 fail_unless (_get_property_count (propmodel, "x") == 0);
387 fail_unless (_get_property_count (propmodel, "y") == 1);
388
389 end_step ();
390
391 /* change entry a so it matches the child query */
392 set_waiting_signal (G_OBJECT (db), "entry-changed");
393 set_entry_string (db, a, RHYTHMDB_PROP_ALBUM, "yy");
394 rhythmdb_commit (db);
395 wait_for_signal ();
396
397 fail_unless (_get_property_count (propmodel, "x") == 0);
398 fail_unless (_get_property_count (propmodel, "y") == 1);
399 fail_unless (_get_property_count (propmodel, "yy") == 1);
400
401 end_step ();
402
403 /* change entry a again */
404 set_waiting_signal (G_OBJECT (db), "entry-changed");
405 set_entry_string (db, a, RHYTHMDB_PROP_ALBUM, "y");
406 rhythmdb_commit (db);
407 wait_for_signal ();
408
409 fail_unless (_get_property_count (propmodel, "y") == 2);
410 fail_unless (_get_property_count (propmodel, "yy") == 0);
411
412 end_step ();
413
414 /* change entry b again */
415 set_waiting_signal (G_OBJECT (db), "entry-changed");
416 set_entry_string (db, b, RHYTHMDB_PROP_ALBUM, "z");
417 rhythmdb_commit (db);
418 wait_for_signal ();
419
420 fail_unless (_get_property_count (propmodel, "y") == 1);
421 fail_unless (_get_property_count (propmodel, "z") == 0);
422
423 end_step ();
424
425 rhythmdb_entry_delete (db, a);
426 rhythmdb_entry_delete (db, b);
427 rhythmdb_commit (db);
428
429 end_test_case ();
430
431 g_object_unref (model);
432 g_object_unref (base_model);
433 g_object_unref (propmodel);
434 }
435 END_TEST
436
437 /* tests sort order of entries in a property model */
438 START_TEST (test_rhythmdb_property_model_sorting)
439 {
440 RhythmDBQueryModel *model;
441 RhythmDBPropertyModel *propmodel;
442 RhythmDBEntry *a, *the_b, *c;
443 GtkTreeIter iter1, iter2;
444
445 start_test_case ();
446
447 /* setup */
448 model = rhythmdb_query_model_new_empty (db);
449 propmodel = rhythmdb_property_model_new (db, RHYTHMDB_PROP_ARTIST);
450 g_object_set (propmodel, "query-model", model, NULL);
451
452 /* create test entries */
453 set_waiting_signal (G_OBJECT (db), "entry_added");
454 a = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///a.ogg");
455 set_entry_string (db, a, RHYTHMDB_PROP_ARTIST, "a");
456 rhythmdb_commit (db);
457 wait_for_signal ();
458
459 set_waiting_signal (G_OBJECT (db), "entry_added");
460 the_b = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///the-b.ogg");
461 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST, "the b");
462 rhythmdb_commit (db);
463 wait_for_signal ();
464
465 set_waiting_signal (G_OBJECT (db), "entry_added");
466 c = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///c.ogg");
467 set_entry_string (db, c, RHYTHMDB_PROP_ARTIST, "c");
468 rhythmdb_commit (db);
469 wait_for_signal ();
470
471 /* add to model */
472 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
473 rhythmdb_query_model_add_entry (model, a, -1);
474 wait_for_signal ();
475 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
476 rhythmdb_query_model_add_entry (model, the_b, -1);
477 wait_for_signal ();
478 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
479 rhythmdb_query_model_add_entry (model, c, -1);
480 wait_for_signal ();
481
482 /* test a comes immediately before c */
483 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
484 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
485 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
486
487 /* test c comes immediately before the_b */
488 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter1);
489 rhythmdb_property_model_iter_from_string (propmodel, "the b", &iter2);
490 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
491
492 end_step ();
493
494 /* change "the b" to sort under "b, the" */
495 set_waiting_signal (G_OBJECT (db), "entry-changed");
496 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST_SORTNAME, "b, the");
497 rhythmdb_commit (db);
498 wait_for_signal ();
499
500 /* test a comes immediately before the_b */
501 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
502 rhythmdb_property_model_iter_from_string (propmodel, "the b", &iter2);
503 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
504
505 /* test the_b comes immediately before c */
506 rhythmdb_property_model_iter_from_string (propmodel, "the b", &iter1);
507 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
508 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
509
510 end_step();
511
512 /* change display name for b */
513 set_waiting_signal (G_OBJECT (db), "entry-changed");
514 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST, "THE B");
515 rhythmdb_commit (db);
516 wait_for_signal ();
517
518 /* property model order shouldn't have changed */
519 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
520 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter2);
521 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
522
523 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter1);
524 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
525 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
526
527 end_step();
528
529 /* change sortname for b */
530 set_waiting_signal (G_OBJECT (db), "entry-changed");
531 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST_SORTNAME, "B, THE");
532 rhythmdb_commit (db);
533 wait_for_signal ();
534
535 /* property model order shouldn't have changed */
536 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
537 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter2);
538 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
539
540 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter1);
541 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
542 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
543
544 end_step();
545
546 /* change sort order for b */
547 set_waiting_signal (G_OBJECT (db), "entry-changed");
548 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST_SORTNAME, "zzz");
549 rhythmdb_commit (db);
550 wait_for_signal ();
551
552 /* property model order should have changed to match */
553 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
554 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
555 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
556
557 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter1);
558 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter2);
559 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
560
561 end_step();
562
563 /* remove sort order for b */
564 set_waiting_signal (G_OBJECT (db), "entry-changed");
565 set_entry_string (db, the_b, RHYTHMDB_PROP_ARTIST_SORTNAME, "");
566 rhythmdb_commit (db);
567 wait_for_signal ();
568
569 /* property model order should have changed to match */
570 rhythmdb_property_model_iter_from_string (propmodel, "a", &iter1);
571 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter2);
572 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
573
574 rhythmdb_property_model_iter_from_string (propmodel, "c", &iter1);
575 rhythmdb_property_model_iter_from_string (propmodel, "THE B", &iter2);
576 fail_unless (iter1.user_data == g_sequence_iter_prev (iter2.user_data));
577
578 end_step();
579
580
581 rhythmdb_entry_delete (db, a);
582 rhythmdb_entry_delete (db, the_b);
583 rhythmdb_entry_delete (db, c);
584 rhythmdb_commit (db);
585
586 end_test_case ();
587
588 g_object_unref (model);
589 g_object_unref (propmodel);
590 }
591 END_TEST
592
593 /* tests handling of empty strings */
594 START_TEST (test_rhythmdb_property_model_empty_strings)
595 {
596 RhythmDBQueryModel *model;
597 RhythmDBPropertyModel *propmodel;
598 RhythmDBEntry *a, *b;
599
600 start_test_case ();
601
602 /* setup */
603 model = rhythmdb_query_model_new_empty (db);
604 propmodel = rhythmdb_property_model_new (db, RHYTHMDB_PROP_GENRE);
605 g_object_set (propmodel, "query-model", model, NULL);
606
607 /* create test entries */
608 set_waiting_signal (G_OBJECT (db), "entry_added");
609 a = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///a.ogg");
610 set_entry_string (db, a, RHYTHMDB_PROP_GENRE, "unknown");
611 rhythmdb_commit (db);
612 wait_for_signal ();
613
614 set_waiting_signal (G_OBJECT (db), "entry_added");
615 b = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///b.ogg");
616 set_entry_string (db, b, RHYTHMDB_PROP_GENRE, "something");
617 rhythmdb_commit (db);
618 wait_for_signal ();
619
620 end_step ();
621
622 /* add to model */
623 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
624 rhythmdb_query_model_add_entry (model, a, -1);
625 wait_for_signal ();
626
627 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
628 rhythmdb_query_model_add_entry (model, b, -1);
629 wait_for_signal ();
630
631 end_step ();
632
633 /* set to empty string */
634 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
635 set_entry_string (db, a, RHYTHMDB_PROP_GENRE, "");
636 rhythmdb_commit (db);
637 wait_for_signal ();
638
639 end_step ();
640
641 /* set to non-empty string */
642 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
643 set_entry_string (db, a, RHYTHMDB_PROP_GENRE, "junk");
644 rhythmdb_commit (db);
645 wait_for_signal ();
646
647 end_step ();
648
649 /* set to empty string again */
650 set_waiting_signal (G_OBJECT (propmodel), "row-inserted");
651 set_entry_string (db, a, RHYTHMDB_PROP_GENRE, "");
652 rhythmdb_commit (db);
653 wait_for_signal ();
654
655 end_step ();
656
657 rhythmdb_entry_delete (db, a);
658 rhythmdb_entry_delete (db, b);
659 rhythmdb_commit (db);
660
661 end_test_case ();
662 g_object_unref (model);
663 g_object_unref (propmodel);
664 }
665 END_TEST
666
667 static Suite *
668 rhythmdb_property_model_suite (void)
669 {
670 Suite *s = suite_create ("rhythmdb-property-model");
671 TCase *tc_chain = tcase_create ("rhythmdb-property-model-core");
672 TCase *tc_bugs = tcase_create ("rhythmdb-property-model-bugs");
673
674 suite_add_tcase (s, tc_chain);
675 tcase_add_checked_fixture (tc_chain, test_rhythmdb_setup, test_rhythmdb_shutdown);
676 suite_add_tcase (s, tc_bugs);
677 tcase_add_checked_fixture (tc_bugs, test_rhythmdb_setup, test_rhythmdb_shutdown);
678
679 /* test core functionality */
680 tcase_add_test (tc_chain, test_rhythmdb_property_model_static);
681 tcase_add_test (tc_chain, test_rhythmdb_property_model_query);
682 tcase_add_test (tc_chain, test_rhythmdb_property_model_query_chain);
683 tcase_add_test (tc_chain, test_rhythmdb_property_model_sorting);
684
685 /* tests for breakable bug fixes */
686 /* tcase_add_test (tc_bugs, test_hidden_chain_filter);*/
687 tcase_add_test (tc_chain, test_rhythmdb_property_model_empty_strings);
688
689 return s;
690 }
691
692 int
693 main (int argc, char **argv)
694 {
695 int ret;
696 SRunner *sr;
697 Suite *s;
698
699 /* init stuff */
700 rb_profile_start ("rhythmdb-property-model test suite");
701
702 rb_threads_init ();
703 setlocale (LC_ALL, NULL);
704 rb_debug_init (TRUE);
705 rb_refstring_system_init ();
706 rb_file_helpers_init (TRUE);
707
708 /* setup tests */
709 s = rhythmdb_property_model_suite ();
710 sr = srunner_create (s);
711
712 init_setup (sr, argc, argv);
713 init_once (FALSE);
714
715 srunner_run_all (sr, CK_NORMAL);
716 ret = srunner_ntests_failed (sr);
717 srunner_free (sr);
718
719 rb_file_helpers_shutdown ();
720 rb_refstring_system_shutdown ();
721
722 rb_profile_end ("rhythmdb-property-model test suite");
723 return ret;
724 }