hythmbox-2.98/tests/test-rhythmdb-query-model.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found test-rhythmdb-query-model.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  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 
 36 #include "rb-debug.h"
 37 #include "rb-file-helpers.h"
 38 #include "rb-util.h"
 39 
 40 static void
 41 test_query_eval (RhythmDB *db, RhythmDBQuery *query, RhythmDBEntry *entry, gboolean expected, const char *what)
 42 {
 43 	RhythmDBQueryModel *model;
 44 	RhythmDBQuery *processed;
 45 	GtkTreeIter iter = {0,};
 46 
 47 	/* direct evaluation - need to preprocess it first */
 48 	processed = rhythmdb_query_copy (query);
 49 	rhythmdb_query_preprocess (db, processed);
 50 	fail_unless (rhythmdb_evaluate_query (db, processed, entry) == expected, what);
 51 	rhythmdb_query_free (processed);
 52 
 53 	/* query evaluation - query is preprocessed by rhythmdb */
 54 	model = rhythmdb_query_model_new_empty (db);
 55 	rhythmdb_do_full_query_parsed (db, RHYTHMDB_QUERY_RESULTS (model), query);
 56 	fail_unless (rhythmdb_query_model_entry_to_iter (model, entry, &iter) == expected, what);
 57 	g_object_unref (model);
 58 }
 59 
 60 static guint32
 61 year_to_julian (guint32 year)
 62 {
 63 	GDate v = {0,};
 64 	g_date_set_dmy (&v, 1, G_DATE_JANUARY, year);
 65 	return g_date_get_julian (&v);
 66 }
 67 
 68 START_TEST (test_rhythmdb_db_queries)
 69 {
 70 	RhythmDBEntry *entry = NULL;
 71 	RhythmDBQuery *query;
 72 	GValue val = {0,};
 73 	GDate testdate = {0,};
 74 
 75 	start_test_case ();
 76 
 77 	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg");
 78 	fail_unless (entry != NULL, "failed to create entry");
 79 
 80 	g_value_init (&val, G_TYPE_STRING);
 81 	g_value_set_static_string (&val, "Rock");
 82 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_GENRE, &val);
 83 	g_value_unset (&val);
 84 
 85 	g_value_init (&val, G_TYPE_STRING);
 86 	g_value_set_static_string (&val, "Nine Inch Nails");
 87 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ARTIST, &val);
 88 	g_value_unset (&val);
 89 
 90 	g_value_init (&val, G_TYPE_STRING);
 91 	g_value_set_static_string (&val, "Pretty Hate Machine");
 92 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_ALBUM, &val);
 93 	g_value_unset (&val);
 94 
 95 	g_value_init (&val, G_TYPE_STRING);
 96 	g_value_set_static_string (&val, "Sin");
 97 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_TITLE, &val);
 98 	g_value_unset (&val);
 99 
100 	g_date_set_dmy (&testdate, 1, 1, 1989);
101 	g_value_init (&val, G_TYPE_ULONG);
102 	g_value_set_ulong (&val, g_date_get_julian (&testdate));
103 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_DATE, &val);
104 	g_value_unset (&val);
105 
106 	rhythmdb_commit (db);
107 
108 	/* basic queries and conjunctions */
109 	query = rhythmdb_query_parse (db,
110 				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE,
111 				      RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin",
112 				      RHYTHMDB_QUERY_END);
113 	test_query_eval (db, query, entry, TRUE, "title query evaluated incorrectly");
114 	rhythmdb_query_free (query);
115 
116 	end_step ();
117 
118 	query = rhythmdb_query_parse (db,
119 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_ARTIST, "Nine Inch",
120 				      RHYTHMDB_QUERY_END);
121 	test_query_eval (db, query, entry, TRUE, "artist query evaluated incorrectly");
122 	rhythmdb_query_free (query);
123 
124 	end_step ();
125 
126 	query = rhythmdb_query_parse (db,
127 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_ALBUM, "Load",
128 				      RHYTHMDB_QUERY_END);
129 	test_query_eval (db, query, entry, FALSE, "album query evaluated incorrectly");
130 	rhythmdb_query_free (query);
131 
132 	end_step ();
133 
134 	query = rhythmdb_query_parse (db,
135 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_SEARCH_MATCH, "Pretty Nine",
136 				      RHYTHMDB_QUERY_END);
137 	test_query_eval (db, query, entry, TRUE, "search query evaluated incorrectly");
138 	rhythmdb_query_free (query);
139 
140 	end_step ();
141 
142 	query = rhythmdb_query_parse (db,
143 				      RHYTHMDB_QUERY_PROP_NOT_EQUAL, RHYTHMDB_PROP_TITLE, "Head Like A Hole",
144 				      RHYTHMDB_QUERY_END);
145 	test_query_eval (db, query, entry, TRUE, "title != query evaluated incorrectly");
146 	rhythmdb_query_free (query);
147 
148 	end_step ();
149 
150 	query = rhythmdb_query_parse (db,
151 				      RHYTHMDB_QUERY_PROP_YEAR_EQUALS, RHYTHMDB_PROP_DATE, year_to_julian (1989),
152 				      RHYTHMDB_QUERY_END);
153 	test_query_eval (db, query, entry, TRUE, "year == query evaluated incorrectly");
154 	rhythmdb_query_free (query);
155 
156 	end_step ();
157 
158 	query = rhythmdb_query_parse (db,
159 				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1990),
160 				      RHYTHMDB_QUERY_END);
161 	test_query_eval (db, query, entry, TRUE, "year != query evaluated incorrectly");
162 	rhythmdb_query_free (query);
163 
164 	end_step ();
165 
166 	query = rhythmdb_query_parse (db,
167 				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1988),
168 				      RHYTHMDB_QUERY_END);
169 	test_query_eval (db, query, entry, TRUE, "year != query evaluated incorrectly");
170 	rhythmdb_query_free (query);
171 
172 	end_step ();
173 
174 	query = rhythmdb_query_parse (db,
175 				      RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL, RHYTHMDB_PROP_DATE, year_to_julian (1989),
176 				      RHYTHMDB_QUERY_END);
177 	test_query_eval (db, query, entry, FALSE, "year != query evaluated incorrectly");
178 	rhythmdb_query_free (query);
179 
180 	end_step ();
181 
182 	/* disjunctions */
183 	query = rhythmdb_query_parse (db,
184 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Sin",
185 				      RHYTHMDB_QUERY_DISJUNCTION,
186 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Son",
187 				      RHYTHMDB_QUERY_END);
188 	test_query_eval (db, query, entry, TRUE, "title disjunction query evaluated incorrectly");
189 	rhythmdb_query_free (query);
190 
191 	end_step ();
192 
193 	query = rhythmdb_query_parse (db,
194 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Sun",
195 				      RHYTHMDB_QUERY_DISJUNCTION,
196 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Sin",
197 				      RHYTHMDB_QUERY_END);
198 	test_query_eval (db, query, entry, TRUE, "title disjunction query evaluated incorrectly");
199 	rhythmdb_query_free (query);
200 
201 	end_step ();
202 
203 	query = rhythmdb_query_parse (db,
204 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Sun",
205 				      RHYTHMDB_QUERY_DISJUNCTION,
206 				      RHYTHMDB_QUERY_PROP_LIKE, RHYTHMDB_PROP_TITLE, "Son",
207 				      RHYTHMDB_QUERY_END);
208 	test_query_eval (db, query, entry, FALSE, "title disjunction query evaluated incorrectly");
209 	rhythmdb_query_free (query);
210 
211 	/* TODO: subqueries */
212 
213 	rhythmdb_entry_delete (db, entry);
214 
215 	end_test_case ();
216 }
217 END_TEST
218 
219 /* this tests that chained query models, where the base shows hidden entries
220  * forwards visibility changes correctly. This is basically what static playlists do */
221 START_TEST (test_hidden_chain_filter)
222 {
223 	RhythmDBQueryModel *base_model;
224 	RhythmDBQueryModel *filter_model;
225 	RhythmDBQuery *query;
226 	RhythmDBEntry *entry;
227 	GtkTreeIter iter;
228 	GValue val = {0,};
229 
230 	start_test_case ();
231 
232 	/* setup */
233 	base_model = rhythmdb_query_model_new_empty (db);
234 	g_object_set (base_model, "show-hidden", TRUE, NULL);
235 
236 	filter_model = rhythmdb_query_model_new_empty (db);
237 	g_object_set (filter_model, "base-model", base_model, NULL);
238 	query = g_ptr_array_new ();
239 	g_object_set (filter_model, "query", query, NULL);
240 	rhythmdb_query_free (query);
241 
242 	entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg");
243 	rhythmdb_commit (db);
244 
245 	g_value_init (&val, G_TYPE_BOOLEAN);
246 
247 
248 	/* add entry to base, should be in both */
249 	rhythmdb_query_model_add_entry (base_model, entry, -1);
250 	fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter));
251 	fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter));
252 
253 	end_step ();
254 
255 	/* hide entry, should be in base and not filtered */
256 	g_value_set_boolean (&val, TRUE);
257 	set_waiting_signal (G_OBJECT (db), "entry-changed");
258 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val);
259 	rhythmdb_commit (db);
260 	wait_for_signal ();
261 
262 	fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter));
263 	fail_if (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter));
264 
265 	end_step ();
266 
267 	/* show entry again, should be in both */
268 	g_value_set_boolean (&val, FALSE);
269 	set_waiting_signal (G_OBJECT (db), "entry-changed");
270 	rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val);
271 	rhythmdb_commit (db);
272 	wait_for_signal ();
273 
274 	fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter));
275 	fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter));
276 
277 	end_step ();
278 
279 	/* tidy up */
280 	rhythmdb_entry_delete (db, entry);
281 	g_object_unref (base_model);
282 	g_object_unref (filter_model);
283 	g_value_unset (&val);
284 
285 	end_test_case ();
286 }
287 END_TEST
288 
289 static Suite *
290 rhythmdb_query_model_suite (void)
291 {
292 	Suite *s = suite_create ("rhythmdb-query-model");
293 	TCase *tc_chain = tcase_create ("rhythmdb-query-model-core");
294 	TCase *tc_bugs = tcase_create ("rhythmdb-query-model-bugs");
295 
296 	suite_add_tcase (s, tc_chain);
297 	tcase_add_checked_fixture (tc_chain, test_rhythmdb_setup, test_rhythmdb_shutdown);
298 	suite_add_tcase (s, tc_bugs);
299 	tcase_add_checked_fixture (tc_bugs, test_rhythmdb_setup, test_rhythmdb_shutdown);
300 
301 	/* test core functionality */
302 	tcase_add_test (tc_chain, test_rhythmdb_db_queries);
303 
304 	/* tests for breakable bug fixes */
305 	tcase_add_test (tc_bugs, test_hidden_chain_filter);
306 
307 	return s;
308 }
309 
310 int
311 main (int argc, char **argv)
312 {
313 	int ret;
314 	SRunner *sr;
315 	Suite *s;
316 
317 	/* init stuff */
318 	rb_profile_start ("rhythmdb-query-model test suite");
319 
320 	rb_threads_init ();
321 	setlocale (LC_ALL, NULL);
322 	rb_debug_init (TRUE);
323 	rb_refstring_system_init ();
324 	rb_file_helpers_init (TRUE);
325 
326 	/* setup tests */
327 	s = rhythmdb_query_model_suite ();
328 	sr = srunner_create (s);
329 
330 	init_setup (sr, argc, argv);
331 	init_once (FALSE);
332 
333 	srunner_run_all (sr, CK_NORMAL);
334 	ret = srunner_ntests_failed (sr);
335 	srunner_free (sr);
336 
337 
338 	rb_file_helpers_shutdown ();
339 	rb_refstring_system_shutdown ();
340 
341 	rb_profile_end ("rhythmdb-query-model test suite");
342 	return ret;
343 }