No issues found
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 |
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 }