1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2013, Openismus GmbH
4 *
5 * This library is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Authors: Tristan Van Berkom <tristanvb@openismus.com>
18 */
19
20 #include "evolution-data-server-config.h"
21
22 #ifdef HAVE_SYS_WAIT_H
23 #include <sys/wait.h>
24 #endif
25
26 #include <locale.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <errno.h>
30
31 #include "data-test-utils.h"
32
33 static const gchar *args_data_dir = NULL;
34
35 void
data_test_utils_read_args(gint argc,gchar ** argv)36 data_test_utils_read_args (gint argc,
37 gchar **argv)
38 {
39 gint ii;
40
41 for (ii = 0; ii < argc; ii++) {
42 if (g_strcmp0 (argv[ii], "--data-dir") == 0) {
43 if (ii + 1 < argc)
44 args_data_dir = argv[ii + 1];
45 break;
46 }
47 }
48 }
49
50 gchar *
new_vcard_from_test_case(const gchar * case_name)51 new_vcard_from_test_case (const gchar *case_name)
52 {
53 gchar *filename;
54 gchar *case_filename;
55 GFile * file;
56 GError *error = NULL;
57 gchar *vcard;
58
59 case_filename = g_strdup_printf ("%s.vcf", case_name);
60
61 /* In the case of installed tests, they run in ${pkglibexecdir}/installed-tests
62 * and the vcards are installed in ${pkglibexecdir}/installed-tests/vcards
63 */
64 if (g_getenv ("TEST_INSTALLED_SERVICES") != NULL) {
65 filename = g_build_filename (INSTALLED_TEST_DIR, "vcards", case_filename, NULL);
66 } else {
67 if (!args_data_dir) {
68 g_warning ("Data directory not set, pass it with `--data-dir PATH`");
69 exit(1);
70 }
71
72 filename = g_build_filename (args_data_dir, case_filename, NULL);
73 }
74
75 file = g_file_new_for_path (filename);
76 if (!g_file_load_contents (file, NULL, &vcard, NULL, NULL, &error))
77 g_error (
78 "failed to read test contact file '%s': %s",
79 filename, error->message);
80
81 g_free (case_filename);
82 g_free (filename);
83 g_object_unref (file);
84
85 return vcard;
86 }
87
88 EContact *
new_contact_from_test_case(const gchar * case_name)89 new_contact_from_test_case (const gchar *case_name)
90 {
91 gchar *vcard;
92 EContact *contact = NULL;
93
94 vcard = new_vcard_from_test_case (case_name);
95 if (vcard)
96 contact = e_contact_new_from_vcard (vcard);
97 g_free (vcard);
98
99 if (!contact)
100 g_error (
101 "failed to construct contact from test case '%s'",
102 case_name);
103
104 return contact;
105 }
106
107 void
add_contact_from_test_case(EbSqlFixture * fixture,const gchar * case_name,EContact ** ret_contact)108 add_contact_from_test_case (EbSqlFixture *fixture,
109 const gchar *case_name,
110 EContact **ret_contact)
111 {
112 EContact *contact;
113 GError *error = NULL;
114
115 contact = new_contact_from_test_case (case_name);
116
117 if (!e_book_sqlite_add_contact (fixture->ebsql,
118 contact, case_name,
119 FALSE, NULL, &error))
120 g_error ("Failed to add contact: %s", error->message);
121
122 if (ret_contact)
123 *ret_contact = g_object_ref (contact);
124
125 /* Hold on to this so we can load vcards */
126 g_hash_table_insert (fixture->contacts, g_strdup (case_name), contact);
127 }
128
129 static void
delete_work_directory(const gchar * filename)130 delete_work_directory (const gchar *filename)
131 {
132 /* XXX Instead of complex error checking here, we should ideally use
133 * a recursive GDir / g_unlink() function.
134 *
135 * We cannot use GFile and the recursive delete function without
136 * corrupting our contained D-Bus environment with service files
137 * from the OS.
138 */
139 const gchar *argv[] = { "/bin/rm", "-rf", filename, NULL };
140 gboolean spawn_succeeded;
141 gint exit_status;
142
143 spawn_succeeded = g_spawn_sync (
144 NULL, (gchar **) argv, NULL, 0, NULL, NULL,
145 NULL, NULL, &exit_status, NULL);
146
147 g_assert (spawn_succeeded);
148 #ifndef G_OS_WIN32
149 g_assert (WIFEXITED (exit_status));
150 g_assert_cmpint (WEXITSTATUS (exit_status), ==, 0);
151 #else
152 g_assert_cmpint (exit_status, ==, 0);
153 #endif
154 }
155
156 ESourceBackendSummarySetup *
setup_empty_book(void)157 setup_empty_book (void)
158 {
159 ESourceBackendSummarySetup *setup;
160 ESource *scratch;
161 GError *error = NULL;
162
163 scratch = e_source_new_with_uid ("test-source", NULL, &error);
164 if (!scratch)
165 g_error ("Error creating scratch source");
166
167 /* This is a bit of a cheat */
168 setup = g_object_new (E_TYPE_SOURCE_BACKEND_SUMMARY_SETUP, "source", scratch, NULL);
169 e_source_backend_summary_setup_set_summary_fields (
170 setup,
171 /* We don't use this field in our tests anyway */
172 E_CONTACT_FILE_AS,
173 0);
174
175 g_object_unref (scratch);
176
177 return setup;
178 }
179
180 static gchar *
fetch_vcard_from_hash(const gchar * uid,const gchar * extra,gpointer user_data)181 fetch_vcard_from_hash (const gchar *uid,
182 const gchar *extra,
183 gpointer user_data)
184 {
185 EbSqlFixture *fixture = user_data;
186 EContact *contact;
187
188 g_assert (extra && extra[0]);
189
190 /* vCards not stored in shallow addressbooks, instead loaded on the fly */
191 contact = g_hash_table_lookup (fixture->contacts, extra);
192 if (contact)
193 return e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30);
194
195 return NULL;
196 }
197
198 static void
contact_change_cb(EbSqlChangeType change_type,const gchar * uid,const gchar * extra,const gchar * vcard,gpointer user_data)199 contact_change_cb (EbSqlChangeType change_type,
200 const gchar *uid,
201 const gchar *extra,
202 const gchar *vcard,
203 gpointer user_data)
204 {
205 EbSqlFixture *fixture = user_data;
206 EContact *contact;
207
208 if (change_type == EBSQL_CHANGE_LOCALE_CHANGED)
209 fixture->n_locale_changes++;
210 else if (change_type == EBSQL_CHANGE_CONTACT_ADDED)
211 fixture->n_add_changes++;
212
213 /* Replace the current contact with the new one */
214 contact = e_contact_new_from_vcard (vcard);
215 g_hash_table_insert (fixture->contacts, g_strdup (extra), contact);
216 }
217
218 void
e_sqlite_fixture_setup(EbSqlFixture * fixture,gconstpointer user_data)219 e_sqlite_fixture_setup (EbSqlFixture *fixture,
220 gconstpointer user_data)
221 {
222 EbSqlClosure *closure = (EbSqlClosure *) user_data;
223 ESourceBackendSummarySetup *setup = NULL;
224 gchar *filename, *directory;
225 GError *error = NULL;
226
227 fixture->contacts =
228 g_hash_table_new_full (
229 g_str_hash,
230 g_str_equal,
231 g_free,
232 g_object_unref);
233
234 /* Cleanup from last test */
235 directory = g_build_filename (g_get_tmp_dir (), "test-sqlite-cache", NULL);
236 delete_work_directory (directory);
237 g_free (directory);
238 filename = g_build_filename (g_get_tmp_dir (), "test-sqlite-cache", "contacts.db", NULL);
239
240 if (closure->setup_summary)
241 setup = closure->setup_summary ();
242
243 if (closure->without_vcards)
244 fixture->ebsql = e_book_sqlite_new_full (
245 filename,
246 NULL,
247 setup,
248 fetch_vcard_from_hash,
249 contact_change_cb,
250 fixture,
251 NULL, NULL,
252 &error);
253 else
254 fixture->ebsql = e_book_sqlite_new_full (
255 filename,
256 NULL,
257 setup,
258 NULL,
259 contact_change_cb,
260 fixture,
261 NULL, NULL,
262 &error);
263
264 g_clear_object (&setup);
265
266 if (!fixture->ebsql)
267 g_error ("Failed to create the SQLite: %s", error->message);
268
269 g_free (filename);
270 }
271
272 void
e_sqlite_fixture_teardown(EbSqlFixture * fixture,gconstpointer user_data)273 e_sqlite_fixture_teardown (EbSqlFixture *fixture,
274 gconstpointer user_data)
275 {
276 g_object_unref (fixture->ebsql);
277 g_hash_table_destroy (fixture->contacts);
278 }
279
280 void
e_sqlite_cursor_fixture_setup(EbSqlCursorFixture * fixture,gconstpointer user_data)281 e_sqlite_cursor_fixture_setup (EbSqlCursorFixture *fixture,
282 gconstpointer user_data)
283 {
284 EbSqlFixture *base_fixture = (EbSqlFixture *) fixture;
285 EbSqlCursorClosure *data = (EbSqlCursorClosure *) user_data;
286 EContactField sort_fields[] = { E_CONTACT_FAMILY_NAME, E_CONTACT_GIVEN_NAME };
287 EBookCursorSortType sort_types[] = { data->sort_type, data->sort_type };
288 GSList *contacts = NULL;
289 GSList *extra_list = NULL;
290 GError *error = NULL;
291 gint i;
292 gchar *sexp = NULL;
293
294 e_sqlite_fixture_setup (base_fixture, user_data);
295
296 if (data->locale)
297 e_sqlite_cursor_fixture_set_locale (fixture, data->locale);
298 else
299 e_sqlite_cursor_fixture_set_locale (fixture, "en_US.UTF-8");
300
301 for (i = 0; i < N_SORTED_CONTACTS; i++) {
302 gchar *case_name = g_strdup_printf ("sorted-%d", i + 1);
303 gchar *vcard;
304 EContact *contact;
305
306 vcard = new_vcard_from_test_case (case_name);
307 contact = e_contact_new_from_vcard (vcard);
308 contacts = g_slist_prepend (contacts, contact);
309 extra_list = g_slist_prepend (extra_list, case_name);
310
311 g_free (vcard);
312
313 fixture->contacts[i] = contact;
314
315 /* These need to be added to the hash as well */
316 g_hash_table_insert (
317 base_fixture->contacts,
318 g_strdup (case_name),
319 g_object_ref (contact));
320 }
321
322 if (!e_book_sqlite_add_contacts (base_fixture->ebsql,
323 contacts, extra_list,
324 FALSE, NULL, &error)) {
325 /* Dont complain here, we re-use the same addressbook for multiple tests
326 * and we can't add the same contacts twice
327 */
328 if (g_error_matches (error, E_BOOK_SQLITE_ERROR,
329 E_BOOK_SQLITE_ERROR_CONSTRAINT))
330 g_clear_error (&error);
331 else
332 g_error ("Failed to add test contacts: %s", error->message);
333 }
334
335 g_slist_free (contacts);
336 g_slist_free_full (extra_list, g_free);
337
338 /* Allow a surrounding fixture setup to add a query here */
339 if (fixture->query) {
340 sexp = e_book_query_to_string (fixture->query);
341 e_book_query_unref (fixture->query);
342 fixture->query = NULL;
343 }
344
345 fixture->cursor = e_book_sqlite_cursor_new (
346 base_fixture->ebsql, sexp,
347 sort_fields, sort_types, 2, &error);
348
349 if (!fixture->cursor)
350 g_error ("Failed to create cursor: %s\n", error->message);
351
352 g_free (sexp);
353 }
354
355 void
e_sqlite_cursor_fixture_filtered_setup(EbSqlCursorFixture * fixture,gconstpointer user_data)356 e_sqlite_cursor_fixture_filtered_setup (EbSqlCursorFixture *fixture,
357 gconstpointer user_data)
358 {
359 fixture->query = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_ENDS_WITH, ".com");
360
361 e_sqlite_cursor_fixture_setup (fixture, user_data);
362 }
363
364 void
e_sqlite_cursor_fixture_teardown(EbSqlCursorFixture * fixture,gconstpointer user_data)365 e_sqlite_cursor_fixture_teardown (EbSqlCursorFixture *fixture,
366 gconstpointer user_data)
367 {
368 EbSqlFixture *base_fixture = (EbSqlFixture *) fixture;
369 gint i;
370
371 for (i = 0; i < N_SORTED_CONTACTS; i++) {
372 if (fixture->contacts[i])
373 g_object_unref (fixture->contacts[i]);
374 }
375
376 e_book_sqlite_cursor_free (base_fixture->ebsql, fixture->cursor);
377 e_sqlite_fixture_teardown (base_fixture, user_data);
378 }
379
380 void
e_sqlite_cursor_fixture_set_locale(EbSqlCursorFixture * fixture,const gchar * locale)381 e_sqlite_cursor_fixture_set_locale (EbSqlCursorFixture *fixture,
382 const gchar *locale)
383 {
384 EbSqlFixture *base_fixture = (EbSqlFixture *) fixture;
385 GError *error = NULL;
386
387 if (!e_book_sqlite_set_locale (base_fixture->ebsql,
388 locale, NULL, &error))
389 g_error ("Failed to set locale: %s", error->message);
390 }
391
392 static gint
find_contact_data(EbSqlSearchData * data,const gchar * uid)393 find_contact_data (EbSqlSearchData *data,
394 const gchar *uid)
395 {
396 return g_strcmp0 (data->uid, uid);
397 }
398
399 void
assert_contacts_order_slist(GSList * results,GSList * uids)400 assert_contacts_order_slist (GSList *results,
401 GSList *uids)
402 {
403 gint position = -1;
404 GSList *link, *l;
405
406 /* Assert that all passed UIDs are found in the
407 * results, and that those UIDs are in the
408 * specified order.
409 */
410 for (l = uids; l; l = l->next) {
411 const gchar *uid = l->data;
412 gint new_position;
413
414 link = g_slist_find_custom (results, uid, (GCompareFunc) find_contact_data);
415 if (!link)
416 g_error ("Specified uid '%s' was not found in results", uid);
417
418 new_position = g_slist_position (results, link);
419 g_assert_cmpint (new_position, >, position);
420 position = new_position;
421 }
422
423 }
424
425 void
assert_contacts_order(GSList * results,const gchar * first_uid,...)426 assert_contacts_order (GSList *results,
427 const gchar *first_uid,
428 ...)
429 {
430 GSList *uids = NULL;
431 gchar *uid;
432 va_list args;
433
434 g_assert (first_uid);
435
436 uids = g_slist_append (uids, (gpointer) first_uid);
437
438 va_start (args, first_uid);
439 uid = va_arg (args, gchar *);
440 while (uid) {
441 uids = g_slist_append (uids, uid);
442 uid = va_arg (args, gchar *);
443 }
444 va_end (args);
445
446 assert_contacts_order_slist (results, uids);
447 g_slist_free (uids);
448 }
449
450 void
print_results(GSList * results)451 print_results (GSList *results)
452 {
453 GSList *l;
454
455 if (g_getenv ("TEST_DEBUG") == NULL)
456 return;
457
458 g_print ("\nPRINTING RESULTS:\n");
459
460 for (l = results; l; l = l->next) {
461 EbSqlSearchData *data = l->data;
462
463 g_print ("\n%s\n", data->vcard);
464 }
465
466 g_print ("\nRESULT LIST_FINISHED\n");
467 }
468
469 /********************************************
470 * Move By Test Helpers
471 ********************************************/
472 #define DEBUG_FIXTURE 0
473
474 static StepData *
step_test_new_internal(const gchar * test_path,const gchar * locale,gboolean store_vcards,gboolean empty_book)475 step_test_new_internal (const gchar *test_path,
476 const gchar *locale,
477 gboolean store_vcards,
478 gboolean empty_book)
479 {
480 StepData *data;
481
482 data = g_slice_new0 (StepData);
483
484 data->parent.locale = g_strdup (locale);
485 data->parent.sort_type = E_BOOK_CURSOR_SORT_ASCENDING;
486
487 data->parent.parent.without_vcards = (store_vcards == FALSE);
488 if (empty_book)
489 data->parent.parent.setup_summary = setup_empty_book;
490
491 data->path = g_strdup (test_path);
492
493 return data;
494 }
495
496 static void
step_test_free(StepData * data)497 step_test_free (StepData *data)
498 {
499 GList *l;
500
501 g_free (data->path);
502 g_free ((gchar *) data->parent.locale);
503
504 for (l = data->assertions; l; l = l->next) {
505 StepAssertion *assertion = l->data;
506
507 g_free (assertion->locale);
508 g_slice_free (StepAssertion, assertion);
509 }
510
511 g_slice_free (StepData, data);
512 }
513
514 StepData *
step_test_new(const gchar * test_prefix,const gchar * test_path,const gchar * locale,gboolean store_vcards,gboolean empty_book)515 step_test_new (const gchar *test_prefix,
516 const gchar *test_path,
517 const gchar *locale,
518 gboolean store_vcards,
519 gboolean empty_book)
520 {
521 StepData *data;
522 gchar *path;
523
524 path = g_strconcat (test_prefix, test_path, NULL);
525 data = step_test_new_internal (path, locale, store_vcards, empty_book);
526 g_free (path);
527
528 return data;
529 }
530
531 StepData *
step_test_new_full(const gchar * test_prefix,const gchar * test_path,const gchar * locale,gboolean store_vcards,gboolean empty_book,EBookCursorSortType sort_type)532 step_test_new_full (const gchar *test_prefix,
533 const gchar *test_path,
534 const gchar *locale,
535 gboolean store_vcards,
536 gboolean empty_book,
537 EBookCursorSortType sort_type)
538 {
539 StepData *data;
540 gchar *path;
541
542 path = g_strconcat (test_prefix, test_path, NULL);
543 data = step_test_new_internal (path, locale, store_vcards, empty_book);
544 data->parent.sort_type = sort_type;
545 g_free (path);
546
547 return data;
548 }
549
550 static void
test_cursor_move_teardown(EbSqlCursorFixture * fixture,gconstpointer user_data)551 test_cursor_move_teardown (EbSqlCursorFixture *fixture,
552 gconstpointer user_data)
553 {
554 StepData *data = (StepData *) user_data;
555
556 e_sqlite_cursor_fixture_teardown (fixture, user_data);
557 step_test_free (data);
558 }
559
560 static void
assert_step(EbSqlCursorFixture * fixture,StepData * data,StepAssertion * assertion,GSList * results,gint n_results,gboolean expect_results)561 assert_step (EbSqlCursorFixture *fixture,
562 StepData *data,
563 StepAssertion *assertion,
564 GSList *results,
565 gint n_results,
566 gboolean expect_results)
567 {
568 GSList *uids = NULL;
569 gint i, expected = 0;
570
571 /* Count the number of really expected results */
572 for (i = 0; i < ABS (assertion->count); i++) {
573 gint index = assertion->expected[i];
574
575 if (index < 0)
576 break;
577
578 expected++;
579 }
580
581 g_assert_cmpint (n_results, ==, expected);
582 if (!expect_results) {
583 g_assert_cmpint (g_slist_length (results), ==, 0);
584 return;
585 }
586
587 /* Assert the exact amount of requested results */
588 g_assert_cmpint (g_slist_length (results), ==, expected);
589
590 #if DEBUG_FIXTURE
591 g_print (
592 "%s: Constructing expected result list for a fetch of %d: ",
593 data->path, assertion->count);
594 #endif
595 for (i = 0; i < ABS (assertion->count); i++) {
596 gint index = assertion->expected[i];
597 gchar *uid;
598
599 if (index < 0)
600 break;
601
602 uid = (gchar *) e_contact_get_const (fixture->contacts[index], E_CONTACT_UID);
603 uids = g_slist_append (uids, uid);
604
605 #if DEBUG_FIXTURE
606 g_print ("%s ", uid);
607 #endif
608
609 }
610 #if DEBUG_FIXTURE
611 g_print ("\n");
612 #endif
613
614 assert_contacts_order_slist (results, uids);
615 g_slist_free (uids);
616 }
617
618 static void
test_step(EbSqlCursorFixture * fixture,gconstpointer user_data)619 test_step (EbSqlCursorFixture *fixture,
620 gconstpointer user_data)
621 {
622 EbSqlFixture *base_fixture = (EbSqlFixture *) fixture;
623 StepData *data = (StepData *) user_data;
624 GSList *results = NULL;
625 GError *error = NULL;
626 gint n_results;
627 EbSqlCursorOrigin origin;
628 GList *l;
629 gboolean reset = TRUE;
630
631 for (l = data->assertions; l; l = l->next) {
632 StepAssertion *assertion = l->data;
633
634 if (assertion->locale) {
635 gint n_locale_changes = base_fixture->n_locale_changes;
636
637 if (!e_book_sqlite_set_locale (base_fixture->ebsql,
638 assertion->locale,
639 NULL, &error))
640 g_error ("Failed to set locale: %s", error->message);
641
642 n_locale_changes = (base_fixture->n_locale_changes - n_locale_changes);
643
644 /* Only check for contact changes is phone numbers are supported,
645 * contact changes only happen because of e164 number interpretations.
646 */
647 if (e_phone_number_is_supported () &&
648 assertion->count != -1 &&
649 assertion->count != n_locale_changes)
650 g_error (
651 "Expected %d e164 numbers to change, %d actually changed.",
652 assertion->count, n_locale_changes);
653
654 reset = TRUE;
655 continue;
656 }
657
658 /* For the first call to e_book_sqlite_cursor_step(),
659 * or the first reset after locale change, set the origin accordingly.
660 */
661 if (reset) {
662 if (assertion->count < 0)
663 origin = EBSQL_CURSOR_ORIGIN_END;
664 else
665 origin = EBSQL_CURSOR_ORIGIN_BEGIN;
666
667 reset = FALSE;
668 } else
669 origin = EBSQL_CURSOR_ORIGIN_CURRENT;
670
671 /* Try only fetching the contacts but not moving the cursor */
672 n_results = e_book_sqlite_cursor_step (
673 base_fixture->ebsql,
674 fixture->cursor,
675 EBSQL_CURSOR_STEP_FETCH,
676 origin,
677 assertion->count,
678 &results,
679 NULL, &error);
680 if (n_results < 0)
681 g_error ("Error fetching cursor results: %s", error->message);
682
683 print_results (results);
684 assert_step (fixture, data, assertion, results, n_results, TRUE);
685 g_slist_foreach (results, (GFunc) e_book_sqlite_search_data_free, NULL);
686 g_slist_free (results);
687 results = NULL;
688
689 /* Do it again, this time only moving the cursor */
690 n_results = e_book_sqlite_cursor_step (
691 base_fixture->ebsql,
692 fixture->cursor,
693 EBSQL_CURSOR_STEP_MOVE,
694 origin,
695 assertion->count,
696 &results,
697 NULL, &error);
698 if (n_results < 0)
699 g_error ("Error fetching cursor results: %s", error->message);
700
701 print_results (results);
702 assert_step (fixture, data, assertion, results, n_results, FALSE);
703 g_slist_foreach (results, (GFunc) e_book_sqlite_search_data_free, NULL);
704 g_slist_free (results);
705 results = NULL;
706 }
707 }
708
709 static void
step_test_add_assertion_va_list(StepData * data,gint count,va_list args)710 step_test_add_assertion_va_list (StepData *data,
711 gint count,
712 va_list args)
713 {
714 StepAssertion *assertion = g_slice_new0 (StepAssertion);
715 gint expected, i;
716
717 assertion->count = count;
718
719 #if DEBUG_FIXTURE
720 g_print ("Adding assertion to test %d: %s\n", i + 1, data->path);
721 g_print (" Test will move by %d and expect: ", count);
722 #endif
723 for (i = 0; i < ABS (count); i++) {
724 expected = va_arg (args, gint);
725
726 #if DEBUG_FIXTURE
727 g_print ("%d ", expected);
728 #endif
729 assertion->expected[i] = expected - 1;
730 }
731 #if DEBUG_FIXTURE
732 g_print ("\n");
733 #endif
734
735 data->assertions = g_list_append (data->assertions, assertion);
736 }
737
738 /* A positive of negative 'count' value
739 * followed by ABS (count) UID indexes.
740 *
741 * The indexes start at 1 so that they
742 * are easier to match up with the chart
743 * in data-test-utils.h
744 */
745 void
step_test_add_assertion(StepData * data,gint count,...)746 step_test_add_assertion (StepData *data,
747 gint count,
748 ...)
749 {
750 va_list args;
751
752 va_start (args, count);
753 step_test_add_assertion_va_list (data, count, args);
754 va_end (args);
755 }
756
757 void
step_test_change_locale(StepData * data,const gchar * locale,gint expected_changes)758 step_test_change_locale (StepData *data,
759 const gchar *locale,
760 gint expected_changes)
761 {
762 StepAssertion *assertion = g_slice_new0 (StepAssertion);
763
764 assertion->locale = g_strdup (locale);
765 assertion->count = expected_changes;
766 data->assertions = g_list_append (data->assertions, assertion);
767 }
768
769 void
step_test_add(StepData * data,gboolean filtered)770 step_test_add (StepData *data,
771 gboolean filtered)
772 {
773 data->filtered = filtered;
774
775 g_test_add (
776 data->path, EbSqlCursorFixture, data,
777 filtered ?
778 e_sqlite_cursor_fixture_filtered_setup :
779 e_sqlite_cursor_fixture_setup,
780 test_step,
781 test_cursor_move_teardown);
782 }
783
784