hythmbox-2.98/tests/test-rhythmdb.c

Location Tool Test ID Function Issue
test-rhythmdb.c:423:2 clang-analyzer Null pointer passed as an argument to a 'nonnull' parameter
  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 <string.h>
 33 #include <glib/gi18n.h>
 34 
 35 #include "test-utils.h"
 36 
 37 #include "rb-debug.h"
 38 #include "rb-file-helpers.h"
 39 #include "rb-util.h"
 40 
 41 #include "rhythmdb.h"
 42 #include "rhythmdb-tree.h"
 43 #include "rhythmdb-query-model.h"
 44 #include "rb-podcast-entry-types.h"
 45 
 46 static void
 47 set_true (RhythmDBEntry *entry, gboolean *b)
 48 {
 49 	*b = TRUE;
 50 }
 51 
 52 
 53 
 54 /* tests */
 55 START_TEST (test_rhythmdb_indexing)
 56 {
 57 	RhythmDBEntry *entry = NULL;
 58 	GValue val = {0,};
 59 	gboolean b;
 60 
 61 	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg");
 62 	fail_unless (entry != NULL, "failed to create entry");
 63 
 64 	g_value_init (&val, G_TYPE_STRING);
 65 	g_value_set_static_string (&val, "Rock");
 66 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val);
 67 	g_value_unset (&val);
 68 
 69 	g_value_init (&val, G_TYPE_STRING);
 70 	g_value_set_static_string (&val, "Nine Inch Nails");
 71 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val);
 72 	g_value_unset (&val);
 73 
 74 	g_value_init (&val, G_TYPE_STRING);
 75 	g_value_set_static_string (&val, "Pretty Hate Machine");
 76 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val);
 77 	g_value_unset (&val);
 78 
 79 	g_value_init (&val, G_TYPE_STRING);
 80 	g_value_set_static_string (&val, "Sin");
 81 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
 82 	g_value_unset (&val);
 83 
 84 	rhythmdb_commit (db);
 85 
 86 	/* check the data is recorded correctly */
 87 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), "file:///whee.ogg") == 0,
 88 		     "LOCATION set incorrectly");
 89 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE), "Rock") == 0,
 90 		     "GENRE set incorrectly");
 91 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST), "Nine Inch Nails") == 0,
 92 		     "ARTIST set incorrectly");
 93 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM), "Pretty Hate Machine") == 0,
 94 		     "ALBUM set incorrectly");
 95 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE), "Sin") == 0,
 96 		     "TITLE set incorrectly");
 97 
 98 	/* check changing album */
 99 	g_value_init (&val, G_TYPE_STRING);
100 	g_value_set_static_string (&val, "Broken");
101 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val);
102 	g_value_unset (&val);
103 	rhythmdb_commit (db);
104 
105 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), "file:///whee.ogg") == 0,
106 		     "LOCATION set incorrectly");
107 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE), "Rock") == 0,
108 		     "GENRE set incorrectly");
109 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST), "Nine Inch Nails") == 0,
110 		     "ARTIST set incorrectly");
111 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM), "Broken") == 0,
112 		     "ALBUM set incorrectly");
113 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE), "Sin") == 0,
114 		     "TITLE set incorrectly");
115 
116 	/* check changing artist */
117 	g_value_init (&val, G_TYPE_STRING);
118 	g_value_set_static_string (&val, "Evanescence");
119 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val);
120 	g_value_unset (&val);
121 	rhythmdb_commit (db);
122 
123 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LOCATION), "file:///whee.ogg") == 0,
124 		     "LOCATION set incorrectly");
125 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_GENRE), "Rock") == 0,
126 		     "GENRE set incorrectly");
127 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST), "Evanescence") == 0,
128 		     "ARTIST set incorrectly");
129 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM), "Broken") == 0,
130 		     "ALBUM set incorrectly");
131 	fail_unless (strcmp (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE), "Sin") == 0,
132 		     "TITLE set incorrectly");
133 
134 	/* check removal */
135 	rhythmdb_entry_delete (db, entry);
136 	entry = NULL;
137 
138 	b = FALSE;
139 	rhythmdb_entry_foreach (db, (GFunc)set_true, &b);
140 	fail_unless (b == FALSE, "entry not deleted");
141 }
142 END_TEST
143 
144 START_TEST (test_rhythmdb_multiple)
145 {
146 	RhythmDBEntry *entry1, *entry2, *entry3;
147 
148 	/* add multiple entries */
149 	entry1 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///foo.mp3");
150 	rhythmdb_commit (db);
151 	fail_unless (entry1 != NULL, "failed to create entry");
152 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing");
153 
154 	entry2 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///bar.mp3");
155 	rhythmdb_commit (db);
156 	fail_unless (entry2 != NULL, "failed to create entry");
157 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == entry2, "entry missing");
158 
159 	entry3 = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///baz.mp3");
160 	rhythmdb_commit (db);
161 	fail_unless (entry3 != NULL, "failed to create entry");
162 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing");
163 
164 	/* check they're still there */
165 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing");
166 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == entry2, "entry missing");
167 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing");
168 
169 	/* remove the middle one and check again */
170 	rhythmdb_entry_delete (db, entry2);
171 	rhythmdb_commit (db);
172 
173 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == entry1, "entry missing");
174 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == NULL, "entry not deleted");
175 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == entry3, "entry missing");
176 
177 	/* and the others */
178 	rhythmdb_entry_delete (db, entry1);
179 	rhythmdb_entry_delete (db, entry3);
180 	rhythmdb_commit (db);
181 
182 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///foo.mp3") == NULL, "entry not deleted");
183 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///bar.mp3") == NULL, "entry not deleted");
184 	fail_unless (rhythmdb_entry_lookup_by_location (db, "file:///baz.mp3") == NULL, "entry not deleted");
185 }
186 END_TEST
187 
188 START_TEST (test_rhythmdb_mirroring)
189 {
190 	GValue val = {0,};
191 	RhythmDBEntry *entry;
192 	const char *str;
193 
194 	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///foo.mp3");
195 	fail_unless (entry != NULL, "failed to create entry");
196 
197 	/* check the last-played date is mirrored */
198 	g_value_init (&val, G_TYPE_ULONG);
199 	g_value_set_ulong (&val, 1354285);
200 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_LAST_PLAYED, &val);
201 	g_value_unset (&val);
202 	rhythmdb_commit (db);
203 
204 	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_LAST_PLAYED_STR);
205 	fail_unless (str && (strlen (str) > 0), "date not converted to string");
206 
207 	/* check folded and sort-key varients */
208 	g_value_init (&val, G_TYPE_STRING);
209 	g_value_set_static_string (&val, "FOO");
210 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
211 	g_value_unset (&val);
212 	rhythmdb_commit (db);
213 
214 	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_SORT_KEY);
215 	fail_unless (str && (strlen (str) > 0), "sort-key not generated");
216 	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_FOLDED);
217 	fail_unless (str && (strcmp (str, "foo") == 0), "folded variant not generated");
218 
219 	g_value_init (&val, G_TYPE_STRING);
220 	g_value_set_static_string (&val, "BAR");
221 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
222 	g_value_unset (&val);
223 	rhythmdb_commit (db);
224 
225 	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_SORT_KEY);
226 	fail_unless (str && (strlen (str) > 0), "sort-key not generated");
227 	str = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE_FOLDED);
228 	fail_unless (str && (strcmp (str, "bar") == 0), "folded variant not generated");
229 
230 
231 }
232 END_TEST
233 
234 static int
235 count_and_free_refstring_list (GList *list)
236 {
237 	int count;
238 
239 	count = g_list_length (list);
240 
241 	g_list_foreach (list, (GFunc)rb_refstring_unref, NULL);
242 	g_list_free (list);
243 
244 	return count;
245 }
246 
247 START_TEST (test_rhythmdb_keywords)
248 {
249 	RhythmDBEntry *entry;
250 	GList *list;
251 	gboolean ret;
252 	RBRefString *keyword_foo, *keyword_bar, *keyword_baz;
253 
254 	keyword_foo = rb_refstring_new ("foo");
255 	keyword_bar = rb_refstring_new ("bar");
256 	keyword_baz = rb_refstring_new ("baz");
257 
258 	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///foo.mp3");
259 	fail_unless (entry != NULL, "failed to create entry");
260 
261 	/* new entries should have 0 keywords */
262 	list = rhythmdb_entry_keywords_get (db, entry);
263 	fail_unless (count_and_free_refstring_list (list) == 0, "new entry had keywords");
264 
265 	/* adding one keyword */
266 	ret = rhythmdb_entry_keyword_add (db, entry, keyword_foo);
267 	fail_unless (ret == FALSE, "entry incorrectly reported as having keyword already");
268 	list = rhythmdb_entry_keywords_get (db, entry);
269 	fail_unless (count_and_free_refstring_list (list) == 1, "entry wrong number of keywords after one was added");
270 
271 	/* has added keyword */
272 	ret = rhythmdb_entry_keyword_has (db, entry, keyword_foo);
273 	fail_unless (ret == TRUE, "reported not having just-added keyword");
274 
275 	/* add keyword again */
276 	ret = rhythmdb_entry_keyword_add (db, entry, keyword_foo);
277 	fail_unless (ret == TRUE, "entry incorrectly reported as not keyword already");
278 
279 	/* check keyword count*/
280 	list = rhythmdb_entry_keywords_get (db, entry);
281 	fail_unless (count_and_free_refstring_list (list) == 1, "entry wrong number of keywords after one was re-added");
282 
283 	/* ensure it has only that keyword */
284 	ret = rhythmdb_entry_keyword_has (db, entry, keyword_bar);
285 	fail_unless (ret == FALSE, "reported having wrong keyword");
286 
287 	/* remove the keyword */
288 	ret = rhythmdb_entry_keyword_remove (db, entry, keyword_foo);
289 	fail_unless (ret == TRUE, "reported having not previously having keyword");
290 
291 	/* has removed keyword */
292 	ret = rhythmdb_entry_keyword_has (db, entry, keyword_foo);
293 	fail_unless (ret == FALSE, "reported having just-removed keyword");
294 
295 	/* check count is back to zero */
296 	list = rhythmdb_entry_keywords_get (db, entry);
297 	fail_unless (count_and_free_refstring_list (list) == 0, "entry has keywords after they were removed");
298 
299 	/* try removing keyword again */
300 	ret = rhythmdb_entry_keyword_remove (db, entry, keyword_foo);
301 	fail_unless (ret == FALSE, "reported previously having already removed keyword");
302 
303 	/* add and remove several keywords */
304 	ret = rhythmdb_entry_keyword_add (db, entry, keyword_foo);
305 	fail_unless (ret == FALSE, "reported previously having already removed keyword");
306 	ret = rhythmdb_entry_keyword_add (db, entry, keyword_bar);
307 	fail_unless (ret == FALSE, "reported previously having already never-added keyword");
308 	ret = rhythmdb_entry_keyword_add (db, entry, keyword_baz);
309 	fail_unless (ret == FALSE, "reported previously having already never-added keyword");
310 
311 	list = rhythmdb_entry_keywords_get (db, entry);
312 	fail_unless (count_and_free_refstring_list (list) == 3, "entry wrong number of keywords after several were added");
313 	ret = rhythmdb_entry_keyword_remove (db, entry, keyword_foo);
314 	fail_unless (ret == TRUE, "reported previously not having added keyword");
315 	list = rhythmdb_entry_keywords_get (db, entry);
316 	fail_unless (count_and_free_refstring_list (list) == 2, "entry wrong number of keywords after several were added");
317 	ret = rhythmdb_entry_keyword_remove (db, entry, keyword_bar);
318 	fail_unless (ret == TRUE, "reported previously not having added keyword");
319 	list = rhythmdb_entry_keywords_get (db, entry);
320 	fail_unless (count_and_free_refstring_list (list) == 1, "entry wrong number of keywords after several were added");
321 	ret = rhythmdb_entry_keyword_remove (db, entry, keyword_baz);
322 	fail_unless (ret == TRUE, "reported previously not having added keyword");
323 	list = rhythmdb_entry_keywords_get (db, entry);
324 	fail_unless (count_and_free_refstring_list (list) == 0, "entry wrong number of keywords after several were added");
325 }
326 END_TEST
327 
328 START_TEST (test_rhythmdb_deserialisation1)
329 {
330 	RhythmDBQueryModel *model;
331 
332 	/* empty db */
333 	g_object_set (G_OBJECT (db), "name", "deserialization-test1.xml", NULL);
334 	set_waiting_signal (G_OBJECT (db), "load-complete");
335 	rhythmdb_load (db);
336 	wait_for_signal ();
337 
338 	model = rhythmdb_query_model_new_empty (db);
339 	g_object_set (G_OBJECT (model), "show-hidden", TRUE, NULL);
340 	set_waiting_signal (G_OBJECT (model), "complete");
341 	rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (model),
342 				NULL,
343 				RHYTHMDB_QUERY_PROP_EQUALS,
344 				RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
345 				RHYTHMDB_QUERY_END);
346 	wait_for_signal ();
347 	fail_unless (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 0, "deserialisation incorrect");
348 	g_object_unref (model);
349 }
350 END_TEST
351 
352 START_TEST (test_rhythmdb_deserialisation2)
353 {
354 	RhythmDBQueryModel *model;
355 
356 	/* single entry db */
357 	g_object_set (G_OBJECT (db), "name", "deserialization-test2.xml", NULL);
358 	set_waiting_signal (G_OBJECT (db), "load-complete");
359 	rhythmdb_load (db);
360 	wait_for_signal ();
361 
362 	model = rhythmdb_query_model_new_empty (db);
363 	g_object_set (G_OBJECT (model), "show-hidden", TRUE, NULL);
364 	set_waiting_signal (G_OBJECT (model), "complete");
365 	rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (model),
366 				RHYTHMDB_QUERY_PROP_EQUALS,
367 				RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
368 				RHYTHMDB_QUERY_END);
369 	wait_for_signal ();
370 	/* FIXME: this fails for some reason
371 	fail_unless (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 1, "deserialisation incorrect");*/
372 	g_object_unref (model);
373 
374 	/* TODO: check values */
375 }
376 END_TEST
377 
378 START_TEST (test_rhythmdb_deserialisation3)
379 {
380 	RhythmDBQueryModel *model;
381 
382 	/* two entries of different types db */
383 	g_object_set (G_OBJECT (db), "name", "deserialization-test3.xml", NULL);
384 	set_waiting_signal (G_OBJECT (db), "load-complete");
385 	rhythmdb_load (db);
386 	wait_for_signal ();
387 
388 	model = rhythmdb_query_model_new_empty (db);
389 	g_object_set (G_OBJECT (model), "show-hidden", TRUE, NULL);
390 	set_waiting_signal (G_OBJECT (model), "complete");
391 	rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (model),
392 				NULL,
393 				RHYTHMDB_QUERY_PROP_EQUALS,
394 				RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
395 				RHYTHMDB_QUERY_END);
396 	wait_for_signal ();
397 	/* FIXME: this fails for some reason
398 	fail_unless (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 1, "deserialisation incorrect");*/
399 	g_object_unref (model);
400 
401 	/* TODO: check values */
402 }
403 END_TEST
404 
405 START_TEST (test_rhythmdb_podcast_upgrade)
406 {
407 	RhythmDBEntry *entry;
408 	const char *mountpoint;
409 
410 	/* load db with old podcasts setups */
411 	g_object_set (G_OBJECT (db), "name", SHARE_UNINSTALLED_DIR "/../tests/podcast-upgrade.xml", NULL);
412 	set_waiting_signal (G_OBJECT (db), "load-complete");
413 	rhythmdb_load (db);
414 	wait_for_signal ();
415 
416 	entry = rhythmdb_entry_lookup_by_location (db, "file:///home/tester/Desktop/BBC%20Xtra/xtra_20080906-1226a.mp3");
417 
418 	fail_unless (entry != NULL, "entry missing");
419 	fail_unless (rhythmdb_entry_get_entry_type (entry) == RHYTHMDB_ENTRY_TYPE_PODCAST_POST, "entry isn't a podcast");
420 	mountpoint = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT);
421 
422 	fail_unless (mountpoint != NULL, "no mountpoint for podcast");
423 	fail_unless (strcmp (mountpoint, "http://downloads.bbc.co.uk/podcasts/worldservice/xtra/xtra_20080906-1226a.mp3") == 0, "wrong mountpoint for podcast");
Null pointer passed as an argument to a 'nonnull' parameter
(emitted by clang-analyzer)

TODO: a detailed trace is available in the data model (not yet rendered in this report)

424 425 entry = rhythmdb_entry_lookup_by_location (db, "http://downloads.bbc.co.uk/podcasts/worldservice/xtra/xtra_20080903-1217a.mp3"); 426 fail_unless (entry != NULL, "entry not upgraded"); 427 fail_unless (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_MOUNTPOINT) == NULL, "wrong mountpoint for podcast"); 428 } 429 END_TEST 430 431 START_TEST (test_rhythmdb_modify_after_delete) 432 { 433 RhythmDBEntry *entry; 434 GValue val = {0,}; 435 436 entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg"); 437 fail_unless (entry != NULL, "failed to create entry"); 438 439 g_value_init (&val, G_TYPE_STRING); 440 g_value_set_static_string (&val, "Anything"); 441 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val); 442 g_value_unset (&val); 443 444 g_value_init (&val, G_TYPE_STRING); 445 g_value_set_static_string (&val, "Nothing"); 446 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val); 447 g_value_unset (&val); 448 449 g_value_init (&val, G_TYPE_STRING); 450 g_value_set_static_string (&val, "Something"); 451 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val); 452 g_value_unset (&val); 453 454 g_value_init (&val, G_TYPE_STRING); 455 g_value_set_static_string (&val, "Thing"); 456 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val); 457 g_value_unset (&val); 458 459 rhythmdb_commit (db); 460 rhythmdb_entry_ref (entry); 461 462 rhythmdb_entry_delete (db, entry); 463 rhythmdb_commit (db); 464 465 g_value_init (&val, G_TYPE_STRING); 466 g_value_set_static_string (&val, "Something Else"); 467 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val); 468 g_value_unset (&val); 469 470 rhythmdb_commit (db); 471 rhythmdb_entry_unref (entry); 472 } 473 END_TEST 474 475 static void 476 commit_change_merge_cb (RhythmDB *db, RhythmDBEntry *entry, GArray *changes, gpointer ok) 477 { 478 int expected = GPOINTER_TO_INT (ok); 479 fail_unless (changes->len == expected, "commit change lists merged"); 480 } 481 482 START_TEST (test_rhythmdb_commit_change_merging) 483 { 484 RhythmDBEntry *entry; 485 GValue val = {0,}; 486 487 entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg"); 488 fail_unless (entry != NULL, "failed to create entry"); 489 490 rhythmdb_commit (db); 491 492 g_value_init (&val, G_TYPE_STRING); 493 g_value_set_static_string (&val, "Anything"); 494 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val); 495 g_value_unset (&val); 496 497 rhythmdb_commit (db); 498 499 g_value_init (&val, G_TYPE_STRING); 500 g_value_set_static_string (&val, "Nothing"); 501 rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val); 502 g_value_unset (&val); 503 504 g_signal_connect (G_OBJECT (db), "entry-changed", G_CALLBACK (commit_change_merge_cb), GINT_TO_POINTER (2)); 505 set_waiting_signal (G_OBJECT (db), "entry-changed"); 506 rhythmdb_commit (db); 507 wait_for_signal (); 508 } 509 END_TEST 510 511 static Suite * 512 rhythmdb_suite (void) 513 { 514 Suite *s = suite_create ("rhythmdb"); 515 TCase *tc_chain = tcase_create ("rhythmdb-core"); 516 TCase *tc_bugs = tcase_create ("rhythmdb-bugs"); 517 518 suite_add_tcase (s, tc_chain); 519 tcase_add_checked_fixture (tc_chain, test_rhythmdb_setup, test_rhythmdb_shutdown); 520 suite_add_tcase (s, tc_bugs); 521 tcase_add_checked_fixture (tc_bugs, test_rhythmdb_setup, test_rhythmdb_shutdown); 522 523 /* test core functionality */ 524 /*tcase_add_test (tc_chain, test_refstring);*/ 525 tcase_add_test (tc_chain, test_rhythmdb_indexing); 526 tcase_add_test (tc_chain, test_rhythmdb_multiple); 527 tcase_add_test (tc_chain, test_rhythmdb_mirroring); 528 tcase_add_test (tc_chain, test_rhythmdb_keywords); 529 /*tcase_add_test (tc_chain, test_rhythmdb_signals);*/ 530 /*tcase_add_test (tc_chain, test_rhythmdb_query);*/ 531 /* FIXME: add some keywords to the deserialisation tests */ 532 tcase_add_test (tc_chain, test_rhythmdb_deserialisation1); 533 tcase_add_test (tc_chain, test_rhythmdb_deserialisation2); 534 tcase_add_test (tc_chain, test_rhythmdb_deserialisation3); 535 /*tcase_add_test (tc_chain, test_rhythmdb_serialisation);*/ 536 537 /* tests for breakable bug fixes */ 538 tcase_add_test (tc_chain, test_rhythmdb_podcast_upgrade); 539 tcase_add_test (tc_chain, test_rhythmdb_modify_after_delete); 540 tcase_add_test (tc_chain, test_rhythmdb_commit_change_merging); 541 542 return s; 543 } 544 545 int 546 main (int argc, char **argv) 547 { 548 int ret; 549 SRunner *sr; 550 Suite *s; 551 552 g_log_set_always_fatal (G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); 553 554 /* init stuff */ 555 rb_profile_start ("rhythmbox test suite"); 556 557 rb_threads_init (); 558 rb_debug_init (TRUE); 559 rb_refstring_system_init (); 560 rb_file_helpers_init (TRUE); 561 562 /* setup tests */ 563 s = rhythmdb_suite (); 564 sr = srunner_create (s); 565 566 init_setup (sr, argc, argv); 567 init_once (FALSE); 568 569 srunner_run_all (sr, CK_NORMAL); 570 ret = srunner_ntests_failed (sr); 571 srunner_free (sr); 572 573 rb_file_helpers_shutdown (); 574 rb_refstring_system_shutdown (); 575 576 rb_profile_end ("rhythmbox test suite"); 577 return ret; 578 }