diff --git a/.gitignore b/.gitignore
index 8065388..578fbda 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
*.pc
*.tar.gz
*.typelib
+*.vapi
.deps
.cproject
.libs
@@ -39,7 +40,8 @@ stamp*
.cproject
/build/coverage*
-/build/m4
+/build/m4/*
+!/build/m4/vapigen.m4
/build/valgrind-suppressions
/docs/reference/libsecret/version.xml
@@ -67,8 +69,11 @@ stamp*
/library/secret-dbus-generated.[ch]
/library/secret-enum-types.[ch]
/library/tests/test-*
+/library/tests/*.metadata
!/library/tests/test-*.c
!/library/tests/test-*.js
!/library/tests/test-*.py
+!/library/tests/test-*.vala
+/library/tests/test-vala-lang.c
/tool/secret-tool
diff --git a/build/m4/vapigen.m4 b/build/m4/vapigen.m4
new file mode 100644
index 0000000..17558df
--- /dev/null
+++ b/build/m4/vapigen.m4
@@ -0,0 +1,96 @@
+dnl vapigen.m4
+dnl
+dnl Copyright 2012 Evan Nemerson
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# VAPIGEN_CHECK([VERSION], [API_VERSION], [FOUND-INTROSPECTION], [DEFAULT])
+# --------------------------------------
+# Check vapigen existence and version
+#
+# See http://live.gnome.org/Vala/UpstreamGuide for detailed documentation
+AC_DEFUN([VAPIGEN_CHECK],
+[
+ AC_BEFORE([GOBJECT_INTROSPECTION_CHECK],[$0])
+ AC_BEFORE([GOBJECT_INTROSPECTION_REQUIRE],[$0])
+
+ AC_ARG_ENABLE([vala],
+ [AS_HELP_STRING([--enable-vala[=@<:@no/auto/yes@:>@]],[build Vala bindings @<:@default=]ifelse($4,,auto,$4)[@:>@])],,[
+ AS_IF([test "x$4" = "x"], [
+ enable_vala=auto
+ ], [
+ enable_vala=$4
+ ])
+ ])
+
+ AS_CASE([$enable_vala], [no], [enable_vala=no],
+ [yes], [
+ AS_IF([test "x$3" != "xyes" -a "x$found_introspection" != "xyes"], [
+ AC_MSG_ERROR([Vala bindings require GObject Introspection])
+ ])
+ ], [auto], [
+ AS_IF([test "x$3" != "xyes" -a "x$found_introspection" != "xyes"], [
+ enable_vala=no
+ ])
+ ], [
+ AC_MSG_ERROR([Invalid argument passed to --enable-vala, should be one of @<:@no/auto/yes@:>@])
+ ])
+
+ AS_IF([test "x$2" = "x"], [
+ vapigen_pkg_name=vapigen
+ ], [
+ vapigen_pkg_name=vapigen-$2
+ ])
+ AS_IF([test "x$1" = "x"], [
+ vapigen_pkg="$vapigen_pkg_name"
+ ], [
+ vapigen_pkg="$vapigen_pkg_name >= $1"
+ ])
+
+ PKG_PROG_PKG_CONFIG
+
+ PKG_CHECK_EXISTS([$vapigen_pkg], [
+ AS_IF([test "$enable_vala" = "auto"], [
+ enable_vala=yes
+ ])
+ ], [
+ AS_CASE([$enable_vala], [yes], [
+ AC_MSG_ERROR([$vapigen_pkg not found])
+ ], [auto], [
+ enable_vala=no
+ ])
+ ])
+
+ AC_MSG_CHECKING([for vapigen])
+
+ AS_CASE([$enable_vala],
+ [yes], [
+ VAPIGEN=`$PKG_CONFIG --variable=vapigen vapigen`
+ VAPIGEN_MAKEFILE=`$PKG_CONFIG --variable=datadir vapigen`/vala/Makefile.vapigen
+ AS_IF([test "x$2" = "x"], [
+ VAPIGEN_VAPIDIR=`$PKG_CONFIG --variable=vapidir vapigen`
+ ], [
+ VAPIGEN_VAPIDIR=`$PKG_CONFIG --variable=vapidir_versioned vapigen`
+ ])
+ ])
+
+ AC_MSG_RESULT([$enable_vala])
+
+ AC_SUBST([VAPIGEN])
+ AC_SUBST([VAPIGEN_VAPIDIR])
+ AC_SUBST([VAPIGEN_MAKEFILE])
+
+ AM_CONDITIONAL(ENABLE_VAPIGEN, test "x$enable_vala" = "xyes")
+])
diff --git a/configure.ac b/configure.ac
index 3077c39..26a3388 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,6 +71,18 @@ GTK_DOC_CHECK(1.9)
GOBJECT_INTROSPECTION_CHECK([1.29])
AC_PATH_PROG(GLIB_MKENUMS, glib-mkenums)
+# --------------------------------------------------------------------
+# Vala
+
+VALA_REQUIRED=0.17.2.12
+
+VAPIGEN_CHECK($VALA_REQUIRED)
+
+if test "$enable_vala" != "no"; then
+ AC_PATH_PROG([VALAC], [valac], [])
+fi
+AM_CONDITIONAL(HAVE_VALAC, test "x$VALAC" != "x")
+
# --------------------------------------------------------------------
# libgcrypt
diff --git a/docs/reference/libsecret/libsecret-examples.sgml b/docs/reference/libsecret/libsecret-examples.sgml
index f885799..67c3bce 100644
--- a/docs/reference/libsecret/libsecret-examples.sgml
+++ b/docs/reference/libsecret/libsecret-examples.sgml
@@ -614,4 +614,172 @@
+
+ Vala examples
+
+
+ Vala example: Define a password schema
+
+ Each stored password has a set of attributes which are later
+ used to lookup the password. The names and types of the attributes
+ are defined in a schema. The schema is usually defined once globally.
+ Here's how to define a schema:
+
+
+
+ See the other examples for how
+ to use the schema.
+
+
+
+ Vala example: Store a password
+
+ Here's how to store a password in the running secret service,
+ like gnome-keyring or ksecretservice.
+
+ Each stored password has a set of attributes which are later
+ used to lookup the password. The attributes should not contain
+ secrets, as they are not stored in an encrypted fashion.
+
+ These examples use the example
+ schema.
+
+ This first example stores a password asynchronously, and is
+ appropriate for GUI applications so that the UI does not block.
+
+ ();
+ attributes["number"] = "8";
+ attributes["string"] = "eight";
+ attributes["even"] = "true";
+
+ Secret.password_storev.begin (example_schema, attributes, Secret.COLLECTION_DEFAULT,
+ "The label", "the password", null, (obj, async_res) => {
+ bool res = Secret.password_store.end (async_res);
+ /* ... do something now that the password has been stored */
+ });
+ ]]>
+
+ If you are already inside of an async function, you can also
+ use the yield keyword:
+
+ ();
+ attributes["number"] = "8";
+ attributes["string"] = "eight";
+ attributes["even"] = "true";
+
+ bool res = yield Secret.password_storev (example_schema, attributes,
+ Secret.COLLECTION_DEFAULT, "The label",
+ "the password", null);
+ ]]>
+
+ If you would like to avoid creating a hash table for the
+ attributes you can just use the variadic version:
+
+
+
+ This next example stores a password synchronously. The function
+ call will block until the password is stored. So this is appropriate for
+ non GUI applications.
+
+
+
+
+
+ Vala example: Lookup a password
+
+ Here's how to lookup a password in the running secret service,
+ like gnome-keyring or ksecretservice.
+
+ Each stored password has a set of attributes which are
+ used to lookup the password. If multiple passwords match the
+ lookup attributes, then the one stored most recently is returned.
+
+ These examples use the example
+ schema.
+
+ This first example looks up a password asynchronously, and is
+ appropriate for GUI applications so that the UI does not block.
+
+ ();
+ attributes["number"] = "8";
+ attributes["string"] = "eight";
+ attributes["even"] = "true";
+
+ Secret.password_lookupv.begin (example_schema, attributes, null, (obj, async_res) => {
+ string password = Secret.password_lookup.end (async_res);
+ });
+ ]]>
+
+ This next example looks up a password synchronously. The function
+ call will block until the lookup completes. So this is appropriate for
+ non GUI applications.
+
+
+
+
+
+ Vala example: Remove a password
+
+ Here's how to remove a password from the running secret service,
+ like gnome-keyring or ksecretservice.
+
+ Each stored password has a set of attributes which are
+ used to find which password to remove. If multiple passwords match the
+ attributes, then the one stored most recently is removed.
+
+ These examples use the example
+ schema.
+
+ This first example removes a password asynchronously, and is
+ appropriate for GUI applications so that the UI does not block.
+
+ ();
+ attributes["number"] = "8";
+ attributes["string"] = "eight";
+ attributes["even"] = "true";
+
+ Secret.password_removev.begin (example_schema, attributes, null, (obj, async_res) => {
+ bool removed = Secret.password_removev.end (async_res);
+ });
+ ]]>
+
+ This next example removes a password synchronously. The function
+ call will block until the removal completes. So this is appropriate for
+ non GUI applications.
+
+ ();
+ attributes["number"] = "8";
+ attributes["string"] = "eight";
+ attributes["even"] = "true";
+
+ bool removed = Secret.password_remove_sync (example_schema, null,
+ "number", 8, "string", "eight", "even", true);
+ /* removed will be true if the password was removed */
+ ]]>
+
+
+
+
diff --git a/library/Makefile.am b/library/Makefile.am
index c6c27ce..3acea9f 100644
--- a/library/Makefile.am
+++ b/library/Makefile.am
@@ -94,6 +94,8 @@ secret-enum-types.h: secret-enum-types.h.template $(HEADER_FILES)
secret-enum-types.c: secret-enum-types.c.template $(HEADER_FILES)
$(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@
+CLEANFILES =
+
# ------------------------------------------------------------------
# INTROSPECTION
@@ -121,7 +123,24 @@ gir_DATA = $(INTROSPECTION_GIRS)
typelibsdir = $(libdir)/girepository-1.0
typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
-endif
+if ENABLE_VAPIGEN
+include $(VAPIGEN_MAKEFILE)
+
+libsecret-@SECRET_MAJOR@.vapi: Secret-@SECRET_MAJOR@.gir Secret-@SECRET_MAJOR@.metadata
+
+VAPIGEN_VAPIS = libsecret-@SECRET_MAJOR@.vapi
+
+libsecret_@SECRET_MAJOR@_vapi_DEPS = gio-2.0
+libsecret_@SECRET_MAJOR@_vapi_METADATADIRS = $(srcdir)
+libsecret_@SECRET_MAJOR@_vapi_FILES = Secret-@SECRET_MAJOR@.gir
+
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = $(VAPIGEN_VAPIS)
+
+CLEANFILES += $(VAPIGEN_VAPIS)
+
+endif # ENABLE_VAPIGEN
+endif # HAVE_INTROSPECTION
# ------------------------------------------------------------------
# PKG CONFIG
@@ -139,9 +158,10 @@ EXTRA_DIST = \
secret-enum-types.h.template \
secret-enum-types.c.template \
org.freedesktop.Secrets.xml \
+ Secret-@SECRET_MAJOR@.metadata \
$(NULL)
-CLEANFILES = \
+CLEANFILES += \
$(pkgconfig_DATA) \
$(gir_DATA) \
$(typelibs_DATA) \
diff --git a/library/Secret-0.metadata b/library/Secret-0.metadata
new file mode 100644
index 0000000..35ce419
--- /dev/null
+++ b/library/Secret-0.metadata
@@ -0,0 +1,26 @@
+// Metadata file for Vala API generation.
+// See https://live.gnome.org/Vala/UpstreamGuide for more information
+
+Service
+ .lookup skip=false
+ .lookupv finish_name="secret_service_lookup_finish"
+ .remove skip=false
+ .removev finish_name="secret_service_remove_finish"
+ .store skip=false
+ .storev finish_name="secret_service_store_finish"
+
+Schema
+ .new skip=false
+
+password_lookup skip=false
+password_lookup_sync skip=false throws="GLib.Error"
+ .error skip
+password_lookupv finish_name="secret_password_lookup_finish"
+password_remove skip=false
+password_remove_sync skip=false throws="GLib.Error"
+ .error skip
+password_removev finish_name="secret_password_remove_finish"
+password_store skip=false
+password_store_sync skip=false throws="GLib.Error"
+ .error skip
+password_storev finish_name="secret_password_store_finish"
diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am
index 0e7908b..77c0d28 100644
--- a/library/tests/Makefile.am
+++ b/library/tests/Makefile.am
@@ -10,7 +10,8 @@ INCLUDES = \
noinst_LTLIBRARIES = libmock_service.la
libmock_service_la_SOURCES = \
- mock-service.c mock-service.h \
+ mock-service.c \
+ mock-service.h \
$(NULL)
libmock_service_la_CFLAGS = \
@@ -30,7 +31,7 @@ LDADD = \
libmock_service.la \
$(NULL)
-TEST_PROGS = \
+C_TESTS = \
test-value \
test-prompt \
test-service \
@@ -41,6 +42,10 @@ TEST_PROGS = \
test-collection \
$(NULL)
+TEST_PROGS = \
+ $(C_TESTS) \
+ $(NULL)
+
check_PROGRAMS = \
$(TEST_PROGS)
@@ -63,8 +68,36 @@ PY_TESTS = \
PY_ENV = $(JS_ENV)
-test-c: $(TEST_PROGS)
- @gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
+if HAVE_VALAC
+
+VALA_V = $(VALA_V_$(V))
+VALA_V_ = $(VALA_V_$(AM_DEFAULT_VERBOSITY))
+VALA_V_0 = @echo " VALAC " $^;
+
+VALA_TESTS = \
+ test-vala-lang \
+ $(NULL)
+
+test-vala-lang.c: test-vala-lang.vala libsecret-@SECRET_MAJOR@.vapi mock-service-0.vapi
+ $(VALA_V)$(VALAC) -C --pkg gio-2.0 $^
+
+TEST_PROGS += $(VALA_TESTS)
+
+test_vala_lang_CFLAGS = -w
+
+DISTCLEANFILES = test-vala-lang.c
+
+test-vala: $(VALA_TESTS)
+ @gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(VALA_TESTS)
+
+else
+
+test-vala:
+
+endif # HAVE_VALAC
+
+test-c: $(C_TESTS)
+ @gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(C_TESTS)
test-js:
@for js in $(JS_TESTS); do echo "TEST: $$js"; $(JS_ENV) gjs $(srcdir)/$$js; done
@@ -72,7 +105,7 @@ test-js:
test-py:
@for py in $(PY_TESTS); do echo "TEST: $$py"; $(PY_ENV) python $(srcdir)/$$py; done
-test: test-c test-py test-js
+test: test-c test-py test-js test-vala
# ------------------------------------------------------------------
# INTROSPECTION
@@ -91,7 +124,7 @@ MockService_0_gir_PACKAGES = gobject-2.0 gio-2.0
MockService_0_gir_EXPORT_PACKAGES = mock-service-0
MockService_0_gir_INCLUDES = GObject-2.0 Gio-2.0
MockService_0_gir_LIBS = libmock_service.la
-MockService_0_gir_CFLAGS = -I$(top_srcdir) -I$(top_builddir)
+MockService_0_gir_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -I$(srcdir)
MockService_0_gir_FILES = $(libmock_service_la_SOURCES)
MockService_0_gir_SCANNERFLAGS = --c-include "mock-service.h"
@@ -99,7 +132,40 @@ noinst_DATA = \
$(INTROSPECTION_GIRS) \
$(INTROSPECTION_GIRS:.gir=.typelib)
-endif
+if ENABLE_VAPIGEN
+include $(VAPIGEN_MAKEFILE)
+
+mock-service-0.vapi: MockService-0.gir libsecret-@SECRET_MAJOR@.vapi
+
+VAPIGEN_VAPIS = mock-service-0.vapi
+
+mock_service_0_vapi_DEPS = gio-2.0 libsecret-@SECRET_MAJOR@
+mock_service_0_vapi_METADATADIRS = $(builddir)
+mock_service_0_vapi_VAPIDIRS = $(builddir)
+mock_service_0_vapi_FILES = MockService-0.gir
+
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = mock-service-0.vapi
+
+# We have to make a version of the VAPI which references the
+# uninstalled C headers.
+
+VAPIGEN_VAPIS += libsecret-@SECRET_MAJOR@.vapi
+
+Secret-@SECRET_MAJOR@.metadata: $(top_srcdir)/library/Secret-@SECRET_MAJOR@.metadata
+ $(AM_V_GEN) echo "* cheader_filename=\"secret-collection.h,secret-item.h,secret-password.h,secret-prompt.h,secret-schema.h,secret-schemas.h,secret-service.h,secret-types.h,secret-value.h\"" > $@ && \
+ cat < $^ >> $@
+
+libsecret-@SECRET_MAJOR@.vapi: Secret-@SECRET_MAJOR@.metadata $(top_builddir)/library/Secret-@SECRET_MAJOR@.gir
+
+libsecret_@SECRET_MAJOR@_vapi_DEPS = gio-2.0
+libsecret_@SECRET_MAJOR@_vapi_METADATADIRS = $(srcdir)
+libsecret_@SECRET_MAJOR@_vapi_FILES = $(top_builddir)/library/Secret-@SECRET_MAJOR@.gir
+
+noinst_DATA += $(VAPIGEN_VAPIS)
+
+endif # ENABLE_VAPIGEN
+endif # HAVE_INTROSPECTION
#--------------------------------------------------------------------
@@ -110,6 +176,8 @@ EXTRA_DIST = \
mock-service-normal.py \
mock-service-only-plain.py \
mock-service-prompt.py \
+ Secret-@SECRET_MAJOR@.metadata \
+ test-vala-lang.vala \
$(JS_TESTS) \
$(PY_TESTS) \
$(NULL)
diff --git a/library/tests/test-vala-lang.vala b/library/tests/test-vala-lang.vala
new file mode 100644
index 0000000..3bcee8d
--- /dev/null
+++ b/library/tests/test-vala-lang.vala
@@ -0,0 +1,172 @@
+Secret.Schema schema;
+Secret.Schema no_name_schema;
+
+private void test_lookup_sync () {
+ try {
+ string? password = Secret.password_lookup_sync (schema, null, "even", false, "string", "one", "number", 1);
+ GLib.assert (password == "111");
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+public async void test_lookup_async_ex () {
+ try {
+ string? password = yield Secret.password_lookup (schema, null, "even", false, "string", "one", "number", 1);
+ GLib.assert (password == "111");
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private void test_lookup_async () {
+ var loop = new GLib.MainLoop ();
+ test_lookup_async_ex.begin ((obj, async_res) => {
+ loop.quit ();
+ });
+ loop.run ();
+}
+
+private void test_lookup_no_name () {
+ try {
+ string? password = Secret.password_lookup_sync (schema, null, "number", 5);
+ GLib.assert (password == null);
+
+ password = Secret.password_lookup_sync (no_name_schema, null, "number", 5);
+ GLib.assert (password == "555");
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private void test_store_sync () {
+ try {
+ var attributes = new GLib.HashTable (GLib.str_hash, GLib.str_equal);
+ attributes["even"] = "false";
+ attributes["string"] = "nine";
+ attributes["number"] = "9";
+
+ string? password = Secret.password_lookupv_sync (schema, attributes);
+ GLib.assert (password == null);
+
+ bool stored = Secret.password_storev_sync (schema, attributes, Secret.COLLECTION_DEFAULT, "The number ", "999");
+ GLib.assert (stored);
+
+ password = Secret.password_lookupv_sync (schema, attributes);
+ GLib.assert (password == "999");
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private async void test_store_async_ex () {
+ var attributes = new GLib.HashTable (GLib.str_hash, GLib.str_equal);
+ attributes["even"] = "true";
+ attributes["string"] = "eight";
+ attributes["number"] = "8";
+
+ try {
+ string? password = yield Secret.password_lookupv (schema, attributes, null);
+ GLib.assert (password == null);
+
+ bool stored = yield Secret.password_storev (schema, attributes, Secret.COLLECTION_DEFAULT, "The number nine", "999", null);
+ GLib.assert (stored);
+
+ password = yield Secret.password_lookupv (schema, attributes, null);
+ GLib.assert (password == "999");
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private void test_store_async () {
+ var loop = new GLib.MainLoop ();
+ test_store_async_ex.begin ((obj, async_res) => {
+ loop.quit ();
+ });
+ loop.run ();
+}
+
+private void test_remove_sync () {
+ try {
+ var attributes = new GLib.HashTable (GLib.str_hash, GLib.str_equal);
+ attributes["even"] = "false";
+ attributes["string"] = "nine";
+ attributes["number"] = "9";
+
+ string? password = Secret.password_lookupv_sync (schema, attributes);
+ GLib.assert (password == "999");
+
+ bool removed = Secret.password_removev_sync (schema, attributes, null);
+ GLib.assert (removed);
+
+ password = Secret.password_lookupv_sync (schema, attributes);
+ GLib.assert (password == null);
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private async void test_remove_async_ex () {
+ var attributes = new GLib.HashTable (GLib.str_hash, GLib.str_equal);
+ attributes["even"] = "true";
+ attributes["string"] = "eight";
+ attributes["number"] = "8";
+
+ try {
+ string? password = yield Secret.password_lookupv (schema, attributes, null);
+ GLib.assert (password == "999");
+
+ bool removed = yield Secret.password_removev (schema, attributes, null);
+ GLib.assert (removed);
+
+ password = yield Secret.password_lookupv (schema, attributes, null);
+ GLib.assert (password == null);
+ } catch ( GLib.Error e ) {
+ GLib.error (e.message);
+ }
+}
+
+private void test_remove_async () {
+ var loop = new GLib.MainLoop ();
+ test_remove_async_ex.begin ((obj, async_res) => {
+ loop.quit ();
+ });
+ loop.run ();
+}
+
+private static int main (string[] args) {
+ GLib.Test.init (ref args);
+
+ try {
+ MockService.start ("mock-service-normal.py");
+ } catch ( GLib.Error e ) {
+ GLib.error ("Unable to start mock service: %s", e.message);
+ }
+
+ {
+ schema = new Secret.Schema ("org.mock.Schema", Secret.SchemaFlags.NONE,
+ "number", Secret.SchemaAttributeType.INTEGER,
+ "string", Secret.SchemaAttributeType.STRING,
+ "even", Secret.SchemaAttributeType.BOOLEAN);
+
+ no_name_schema = new Secret.Schema ("unused.Schema.Name", Secret.SchemaFlags.DONT_MATCH_NAME,
+ "number", Secret.SchemaAttributeType.INTEGER,
+ "string", Secret.SchemaAttributeType.STRING);
+ }
+
+ GLib.Test.add_data_func ("/vala/lookup/sync", test_lookup_sync);
+ GLib.Test.add_data_func ("/vala/lookup/async", test_lookup_async);
+ GLib.Test.add_data_func ("/vala/lookup/no-name", test_lookup_no_name);
+ GLib.Test.add_data_func ("/vala/store/sync", test_store_sync);
+ GLib.Test.add_data_func ("/vala/store/async", test_store_async);
+ GLib.Test.add_data_func ("/vala/remove/sync", test_remove_sync);
+ GLib.Test.add_data_func ("/vala/remove/async", test_remove_async);
+
+ var res = GLib.Test.run ();
+
+ MockService.stop ();
+ schema = null;
+
+ return res;
+}