Import Upstream version 2.72.4

This commit is contained in:
evinadmin 2023-07-04 11:23:22 +02:00
commit 4ef3ff9793
2003 changed files with 1332420 additions and 0 deletions

146
gio/tests/.gitignore vendored Normal file
View file

@ -0,0 +1,146 @@
actions
appinfo
appinfo-test
appmonitor
apps
async-close-output-stream
async-splice-output-stream
autoptr
basic-application
buffered-input-stream
buffered-output-stream
cancellable
connectable
contenttype
contexts
converter-stream
credentials
data-input-stream
data-output-stream
dbus-appinfo
dbus-launch
de/
defaultvalue
desktop-app-info
echo-server
file
fileattributematcher
filter-cat
filter-streams
gapplication
gapplication-example-actions
gapplication-example-cmdline
gapplication-example-cmdline2
gapplication-example-cmdline3
gapplication-example-dbushooks
gapplication-example-menu
gapplication-example-open
gdbus-addresses
gdbus-auth
gdbus-bz627724
gdbus-close-pending
gdbus-connection
gdbus-connection-flush
gdbus-connection-flush-helper
gdbus-connection-loss
gdbus-connection-slow
gdbus-daemon
gdbus-error
gdbus-example-export
gdbus-example-objectmanager-client
gdbus-example-objectmanager-server
gdbus-example-own-name
gdbus-example-peer
gdbus-example-proxy-subclass
gdbus-example-server
gdbus-example-subtree
gdbus-example-unix-fd-client
gdbus-example-watch-name
gdbus-example-watch-proxy
gdbus-exit-on-close
gdbus-export
gdbus-introspection
gdbus-message
gdbus-names
gdbus-non-socket
gdbus-overflow
gdbus-peer
gdbus-peer-object-manager
gdbus-proxy
gdbus-proxy-threads
gdbus-proxy-well-known-name
gdbus-serialization
gdbus-test-codegen
gdbus-test-codegen-generated*
gdbus-test-codegen-old
gdbus-test-fixture
gdbus-testserver
gdbus-threading
gdbus-address-get-session
glistmodel
gio-du
giomodule
giotypefuncs.inc
gnotification
gsubprocess
gsubprocess-testprog
g-file
g-file-info
g-icon
gmenumodel
gschemas.compiled
gsettings
gsettings.store
httpd
icons
inet-address
io-stream
live-g-file
memory-input-stream
memory-output-stream
mimeapps
monitor
network-address
network-monitor
org.gtk.test.enums.xml
org.gtk.test.gschema.xml
permission
pollable
plugin_resources.c
proxy
proxy-test
readwrite
resolver
resources
send-data
services/org.gtk.GDBus.Examples.ObjectManager.service
simple-async-result
simple-proxy
sleepy-stream
stream-rw_all
socket
socket-address
socket-client
socket-listener
socket-service
socket-server
srvtarget
task
test-generated.txt
test.gresource
test.mo
test_resources.c
test_resources2.c
test_resources2.h
testfilemonitor
thumbnail-verification
tls-certificate
tls-database
tls-interaction
unix-fd
unix-streams
vfs
volumemonitor
xgen-gio
xgen-giosrc.c
gresource-big-test.txt

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/digit_test">
<file>test1.txt</file>
</gresource>
</gresources>

1249
gio/tests/actions.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
[Desktop Entry]
Type=Application
Actions=frob;tweak;twiddle;broken;
Exec=true
[Desktop Action frob]
Name=Frobnicate
Exec=touch frob
[Desktop Action tweak]
Name=Tweak
Exec=touch tweak
[Desktop Action twiddle]
Name=Twiddle
Exec=touch twiddle

View file

@ -0,0 +1,6 @@
[Desktop Entry]
Type=Application
Name=appinfo-test
Exec=@installed_tests_dir@/appinfo-test --option
OnlyShowIn=GNOME;KDE;
NotShowIn=ROX;

View file

@ -0,0 +1,6 @@
[Desktop Entry]
Type=Application
Name=appinfo-test
Exec=@installed_tests_dir@/appinfo-test --option
OnlyShowIn=KDE;
NotShowIn=GNOME;

View file

@ -0,0 +1,19 @@
[Desktop Entry]
Type=Application
GenericName=generic-appinfo-test
Name=appinfo-test
Name[de]=appinfo-test-de
X-GNOME-FullName=example
X-GNOME-FullName[de]=Beispiel
Comment=GAppInfo example
Comment[de]=GAppInfo Beispiel
Exec=true --option %U %i --name %c --filename %k %m %%
Icon=testicon.svg
Terminal=true
StartupNotify=true
StartupWMClass=appinfo-class
MimeType=image/png;image/jpeg;
Keywords=keyword1;test keyword;
Categories=GNOME;GTK;
X-JunkFood=Burger
X-JunkFood[de]=Bratwurst

28
gio/tests/appinfo-test.c Normal file
View file

@ -0,0 +1,28 @@
#include <stdlib.h>
#include <gio/gio.h>
int
main (int argc, char *argv[])
{
const gchar *envvar;
g_test_init (&argc, &argv, NULL);
envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE");
if (envvar != NULL)
{
gchar *expected;
gint pid_from_env;
expected = g_test_build_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
g_assert_cmpstr (envvar, ==, expected);
g_free (expected);
envvar = g_getenv ("GIO_LAUNCHED_DESKTOP_FILE_PID");
g_assert (envvar != NULL);
pid_from_env = atoi (envvar);
g_assert_cmpint (pid_from_env, ==, getpid ());
}
return 0;
}

View file

@ -0,0 +1,19 @@
[Desktop Entry]
Type=Application
GenericName=generic-appinfo-test
Name=appinfo-test
Name[de]=appinfo-test-de
X-GNOME-FullName=example
X-GNOME-FullName[de]=Beispiel
Comment=GAppInfo example
Comment[de]=GAppInfo Beispiel
Exec=@installed_tests_dir@/appinfo-test --option %U %i --name %c --filename %k %m %%
Icon=testicon.svg
Terminal=false
StartupNotify=true
StartupWMClass=appinfo-class
MimeType=image/png;image/jpeg;
Keywords=keyword1;test keyword;
Categories=GNOME;GTK;
X-JunkFood=Burger
X-JunkFood[de]=Bratwurst

View file

@ -0,0 +1,11 @@
[Desktop Entry]
Type=Application
Name=appinfo-test
Name[de]=appinfo-test-de
X-GNOME-FullName=example
X-GNOME-FullName[de]=Beispiel
Comment=GAppInfo example
Comment[de]=GAppInfo Beispiel
Exec=@installed_tests_dir@/appinfo-test --option
TryExec=does-not-exist
Icon=testicon

601
gio/tests/appinfo.c Normal file
View file

@ -0,0 +1,601 @@
#include <locale.h>
#include <string.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
static void
test_launch_for_app_info (GAppInfo *appinfo)
{
GError *error = NULL;
gboolean success;
GFile *file;
GList *l;
const gchar *path;
gchar *uri;
if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0')
{
g_test_skip ("No DISPLAY set");
return;
}
success = g_app_info_launch (appinfo, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_true (success);
success = g_app_info_launch_uris (appinfo, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_true (success);
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
file = g_file_new_for_path (path);
l = NULL;
l = g_list_append (l, file);
success = g_app_info_launch (appinfo, l, NULL, &error);
g_assert_no_error (error);
g_assert_true (success);
g_list_free (l);
g_object_unref (file);
l = NULL;
uri = g_strconcat ("file://", g_test_get_dir (G_TEST_BUILT), "/appinfo-test.desktop", NULL);
l = g_list_append (l, uri);
l = g_list_append (l, "file:///etc/group#adm");
success = g_app_info_launch_uris (appinfo, l, NULL, &error);
g_assert_no_error (error);
g_assert_true (success);
g_list_free (l);
g_free (uri);
}
static void
test_launch (void)
{
GAppInfo *appinfo;
const gchar *path;
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
if (appinfo == NULL)
{
g_test_skip ("appinfo-test binary not installed");
return;
}
test_launch_for_app_info (appinfo);
g_object_unref (appinfo);
}
static void
test_launch_no_app_id (void)
{
const gchar desktop_file_base_contents[] =
"[Desktop Entry]\n"
"Type=Application\n"
"GenericName=generic-appinfo-test\n"
"Name=appinfo-test\n"
"Name[de]=appinfo-test-de\n"
"X-GNOME-FullName=example\n"
"X-GNOME-FullName[de]=Beispiel\n"
"Comment=GAppInfo example\n"
"Comment[de]=GAppInfo Beispiel\n"
"Icon=testicon.svg\n"
"Terminal=false\n"
"StartupNotify=true\n"
"StartupWMClass=appinfo-class\n"
"MimeType=image/png;image/jpeg;\n"
"Keywords=keyword1;test keyword;\n"
"Categories=GNOME;GTK;\n";
gchar *exec_line_variants[2];
gsize i;
exec_line_variants[0] = g_strdup_printf (
"Exec=%s/appinfo-test --option %%U %%i --name %%c --filename %%k %%m %%%%",
g_test_get_dir (G_TEST_BUILT));
exec_line_variants[1] = g_strdup_printf (
"Exec=%s/appinfo-test --option %%u %%i --name %%c --filename %%k %%m %%%%",
g_test_get_dir (G_TEST_BUILT));
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=791337");
for (i = 0; i < G_N_ELEMENTS (exec_line_variants); i++)
{
gchar *desktop_file_contents;
GKeyFile *fake_desktop_file;
GAppInfo *appinfo;
gboolean loaded;
g_test_message ("Exec line variant #%" G_GSIZE_FORMAT, i);
desktop_file_contents = g_strdup_printf ("%s\n%s",
desktop_file_base_contents,
exec_line_variants[i]);
/* We load a desktop file from memory to force the app not
* to have an app ID, which would check different codepaths.
*/
fake_desktop_file = g_key_file_new ();
loaded = g_key_file_load_from_data (fake_desktop_file, desktop_file_contents, -1, G_KEY_FILE_NONE, NULL);
g_assert_true (loaded);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_keyfile (fake_desktop_file);
g_assert_nonnull (appinfo);
test_launch_for_app_info (appinfo);
g_free (desktop_file_contents);
g_object_unref (appinfo);
g_key_file_unref (fake_desktop_file);
}
g_free (exec_line_variants[1]);
g_free (exec_line_variants[0]);
}
static void
test_locale (const char *locale)
{
GAppInfo *appinfo;
gchar *orig = NULL;
const gchar *path;
orig = g_strdup (setlocale (LC_ALL, NULL));
g_setenv ("LANGUAGE", locale, TRUE);
setlocale (LC_ALL, "");
path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
if (g_strcmp0 (locale, "C") == 0)
{
g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
}
else if (g_str_has_prefix (locale, "en"))
{
g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test");
g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo example");
g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "example");
}
else if (g_str_has_prefix (locale, "de"))
{
g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "appinfo-test-de");
g_assert_cmpstr (g_app_info_get_description (appinfo), ==, "GAppInfo Beispiel");
g_assert_cmpstr (g_app_info_get_display_name (appinfo), ==, "Beispiel");
}
g_object_unref (appinfo);
g_setenv ("LANGUAGE", orig, TRUE);
setlocale (LC_ALL, "");
g_free (orig);
}
static void
test_text (void)
{
test_locale ("C");
test_locale ("en_US");
test_locale ("de");
test_locale ("de_DE.UTF-8");
}
static void
test_basic (void)
{
GAppInfo *appinfo;
GAppInfo *appinfo2;
GIcon *icon, *icon2;
const gchar *path;
path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
g_assert_nonnull (appinfo);
g_assert_cmpstr (g_app_info_get_id (appinfo), ==, "appinfo-test-static.desktop");
g_assert_nonnull (strstr (g_app_info_get_executable (appinfo), "true"));
icon = g_app_info_get_icon (appinfo);
g_assert_true (G_IS_THEMED_ICON (icon));
icon2 = g_themed_icon_new ("testicon");
g_assert_true (g_icon_equal (icon, icon2));
g_object_unref (icon2);
appinfo2 = g_app_info_dup (appinfo);
g_assert_cmpstr (g_app_info_get_id (appinfo), ==, g_app_info_get_id (appinfo2));
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
g_object_unref (appinfo);
g_object_unref (appinfo2);
}
static void
test_show_in (void)
{
GAppInfo *appinfo;
const gchar *path;
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
if (appinfo == NULL)
{
g_test_skip ("appinfo-test binary not installed");
return;
}
g_assert_true (g_app_info_should_show (appinfo));
g_object_unref (appinfo);
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-gnome.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
g_assert_true (g_app_info_should_show (appinfo));
g_object_unref (appinfo);
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test-notgnome.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
g_assert_false (g_app_info_should_show (appinfo));
g_object_unref (appinfo);
}
static void
test_commandline (void)
{
GAppInfo *appinfo;
GError *error;
gchar *cmdline;
gchar *cmdline_out;
cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
cmdline_out = g_strconcat (cmdline, " %u", NULL);
error = NULL;
appinfo = g_app_info_create_from_commandline (cmdline,
"cmdline-app-test",
G_APP_INFO_CREATE_SUPPORTS_URIS,
&error);
g_assert_no_error (error);
g_assert_nonnull (appinfo);
g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
g_assert_true (g_app_info_supports_uris (appinfo));
g_assert_false (g_app_info_supports_files (appinfo));
g_object_unref (appinfo);
g_free (cmdline_out);
cmdline_out = g_strconcat (cmdline, " %f", NULL);
error = NULL;
appinfo = g_app_info_create_from_commandline (cmdline,
"cmdline-app-test",
G_APP_INFO_CREATE_NONE,
&error);
g_assert_no_error (error);
g_assert_nonnull (appinfo);
g_assert_cmpstr (g_app_info_get_name (appinfo), ==, "cmdline-app-test");
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, cmdline_out);
g_assert_false (g_app_info_supports_uris (appinfo));
g_assert_true (g_app_info_supports_files (appinfo));
g_object_unref (appinfo);
g_free (cmdline);
g_free (cmdline_out);
}
static void
test_launch_context (void)
{
GAppLaunchContext *context;
GAppInfo *appinfo;
gchar *str;
gchar *cmdline;
cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
context = g_app_launch_context_new ();
appinfo = g_app_info_create_from_commandline (cmdline,
"cmdline-app-test",
G_APP_INFO_CREATE_SUPPORTS_URIS,
NULL);
str = g_app_launch_context_get_display (context, appinfo, NULL);
g_assert_null (str);
str = g_app_launch_context_get_startup_notify_id (context, appinfo, NULL);
g_assert_null (str);
g_object_unref (appinfo);
g_object_unref (context);
g_free (cmdline);
}
static gboolean launched_reached;
static void
launched (GAppLaunchContext *context,
GAppInfo *info,
GVariant *platform_data,
gpointer user_data)
{
gint pid;
pid = 0;
g_assert_true (g_variant_lookup (platform_data, "pid", "i", &pid));
g_assert_cmpint (pid, !=, 0);
launched_reached = TRUE;
}
static void
launch_failed (GAppLaunchContext *context,
const gchar *startup_notify_id)
{
g_assert_not_reached ();
}
static void
test_launch_context_signals (void)
{
GAppLaunchContext *context;
GAppInfo *appinfo;
GError *error = NULL;
gboolean success;
gchar *cmdline;
cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
context = g_app_launch_context_new ();
g_signal_connect (context, "launched", G_CALLBACK (launched), NULL);
g_signal_connect (context, "launch_failed", G_CALLBACK (launch_failed), NULL);
appinfo = g_app_info_create_from_commandline (cmdline,
"cmdline-app-test",
G_APP_INFO_CREATE_SUPPORTS_URIS,
NULL);
success = g_app_info_launch (appinfo, NULL, context, &error);
g_assert_no_error (error);
g_assert_true (success);
g_assert_true (launched_reached);
g_object_unref (appinfo);
g_object_unref (context);
g_free (cmdline);
}
static void
test_tryexec (void)
{
GAppInfo *appinfo;
const gchar *path;
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test2.desktop", NULL);
appinfo = (GAppInfo*)g_desktop_app_info_new_from_filename (path);
g_assert_null (appinfo);
}
/* Test that we can set an appinfo as default for a mime type or
* file extension, and also add and remove handled mime types.
*/
static void
test_associations (void)
{
GAppInfo *appinfo;
GAppInfo *appinfo2;
GError *error = NULL;
gboolean result;
GList *list;
gchar *cmdline;
cmdline = g_strconcat (g_test_get_dir (G_TEST_BUILT), "/appinfo-test --option", NULL);
appinfo = g_app_info_create_from_commandline (cmdline,
"cmdline-app-test",
G_APP_INFO_CREATE_SUPPORTS_URIS,
NULL);
g_free (cmdline);
result = g_app_info_set_as_default_for_type (appinfo, "application/x-glib-test", &error);
g_assert_no_error (error);
g_assert_true (result);
appinfo2 = g_app_info_get_default_for_type ("application/x-glib-test", FALSE);
g_assert_nonnull (appinfo2);
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
g_object_unref (appinfo2);
result = g_app_info_set_as_default_for_extension (appinfo, "gio-tests", &error);
g_assert_no_error (error);
g_assert_true (result);
appinfo2 = g_app_info_get_default_for_type ("application/x-extension-gio-tests", FALSE);
g_assert_nonnull (appinfo2);
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
g_object_unref (appinfo2);
result = g_app_info_add_supports_type (appinfo, "application/x-gio-test", &error);
g_assert_no_error (error);
g_assert_true (result);
list = g_app_info_get_all_for_type ("application/x-gio-test");
g_assert_cmpint (g_list_length (list), ==, 1);
appinfo2 = list->data;
g_assert_cmpstr (g_app_info_get_commandline (appinfo), ==, g_app_info_get_commandline (appinfo2));
g_object_unref (appinfo2);
g_list_free (list);
g_assert_true (g_app_info_can_remove_supports_type (appinfo));
result = g_app_info_remove_supports_type (appinfo, "application/x-gio-test", &error);
g_assert_no_error (error);
g_assert_true (result);
g_assert_true (g_app_info_can_delete (appinfo));
g_assert_true (g_app_info_delete (appinfo));
g_object_unref (appinfo);
}
static void
test_environment (void)
{
GAppLaunchContext *ctx;
gchar **env;
const gchar *path;
g_unsetenv ("FOO");
g_unsetenv ("BLA");
path = g_getenv ("PATH");
ctx = g_app_launch_context_new ();
env = g_app_launch_context_get_environment (ctx);
g_assert_null (g_environ_getenv (env, "FOO"));
g_assert_null (g_environ_getenv (env, "BLA"));
g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
g_strfreev (env);
g_app_launch_context_setenv (ctx, "FOO", "bar");
g_app_launch_context_setenv (ctx, "BLA", "bla");
env = g_app_launch_context_get_environment (ctx);
g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "bar");
g_assert_cmpstr (g_environ_getenv (env, "BLA"), ==, "bla");
g_assert_cmpstr (g_environ_getenv (env, "PATH"), ==, path);
g_strfreev (env);
g_app_launch_context_setenv (ctx, "FOO", "baz");
g_app_launch_context_unsetenv (ctx, "BLA");
env = g_app_launch_context_get_environment (ctx);
g_assert_cmpstr (g_environ_getenv (env, "FOO"), ==, "baz");
g_assert_null (g_environ_getenv (env, "BLA"));
g_strfreev (env);
g_object_unref (ctx);
}
static void
test_startup_wm_class (void)
{
GDesktopAppInfo *appinfo;
const char *wm_class;
const gchar *path;
path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
appinfo = g_desktop_app_info_new_from_filename (path);
wm_class = g_desktop_app_info_get_startup_wm_class (appinfo);
g_assert_cmpstr (wm_class, ==, "appinfo-class");
g_object_unref (appinfo);
}
static void
test_supported_types (void)
{
GAppInfo *appinfo;
const char * const *content_types;
const gchar *path;
path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
appinfo = G_APP_INFO (g_desktop_app_info_new_from_filename (path));
content_types = g_app_info_get_supported_types (appinfo);
g_assert_cmpint (g_strv_length ((char**)content_types), ==, 2);
g_assert_cmpstr (content_types[0], ==, "image/png");
g_object_unref (appinfo);
}
static void
test_from_keyfile (void)
{
GDesktopAppInfo *info;
GKeyFile *kf;
GError *error = NULL;
const gchar *categories;
gchar **categories_list;
gsize categories_count;
gchar **keywords;
const gchar *file;
const gchar *name;
const gchar *path;
path = g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL);
kf = g_key_file_new ();
g_key_file_load_from_file (kf, path, G_KEY_FILE_NONE, &error);
g_assert_no_error (error);
info = g_desktop_app_info_new_from_keyfile (kf);
g_key_file_unref (kf);
g_assert_nonnull (info);
g_object_get (info, "filename", &file, NULL);
g_assert_null (file);
file = g_desktop_app_info_get_filename (info);
g_assert_null (file);
categories = g_desktop_app_info_get_categories (info);
g_assert_cmpstr (categories, ==, "GNOME;GTK;");
categories_list = g_desktop_app_info_get_string_list (info, "Categories", &categories_count);
g_assert_cmpint (categories_count, ==, 2);
g_assert_cmpint (g_strv_length (categories_list), ==, 2);
g_assert_cmpstr (categories_list[0], ==, "GNOME");
g_assert_cmpstr (categories_list[1], ==, "GTK");
keywords = (gchar **)g_desktop_app_info_get_keywords (info);
g_assert_cmpint (g_strv_length (keywords), ==, 2);
g_assert_cmpstr (keywords[0], ==, "keyword1");
g_assert_cmpstr (keywords[1], ==, "test keyword");
name = g_desktop_app_info_get_generic_name (info);
g_assert_cmpstr (name, ==, "generic-appinfo-test");
g_assert_false (g_desktop_app_info_get_nodisplay (info));
g_strfreev (categories_list);
g_object_unref (info);
}
int
main (int argc, char *argv[])
{
g_setenv ("XDG_CURRENT_DESKTOP", "GNOME", TRUE);
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
g_test_add_func ("/appinfo/basic", test_basic);
g_test_add_func ("/appinfo/text", test_text);
g_test_add_func ("/appinfo/launch", test_launch);
g_test_add_func ("/appinfo/launch/no-appid", test_launch_no_app_id);
g_test_add_func ("/appinfo/show-in", test_show_in);
g_test_add_func ("/appinfo/commandline", test_commandline);
g_test_add_func ("/appinfo/launch-context", test_launch_context);
g_test_add_func ("/appinfo/launch-context-signals", test_launch_context_signals);
g_test_add_func ("/appinfo/tryexec", test_tryexec);
g_test_add_func ("/appinfo/associations", test_associations);
g_test_add_func ("/appinfo/environment", test_environment);
g_test_add_func ("/appinfo/startup-wm-class", test_startup_wm_class);
g_test_add_func ("/appinfo/supported-types", test_supported_types);
g_test_add_func ("/appinfo/from-keyfile", test_from_keyfile);
return g_test_run ();
}

130
gio/tests/appmonitor.c Normal file
View file

@ -0,0 +1,130 @@
#include <gio/gio.h>
#include <gstdio.h>
typedef struct
{
gchar *applications_dir;
} Fixture;
static void
setup (Fixture *fixture,
gconstpointer user_data)
{
fixture->applications_dir = g_build_filename (g_get_user_data_dir (), "applications", NULL);
g_assert_no_errno (g_mkdir_with_parents (fixture->applications_dir, 0755));
g_test_message ("Using data directory: %s", g_get_user_data_dir ());
}
static void
teardown (Fixture *fixture,
gconstpointer user_data)
{
g_assert_no_errno (g_rmdir (fixture->applications_dir));
g_clear_pointer (&fixture->applications_dir, g_free);
}
static gboolean
create_app (gpointer data)
{
const gchar *path = data;
GError *error = NULL;
const gchar *contents =
"[Desktop Entry]\n"
"Name=Application\n"
"Version=1.0\n"
"Type=Application\n"
"Exec=true\n";
g_file_set_contents (path, contents, -1, &error);
g_assert_no_error (error);
return G_SOURCE_REMOVE;
}
static void
delete_app (gpointer data)
{
const gchar *path = data;
g_remove (path);
}
static gboolean changed_fired;
static void
changed_cb (GAppInfoMonitor *monitor, GMainLoop *loop)
{
changed_fired = TRUE;
g_main_loop_quit (loop);
}
static gboolean
quit_loop (gpointer data)
{
GMainLoop *loop = data;
if (g_main_loop_is_running (loop))
g_main_loop_quit (loop);
return G_SOURCE_REMOVE;
}
static void
test_app_monitor (Fixture *fixture,
gconstpointer user_data)
{
gchar *app_path;
GAppInfoMonitor *monitor;
GMainLoop *loop;
#ifdef G_OS_WIN32
g_test_skip (".desktop monitor on win32");
return;
#endif
app_path = g_build_filename (fixture->applications_dir, "app.desktop", NULL);
/* FIXME: this shouldn't be required */
g_list_free_full (g_app_info_get_all (), g_object_unref);
monitor = g_app_info_monitor_get ();
loop = g_main_loop_new (NULL, FALSE);
g_signal_connect (monitor, "changed", G_CALLBACK (changed_cb), loop);
g_idle_add (create_app, app_path);
g_timeout_add_seconds (3, quit_loop, loop);
g_main_loop_run (loop);
g_assert (changed_fired);
changed_fired = FALSE;
/* FIXME: this shouldn't be required */
g_list_free_full (g_app_info_get_all (), g_object_unref);
g_timeout_add_seconds (3, quit_loop, loop);
delete_app (app_path);
g_main_loop_run (loop);
g_assert (changed_fired);
g_main_loop_unref (loop);
g_remove (app_path);
g_object_unref (monitor);
g_free (app_path);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
g_test_add ("/monitor/app", Fixture, NULL, setup, test_app_monitor, teardown);
return g_test_run ();
}

147
gio/tests/apps.c Normal file
View file

@ -0,0 +1,147 @@
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
#include <locale.h>
#include <stdlib.h>
static void
print (const gchar *str)
{
g_print ("%s\n", str ? str : "nil");
}
static void
print_app_list (GList *list)
{
while (list)
{
GAppInfo *info = list->data;
print (g_app_info_get_id (info));
list = g_list_delete_link (list, list);
g_object_unref (info);
}
}
static void
quit (gpointer user_data)
{
g_print ("appinfo database changed.\n");
exit (0);
}
int
main (int argc, char **argv)
{
setlocale (LC_ALL, "");
if (argv[1] == NULL)
;
else if (g_str_equal (argv[1], "list"))
{
GList *all, *i;
all = g_app_info_get_all ();
for (i = all; i; i = i->next)
g_print ("%s%s", g_app_info_get_id (i->data), i->next ? " " : "\n");
g_list_free_full (all, g_object_unref);
}
else if (g_str_equal (argv[1], "search"))
{
gchar ***results;
gint i, j;
results = g_desktop_app_info_search (argv[2]);
for (i = 0; results[i]; i++)
{
for (j = 0; results[i][j]; j++)
g_print ("%s%s", j ? " " : "", results[i][j]);
g_print ("\n");
g_strfreev (results[i]);
}
g_free (results);
}
else if (g_str_equal (argv[1], "implementations"))
{
GList *results;
results = g_desktop_app_info_get_implementations (argv[2]);
print_app_list (results);
}
else if (g_str_equal (argv[1], "show-info"))
{
GAppInfo *info;
info = (GAppInfo *) g_desktop_app_info_new (argv[2]);
if (info)
{
print (g_app_info_get_id (info));
print (g_app_info_get_name (info));
print (g_app_info_get_display_name (info));
print (g_app_info_get_description (info));
g_object_unref (info);
}
}
else if (g_str_equal (argv[1], "default-for-type"))
{
GAppInfo *info;
info = g_app_info_get_default_for_type (argv[2], FALSE);
if (info)
{
print (g_app_info_get_id (info));
g_object_unref (info);
}
}
else if (g_str_equal (argv[1], "recommended-for-type"))
{
GList *list;
list = g_app_info_get_recommended_for_type (argv[2]);
print_app_list (list);
}
else if (g_str_equal (argv[1], "all-for-type"))
{
GList *list;
list = g_app_info_get_all_for_type (argv[2]);
print_app_list (list);
}
else if (g_str_equal (argv[1], "fallback-for-type"))
{
GList *list;
list = g_app_info_get_fallback_for_type (argv[2]);
print_app_list (list);
}
else if (g_str_equal (argv[1], "should-show"))
{
GAppInfo *info;
info = (GAppInfo *) g_desktop_app_info_new (argv[2]);
if (info)
{
g_print ("%s\n", g_app_info_should_show (info) ? "true" : "false");
g_object_unref (info);
}
}
else if (g_str_equal (argv[1], "monitor"))
{
GAppInfoMonitor *monitor;
GAppInfo *info;
monitor = g_app_info_monitor_get ();
info = (GAppInfo *) g_desktop_app_info_new ("this-desktop-file-does-not-exist");
g_assert (!info);
g_signal_connect (monitor, "changed", G_CALLBACK (quit), NULL);
while (1)
g_main_context_iteration (NULL, TRUE);
}
return 0;
}

View file

@ -0,0 +1,276 @@
/* GLib testing framework examples and tests
* Authors: Jesse van den Kieboom <jessevdk@gnome.org>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define DATA_TO_WRITE "Hello world\n"
typedef struct
{
GOutputStream *conv_stream;
GOutputStream *data_stream;
gchar *expected_output;
gsize expected_size;
GMainLoop *main_loop;
} SetupData;
static void
create_streams (SetupData *data)
{
GConverter *converter;
converter = G_CONVERTER (g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1));
data->data_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
data->conv_stream = g_converter_output_stream_new (data->data_stream,
converter);
g_object_unref (converter);
}
static void
destroy_streams (SetupData *data)
{
g_object_unref (data->data_stream);
g_object_unref (data->conv_stream);
}
static void
write_data_to_stream (SetupData *data)
{
gsize bytes_written;
GError *error = NULL;
/* just write the data synchronously */
g_output_stream_write_all (data->conv_stream,
DATA_TO_WRITE,
sizeof (DATA_TO_WRITE),
&bytes_written,
NULL,
&error);
g_assert_no_error (error);
g_assert_cmpint (sizeof (DATA_TO_WRITE), ==, bytes_written);
}
static void
setup_data (SetupData *data,
gconstpointer user_data)
{
data->main_loop = g_main_loop_new (NULL, FALSE);
create_streams (data);
}
static void
teardown_data (SetupData *data,
gconstpointer user_data)
{
/* cleanup */
g_main_loop_unref (data->main_loop);
destroy_streams (data);
g_free (data->expected_output);
}
static void
compare_output (SetupData *data)
{
gsize size;
gpointer written;
written = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->data_stream));
size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
g_assert_cmpmem (written, size, data->expected_output, data->expected_size);
}
static void
async_close_ready (GOutputStream *stream,
GAsyncResult *result,
SetupData *data)
{
GError *error = NULL;
/* finish the close */
g_output_stream_close_finish (stream, result, &error);
g_assert_no_error (error);
/* compare the output with the desired output */
compare_output (data);
g_main_loop_quit (data->main_loop);
}
static void
prepare_data (SetupData *data,
gboolean manual_flush)
{
GError *error = NULL;
gpointer written;
write_data_to_stream (data);
if (manual_flush)
{
g_output_stream_flush (data->conv_stream, NULL, &error);
g_assert_no_error (error);
}
g_output_stream_close (data->conv_stream, NULL, &error);
g_assert_no_error (error);
written = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->data_stream));
data->expected_size = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (data->data_stream));
g_assert_cmpuint (data->expected_size, >, 0);
data->expected_output = g_memdup2 (written, data->expected_size);
/* then recreate the streams and prepare them for the asynchronous close */
destroy_streams (data);
create_streams (data);
write_data_to_stream (data);
}
static void
test_without_flush (SetupData *data,
gconstpointer user_data)
{
prepare_data (data, FALSE);
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
/* just close asynchronously */
g_output_stream_close_async (data->conv_stream,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback)async_close_ready,
data);
g_main_loop_run (data->main_loop);
}
static void
test_with_flush (SetupData *data, gconstpointer user_data)
{
GError *error = NULL;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
prepare_data (data, TRUE);
g_output_stream_flush (data->conv_stream, NULL, &error);
g_assert_no_error (error);
/* then close asynchronously */
g_output_stream_close_async (data->conv_stream,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback)async_close_ready,
data);
g_main_loop_run (data->main_loop);
}
static void
async_flush_ready (GOutputStream *stream,
GAsyncResult *result,
SetupData *data)
{
GError *error = NULL;
g_output_stream_flush_finish (stream, result, &error);
g_assert_no_error (error);
/* then close async after the flush */
g_output_stream_close_async (data->conv_stream,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback)async_close_ready,
data);
}
static void
test_with_async_flush (SetupData *data,
gconstpointer user_data)
{
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=617937");
prepare_data (data, TRUE);
/* first flush async */
g_output_stream_flush_async (data->conv_stream,
G_PRIORITY_DEFAULT,
NULL,
(GAsyncReadyCallback)async_flush_ready,
data);
g_main_loop_run (data->main_loop);
}
int
main (int argc,
char *argv[])
{
SetupData *data;
g_test_init (&argc, &argv, NULL);
data = g_slice_new (SetupData);
/* test closing asynchronously without flushing manually */
g_test_add ("/close-async/without-flush",
SetupData,
data,
setup_data,
test_without_flush,
teardown_data);
/* test closing asynchronously with a synchronous manually flush */
g_test_add ("/close-async/with-flush",
SetupData,
data,
setup_data,
test_with_flush,
teardown_data);
/* test closing asynchronously with an asynchronous manually flush */
g_test_add ("/close-async/with-async-flush",
SetupData,
data,
setup_data,
test_with_async_flush,
teardown_data);
g_slice_free (SetupData, data);
return g_test_run();
}

View file

@ -0,0 +1,231 @@
/* GLib testing framework examples and tests
* Copyright (C) 2010-2012 Collabora Ltd.
* Authors: Xavier Claessens <xclaesse@gmail.com>
* Mike Ruprecht <mike.ruprecht@collabora.co.uk>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
typedef enum
{
TEST_THREADED_NONE = 0,
TEST_THREADED_ISTREAM = 1,
TEST_THREADED_OSTREAM = 2,
TEST_CANCEL = 4,
TEST_THREADED_BOTH = TEST_THREADED_ISTREAM | TEST_THREADED_OSTREAM,
} TestThreadedFlags;
typedef struct
{
GMainLoop *main_loop;
const gchar *data;
GInputStream *istream;
GOutputStream *ostream;
TestThreadedFlags flags;
gchar *input_path;
gchar *output_path;
} TestCopyChunksData;
static void
test_copy_chunks_splice_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
{
TestCopyChunksData *data = user_data;
gchar *received_data;
GError *error = NULL;
gssize bytes_spliced;
bytes_spliced = g_output_stream_splice_finish (G_OUTPUT_STREAM (source),
res, &error);
if (data->flags & TEST_CANCEL)
{
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
g_error_free (error);
g_main_loop_quit (data->main_loop);
return;
}
g_assert_no_error (error);
g_assert_cmpint (bytes_spliced, ==, strlen (data->data));
if (data->flags & TEST_THREADED_OSTREAM)
{
gsize length = 0;
g_file_get_contents (data->output_path, &received_data,
&length, &error);
g_assert_no_error (error);
g_assert_cmpstr (received_data, ==, data->data);
g_free (received_data);
}
else
{
received_data = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (data->ostream));
g_assert_cmpstr (received_data, ==, data->data);
}
g_assert (g_input_stream_is_closed (data->istream));
g_assert (g_output_stream_is_closed (data->ostream));
if (data->flags & TEST_THREADED_ISTREAM)
{
g_unlink (data->input_path);
g_free (data->input_path);
}
if (data->flags & TEST_THREADED_OSTREAM)
{
g_unlink (data->output_path);
g_free (data->output_path);
}
g_main_loop_quit (data->main_loop);
}
static void
test_copy_chunks_start (TestThreadedFlags flags)
{
TestCopyChunksData data;
GError *error = NULL;
GCancellable *cancellable = NULL;
data.main_loop = g_main_loop_new (NULL, FALSE);
data.data = "abcdefghijklmnopqrstuvwxyz";
data.flags = flags;
if (data.flags & TEST_CANCEL)
{
cancellable = g_cancellable_new ();
g_cancellable_cancel (cancellable);
}
if (data.flags & TEST_THREADED_ISTREAM)
{
GFile *file;
GFileIOStream *stream;
file = g_file_new_tmp ("test-inputXXXXXX", &stream, &error);
g_assert_no_error (error);
g_object_unref (stream);
data.input_path = g_file_get_path (file);
g_file_set_contents (data.input_path,
data.data, strlen (data.data),
&error);
g_assert_no_error (error);
data.istream = G_INPUT_STREAM (g_file_read (file, NULL, &error));
g_assert_no_error (error);
g_object_unref (file);
}
else
{
data.istream = g_memory_input_stream_new_from_data (data.data, -1, NULL);
}
if (data.flags & TEST_THREADED_OSTREAM)
{
GFile *file;
GFileIOStream *stream;
file = g_file_new_tmp ("test-outputXXXXXX", &stream, &error);
g_assert_no_error (error);
g_object_unref (stream);
data.output_path = g_file_get_path (file);
data.ostream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE,
G_FILE_CREATE_NONE,
NULL, &error));
g_assert_no_error (error);
g_object_unref (file);
}
else
{
data.ostream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
}
g_output_stream_splice_async (data.ostream, data.istream,
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
G_PRIORITY_DEFAULT, cancellable,
test_copy_chunks_splice_cb, &data);
/* We do not hold a ref in data struct, this is to make sure the operation
* keeps the iostream objects alive until it finishes
*/
g_object_unref (data.istream);
g_object_unref (data.ostream);
g_clear_object (&cancellable);
g_main_loop_run (data.main_loop);
g_main_loop_unref (data.main_loop);
}
static void
test_copy_chunks (void)
{
test_copy_chunks_start (TEST_THREADED_NONE);
}
static void
test_copy_chunks_threaded_input (void)
{
test_copy_chunks_start (TEST_THREADED_ISTREAM);
}
static void
test_copy_chunks_threaded_output (void)
{
test_copy_chunks_start (TEST_THREADED_OSTREAM);
}
static void
test_copy_chunks_threaded (void)
{
test_copy_chunks_start (TEST_THREADED_BOTH);
}
static void
test_cancelled (void)
{
test_copy_chunks_start (TEST_THREADED_NONE | TEST_CANCEL);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/async-splice/copy-chunks", test_copy_chunks);
g_test_add_func ("/async-splice/copy-chunks-threaded-input",
test_copy_chunks_threaded_input);
g_test_add_func ("/async-splice/copy-chunks-threaded-output",
test_copy_chunks_threaded_output);
g_test_add_func ("/async-splice/copy-chunks-threaded",
test_copy_chunks_threaded);
g_test_add_func ("/async-splice/cancelled",
test_cancelled);
return g_test_run();
}

23
gio/tests/autoptr.c Normal file
View file

@ -0,0 +1,23 @@
#include <gio/gio.h>
static void
test_autoptr (void)
{
g_autoptr(GFile) p = g_file_new_for_path ("/blah");
g_autoptr(GInetAddress) a = g_inet_address_new_from_string ("127.0.0.1");
g_autofree gchar *path = g_file_get_path (p);
g_autofree gchar *istr = g_inet_address_to_string (a);
g_assert_cmpstr (path, ==, G_DIR_SEPARATOR_S "blah");
g_assert_cmpstr (istr, ==, "127.0.0.1");
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/autoptr/autoptr", test_autoptr);
return g_test_run ();
}

View file

@ -0,0 +1,274 @@
#include <gio/gio.h>
#include <string.h>
static void
new_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = user_data;
g_application_activate (app);
}
static void
quit_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = user_data;
g_application_quit (app);
}
static void
action1_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_print ("activate action1\n");
}
static void
action2_activated (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GVariant *state;
state = g_action_get_state (G_ACTION (action));
g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
g_print ("activate action2 %d\n", !g_variant_get_boolean (state));
g_variant_unref (state);
}
static void
change_action2 (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
g_print ("change action2 %d\n", g_variant_get_boolean (state));
}
static void
startup (GApplication *app)
{
static GActionEntry actions[] = {
{ "new", new_activated, NULL, NULL, NULL, { 0 } },
{ "quit", quit_activated, NULL, NULL, NULL, { 0 } },
{ "action1", action1_activated, NULL, NULL, NULL, { 0 } },
{ "action2", action2_activated, "b", "false", change_action2, { 0 } }
};
g_action_map_add_action_entries (G_ACTION_MAP (app),
actions, G_N_ELEMENTS (actions),
app);
}
static void
activate (GApplication *application)
{
g_application_hold (application);
g_print ("activated\n");
g_application_release (application);
}
static void
open (GApplication *application,
GFile **files,
gint n_files,
const gchar *hint)
{
gint i;
g_application_hold (application);
g_print ("open");
for (i = 0; i < n_files; i++)
{
gchar *uri = g_file_get_uri (files[i]);
g_print (" %s", uri);
g_free (uri);
}
g_print ("\n");
g_application_release (application);
}
static int
command_line (GApplication *application,
GApplicationCommandLine *cmdline)
{
gchar **argv;
gint argc;
gint i;
g_application_hold (application);
argv = g_application_command_line_get_arguments (cmdline, &argc);
if (argc > 1)
{
if (g_strcmp0 (argv[1], "echo") == 0)
{
g_print ("cmdline");
for (i = 0; i < argc; i++)
g_print (" %s", argv[i]);
g_print ("\n");
}
else if (g_strcmp0 (argv[1], "env") == 0)
{
const gchar * const *env;
env = g_application_command_line_get_environ (cmdline);
g_print ("environment");
for (i = 0; env[i]; i++)
if (g_str_has_prefix (env[i], "TEST="))
g_print (" %s", env[i]);
g_print ("\n");
}
else if (g_strcmp0 (argv[1], "getenv") == 0)
{
g_print ("getenv TEST=%s\n", g_application_command_line_getenv (cmdline, "TEST"));
}
else if (g_strcmp0 (argv[1], "print") == 0)
{
g_application_command_line_print (cmdline, "print %s\n", argv[2]);
}
else if (g_strcmp0 (argv[1], "printerr") == 0)
{
g_application_command_line_printerr (cmdline, "printerr %s\n", argv[2]);
}
else if (g_strcmp0 (argv[1], "file") == 0)
{
GFile *file;
file = g_application_command_line_create_file_for_arg (cmdline, argv[2]);
g_print ("file %s\n", g_file_get_path (file));
g_object_unref (file);
}
else if (g_strcmp0 (argv[1], "properties") == 0)
{
gboolean remote;
GVariant *data;
g_object_get (cmdline,
"is-remote", &remote,
NULL);
data = g_application_command_line_get_platform_data (cmdline);
g_assert (remote);
g_assert (g_variant_is_of_type (data, G_VARIANT_TYPE ("a{sv}")));
g_variant_unref (data);
g_print ("properties ok\n");
}
else if (g_strcmp0 (argv[1], "cwd") == 0)
{
g_print ("cwd %s\n", g_application_command_line_get_cwd (cmdline));
}
else if (g_strcmp0 (argv[1], "busy") == 0)
{
g_application_mark_busy (g_application_get_default ());
g_print ("busy\n");
}
else if (g_strcmp0 (argv[1], "idle") == 0)
{
g_application_unmark_busy (g_application_get_default ());
g_print ("idle\n");
}
else if (g_strcmp0 (argv[1], "stdin") == 0)
{
GInputStream *stream;
stream = g_application_command_line_get_stdin (cmdline);
g_assert (stream == NULL || G_IS_INPUT_STREAM (stream));
g_object_unref (stream);
g_print ("stdin ok\n");
}
else
g_print ("unexpected command: %s\n", argv[1]);
}
else
g_print ("got ./cmd %d\n", g_application_command_line_get_is_remote (cmdline));
g_strfreev (argv);
g_application_release (application);
return 0;
}
static gboolean
action_cb (gpointer data)
{
gchar **argv = data;
GApplication *app;
gchar **actions;
gint i;
if (g_strcmp0 (argv[1], "./actions") == 0)
{
app = g_application_get_default ();
if (g_strcmp0 (argv[2], "list") == 0)
{
g_print ("actions");
actions = g_action_group_list_actions (G_ACTION_GROUP (app));
for (i = 0; actions[i]; i++)
g_print (" %s", actions[i]);
g_print ("\n");
g_strfreev (actions);
}
else if (g_strcmp0 (argv[2], "activate") == 0)
{
g_action_group_activate_action (G_ACTION_GROUP (app),
"action1", NULL);
}
else if (g_strcmp0 (argv[2], "set-state") == 0)
{
g_action_group_change_action_state (G_ACTION_GROUP (app),
"action2",
g_variant_new_boolean (TRUE));
}
g_application_release (app);
}
return G_SOURCE_REMOVE;
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
app = g_application_new ("org.gtk.TestApplication",
G_APPLICATION_SEND_ENVIRONMENT |
(g_strcmp0 (argv[1], "./cmd") == 0
? G_APPLICATION_HANDLES_COMMAND_LINE
: G_APPLICATION_HANDLES_OPEN));
g_signal_connect (app, "startup", G_CALLBACK (startup), NULL);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_signal_connect (app, "open", G_CALLBACK (open), NULL);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
#ifdef STANDALONE
g_application_set_inactivity_timeout (app, 10000);
#else
g_application_set_inactivity_timeout (app, 1000);
#endif
if (g_strcmp0 (argv[1], "./actions") == 0)
{
g_application_set_inactivity_timeout (app, 0);
g_application_hold (app);
g_idle_add (action_cb, argv);
}
status = g_application_run (app, argc - 1, argv + 1);
g_object_unref (app);
g_print ("exit status: %d\n", status);
return 0;
}

View file

@ -0,0 +1,552 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Matthias Clasen <mclasen@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_peek (void)
{
GInputStream *base;
GInputStream *in;
gssize npeek;
char *buffer;
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 64);
g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), 5, NULL, NULL);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 5);
g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), -1, NULL, NULL);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, strlen ("abcdefjhijk"));
buffer = g_new0 (char, 64);
npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 2, 3);
g_assert_cmpint (npeek, ==, 3);
g_assert_cmpstr ("cde", ==, buffer);
g_free (buffer);
buffer = g_new0 (char, 64);
npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 9, 5);
g_assert_cmpint (npeek, ==, 2);
g_assert_cmpstr ("jk", ==, buffer);
g_free (buffer);
buffer = g_new0 (char, 64);
npeek = g_buffered_input_stream_peek (G_BUFFERED_INPUT_STREAM (in), buffer, 75, 3);
g_assert_cmpint (npeek, ==, 0);
g_free (buffer);
g_object_unref (in);
g_object_unref (base);
}
static void
test_peek_buffer (void)
{
GInputStream *base;
GInputStream *in;
gssize nfill;
gsize bufsize;
char *buffer;
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
in = g_buffered_input_stream_new (base);
nfill = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), strlen ("abcdefghijk"), NULL, NULL);
buffer = (char *) g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (in), &bufsize);
g_assert_cmpint (nfill, ==, bufsize);
g_assert (0 == strncmp ("abcdefghijk", buffer, bufsize));
g_object_unref (in);
g_object_unref (base);
}
static void
test_set_buffer_size (void)
{
GInputStream *base;
GInputStream *in;
guint bufsize_prop;
gsize size, bufsize;
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
in = g_buffered_input_stream_new (base);
size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in));
g_assert_cmpint (size, ==, 4096);
g_buffered_input_stream_set_buffer_size (G_BUFFERED_INPUT_STREAM (in), 64);
size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in));
g_assert_cmpint (size, ==, 64);
/* size cannot shrink below current content len */
g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), strlen ("abcdefghijk"), NULL, NULL);
g_buffered_input_stream_peek_buffer (G_BUFFERED_INPUT_STREAM (in), &bufsize);
g_buffered_input_stream_set_buffer_size (G_BUFFERED_INPUT_STREAM (in), 2);
size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in));
g_assert_cmpint (size, ==, bufsize);
g_object_get (in, "buffer-size", &bufsize_prop, NULL);
g_assert_cmpint (bufsize_prop, ==, bufsize);
g_object_unref (in);
in = g_buffered_input_stream_new_sized (base, 64);
size = g_buffered_input_stream_get_buffer_size (G_BUFFERED_INPUT_STREAM (in));
g_assert_cmpint (size, ==, 64);
g_object_unref (in);
g_object_unref (base);
}
static void
test_read_byte (void)
{
GInputStream *base;
GInputStream *in;
GError *error;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=562393");
base = g_memory_input_stream_new_from_data ("abcdefgh", -1, NULL);
in = g_buffered_input_stream_new (base);
error = NULL;
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c');
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 3, NULL, &error), ==, 3);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'g');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'h');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, -1);
g_assert_no_error (error);
g_assert (g_input_stream_close (in, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, -1);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
g_error_free (error);
g_object_unref (in);
g_object_unref (base);
}
static void
test_read (void)
{
GInputStream *base;
GInputStream *in;
gchar buffer[20];
GError *error;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 8);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0);
error = NULL;
g_assert_cmpint (g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (in), 8, NULL, &error), ==, 8);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 8);
memset (buffer, 0, 20);
g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "abcdefghijklmnop");
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0);
memset (buffer, 0, 20);
g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "qrstuvwxyzABCDEF");
g_assert_no_error (error);
memset (buffer, 0, 20);
g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "GHIJKLMNOPQRSTUV");
g_assert_no_error (error);
memset (buffer, 0, 20);
g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 4);
g_assert_cmpstr (buffer, ==, "WXYZ");
g_assert_no_error (error);
memset (buffer, 0, 20);
g_assert_cmpint (g_input_stream_read (in, &buffer, 16, NULL, &error), ==, 0);
g_assert_no_error (error);
g_object_unref (in);
g_object_unref (base);
}
static void
return_result_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GAsyncResult **ret = user_data;
*ret = g_object_ref (result);
}
static void
test_read_async (void)
{
GInputStream *base;
GInputStream *in;
gchar buffer[20];
GError *error;
GAsyncResult *result;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 8);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0);
error = NULL;
result = NULL;
g_buffered_input_stream_fill_async (G_BUFFERED_INPUT_STREAM (in), 8,
G_PRIORITY_DEFAULT, NULL,
return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_buffered_input_stream_fill_finish (G_BUFFERED_INPUT_STREAM (in), result, &error), ==, 8);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 8);
memset (buffer, 0, 20);
g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "abcdefghijklmnop");
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (in)), ==, 0);
memset (buffer, 0, 20);
g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "qrstuvwxyzABCDEF");
g_assert_no_error (error);
g_clear_object (&result);
memset (buffer, 0, 20);
g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 16);
g_assert_cmpstr (buffer, ==, "GHIJKLMNOPQRSTUV");
g_assert_no_error (error);
g_clear_object (&result);
memset (buffer, 0, 20);
g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 4);
g_assert_cmpstr (buffer, ==, "WXYZ");
g_assert_no_error (error);
g_clear_object (&result);
memset (buffer, 0, 20);
g_input_stream_read_async (in, &buffer, 16, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_read_finish (in, result, &error), ==, 0);
g_assert_no_error (error);
g_clear_object (&result);
g_object_unref (in);
g_object_unref (base);
}
static void
test_skip (void)
{
GInputStream *base;
GInputStream *in;
GError *error;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 5);
error = NULL;
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c');
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 7, NULL, &error), ==, 7);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'k');
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 10);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'v');
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 20, NULL, &error), ==, 20);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'Q');
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 8);
g_assert_no_error (error);
g_assert_cmpint (g_input_stream_skip (in, 10, NULL, &error), ==, 0);
g_assert_no_error (error);
g_object_unref (in);
g_object_unref (base);
}
static void
test_skip_async (void)
{
GInputStream *base;
GInputStream *in;
GError *error;
GAsyncResult *result;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 5);
error = NULL;
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'a');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'b');
g_assert_no_error (error);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'c');
g_assert_no_error (error);
result = NULL;
g_input_stream_skip_async (in, 7, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 7);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'k');
g_assert_no_error (error);
g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 10);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'v');
g_assert_no_error (error);
g_input_stream_skip_async (in, 20, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 20);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error), ==, 'Q');
g_assert_no_error (error);
g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 8);
g_clear_object (&result);
g_assert_no_error (error);
g_input_stream_skip_async (in, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
while (!result)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (g_input_stream_skip_finish (in, result, &error), ==, 0);
g_clear_object (&result);
g_assert_no_error (error);
g_object_unref (in);
g_object_unref (base);
}
static void
test_close (void)
{
GInputStream *base;
GInputStream *in;
GError *error;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL);
in = g_buffered_input_stream_new (base);
g_assert (g_filter_input_stream_get_close_base_stream (G_FILTER_INPUT_STREAM (in)));
error = NULL;
g_assert (g_input_stream_close (in, NULL, &error));
g_assert_no_error (error);
g_assert (g_input_stream_is_closed (base));
g_object_unref (in);
g_object_unref (base);
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL);
in = g_buffered_input_stream_new (base);
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (in), FALSE);
error = NULL;
g_assert (g_input_stream_close (in, NULL, &error));
g_assert_no_error (error);
g_assert (!g_input_stream_is_closed (base));
g_object_unref (in);
g_object_unref (base);
}
static void
test_seek (void)
{
GInputStream *base;
GInputStream *in;
GError *error;
gint byte;
gboolean ret;
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVXYZ", -1, NULL);
in = g_buffered_input_stream_new_sized (base, 4);
error = NULL;
/* Seek by read */
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 0);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'a');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 1);
/* Seek forward (in buffer) */
ret = g_seekable_seek (G_SEEKABLE (in), 1, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 2);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'c');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 3);
/* Seek backward (in buffer) */
ret = g_seekable_seek (G_SEEKABLE (in), -2, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 1);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'b');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 2);
/* Seek forward (outside buffer) */
ret = g_seekable_seek (G_SEEKABLE (in), 6, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 8);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'i');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 9);
/* Seek backward (outside buffer) */
ret = g_seekable_seek (G_SEEKABLE (in), -6, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 3);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'd');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 4);
/* Seek from beginning */
ret = g_seekable_seek (G_SEEKABLE (in), 8, G_SEEK_SET, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 8);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'i');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 9);
/* Seek from end */
ret = g_seekable_seek (G_SEEKABLE (in), -1, G_SEEK_END, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 50);
byte = g_buffered_input_stream_read_byte (G_BUFFERED_INPUT_STREAM (in), NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (byte, ==, 'Z');
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (in)), ==, 51);
/* Cleanup */
g_object_unref (in);
g_object_unref (base);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/buffered-input-stream/peek", test_peek);
g_test_add_func ("/buffered-input-stream/peek-buffer", test_peek_buffer);
g_test_add_func ("/buffered-input-stream/set-buffer-size", test_set_buffer_size);
g_test_add_func ("/buffered-input-stream/read-byte", test_read_byte);
g_test_add_func ("/buffered-input-stream/read", test_read);
g_test_add_func ("/buffered-input-stream/read-async", test_read_async);
g_test_add_func ("/buffered-input-stream/skip", test_skip);
g_test_add_func ("/buffered-input-stream/skip-async", test_skip_async);
g_test_add_func ("/buffered-input-stream/seek", test_seek);
g_test_add_func ("/filter-input-stream/close", test_close);
return g_test_run();
}

View file

@ -0,0 +1,329 @@
#include <gio/gio.h>
static void
test_write (void)
{
GOutputStream *base;
GOutputStream *out;
GError *error;
const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz";
base = g_memory_output_stream_new (g_malloc0 (20), 20, NULL, g_free);
out = g_buffered_output_stream_new (base);
g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 4096);
g_assert (!g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out)));
g_object_set (out, "auto-grow", TRUE, NULL);
g_assert (g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out)));
g_object_set (out, "auto-grow", FALSE, NULL);
g_buffered_output_stream_set_buffer_size (G_BUFFERED_OUTPUT_STREAM (out), 16);
g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16);
error = NULL;
g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10);
g_assert_no_error (error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0);
g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 6);
g_assert_no_error (error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0);
g_assert (g_output_stream_flush (out, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 16);
g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnop");
g_object_unref (out);
g_object_unref (base);
}
static void
test_grow (void)
{
GOutputStream *base;
GOutputStream *out;
GError *error;
const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz";
gint size;
gboolean grow;
base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free);
out = g_buffered_output_stream_new_sized (base, 16);
g_buffered_output_stream_set_auto_grow (G_BUFFERED_OUTPUT_STREAM (out), TRUE);
g_object_get (out, "buffer-size", &size, "auto-grow", &grow, NULL);
g_assert_cmpint (size, ==, 16);
g_assert (grow);
g_assert (g_seekable_can_seek (G_SEEKABLE (out)));
error = NULL;
g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0);
g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 10);
g_assert_no_error (error);
g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), >=, 20);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0);
g_assert (g_output_stream_flush (out, NULL, &error));
g_assert_no_error (error);
g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrst");
g_object_unref (out);
g_object_unref (base);
}
static void
test_close (void)
{
GOutputStream *base;
GOutputStream *out;
GError *error;
base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free);
out = g_buffered_output_stream_new (base);
g_assert (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (out)));
error = NULL;
g_assert (g_output_stream_close (out, NULL, &error));
g_assert_no_error (error);
g_assert (g_output_stream_is_closed (base));
g_object_unref (out);
g_object_unref (base);
base = g_memory_output_stream_new (g_malloc0 (30), 30, g_realloc, g_free);
out = g_buffered_output_stream_new (base);
g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (out), FALSE);
error = NULL;
g_assert (g_output_stream_close (out, NULL, &error));
g_assert_no_error (error);
g_assert (!g_output_stream_is_closed (base));
g_object_unref (out);
g_object_unref (base);
}
static void
test_seek (void)
{
GMemoryOutputStream *base;
GOutputStream *out;
GSeekable *seekable;
GError *error;
gsize bytes_written;
gboolean ret;
const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz";
base = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (g_malloc0 (30), 30, NULL, g_free));
out = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base), 8);
seekable = G_SEEKABLE (out);
error = NULL;
/* Write data */
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 0);
ret = g_output_stream_write_all (out, buffer, 4, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (bytes_written, ==, 4);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4);
g_assert_cmpint (g_memory_output_stream_get_data_size (base), ==, 0);
/* Forward relative seek */
ret = g_seekable_seek (seekable, 2, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]);
g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]);
g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]);
ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8);
/* Backward relative seek */
ret = g_seekable_seek (seekable, -4, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]);
g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]);
g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]);
ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6);
/* From start */
ret = g_seekable_seek (seekable, 2, G_SEEK_SET, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 2);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]);
g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]);
g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]);
ret = g_output_stream_write_all (out, buffer, 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4);
/* From end */
ret = g_seekable_seek (seekable, 6 - 30, G_SEEK_END, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]);
ret = g_output_stream_write_all (out, buffer + 2, 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (bytes_written, ==, 2);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8);
/* Check flush */
ret = g_output_stream_flush (out, NULL, &error);
g_assert_no_error (error);
g_assert (ret);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]);
g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]);
g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]);
g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]);
g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]);
g_object_unref (out);
g_object_unref (base);
}
static void
test_truncate(void)
{
GMemoryOutputStream *base_stream;
GOutputStream *stream;
GSeekable *seekable;
GError *error;
gsize bytes_written;
guchar *stream_data;
gsize len;
gboolean res;
len = 8;
/* Create objects */
stream_data = g_malloc0 (len);
base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, g_realloc, g_free));
stream = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base_stream), 8);
seekable = G_SEEKABLE (stream);
g_assert (g_seekable_can_truncate (seekable));
/* Write */
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 0);
error = NULL;
res = g_output_stream_write_all (stream, "ab", 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (res);
res = g_output_stream_write_all (stream, "cd", 2, &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert (res);
res = g_output_stream_flush (stream, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 'a');
g_assert_cmpint (stream_data[1], ==, 'b');
g_assert_cmpint (stream_data[2], ==, 'c');
g_assert_cmpint (stream_data[3], ==, 'd');
/* Truncate at position */
res = g_seekable_truncate (seekable, 4, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 4);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 'a');
g_assert_cmpint (stream_data[1], ==, 'b');
g_assert_cmpint (stream_data[2], ==, 'c');
g_assert_cmpint (stream_data[3], ==, 'd');
/* Truncate beyond position */
res = g_seekable_truncate (seekable, 6, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 6);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 6);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 'a');
g_assert_cmpint (stream_data[1], ==, 'b');
g_assert_cmpint (stream_data[2], ==, 'c');
g_assert_cmpint (stream_data[3], ==, 'd');
/* Truncate before position */
res = g_seekable_truncate (seekable, 2, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 2);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 2);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 'a');
g_assert_cmpint (stream_data[1], ==, 'b');
g_object_unref (stream);
g_object_unref (base_stream);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/buffered-output-stream/write", test_write);
g_test_add_func ("/buffered-output-stream/grow", test_grow);
g_test_add_func ("/buffered-output-stream/seek", test_seek);
g_test_add_func ("/buffered-output-stream/truncate", test_truncate);
g_test_add_func ("/filter-output-stream/close", test_close);
return g_test_run ();
}

349
gio/tests/cancellable.c Normal file
View file

@ -0,0 +1,349 @@
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2011 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Stef Walter <stefw@collabora.co.uk>
*/
#include <locale.h>
#include <gio/gio.h>
#include "glib/glib-private.h"
/* How long to wait in ms for each iteration */
#define WAIT_ITERATION (10)
static gint num_async_operations = 0;
typedef struct
{
guint iterations_requested; /* construct-only */
guint iterations_done; /* (atomic) */
} MockOperationData;
static void
mock_operation_free (gpointer user_data)
{
MockOperationData *data = user_data;
g_free (data);
}
static void
mock_operation_thread (GTask *task,
gpointer source_object,
gpointer task_data,
GCancellable *cancellable)
{
MockOperationData *data = task_data;
guint i;
for (i = 0; i < data->iterations_requested; i++)
{
if (g_cancellable_is_cancelled (cancellable))
break;
if (g_test_verbose ())
g_test_message ("THRD: %u iteration %u", data->iterations_requested, i);
g_usleep (WAIT_ITERATION * 1000);
}
if (g_test_verbose ())
g_test_message ("THRD: %u stopped at %u", data->iterations_requested, i);
g_atomic_int_add (&data->iterations_done, i);
g_task_return_boolean (task, TRUE);
}
static gboolean
mock_operation_timeout (gpointer user_data)
{
GTask *task;
MockOperationData *data;
gboolean done = FALSE;
guint iterations_done;
task = G_TASK (user_data);
data = g_task_get_task_data (task);
iterations_done = g_atomic_int_get (&data->iterations_done);
if (iterations_done >= data->iterations_requested)
done = TRUE;
if (g_cancellable_is_cancelled (g_task_get_cancellable (task)))
done = TRUE;
if (done)
{
if (g_test_verbose ())
g_test_message ("LOOP: %u stopped at %u",
data->iterations_requested, iterations_done);
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
else
{
g_atomic_int_inc (&data->iterations_done);
if (g_test_verbose ())
g_test_message ("LOOP: %u iteration %u",
data->iterations_requested, iterations_done + 1);
return G_SOURCE_CONTINUE;
}
}
static void
mock_operation_async (guint wait_iterations,
gboolean run_in_thread,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
MockOperationData *data;
task = g_task_new (NULL, cancellable, callback, user_data);
data = g_new0 (MockOperationData, 1);
data->iterations_requested = wait_iterations;
g_task_set_task_data (task, data, mock_operation_free);
if (run_in_thread)
{
g_task_run_in_thread (task, mock_operation_thread);
if (g_test_verbose ())
g_test_message ("THRD: %d started", wait_iterations);
}
else
{
g_timeout_add_full (G_PRIORITY_DEFAULT, WAIT_ITERATION, mock_operation_timeout,
g_object_ref (task), g_object_unref);
if (g_test_verbose ())
g_test_message ("LOOP: %d started", wait_iterations);
}
g_object_unref (task);
}
static guint
mock_operation_finish (GAsyncResult *result,
GError **error)
{
MockOperationData *data;
GTask *task;
g_assert_true (g_task_is_valid (result, NULL));
/* This test expects the return value to be iterations_done even
* when an error is set.
*/
task = G_TASK (result);
data = g_task_get_task_data (task);
g_task_propagate_boolean (task, error);
return g_atomic_int_get (&data->iterations_done);
}
static void
on_mock_operation_ready (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
guint iterations_requested;
guint iterations_done;
GError *error = NULL;
iterations_requested = GPOINTER_TO_UINT (user_data);
iterations_done = mock_operation_finish (result, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
g_error_free (error);
g_assert_cmpint (iterations_requested, >, iterations_done);
num_async_operations--;
g_main_context_wakeup (NULL);
}
static void
test_cancel_multiple_concurrent (void)
{
GCancellable *cancellable;
guint i, iterations;
if (!g_test_thorough ())
{
g_test_skip ("Not running timing heavy test");
return;
}
cancellable = g_cancellable_new ();
for (i = 0; i < 45; i++)
{
iterations = i + 10;
mock_operation_async (iterations, g_random_boolean (), cancellable,
on_mock_operation_ready, GUINT_TO_POINTER (iterations));
num_async_operations++;
}
/* Wait for the threads to start up */
while (num_async_operations != 45)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (num_async_operations, ==, 45);\
if (g_test_verbose ())
g_test_message ("CANCEL: %d operations", num_async_operations);
g_cancellable_cancel (cancellable);
g_assert_true (g_cancellable_is_cancelled (cancellable));
/* Wait for all operations to be cancelled */
while (num_async_operations != 0)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (num_async_operations, ==, 0);
g_object_unref (cancellable);
}
static void
test_cancel_null (void)
{
g_cancellable_cancel (NULL);
}
typedef struct
{
GCond cond;
GMutex mutex;
gboolean thread_ready;
GAsyncQueue *cancellable_source_queue; /* (owned) (element-type GCancellableSource) */
} ThreadedDisposeData;
static gboolean
cancelled_cb (GCancellable *cancellable,
gpointer user_data)
{
/* Nothing needs to be done here. */
return G_SOURCE_CONTINUE;
}
static gpointer
threaded_dispose_thread_cb (gpointer user_data)
{
ThreadedDisposeData *data = user_data;
GSource *cancellable_source;
g_mutex_lock (&data->mutex);
data->thread_ready = TRUE;
g_cond_broadcast (&data->cond);
g_mutex_unlock (&data->mutex);
while ((cancellable_source = g_async_queue_pop (data->cancellable_source_queue)) != (gpointer) 1)
{
/* Race with cancellation of the cancellable. */
g_source_unref (cancellable_source);
}
return NULL;
}
static void
test_cancellable_source_threaded_dispose (void)
{
#ifdef _GLIB_ADDRESS_SANITIZER
g_test_incomplete ("FIXME: Leaks lots of GCancellableSource objects, see glib#2309");
(void) cancelled_cb;
(void) threaded_dispose_thread_cb;
#else
ThreadedDisposeData data;
GThread *thread = NULL;
guint i;
GPtrArray *cancellables_pending_unref = g_ptr_array_new_with_free_func (g_object_unref);
g_test_summary ("Test a thread race between disposing of a GCancellableSource "
"(in one thread) and cancelling the GCancellable it refers "
"to (in another thread)");
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/issues/1841");
/* Create a new thread and wait until its ready to execute. Each iteration of
* the test will pass it a new #GCancellableSource. */
g_cond_init (&data.cond);
g_mutex_init (&data.mutex);
data.cancellable_source_queue = g_async_queue_new_full ((GDestroyNotify) g_source_unref);
data.thread_ready = FALSE;
g_mutex_lock (&data.mutex);
thread = g_thread_new ("/cancellable-source/threaded-dispose",
threaded_dispose_thread_cb, &data);
while (!data.thread_ready)
g_cond_wait (&data.cond, &data.mutex);
g_mutex_unlock (&data.mutex);
for (i = 0; i < 100000; i++)
{
GCancellable *cancellable = NULL;
GSource *cancellable_source = NULL;
/* Create a cancellable and a cancellable source for it. For this test,
* theres no need to attach the source to a #GMainContext. */
cancellable = g_cancellable_new ();
cancellable_source = g_cancellable_source_new (cancellable);
g_source_set_callback (cancellable_source, G_SOURCE_FUNC (cancelled_cb), NULL, NULL);
/* Send it to the thread and wait until its ready to execute before
* cancelling our cancellable. */
g_async_queue_push (data.cancellable_source_queue, g_steal_pointer (&cancellable_source));
/* Race with disposal of the cancellable source. */
g_cancellable_cancel (cancellable);
/* This thread cant drop its reference to the #GCancellable here, as it
* might not be the final reference (depending on how the race is
* resolved: #GCancellableSource holds a strong ref on the #GCancellable),
* and at this point we cant guarantee to support disposing of a
* #GCancellable in a different thread from where its created, especially
* when signal handlers are connected to it.
*
* So this is a workaround for a disposal-in-another-thread bug for
* #GCancellable, but theres no hope of debugging and resolving it with
* this test setup, and the bug is orthogonal to whats being tested here
* (a race between #GCancellable and #GCancellableSource). */
g_ptr_array_add (cancellables_pending_unref, g_steal_pointer (&cancellable));
}
/* Indicate that the test has finished. Cant use %NULL as #GAsyncQueue
* doesnt allow that.*/
g_async_queue_push (data.cancellable_source_queue, (gpointer) 1);
g_thread_join (g_steal_pointer (&thread));
g_assert (g_async_queue_length (data.cancellable_source_queue) == 0);
g_async_queue_unref (data.cancellable_source_queue);
g_mutex_clear (&data.mutex);
g_cond_clear (&data.cond);
g_ptr_array_unref (cancellables_pending_unref);
#endif
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/cancellable/multiple-concurrent", test_cancel_multiple_concurrent);
g_test_add_func ("/cancellable/null", test_cancel_null);
g_test_add_func ("/cancellable-source/threaded-dispose", test_cancellable_source_threaded_dispose);
return g_test_run ();
}

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw
BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR
q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS
+5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw
BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR
q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS
+5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,68 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw
BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR
q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS
+5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCVO34vew4kvTANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NTI1M1oXDTEyMDcyNDE4NTI1M1owgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAiaJ6bO5NJ
pyS8p//UVQM/T+exyZxznULwqCuVKv7uwss2QiKiQGJPfVc0iy650cTegtoc4ki5
Zfg/Cllxj2KAmbkWGlzVw7IvuBouruxdojm+0y60DzWr1rQUkL6VX/VBZXL51VPp
zCdTCzI3v4ztFStbUyC99xx1hdHOSleLOQ==
-----END CERTIFICATE-----
>>>> Garbage to be ignore <<<<
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQD9ny7saeYnDDANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NTMwMVoXDTEyMDcyNDE4NTMwMVowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAGBjOlcmD6
E6GlY2rvjCf0BpW0t4zKL/wvA5tBmuOWYg93psHgIdSNgkmfbA1kvD6kXehQlt1F
5yZJP91/VND5LHvXf5TcAmr/KeQAPYvqfiGYXuvHDLA9y9OOyTBMURLYfWuo9HZt
xeI14sZ9udXwtUhgcvXrBFzlRfkbojuMZw==
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----
>>>> Garbage to be ignore <<<<

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw
BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR
q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS
+5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCVO34vew4kvTANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NTI1M1oXDTEyMDcyNDE4NTI1M1owgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAiaJ6bO5NJ
pyS8p//UVQM/T+exyZxznULwqCuVKv7uwss2QiKiQGJPfVc0iy650cTegtoc4ki5
Zfg/Cllxj2KAmbkWGlzVw7IvuBouruxdojm+0y60DzWr1rQUkL6VX/VBZXL51VPp
zCdTCzI3v4ztFStbUyC99xx1hdHOSleLOQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQD9ny7saeYnDDANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NTMwMVoXDTEyMDcyNDE4NTMwMVowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAGBjOlcmD6
E6GlY2rvjCf0BpW0t4zKL/wvA5tBmuOWYg93psHgIdSNgkmfbA1kvD6kXehQlt1F
5yZJP91/VND5LHvXf5TcAmr/KeQAPYvqfiGYXuvHDLA9y9OOyTBMURLYfWuo9HZt
xeI14sZ9udXwtUhgcvXrBFzlRfkbojuMZw==
-----END CERTIFICATE-----

Binary file not shown.

View file

@ -0,0 +1,32 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICtTCCAh4CCQCMmwFMUPAJYzANBgkqhkiG9w0BAQUFADCBnjELMAkGA1UEBhMC
Q0ExDzANBgNVBAgMBlF1ZWJlYzERMA8GA1UEBwwITW9udHJlYWwxFzAVBgNVBAoM
DkNvbGxhYm9yYSBMdGQuMQ8wDQYDVQQLDAZDYW5hZGExEjAQBgNVBAMMCTEyNy4w
LjAuMTEtMCsGCSqGSIb3DQEJARYebmljb2xhcy5kdWZyZXNuZUBjb2xsYWJvcmEu
Y29tMB4XDTExMDcyNTE4NDkzNFoXDTEyMDcyNDE4NDkzNFowgZ4xCzAJBgNVBAYT
AkNBMQ8wDQYDVQQIDAZRdWViZWMxETAPBgNVBAcMCE1vbnRyZWFsMRcwFQYDVQQK
DA5Db2xsYWJvcmEgTHRkLjEPMA0GA1UECwwGQ2FuYWRhMRIwEAYDVQQDDAkxMjcu
MC4wLjExLTArBgkqhkiG9w0BCQEWHm5pY29sYXMuZHVmcmVzbmVAY29sbGFib3Jh
LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArJa05foKd5ULBBjHoI4U
DKMOcoYp6UO8o4t+rKBrlKVMp0D7Oz+bZt6I2T3kBjZmKH9wrHNsk6zC6wonbfMR
ZHILWcnTifbEEhIMHNqH+J5b33yGW3SEftd1jj1UZkubQVZEFha5UhbUO9AQ4TSt
0mX5AG+PkJi0kdTCRWlD1q0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQCaaBfCfCiw
BJ/2pzZOjoFQcMqwPWufJ+F7hv8AK0zaEhsYW/JPPNpVVjM4Rf9dhMFG513GQ6IR
q3K+okin/2H6XyLD1eyAxAreuyMZPwOsTdgkVROhl+NJEfZKnFZSxK9wkiQRnNhS
+5L8/na5o3vsgGerggQi8pj2JjfVE0R/aQ==
-----END CERTIFICATE-----

View file

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----

View file

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKyWtOX6CneVCwQY
x6COFAyjDnKGKelDvKOLfqyga5SlTKdA+zs/m2beiNk95AY2Zih/cKxzbJOswusK
J23zEWRyC1nJ04n2xBISDBzah/ieW998hlt0hH7XdY49VGZLm0FWRBYWuVIW1DvQ
EOE0rdJl+QBvj5CYtJHUwkVpQ9atAgMBAAECgYBROeyRgAiFF0RD/VWWnseY2vTl
uXboLdUOM4y+uhFnuBRHczHKRLlixMErXRGASwHxdWkWAIzNQ7XI4NKF0KwSD2QI
Hd/NJaS6crz5MXZMo4zm5aVDCJ8om9w2KxE1uDevxbKAwxdpZIUDfFahG5nki3SM
5fXy/7HlEceif+RpEQJBAOXoVLCAkt40CRGkw1AZ1GGYx6wdaY00G/dajOqbpamT
Cjllc+wu3emmt3QY3mNfQgbtyVPX94wP38b7dQapOPcCQQDALQzaC/5BSFtoH4pK
U5kM6LiCyeGeydozsdAYMknmejjLYS+dgjdjms8lZ515iUJXdxwyK2OeNwgkcidF
kEh7AkEA2CxqZUOf1RrsZBCeLVT8I4B6TtWhB8o1eZFE6tvLGvVNKcbBBxTSR/4g
hSNVB+7rsIQpR5LMCoBqkzihQtAe5QJBAL0n2p2I7oNdcDNF0D2mmWAedPavNXex
ISh+3d/jJ+BG7z4oc9CqSlCtITWlDliBZR5obAVptc0WR9pvzf3nrZ8CQGXyM+J1
B0pYSBJrqHmmbj76xct1aXunqOLJ60frhbseeFGvITem2tEY7SFJXW/hvHcMrN4m
IlGVZRaJKXvzby0=
-----END PRIVATE KEY-----

View file

@ -0,0 +1,18 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIdjDoEOJTH2ICAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBDNLC2sDVjClaQyT8BfXTt1BIIC
gCN4s9Z5bmfKogL7YHIJly2zLX5uILHeCr3iQpoPS8057V9Af1wqB/8AUOJrLY96
R2amkXjlxuqA0BebEk4gcR4tWvCNQ2VCOqvQozUt8LnA+2xQRgzNwaW0HPxcAUzf
6GVZKL7xfpwFD2ootfLwTHB2zAIVMo8nwgEzdDz93ZwsMmXJmOfSO7vpDQUnVqUX
jVlue0i8n7fO4ClQ8fz5J8zyvPj403bR9qxsIJjQZACNVLMIksQXjTDngymy/ziI
lZD4JDLXCQwAOgFz6N6vsyD/mHROyL4/4q8ujYFPmVpuAlQzuZJe6TFnmZHiSfoI
we6wi1Nee1rbM4VzsGFzMa4Fr0ZhElHEKBXXje4YKWCAOWEo3tLjow4+0dQxNx5W
tsbQdRt2fRYNYTgt18O55kq3DVfy93aMQVYIMuXkxwAuCWBeiLQrCfAM5r7kDwfc
owp2AQ5Ndf+aAwr89k2fYUpexz9kZzU+eIY2K1cRhpUlLRAr5SG2oVy7n9IvYs1m
O7/hjVBvXeAPDADVOtx/YNxPYr9ZI1X2QNDYGxNuSUNF1qGps66Gj+fcRe2NO+Ej
YfSyfBvw+0h8sad81ZPepCSpIkYX91p6lCdCmRnJWYBwYyn6V5tXOx6tn5ntKJZ9
9OtTGr7CMm7PLs9S8b03MV9IDJH+TBqR7msP1KWZbTxCNOws28EXo75tQ51ywElF
FJI6ZU2gBYaX39i8WyvEMXFRRqzYUMzV0Yw2KeVRiGLh0ZX/4rlh2PQqVXGyakvn
XttDRKEYPEvXDSRpO+tIvESlq9T0Pfo/rpnD4xJd2JWO6z/CSrn8cujs80e1+YjT
HXksoJzsoLGeiYG2DzTK9lY=
-----END ENCRYPTED PRIVATE KEY-----

View file

@ -0,0 +1,14 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t

View file

@ -0,0 +1,14 @@
MIICXQIBAAKBgQCslrTl+gp3lQsEGMegjhQMow5yhinpQ7yji36soGuUpUynQPs7
P5tm3ojZPeQGNmYof3Csc2yTrMLrCidt8xFkcgtZydOJ9sQSEgwc2of4nlvffIZb
dIR+13WOPVRmS5tBVkQWFrlSFtQ70BDhNK3SZfkAb4+QmLSR1MJFaUPWrQIDAQAB
AoGAUTnskYAIhRdEQ/1Vlp7HmNr05bl26C3VDjOMvroRZ7gUR3MxykS5YsTBK10R
gEsB8XVpFgCMzUO1yODShdCsEg9kCB3fzSWkunK8+TF2TKOM5uWlQwifKJvcNisR
Nbg3r8WygMMXaWSFA3xWoRuZ5It0jOX18v+x5RHHon/kaRECQQDl6FSwgJLeNAkR
pMNQGdRhmMesHWmNNBv3Wozqm6Wpkwo5ZXPsLt3pprd0GN5jX0IG7clT1/eMD9/G
+3UGqTj3AkEAwC0M2gv+QUhbaB+KSlOZDOi4gsnhnsnaM7HQGDJJ5no4y2EvnYI3
Y5rPJWedeYlCV3ccMitjnjcIJHInRZBIewJBANgsamVDn9Ua7GQQni1U/COAek7V
oQfKNXmRROrbyxr1TSnGwQcU0kf+IIUjVQfu67CEKUeSzAqAapM4oULQHuUCQQC9
J9qdiO6DXXAzRdA9pplgHnT2rzV3sSEoft3f4yfgRu8+KHPQqkpQrSE1pQ5YgWUe
aGwFabXNFkfab839562fAkBl8jPidQdKWEgSa6h5pm4++sXLdWl7p6jiyetH64W7
HnhRryE3ptrRGO0hSV1v4bx3DKzeJiJRlWUWiSl7828t
-----END RSA PRIVATE KEY-----

View file

682
gio/tests/codegen.py Normal file
View file

@ -0,0 +1,682 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Copyright © 2018, 2019 Endless Mobile, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301 USA
"""Integration tests for gdbus-codegen utility."""
import collections
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
import xml.etree.ElementTree as ET
import taptestrunner
# Disable line length warnings as wrapping the C code templates would be hard
# flake8: noqa: E501
Result = collections.namedtuple("Result", ("info", "out", "err", "subs"))
def on_win32():
return sys.platform.find('win') != -1
class TestCodegen(unittest.TestCase):
"""Integration test for running gdbus-codegen.
This can be run when installed or uninstalled. When uninstalled, it
requires G_TEST_BUILDDIR and G_TEST_SRCDIR to be set.
The idea with this test harness is to test the gdbus-codegen utility, its
handling of command line arguments, its exit statuses, and its handling of
various C source codes. In future we could split out tests for the core
parsing and generation code of gdbus-codegen into separate unit tests, and
just test command line behaviour in this integration test.
"""
# Track the cwd, we want to back out to that to clean up our tempdir
cwd = ""
def setUp(self):
self.timeout_seconds = 100 # seconds per test
self.tmpdir = tempfile.TemporaryDirectory()
self.cwd = os.getcwd()
os.chdir(self.tmpdir.name)
print("tmpdir:", self.tmpdir.name)
if "G_TEST_BUILDDIR" in os.environ:
self.__codegen = os.path.join(
os.environ["G_TEST_BUILDDIR"],
"..",
"gdbus-2.0",
"codegen",
"gdbus-codegen",
)
else:
self.__codegen = shutil.which("gdbus-codegen")
print("codegen:", self.__codegen)
def tearDown(self):
os.chdir(self.cwd)
self.tmpdir.cleanup()
def runCodegen(self, *args):
argv = [self.__codegen]
# shebang lines are not supported on native
# Windows consoles
if os.name == "nt":
argv.insert(0, sys.executable)
argv.extend(args)
print("Running:", argv)
env = os.environ.copy()
env["LC_ALL"] = "C.UTF-8"
print("Environment:", env)
# We want to ensure consistent line endings...
info = subprocess.run(
argv,
timeout=self.timeout_seconds,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=env,
universal_newlines=True,
)
info.check_returncode()
out = info.stdout.strip()
err = info.stderr.strip()
# Known substitutions for standard boilerplate
subs = {
"standard_top_comment": "/*\n"
" * This file is generated by gdbus-codegen, do not modify it.\n"
" *\n"
" * The license of this code is the same as for the D-Bus interface description\n"
" * it was derived from. Note that it links to GLib, so must comply with the\n"
" * LGPL linking clauses.\n"
" */",
"standard_config_h_include": "#ifdef HAVE_CONFIG_H\n"
'# include "config.h"\n'
"#endif",
"standard_header_includes": "#include <string.h>\n"
"#ifdef G_OS_UNIX\n"
"# include <gio/gunixfdlist.h>\n"
"#endif",
"standard_typedefs_and_helpers": "typedef struct\n"
"{\n"
" GDBusArgInfo parent_struct;\n"
" gboolean use_gvariant;\n"
"} _ExtendedGDBusArgInfo;\n"
"\n"
"typedef struct\n"
"{\n"
" GDBusMethodInfo parent_struct;\n"
" const gchar *signal_name;\n"
" gboolean pass_fdlist;\n"
"} _ExtendedGDBusMethodInfo;\n"
"\n"
"typedef struct\n"
"{\n"
" GDBusSignalInfo parent_struct;\n"
" const gchar *signal_name;\n"
"} _ExtendedGDBusSignalInfo;\n"
"\n"
"typedef struct\n"
"{\n"
" GDBusPropertyInfo parent_struct;\n"
" const gchar *hyphen_name;\n"
" guint use_gvariant : 1;\n"
" guint emits_changed_signal : 1;\n"
"} _ExtendedGDBusPropertyInfo;\n"
"\n"
"typedef struct\n"
"{\n"
" GDBusInterfaceInfo parent_struct;\n"
" const gchar *hyphen_name;\n"
"} _ExtendedGDBusInterfaceInfo;\n"
"\n"
"typedef struct\n"
"{\n"
" const _ExtendedGDBusPropertyInfo *info;\n"
" guint prop_id;\n"
" GValue orig_value; /* the value before the change */\n"
"} ChangedProperty;\n"
"\n"
"static void\n"
"_changed_property_free (ChangedProperty *data)\n"
"{\n"
" g_value_unset (&data->orig_value);\n"
" g_free (data);\n"
"}\n"
"\n"
"static gboolean\n"
"_g_strv_equal0 (gchar **a, gchar **b)\n"
"{\n"
" gboolean ret = FALSE;\n"
" guint n;\n"
" if (a == NULL && b == NULL)\n"
" {\n"
" ret = TRUE;\n"
" goto out;\n"
" }\n"
" if (a == NULL || b == NULL)\n"
" goto out;\n"
" if (g_strv_length (a) != g_strv_length (b))\n"
" goto out;\n"
" for (n = 0; a[n] != NULL; n++)\n"
" if (g_strcmp0 (a[n], b[n]) != 0)\n"
" goto out;\n"
" ret = TRUE;\n"
"out:\n"
" return ret;\n"
"}\n"
"\n"
"static gboolean\n"
"_g_variant_equal0 (GVariant *a, GVariant *b)\n"
"{\n"
" gboolean ret = FALSE;\n"
" if (a == NULL && b == NULL)\n"
" {\n"
" ret = TRUE;\n"
" goto out;\n"
" }\n"
" if (a == NULL || b == NULL)\n"
" goto out;\n"
" ret = g_variant_equal (a, b);\n"
"out:\n"
" return ret;\n"
"}\n"
"\n"
"G_GNUC_UNUSED static gboolean\n"
"_g_value_equal (const GValue *a, const GValue *b)\n"
"{\n"
" gboolean ret = FALSE;\n"
" g_assert (G_VALUE_TYPE (a) == G_VALUE_TYPE (b));\n"
" switch (G_VALUE_TYPE (a))\n"
" {\n"
" case G_TYPE_BOOLEAN:\n"
" ret = (g_value_get_boolean (a) == g_value_get_boolean (b));\n"
" break;\n"
" case G_TYPE_UCHAR:\n"
" ret = (g_value_get_uchar (a) == g_value_get_uchar (b));\n"
" break;\n"
" case G_TYPE_INT:\n"
" ret = (g_value_get_int (a) == g_value_get_int (b));\n"
" break;\n"
" case G_TYPE_UINT:\n"
" ret = (g_value_get_uint (a) == g_value_get_uint (b));\n"
" break;\n"
" case G_TYPE_INT64:\n"
" ret = (g_value_get_int64 (a) == g_value_get_int64 (b));\n"
" break;\n"
" case G_TYPE_UINT64:\n"
" ret = (g_value_get_uint64 (a) == g_value_get_uint64 (b));\n"
" break;\n"
" case G_TYPE_DOUBLE:\n"
" {\n"
" /* Avoid -Wfloat-equal warnings by doing a direct bit compare */\n"
" gdouble da = g_value_get_double (a);\n"
" gdouble db = g_value_get_double (b);\n"
" ret = memcmp (&da, &db, sizeof (gdouble)) == 0;\n"
" }\n"
" break;\n"
" case G_TYPE_STRING:\n"
" ret = (g_strcmp0 (g_value_get_string (a), g_value_get_string (b)) == 0);\n"
" break;\n"
" case G_TYPE_VARIANT:\n"
" ret = _g_variant_equal0 (g_value_get_variant (a), g_value_get_variant (b));\n"
" break;\n"
" default:\n"
" if (G_VALUE_TYPE (a) == G_TYPE_STRV)\n"
" ret = _g_strv_equal0 (g_value_get_boxed (a), g_value_get_boxed (b));\n"
" else\n"
' g_critical ("_g_value_equal() does not handle type %s", g_type_name (G_VALUE_TYPE (a)));\n'
" break;\n"
" }\n"
" return ret;\n"
"}",
}
result = Result(info, out, err, subs)
print("Output:", result.out)
return result
def runCodegenWithInterface(self, interface_contents, *args):
with tempfile.NamedTemporaryFile(
dir=self.tmpdir.name, suffix=".xml", delete=False
) as interface_file:
# Write out the interface.
interface_file.write(interface_contents.encode("utf-8"))
print(interface_file.name + ":", interface_contents)
interface_file.flush()
return self.runCodegen(interface_file.name, *args)
def test_help(self):
"""Test the --help argument."""
result = self.runCodegen("--help")
self.assertIn("usage: gdbus-codegen", result.out)
def test_no_args(self):
"""Test running with no arguments at all."""
with self.assertRaises(subprocess.CalledProcessError):
self.runCodegen()
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_empty_interface_header(self):
"""Test generating a header with an empty interface file."""
result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--header")
self.assertEqual("", result.err)
self.assertEqual(
"""{standard_top_comment}
#ifndef __STDOUT__
#define __STDOUT__
#include <gio/gio.h>
G_BEGIN_DECLS
G_END_DECLS
#endif /* __STDOUT__ */""".format(
**result.subs
),
result.out.strip(),
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_empty_interface_body(self):
"""Test generating a body with an empty interface file."""
result = self.runCodegenWithInterface("", "--output", "/dev/stdout", "--body")
self.assertEqual("", result.err)
self.assertEqual(
"""{standard_top_comment}
{standard_config_h_include}
#include "stdout.h"
{standard_header_includes}
{standard_typedefs_and_helpers}""".format(
**result.subs
),
result.out.strip(),
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_reproducible(self):
"""Test builds are reproducible regardless of file ordering."""
xml_contents1 = """
<node>
<interface name="com.acme.Coyote">
<method name="Run"/>
<method name="Sleep"/>
<method name="Attack"/>
<signal name="Surprised"/>
<property name="Mood" type="s" access="read"/>
</interface>
</node>
"""
xml_contents2 = """
<node>
<interface name="org.project.Bar.Frobnicator">
<method name="RandomMethod"/>
</interface>
</node>
"""
with tempfile.NamedTemporaryFile(
dir=self.tmpdir.name, suffix="1.xml", delete=False
) as xml_file1, tempfile.NamedTemporaryFile(
dir=self.tmpdir.name, suffix="2.xml", delete=False
) as xml_file2:
# Write out the interfaces.
xml_file1.write(xml_contents1.encode("utf-8"))
xml_file2.write(xml_contents2.encode("utf-8"))
xml_file1.flush()
xml_file2.flush()
# Repeat this for headers and bodies.
for header_or_body in ["--header", "--body"]:
# Run gdbus-codegen with the interfaces in one order, and then
# again in another order.
result1 = self.runCodegen(
xml_file1.name,
xml_file2.name,
"--output",
"/dev/stdout",
header_or_body,
)
self.assertEqual("", result1.err)
result2 = self.runCodegen(
xml_file2.name,
xml_file1.name,
"--output",
"/dev/stdout",
header_or_body,
)
self.assertEqual("", result2.err)
# The output should be the same.
self.assertEqual(result1.out, result2.out)
def test_generate_docbook(self):
"""Test the basic functionality of the docbook generator."""
xml_contents = """
<node>
<interface name="org.project.Bar.Frobnicator">
<method name="RandomMethod"/>
</interface>
</node>
"""
res = self.runCodegenWithInterface(
xml_contents,
"--generate-docbook",
"test",
)
self.assertEqual("", res.err)
self.assertEqual("", res.out)
with open("test-org.project.Bar.Frobnicator.xml", "r") as f:
xml_data = f.readlines()
self.assertTrue(len(xml_data) != 0)
def test_generate_rst(self):
"""Test the basic functionality of the rst generator."""
xml_contents = """
<node>
<interface name="org.project.Bar.Frobnicator">
<method name="RandomMethod"/>
</interface>
</node>
"""
res = self.runCodegenWithInterface(
xml_contents,
"--generate-rst",
"test",
)
self.assertEqual("", res.err)
self.assertEqual("", res.out)
with open("test-org.project.Bar.Frobnicator.rst", "r") as f:
rst = f.readlines()
self.assertTrue(len(rst) != 0)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_min_required_invalid(self):
"""Test running with an invalid --glib-min-required."""
with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface(
"",
"--output",
"/dev/stdout",
"--body",
"--glib-min-required",
"hello mum",
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_min_required_too_low(self):
"""Test running with a --glib-min-required which is too low (and hence
probably a typo)."""
with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface(
"", "--output", "/dev/stdout", "--body", "--glib-min-required", "2.6"
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_min_required_major_only(self):
"""Test running with a --glib-min-required which contains only a major version."""
result = self.runCodegenWithInterface(
"",
"--output",
"/dev/stdout",
"--header",
"--glib-min-required",
"3",
"--glib-max-allowed",
"3.2",
)
self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip())
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_min_required_with_micro(self):
"""Test running with a --glib-min-required which contains a micro version."""
result = self.runCodegenWithInterface(
"", "--output", "/dev/stdout", "--header", "--glib-min-required", "2.46.2"
)
self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip())
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_max_allowed_too_low(self):
"""Test running with a --glib-max-allowed which is too low (and hence
probably a typo)."""
with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface(
"", "--output", "/dev/stdout", "--body", "--glib-max-allowed", "2.6"
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_max_allowed_major_only(self):
"""Test running with a --glib-max-allowed which contains only a major version."""
result = self.runCodegenWithInterface(
"", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "3"
)
self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip())
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_max_allowed_with_micro(self):
"""Test running with a --glib-max-allowed which contains a micro version."""
result = self.runCodegenWithInterface(
"", "--output", "/dev/stdout", "--header", "--glib-max-allowed", "2.46.2"
)
self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip())
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_max_allowed_unstable(self):
"""Test running with a --glib-max-allowed which is unstable. It should
be rounded up to the next stable version number, and hence should not
end up less than --glib-min-required."""
result = self.runCodegenWithInterface(
"",
"--output",
"/dev/stdout",
"--header",
"--glib-max-allowed",
"2.63",
"--glib-min-required",
"2.64",
)
self.assertEqual("", result.err)
self.assertNotEqual("", result.out.strip())
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_glib_max_allowed_less_than_min_required(self):
"""Test running with a --glib-max-allowed which is less than
--glib-min-required."""
with self.assertRaises(subprocess.CalledProcessError):
self.runCodegenWithInterface(
"",
"--output",
"/dev/stdout",
"--body",
"--glib-max-allowed",
"2.62",
"--glib-min-required",
"2.64",
)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_unix_fd_types_and_annotations(self):
"""Test an interface with `h` arguments, no annotation, and GLib < 2.64.
See issue #1726.
"""
interface_xml = """
<node>
<interface name="FDPassing">
<method name="HelloFD">
<annotation name="org.gtk.GDBus.C.UnixFD" value="1"/>
<arg name="greeting" direction="in" type="s"/>
<arg name="response" direction="out" type="s"/>
</method>
<method name="NoAnnotation">
<arg name="greeting" direction="in" type="h"/>
<arg name="greeting_locale" direction="in" type="s"/>
<arg name="response" direction="out" type="h"/>
<arg name="response_locale" direction="out" type="s"/>
</method>
<method name="NoAnnotationNested">
<arg name="files" type="a{sh}" direction="in"/>
</method>
</interface>
</node>"""
# Try without specifying --glib-min-required.
result = self.runCodegenWithInterface(
interface_xml, "--output", "/dev/stdout", "--header"
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GUnixFDList"), 6)
# Specify an old --glib-min-required.
result = self.runCodegenWithInterface(
interface_xml,
"--output",
"/dev/stdout",
"--header",
"--glib-min-required",
"2.32",
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GUnixFDList"), 6)
# Specify a --glib-min-required ≥ 2.64. There should be more
# mentions of `GUnixFDList` now, since the annotation is not needed to
# trigger its use.
result = self.runCodegenWithInterface(
interface_xml,
"--output",
"/dev/stdout",
"--header",
"--glib-min-required",
"2.64",
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GUnixFDList"), 18)
@unittest.skipIf(on_win32(), "requires /dev/stdout")
def test_call_flags_and_timeout_method_args(self):
"""Test that generated method call functions have @call_flags and
@timeout_msec args if and only if GLib >= 2.64.
"""
interface_xml = """
<node>
<interface name="org.project.UsefulInterface">
<method name="UsefulMethod"/>
</interface>
</node>"""
# Try without specifying --glib-min-required.
result = self.runCodegenWithInterface(
interface_xml, "--output", "/dev/stdout", "--header"
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0)
self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0)
# Specify an old --glib-min-required.
result = self.runCodegenWithInterface(
interface_xml,
"--output",
"/dev/stdout",
"--header",
"--glib-min-required",
"2.32",
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 0)
self.assertEqual(result.out.strip().count("gint timeout_msec,"), 0)
# Specify a --glib-min-required ≥ 2.64. The two arguments should be
# present for both the async and sync method call functions.
result = self.runCodegenWithInterface(
interface_xml,
"--output",
"/dev/stdout",
"--header",
"--glib-min-required",
"2.64",
)
self.assertEqual("", result.err)
self.assertEqual(result.out.strip().count("GDBusCallFlags call_flags,"), 2)
self.assertEqual(result.out.strip().count("gint timeout_msec,"), 2)
def test_generate_valid_docbook(self):
"""Test the basic functionality of the docbook generator."""
xml_contents = """
<node>
<interface name="org.project.Bar.Frobnicator">
<!-- Resize:
@size: New partition size in bytes, 0 for maximal size.
@options: Options.
@since 2.7.2
Resizes the partition.
The partition will not change its position but might be slightly bigger
than requested due to sector counts and alignment (e.g. 1MiB).
If the requested size can't be allocated it results in an error.
The maximal size can automatically be set by using 0 as size.
-->
<method name="Resize">
<arg name="size" direction="in" type="t"/>
<arg name="options" direction="in" type="a{sv}"/>
</method>
</interface>
</node>
"""
res = self.runCodegenWithInterface(
xml_contents,
"--generate-docbook",
"test",
)
self.assertEqual("", res.err)
self.assertEqual("", res.out)
with open("test-org.project.Bar.Frobnicator.xml", "r") as f:
self.assertTrue(ET.parse(f) is not None)
if __name__ == "__main__":
unittest.main(testRunner=taptestrunner.TAPTestRunner())

449
gio/tests/contenttype.c Normal file
View file

@ -0,0 +1,449 @@
#include <gio/gio.h>
#include <string.h>
#define g_assert_content_type_equals(s1, s2) \
do { \
const char *__s1 = (s1), *__s2 = (s2); \
if (g_content_type_equals (__s1, __s2)) ; \
else \
g_assertion_message_cmpstr (G_LOG_DOMAIN, \
__FILE__, __LINE__, \
G_STRFUNC, \
#s1 " == " #s2, \
__s1, " == ", __s2); \
} while (0)
static void
test_guess (void)
{
gchar *res;
gchar *expected;
gchar *existing_directory;
gboolean uncertain;
guchar data[] =
"[Desktop Entry]\n"
"Type=Application\n"
"Name=appinfo-test\n"
"Exec=./appinfo-test --option\n";
#ifdef G_OS_WIN32
existing_directory = (gchar *) g_getenv ("SYSTEMROOT");
if (existing_directory)
existing_directory = g_strdup_printf ("%s" G_DIR_SEPARATOR_S, existing_directory);
#else
existing_directory = g_strdup ("/etc/");
#endif
res = g_content_type_guess (existing_directory, NULL, 0, &uncertain);
g_free (existing_directory);
expected = g_content_type_from_mime_type ("inode/directory");
g_assert_content_type_equals (expected, res);
g_assert_true (uncertain);
g_free (res);
g_free (expected);
res = g_content_type_guess ("foo.txt", NULL, 0, &uncertain);
expected = g_content_type_from_mime_type ("text/plain");
g_assert_content_type_equals (expected, res);
g_free (res);
g_free (expected);
res = g_content_type_guess ("foo.txt", data, sizeof (data) - 1, &uncertain);
expected = g_content_type_from_mime_type ("text/plain");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
/* Sadly win32 & OSX just don't have as large and robust of a mime type database as Linux */
#ifndef G_OS_WIN32
#ifndef __APPLE__
res = g_content_type_guess ("foo", data, sizeof (data) - 1, &uncertain);
expected = g_content_type_from_mime_type ("text/plain");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
res = g_content_type_guess ("foo.desktop", data, sizeof (data) - 1, &uncertain);
expected = g_content_type_from_mime_type ("application/x-desktop");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
res = g_content_type_guess (NULL, data, sizeof (data) - 1, &uncertain);
expected = g_content_type_from_mime_type ("application/x-desktop");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
/* this is potentially ambiguous: it does not match the PO template format,
* but looks like text so it can't be Powerpoint */
res = g_content_type_guess ("test.pot", (guchar *)"ABC abc", 7, &uncertain);
expected = g_content_type_from_mime_type ("text/x-gettext-translation-template");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
res = g_content_type_guess ("test.pot", (guchar *)"msgid \"", 7, &uncertain);
expected = g_content_type_from_mime_type ("text/x-gettext-translation-template");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
res = g_content_type_guess ("test.pot", (guchar *)"\xCF\xD0\xE0\x11", 4, &uncertain);
expected = g_content_type_from_mime_type ("application/vnd.ms-powerpoint");
g_assert_content_type_equals (expected, res);
/* we cannot reliably detect binary powerpoint files as long as there is no
* defined MIME magic, so do not check uncertain here
*/
g_free (res);
g_free (expected);
res = g_content_type_guess ("test.otf", (guchar *)"OTTO", 4, &uncertain);
expected = g_content_type_from_mime_type ("application/x-font-otf");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
#endif /* __APPLE__ */
res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 23, &uncertain);
expected = g_content_type_from_mime_type ("image/x-eps");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
/* The data below would be detected as a valid content type, but shouldnt be read at all. */
res = g_content_type_guess (NULL, (guchar *)"%!PS-Adobe-2.0 EPSF-1.2", 0, &uncertain);
expected = g_content_type_from_mime_type ("application/x-zerosize");
g_assert_content_type_equals (expected, res);
g_assert_false (uncertain);
g_free (res);
g_free (expected);
#endif /* G_OS_WIN32 */
}
static void
test_unknown (void)
{
gchar *unknown;
gchar *str;
unknown = g_content_type_from_mime_type ("application/octet-stream");
g_assert_true (g_content_type_is_unknown (unknown));
str = g_content_type_get_mime_type (unknown);
g_assert_cmpstr (str, ==, "application/octet-stream");
g_free (str);
g_free (unknown);
}
static void
test_subtype (void)
{
gchar *plain;
gchar *xml;
plain = g_content_type_from_mime_type ("text/plain");
xml = g_content_type_from_mime_type ("application/xml");
g_assert_true (g_content_type_is_a (xml, plain));
g_assert_true (g_content_type_is_mime_type (xml, "text/plain"));
g_free (plain);
g_free (xml);
}
static gint
find_mime (gconstpointer a, gconstpointer b)
{
if (g_content_type_equals (a, b))
return 0;
return 1;
}
static void
test_list (void)
{
GList *types;
gchar *plain;
gchar *xml;
#ifdef __APPLE__
g_test_skip ("The OSX backend does not implement g_content_types_get_registered()");
return;
#endif
plain = g_content_type_from_mime_type ("text/plain");
xml = g_content_type_from_mime_type ("application/xml");
types = g_content_types_get_registered ();
g_assert_cmpuint (g_list_length (types), >, 1);
/* just check that some types are in the list */
g_assert_nonnull (g_list_find_custom (types, plain, find_mime));
g_assert_nonnull (g_list_find_custom (types, xml, find_mime));
g_list_free_full (types, g_free);
g_free (plain);
g_free (xml);
}
static void
test_executable (void)
{
gchar *type;
#ifdef G_OS_WIN32
type = g_content_type_from_mime_type ("application/vnd.microsoft.portable-executable");
/* FIXME: the MIME is not in the default `MIME\Database\Content Type` registry.
* g_assert_true (g_content_type_can_be_executable (type));
*/
g_free (type);
#else
type = g_content_type_from_mime_type ("application/x-executable");
g_assert_true (g_content_type_can_be_executable (type));
g_free (type);
type = g_content_type_from_mime_type ("text/plain");
g_assert_true (g_content_type_can_be_executable (type));
g_free (type);
#endif
type = g_content_type_from_mime_type ("image/png");
g_assert_false (g_content_type_can_be_executable (type));
g_free (type);
}
static void
test_description (void)
{
gchar *type;
gchar *desc;
type = g_content_type_from_mime_type ("text/plain");
desc = g_content_type_get_description (type);
g_assert_nonnull (desc);
g_free (desc);
g_free (type);
}
static void
test_icon (void)
{
gchar *type;
GIcon *icon;
type = g_content_type_from_mime_type ("text/plain");
icon = g_content_type_get_icon (type);
g_assert_true (G_IS_ICON (icon));
if (G_IS_THEMED_ICON (icon))
{
const gchar *const *names;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
#ifdef __APPLE__
g_assert_true (g_strv_contains (names, "text-*"));
#else
#ifndef G_OS_WIN32
g_assert_true (g_strv_contains (names, "text-plain"));
#endif
g_assert_true (g_strv_contains (names, "text-x-generic"));
#endif
}
g_object_unref (icon);
g_free (type);
type = g_content_type_from_mime_type ("application/rtf");
icon = g_content_type_get_icon (type);
g_assert_true (G_IS_ICON (icon));
if (G_IS_THEMED_ICON (icon))
{
const gchar *const *names;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
#ifdef G_OS_WIN32
g_assert_true (g_strv_contains (names, "text-x-generic"));
#else
g_assert_true (g_strv_contains (names, "application-rtf"));
#ifndef __APPLE__
g_assert_true (g_strv_contains (names, "x-office-document"));
#endif
#endif
}
g_object_unref (icon);
g_free (type);
}
static void
test_symbolic_icon (void)
{
#ifndef G_OS_WIN32
gchar *type;
GIcon *icon;
type = g_content_type_from_mime_type ("text/plain");
icon = g_content_type_get_symbolic_icon (type);
g_assert_true (G_IS_ICON (icon));
if (G_IS_THEMED_ICON (icon))
{
const gchar *const *names;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
#ifdef __APPLE__
g_assert_true (g_strv_contains (names, "text-*-symbolic"));
g_assert_true (g_strv_contains (names, "text-*"));
#else
g_assert_true (g_strv_contains (names, "text-plain-symbolic"));
g_assert_true (g_strv_contains (names, "text-x-generic-symbolic"));
g_assert_true (g_strv_contains (names, "text-plain"));
g_assert_true (g_strv_contains (names, "text-x-generic"));
#endif
}
g_object_unref (icon);
g_free (type);
type = g_content_type_from_mime_type ("application/rtf");
icon = g_content_type_get_symbolic_icon (type);
g_assert_true (G_IS_ICON (icon));
if (G_IS_THEMED_ICON (icon))
{
const gchar *const *names;
names = g_themed_icon_get_names (G_THEMED_ICON (icon));
g_assert_true (g_strv_contains (names, "application-rtf-symbolic"));
g_assert_true (g_strv_contains (names, "application-rtf"));
#ifndef __APPLE__
g_assert_true (g_strv_contains (names, "x-office-document-symbolic"));
g_assert_true (g_strv_contains (names, "x-office-document"));
#endif
}
g_object_unref (icon);
g_free (type);
#endif
}
static void
test_tree (void)
{
const gchar *tests[] = {
"x-content/image-dcf",
"x-content/unix-software",
"x-content/win32-software"
};
const gchar *path;
GFile *file;
gchar **types;
gsize i;
#if defined(__APPLE__) || defined(G_OS_WIN32)
g_test_skip ("The OSX & Windows backends do not implement g_content_type_guess_for_tree()");
return;
#endif
for (i = 0; i < G_N_ELEMENTS (tests); i++)
{
path = g_test_get_filename (G_TEST_DIST, tests[i], NULL);
file = g_file_new_for_path (path);
types = g_content_type_guess_for_tree (file);
g_assert_content_type_equals (types[0], tests[i]);
g_strfreev (types);
g_object_unref (file);
}
}
static void
test_type_is_a_special_case (void)
{
gboolean res;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=782311");
/* Everything but the inode type is application/octet-stream */
res = g_content_type_is_a ("inode/directory", "application/octet-stream");
g_assert_false (res);
#if !defined(__APPLE__) && !defined(G_OS_WIN32)
res = g_content_type_is_a ("anything", "application/octet-stream");
g_assert_true (res);
#endif
}
static void
test_guess_svg_from_data (void)
{
const gchar svgfilecontent[] = "<svg xmlns=\"http://www.w3.org/2000/svg\"\
xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n\
<rect x=\"10\" y=\"10\" height=\"100\" width=\"100\"\n\
style=\"stroke:#ff0000; fill: #0000ff\"/>\n\
</svg>\n";
gboolean uncertain = TRUE;
gchar *res = g_content_type_guess (NULL, (guchar *)svgfilecontent,
sizeof (svgfilecontent) - 1, &uncertain);
#ifdef __APPLE__
g_assert_cmpstr (res, ==, "public.svg-image");
#elif defined(G_OS_WIN32)
g_test_skip ("svg type detection from content is not implemented on WIN32");
#else
g_assert_cmpstr (res, ==, "image/svg+xml");
#endif
g_assert_false (uncertain);
g_free (res);
}
static void
test_mime_from_content (void)
{
#ifdef __APPLE__
gchar *mime_type;
mime_type = g_content_type_get_mime_type ("com.microsoft.bmp");
g_assert_cmpstr (mime_type, ==, "image/bmp");
g_free (mime_type);
mime_type = g_content_type_get_mime_type ("com.compuserve.gif");
g_assert_cmpstr (mime_type, ==, "image/gif");
g_free (mime_type);
mime_type = g_content_type_get_mime_type ("public.png");
g_assert_cmpstr (mime_type, ==, "image/png");
g_free (mime_type);
mime_type = g_content_type_get_mime_type ("public.text");
g_assert_cmpstr (mime_type, ==, "text/*");
g_free (mime_type);
mime_type = g_content_type_get_mime_type ("public.svg-image");
g_assert_cmpstr (mime_type, ==, "image/svg+xml");
g_free (mime_type);
#elif defined(G_OS_WIN32)
g_test_skip ("mime from content type test not implemented on WIN32");
#else
g_test_skip ("mime from content type test not implemented on UNIX");
#endif
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/contenttype/guess", test_guess);
g_test_add_func ("/contenttype/guess_svg_from_data", test_guess_svg_from_data);
g_test_add_func ("/contenttype/mime_from_content", test_mime_from_content);
g_test_add_func ("/contenttype/unknown", test_unknown);
g_test_add_func ("/contenttype/subtype", test_subtype);
g_test_add_func ("/contenttype/list", test_list);
g_test_add_func ("/contenttype/executable", test_executable);
g_test_add_func ("/contenttype/description", test_description);
g_test_add_func ("/contenttype/icon", test_icon);
g_test_add_func ("/contenttype/symbolic-icon", test_symbolic_icon);
g_test_add_func ("/contenttype/tree", test_tree);
g_test_add_func ("/contenttype/test_type_is_a_special_case",
test_type_is_a_special_case);
return g_test_run ();
}

441
gio/tests/contexts.c Normal file
View file

@ -0,0 +1,441 @@
#include "gcontextspecificgroup.c"
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define N_THREADS 10
static gchar *test_file;
char *test_file_buffer;
gsize test_file_size;
static char async_read_buffer[8192];
static void
read_data (GObject *source, GAsyncResult *result, gpointer loop)
{
GInputStream *in = G_INPUT_STREAM (source);
GError *error = NULL;
gssize nread;
nread = g_input_stream_read_finish (in, result, &error);
g_assert_no_error (error);
g_assert_cmpint (nread, >, 0);
g_assert_cmpint (nread, <=, MIN(sizeof (async_read_buffer), test_file_size));
g_assert (memcmp (async_read_buffer, test_file_buffer, nread) == 0);
g_main_loop_quit (loop);
}
static void
opened_for_read (GObject *source, GAsyncResult *result, gpointer loop)
{
GFile *file = G_FILE (source);
GFileInputStream *in;
GError *error = NULL;
in = g_file_read_finish (file, result, &error);
g_assert_no_error (error);
memset (async_read_buffer, 0, sizeof (async_read_buffer));
g_input_stream_read_async (G_INPUT_STREAM (in),
async_read_buffer, sizeof (async_read_buffer),
G_PRIORITY_DEFAULT, NULL,
read_data, loop);
g_object_unref (in);
}
/* Test 1: Async I/O started in a thread with a thread-default context
* will stick to that thread, and will complete even if the default
* main loop is blocked. (NB: the last part would not be true if we
* were testing GFileMonitor!)
*/
static gboolean idle_start_test1_thread (gpointer loop);
static gpointer test1_thread (gpointer user_data);
static gboolean test1_done;
static GCond test1_cond;
static GMutex test1_mutex;
static void
test_thread_independence (void)
{
GMainLoop *loop;
loop = g_main_loop_new (NULL, FALSE);
g_idle_add (idle_start_test1_thread, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
static gboolean
idle_start_test1_thread (gpointer loop)
{
gint64 time;
GThread *thread;
gboolean io_completed;
g_mutex_lock (&test1_mutex);
thread = g_thread_new ("test1", test1_thread, NULL);
time = g_get_monotonic_time () + 2 * G_TIME_SPAN_SECOND;
while (!test1_done)
{
io_completed = g_cond_wait_until (&test1_cond, &test1_mutex, time);
g_assert (io_completed);
}
g_thread_join (thread);
g_mutex_unlock (&test1_mutex);
g_main_loop_quit (loop);
return G_SOURCE_REMOVE;
}
static gpointer
test1_thread (gpointer user_data)
{
GMainContext *context;
GMainLoop *loop;
GFile *file;
/* Wait for main thread to be waiting on test1_cond */
g_mutex_lock (&test1_mutex);
context = g_main_context_new ();
g_assert (g_main_context_get_thread_default () == NULL);
g_main_context_push_thread_default (context);
g_assert (g_main_context_get_thread_default () == context);
file = g_file_new_for_path (test_file);
g_assert (g_file_supports_thread_contexts (file));
loop = g_main_loop_new (context, FALSE);
g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
opened_for_read, loop);
g_object_unref (file);
g_main_loop_run (loop);
g_main_loop_unref (loop);
test1_done = TRUE;
g_cond_signal (&test1_cond);
g_mutex_unlock (&test1_mutex);
g_main_context_pop_thread_default (context);
g_main_context_unref (context);
return NULL;
}
/* Test 2: If we push a thread-default context in the main thread, we
* can run async ops in that context without running the default
* context.
*/
static gboolean test2_fail (gpointer user_data);
static void
test_context_independence (void)
{
GMainContext *context;
GMainLoop *loop;
GFile *file;
guint default_timeout;
GSource *thread_default_timeout;
context = g_main_context_new ();
g_assert (g_main_context_get_thread_default () == NULL);
g_main_context_push_thread_default (context);
g_assert (g_main_context_get_thread_default () == context);
file = g_file_new_for_path (test_file);
g_assert (g_file_supports_thread_contexts (file));
/* Add a timeout to the main loop, to fail immediately if it gets run */
default_timeout = g_timeout_add_full (G_PRIORITY_HIGH, 0,
test2_fail, NULL, NULL);
/* Add a timeout to the alternate loop, to fail if the I/O *doesn't* run */
thread_default_timeout = g_timeout_source_new_seconds (2);
g_source_set_callback (thread_default_timeout, test2_fail, NULL, NULL);
g_source_attach (thread_default_timeout, context);
loop = g_main_loop_new (context, FALSE);
g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
opened_for_read, loop);
g_object_unref (file);
g_main_loop_run (loop);
g_main_loop_unref (loop);
g_source_remove (default_timeout);
g_source_destroy (thread_default_timeout);
g_source_unref (thread_default_timeout);
g_main_context_pop_thread_default (context);
g_main_context_unref (context);
}
static gboolean
test2_fail (gpointer user_data)
{
g_assert_not_reached ();
return FALSE;
}
typedef struct
{
GObject parent_instance;
GMainContext *context;
} PerThreadThing;
typedef GObjectClass PerThreadThingClass;
static GType per_thread_thing_get_type (void);
G_DEFINE_TYPE (PerThreadThing, per_thread_thing, G_TYPE_OBJECT)
static GContextSpecificGroup group;
static gpointer instances[N_THREADS];
static gint is_running;
static gint current_value;
static gint observed_values[N_THREADS];
static void
start_func (void)
{
g_assert (!is_running);
g_atomic_int_set (&is_running, TRUE);
}
static void
stop_func (void)
{
g_assert (is_running);
g_atomic_int_set (&is_running, FALSE);
}
static void
per_thread_thing_finalize (GObject *object)
{
PerThreadThing *thing = (PerThreadThing *) object;
g_context_specific_group_remove (&group, thing->context, thing, stop_func);
G_OBJECT_CLASS (per_thread_thing_parent_class)->finalize (object);
}
static void
per_thread_thing_init (PerThreadThing *thing)
{
}
static void
per_thread_thing_class_init (PerThreadThingClass *class)
{
class->finalize = per_thread_thing_finalize;
g_signal_new ("changed", per_thread_thing_get_type (), G_SIGNAL_RUN_FIRST, 0,
NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
static gpointer
per_thread_thing_get (void)
{
return g_context_specific_group_get (&group, per_thread_thing_get_type (),
G_STRUCT_OFFSET (PerThreadThing, context),
start_func);
}
static gpointer
test_identity_thread (gpointer user_data)
{
guint thread_nr = GPOINTER_TO_UINT (user_data);
GMainContext *my_context;
guint i, j;
my_context = g_main_context_new ();
g_main_context_push_thread_default (my_context);
g_assert (!instances[thread_nr]);
instances[thread_nr] = per_thread_thing_get ();
g_assert (g_atomic_int_get (&is_running));
for (i = 0; i < 100; i++)
{
gpointer instance = per_thread_thing_get ();
for (j = 0; j < N_THREADS; j++)
g_assert ((instance == instances[j]) == (thread_nr == j));
g_assert (g_atomic_int_get (&is_running));
g_thread_yield ();
g_assert (g_atomic_int_get (&is_running));
}
for (i = 0; i < 100; i++)
{
g_object_unref (instances[thread_nr]);
for (j = 0; j < N_THREADS; j++)
g_assert ((instances[thread_nr] == instances[j]) == (thread_nr == j));
g_assert (g_atomic_int_get (&is_running));
g_thread_yield ();
}
/* drop the last ref */
g_object_unref (instances[thread_nr]);
instances[thread_nr] = NULL;
g_main_context_pop_thread_default (my_context);
g_main_context_unref (my_context);
/* at least one thread should see this cleared on exit */
return GUINT_TO_POINTER (!group.requested_state);
}
static void
test_context_specific_identity (void)
{
GThread *threads[N_THREADS];
gboolean exited = FALSE;
guint i;
g_assert (!g_atomic_int_get (&is_running));
for (i = 0; i < N_THREADS; i++)
threads[i] = g_thread_new ("test", test_identity_thread, GUINT_TO_POINTER (i));
for (i = 0; i < N_THREADS; i++)
exited |= GPOINTER_TO_UINT (g_thread_join (threads[i]));
g_assert (exited);
g_assert (!group.requested_state);
}
static void
changed_emitted (PerThreadThing *thing,
gpointer user_data)
{
gint *observed_value = user_data;
g_atomic_int_set (observed_value, g_atomic_int_get (&current_value));
}
static gpointer
test_emit_thread (gpointer user_data)
{
gint *observed_value = user_data;
GMainContext *my_context;
gpointer instance;
my_context = g_main_context_new ();
g_main_context_push_thread_default (my_context);
instance = per_thread_thing_get ();
g_assert (g_atomic_int_get (&is_running));
g_signal_connect (instance, "changed", G_CALLBACK (changed_emitted), observed_value);
/* observe after connection */
g_atomic_int_set (observed_value, g_atomic_int_get (&current_value));
while (g_atomic_int_get (&current_value) != -1)
g_main_context_iteration (my_context, TRUE);
g_object_unref (instance);
g_main_context_pop_thread_default (my_context);
g_main_context_unref (my_context);
/* at least one thread should see this cleared on exit */
return GUINT_TO_POINTER (!group.requested_state);
}
static void
test_context_specific_emit (void)
{
GThread *threads[N_THREADS];
gboolean exited = FALSE;
gsize i;
gint k, n;
for (i = 0; i < N_THREADS; i++)
threads[i] = g_thread_new ("test", test_emit_thread, &observed_values[i]);
/* make changes and ensure that they are observed */
for (n = 0; n < 1000; n++)
{
gint64 expiry;
/* don't burn CPU forever */
expiry = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
g_atomic_int_set (&current_value, n);
/* wake them to notice */
for (k = 0; k < g_test_rand_int_range (1, 5); k++)
g_context_specific_group_emit (&group, g_signal_lookup ("changed", per_thread_thing_get_type ()));
for (i = 0; i < N_THREADS; i++)
while (g_atomic_int_get (&observed_values[i]) != n)
{
g_thread_yield ();
if (g_get_monotonic_time () > expiry)
g_error ("timed out");
}
}
/* tell them to quit */
g_atomic_int_set (&current_value, -1);
g_context_specific_group_emit (&group, g_signal_lookup ("notify", G_TYPE_OBJECT));
for (i = 0; i < N_THREADS; i++)
exited |= GPOINTER_TO_UINT (g_thread_join (threads[i]));
g_assert (exited);
g_assert (!group.requested_state);
}
static void
test_context_specific_emit_and_unref (void)
{
gpointer obj;
obj = per_thread_thing_get ();
g_context_specific_group_emit (&group, g_signal_lookup ("changed", per_thread_thing_get_type ()));
g_object_unref (obj);
while (g_main_context_iteration (NULL, 0))
;
}
int
main (int argc, char **argv)
{
GError *error = NULL;
int ret;
g_test_init (&argc, &argv, NULL);
test_file = g_test_build_filename (G_TEST_DIST, "contexts.c", NULL);
g_file_get_contents (test_file, &test_file_buffer,
&test_file_size, &error);
g_assert_no_error (error);
g_test_add_func ("/gio/contexts/thread-independence", test_thread_independence);
g_test_add_func ("/gio/contexts/context-independence", test_context_independence);
g_test_add_func ("/gio/contexts/context-specific/identity", test_context_specific_identity);
g_test_add_func ("/gio/contexts/context-specific/emit", test_context_specific_emit);
g_test_add_func ("/gio/contexts/context-specific/emit-and-unref", test_context_specific_emit_and_unref);
ret = g_test_run();
g_free (test_file_buffer);
g_free (test_file);
return ret;
}

1235
gio/tests/converter-stream.c Normal file

File diff suppressed because it is too large Load diff

213
gio/tests/credentials.c Normal file
View file

@ -0,0 +1,213 @@
/* GLib testing framework examples and tests
*
* Copyright © 2012 Collabora Ltd.
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include "config.h"
#include <gio/gio.h>
#include <gio/gcredentialsprivate.h>
#ifdef G_OS_WIN32
static void
test_basic (void)
{
GCredentials *creds = g_credentials_new ();
gchar *stringified;
DWORD *pid;
stringified = g_credentials_to_string (creds);
g_test_message ("%s", stringified);
g_free (stringified);
pid = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_WIN32_PID);
g_assert_cmpuint (*pid, ==, GetCurrentProcessId ());
g_object_unref (creds);
}
#else
static void
test_basic (void)
{
GCredentials *creds = g_credentials_new ();
GCredentials *other = g_credentials_new ();
gpointer bad_native_creds;
#if G_CREDENTIALS_SUPPORTED
GError *error = NULL;
gboolean set;
pid_t not_me;
gchar *stringified;
#endif
/* You can always get a credentials object, but it might not work. */
g_assert (creds != NULL);
g_assert (other != NULL);
#if G_CREDENTIALS_SUPPORTED
g_assert (g_credentials_is_same_user (creds, other, &error));
g_assert_no_error (error);
if (geteuid () == 0)
not_me = 65534; /* traditionally 'nobody' */
else
not_me = 0;
g_assert_cmpuint (g_credentials_get_unix_user (creds, &error), ==,
geteuid ());
g_assert_no_error (error);
#if G_CREDENTIALS_HAS_PID
g_assert_cmpint (g_credentials_get_unix_pid (creds, &error), ==,
getpid ());
g_assert_no_error (error);
#else
g_assert_cmpint (g_credentials_get_unix_pid (creds, &error), ==, -1);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
g_clear_error (&error);
#endif
set = g_credentials_set_unix_user (other, not_me, &error);
#if G_CREDENTIALS_SPOOFING_SUPPORTED
g_assert_no_error (error);
g_assert (set);
g_assert_cmpuint (g_credentials_get_unix_user (other, &error), ==, not_me);
g_assert (!g_credentials_is_same_user (creds, other, &error));
g_assert_no_error (error);
#else
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
g_assert (!set);
g_clear_error (&error);
g_assert_cmpuint (g_credentials_get_unix_user (other, &error), ==, geteuid ());
g_assert (g_credentials_is_same_user (creds, other, &error));
g_assert_no_error (error);
#endif
stringified = g_credentials_to_string (creds);
g_test_message ("%s", stringified);
g_free (stringified);
stringified = g_credentials_to_string (other);
g_test_message ("%s", stringified);
g_free (stringified);
#if G_CREDENTIALS_USE_LINUX_UCRED
{
struct ucred *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_LINUX_UCRED);
g_assert_cmpuint (native->uid, ==, geteuid ());
g_assert_cmpuint (native->pid, ==, getpid ());
}
#elif G_CREDENTIALS_USE_APPLE_XUCRED
{
struct xucred *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_APPLE_XUCRED);
g_assert_cmpuint (native->cr_version, ==, XUCRED_VERSION);
g_assert_cmpuint (native->cr_uid, ==, geteuid ());
}
#elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
{
struct cmsgcred *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED);
g_assert_cmpuint (native->cmcred_euid, ==, geteuid ());
g_assert_cmpuint (native->cmcred_pid, ==, getpid ());
}
#elif G_CREDENTIALS_USE_NETBSD_UNPCBID
{
struct unpcbid *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_NETBSD_UNPCBID);
g_assert_cmpuint (native->unp_euid, ==, geteuid ());
g_assert_cmpuint (native->unp_pid, ==, getpid ());
}
#elif G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
{
struct sockpeercred *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_OPENBSD_SOCKPEERCRED);
g_assert_cmpuint (native->uid, ==, geteuid ());
g_assert_cmpuint (native->pid, ==, getpid ());
}
#elif G_CREDENTIALS_USE_SOLARIS_UCRED
{
ucred_t *native = g_credentials_get_native (creds,
G_CREDENTIALS_TYPE_SOLARIS_UCRED);
g_assert_cmpuint (ucred_geteuid (native), ==, geteuid ());
g_assert_cmpuint (ucred_getpid (native), ==, getpid ());
}
#else
#error "G_CREDENTIALS_SUPPORTED is set but there is no test for this platform"
#endif
#if G_CREDENTIALS_USE_LINUX_UCRED
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*g_credentials_get_native: Trying to get*"
"G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED "
"but only G_CREDENTIALS_TYPE_LINUX_UCRED*"
"supported*");
bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_FREEBSD_CMSGCRED);
g_test_assert_expected_messages ();
g_assert_null (bad_native_creds);
#else
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*g_credentials_get_native: Trying to get*"
"G_CREDENTIALS_TYPE_LINUX_UCRED "
"but only G_CREDENTIALS_TYPE_*supported*");
bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED);
g_test_assert_expected_messages ();
g_assert_null (bad_native_creds);
#endif
#else /* ! G_CREDENTIALS_SUPPORTED */
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*g_credentials_get_native: Trying to get "
"credentials *but*no support*");
bad_native_creds = g_credentials_get_native (creds, G_CREDENTIALS_TYPE_LINUX_UCRED);
g_test_assert_expected_messages ();
g_assert_null (bad_native_creds);
#endif
g_object_unref (creds);
g_object_unref (other);
}
#endif /* !G_OS_WIN32 */
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/credentials/basic", test_basic);
return g_test_run();
}

26
gio/tests/cxx.cpp Normal file
View file

@ -0,0 +1,26 @@
/* Copyright (C) 2001 Sebastian Wilhelmi <wilhelmi@google.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/* A trivial C++ program to be compiled in C++ mode, which
* smoketests that the GIO headers are valid C++ headers. */
#include <gio/gio.h>
int
main ()
{
return 0;
}

View file

@ -0,0 +1,507 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 0xFFF
#define MAX_BYTES 0x10000
static void
test_basic (void)
{
GInputStream *stream;
GInputStream *base_stream;
gint val;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_object_get (stream, "byte-order", &val, NULL);
g_assert_cmpint (val, ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_object_set (stream, "byte-order", G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, NULL);
g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_object_get (stream, "newline-type", &val, NULL);
g_assert_cmpint (val, ==, G_DATA_STREAM_NEWLINE_TYPE_LF);
g_object_set (stream, "newline-type", G_DATA_STREAM_NEWLINE_TYPE_CR_LF, NULL);
g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
g_object_unref (stream);
g_object_unref (base_stream);
}
static void
test_seek_to_start (GInputStream *stream)
{
GError *error = NULL;
gboolean res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
g_assert_cmpint (res, ==, TRUE);
g_assert_no_error (error);
}
static void
test_read_lines (GDataStreamNewlineType newline_type)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *data;
int line;
const char* lines[MAX_LINES];
const char* endl[4] = {"\n", "\r", "\r\n", "\n"};
/* prepare data */
int i;
for (i = 0; i < MAX_LINES; i++)
lines[i] = "some_text";
base_stream = g_memory_input_stream_new ();
g_assert (base_stream != NULL);
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_assert(stream != NULL);
/* Byte order testing */
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
/* Line ends testing */
g_data_input_stream_set_newline_type (G_DATA_INPUT_STREAM (stream), newline_type);
g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, newline_type);
/* Add sample data */
for (i = 0; i < MAX_LINES; i++)
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream),
g_strconcat (lines[i], endl[newline_type], NULL), -1, g_free);
/* Seek to the start */
test_seek_to_start (base_stream);
/* Test read line */
error = NULL;
data = (char*)1;
line = 0;
while (data)
{
gsize length = -1;
data = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (stream), &length, NULL, &error);
if (data)
{
g_assert_cmpstr (data, ==, lines[line]);
g_free (data);
g_assert_no_error (error);
line++;
}
if (error)
g_error_free (error);
}
g_assert_cmpint (line, ==, MAX_LINES);
g_object_unref (base_stream);
g_object_unref (stream);
}
static void
test_read_lines_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF);
}
static void
test_read_lines_CR (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR);
}
static void
test_read_lines_CR_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
}
static void
test_read_lines_any (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_ANY);
}
static void
test_read_lines_LF_valid_utf8 (void)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *line;
guint n_lines = 0;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream),
"foo\nthis is valid UTF-8 ☺!\nbar\n", -1, NULL);
/* Test read line */
error = NULL;
while (TRUE)
{
gsize length = -1;
line = g_data_input_stream_read_line_utf8 (G_DATA_INPUT_STREAM (stream), &length, NULL, &error);
g_assert_no_error (error);
if (line == NULL)
break;
n_lines++;
g_free (line);
}
g_assert_cmpint (n_lines, ==, 3);
g_object_unref (base_stream);
g_object_unref (stream);
}
static void
test_read_lines_LF_invalid_utf8 (void)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *line;
guint n_lines = 0;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream),
"foo\nthis is not valid UTF-8 \xE5 =(\nbar\n", -1, NULL);
/* Test read line */
error = NULL;
while (TRUE)
{
gsize length = -1;
line = g_data_input_stream_read_line_utf8 (G_DATA_INPUT_STREAM (stream), &length, NULL, &error);
if (n_lines == 0)
g_assert_no_error (error);
else
{
g_assert (error != NULL);
g_clear_error (&error);
g_free (line);
break;
}
n_lines++;
g_free (line);
}
g_assert_cmpint (n_lines, ==, 1);
g_object_unref (base_stream);
g_object_unref (stream);
}
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
static void
test_read_until (void)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *data;
int line;
int i;
#define REPEATS 10 /* number of rounds */
#define DATA_STRING " part1 # part2 $ part3 % part4 ^"
#define DATA_PART_LEN 7 /* number of characters between separators */
#define DATA_SEP "#$%^"
#define DATA_SEP_LEN 4
const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
for (i = 0; i < REPEATS; i++)
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, -1, NULL);
/* Test stop characters */
error = NULL;
data = (char*)1;
line = 0;
while (data)
{
gsize length = -1;
data = g_data_input_stream_read_until (G_DATA_INPUT_STREAM (stream), DATA_SEP, &length, NULL, &error);
if (data)
{
g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
g_free (data);
g_assert_no_error (error);
line++;
}
}
g_assert_no_error (error);
g_assert_cmpint (line, ==, DATA_PARTS_NUM);
g_object_unref (base_stream);
g_object_unref (stream);
}
G_GNUC_END_IGNORE_DEPRECATIONS
static void
test_read_upto (void)
{
GInputStream *stream;
GInputStream *base_stream;
GError *error = NULL;
char *data;
int line;
int i;
guchar stop_char;
#undef REPEATS
#undef DATA_STRING
#undef DATA_PART_LEN
#undef DATA_SEP
#undef DATA_SEP_LEN
#define REPEATS 10 /* number of rounds */
#define DATA_STRING " part1 # part2 $ part3 \0 part4 ^"
#define DATA_PART_LEN 7 /* number of characters between separators */
#define DATA_SEP "#$\0^"
#define DATA_SEP_LEN 4
const int DATA_PARTS_NUM = DATA_SEP_LEN * REPEATS;
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
for (i = 0; i < REPEATS; i++)
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, 32, NULL);
/* Test stop characters */
error = NULL;
data = (char*)1;
line = 0;
while (data)
{
gsize length = -1;
data = g_data_input_stream_read_upto (G_DATA_INPUT_STREAM (stream), DATA_SEP, DATA_SEP_LEN, &length, NULL, &error);
if (data)
{
g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
g_assert_no_error (error);
line++;
stop_char = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
g_assert (memchr (DATA_SEP, stop_char, DATA_SEP_LEN) != NULL);
g_assert_no_error (error);
}
g_free (data);
}
g_assert_no_error (error);
g_assert_cmpint (line, ==, DATA_PARTS_NUM);
g_object_unref (base_stream);
g_object_unref (stream);
}
enum TestDataType {
TEST_DATA_BYTE = 0,
TEST_DATA_INT16,
TEST_DATA_UINT16,
TEST_DATA_INT32,
TEST_DATA_UINT32,
TEST_DATA_INT64,
TEST_DATA_UINT64
};
/* The order is reversed to avoid -Wduplicated-branches. */
#define TEST_DATA_RETYPE_BUFF(a, t, v) \
(a == TEST_DATA_UINT64 ? (t) *(guint64*)v : \
(a == TEST_DATA_INT64 ? (t) *(gint64*)v : \
(a == TEST_DATA_UINT32 ? (t) *(guint32*)v : \
(a == TEST_DATA_INT32 ? (t) *(gint32*)v : \
(a == TEST_DATA_UINT16 ? (t) *(guint16*)v : \
(a == TEST_DATA_INT16 ? (t) *(gint16*)v : \
(t) *(guchar*)v ))))))
static void
test_data_array (GInputStream *stream, GInputStream *base_stream,
gpointer buffer, int len,
enum TestDataType data_type, GDataStreamByteOrder byte_order)
{
GError *error = NULL;
int pos = 0;
int data_size = 1;
gint64 data;
GDataStreamByteOrder native;
gboolean swap;
/* Seek to start */
test_seek_to_start (base_stream);
/* Set correct data size */
switch (data_type)
{
case TEST_DATA_BYTE:
data_size = 1;
break;
case TEST_DATA_INT16:
case TEST_DATA_UINT16:
data_size = 2;
break;
case TEST_DATA_INT32:
case TEST_DATA_UINT32:
data_size = 4;
break;
case TEST_DATA_INT64:
case TEST_DATA_UINT64:
data_size = 8;
break;
default:
g_assert_not_reached ();
break;
}
/* Set flag to swap bytes if needed */
native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native);
data = 1;
while (data != 0)
{
switch (data_type)
{
case TEST_DATA_BYTE:
data = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
break;
case TEST_DATA_INT16:
data = g_data_input_stream_read_int16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint16)GUINT16_SWAP_LE_BE((gint16)data);
break;
case TEST_DATA_UINT16:
data = g_data_input_stream_read_uint16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint16)GUINT16_SWAP_LE_BE((guint16)data);
break;
case TEST_DATA_INT32:
data = g_data_input_stream_read_int32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint32)GUINT32_SWAP_LE_BE((gint32)data);
break;
case TEST_DATA_UINT32:
data = g_data_input_stream_read_uint32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint32)GUINT32_SWAP_LE_BE((guint32)data);
break;
case TEST_DATA_INT64:
data = g_data_input_stream_read_int64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (gint64)GUINT64_SWAP_LE_BE((gint64)data);
break;
case TEST_DATA_UINT64:
data = g_data_input_stream_read_uint64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
if (swap)
data = (guint64)GUINT64_SWAP_LE_BE((guint64)data);
break;
default:
g_assert_not_reached ();
break;
}
if (!error)
g_assert_cmpint (data, ==, TEST_DATA_RETYPE_BUFF(data_type, gint64, ((guchar*)buffer + pos)));
pos += data_size;
}
if (pos < len + 1)
g_assert_no_error (error);
if (error)
g_error_free (error);
g_assert_cmpint (pos - data_size, ==, len);
}
static void
test_read_int (void)
{
GInputStream *stream;
GInputStream *base_stream;
GRand *randomizer;
int i;
gpointer buffer;
randomizer = g_rand_new ();
buffer = g_malloc0 (MAX_BYTES);
/* Fill in some random data */
for (i = 0; i < MAX_BYTES; i++)
{
guchar x = 0;
while (! x)
x = (guchar)g_rand_int (randomizer);
*(guchar*)((guchar*)buffer + sizeof(guchar) * i) = x;
}
base_stream = g_memory_input_stream_new ();
stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), buffer, MAX_BYTES, NULL);
for (i = 0; i < 3; i++)
{
int j;
g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), i);
for (j = 0; j <= TEST_DATA_UINT64; j++)
test_data_array (stream, base_stream, buffer, MAX_BYTES, j, i);
}
g_object_unref (base_stream);
g_object_unref (stream);
g_rand_free (randomizer);
g_free (buffer);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/data-input-stream/basic", test_basic);
g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF);
g_test_add_func ("/data-input-stream/read-lines-LF-valid-utf8", test_read_lines_LF_valid_utf8);
g_test_add_func ("/data-input-stream/read-lines-LF-invalid-utf8", test_read_lines_LF_invalid_utf8);
g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR);
g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF);
g_test_add_func ("/data-input-stream/read-lines-any", test_read_lines_any);
g_test_add_func ("/data-input-stream/read-until", test_read_until);
g_test_add_func ("/data-input-stream/read-upto", test_read_upto);
g_test_add_func ("/data-input-stream/read-int", test_read_int);
return g_test_run();
}

View file

@ -0,0 +1,514 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 0xFFF
#define MAX_LINES_BUFF 0xFFFFFF
#define MAX_BYTES_BINARY 0x100
static void
test_basic (void)
{
GOutputStream *stream;
GOutputStream *base_stream;
gpointer data;
gint val;
data = g_malloc0 (MAX_LINES_BUFF);
/* initialize objects */
base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL);
stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream));
g_object_get (stream, "byte-order", &val, NULL);
g_assert_cmpint (val, ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_object_set (stream, "byte-order", G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, NULL);
g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_object_unref (stream);
g_object_unref (base_stream);
g_free (data);
}
static void
test_read_lines (GDataStreamNewlineType newline_type)
{
GOutputStream *stream;
GOutputStream *base_stream;
GError *error = NULL;
gpointer data;
char *lines;
int size;
int i;
#define TEST_STRING "some_text"
const char* endl[4] = {"\n", "\r", "\r\n", "\n"};
data = g_malloc0 (MAX_LINES_BUFF);
lines = g_malloc0 ((strlen (TEST_STRING) + strlen (endl[newline_type])) * MAX_LINES + 1);
/* initialize objects */
base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL);
stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream));
/* fill data */
for (i = 0; i < MAX_LINES; i++)
{
gboolean res;
char *s = g_strconcat (TEST_STRING, endl[newline_type], NULL);
res = g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (stream), s, NULL, &error);
g_stpcpy ((char*)(lines + i*strlen(s)), s);
g_assert_no_error (error);
g_assert (res == TRUE);
g_free (s);
}
/* Byte order testing */
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
/* compare data */
size = strlen (data);
g_assert_cmpint (size, <, MAX_LINES_BUFF);
g_assert_cmpstr ((char*)data, ==, lines);
g_object_unref (base_stream);
g_object_unref (stream);
g_free (data);
g_free (lines);
}
static void
test_read_lines_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF);
}
static void
test_read_lines_CR (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR);
}
static void
test_read_lines_CR_LF (void)
{
test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
}
enum TestDataType {
TEST_DATA_BYTE = 0,
TEST_DATA_INT16,
TEST_DATA_UINT16,
TEST_DATA_INT32,
TEST_DATA_UINT32,
TEST_DATA_INT64,
TEST_DATA_UINT64
};
static void
test_data_array (guchar *buffer, gsize len,
enum TestDataType data_type, GDataStreamByteOrder byte_order)
{
GOutputStream *stream;
GOutputStream *base_stream;
guchar *stream_data;
GError *error = NULL;
guint pos;
GDataStreamByteOrder native;
gboolean swap;
gboolean res;
/* create objects */
stream_data = g_malloc0 (len);
base_stream = g_memory_output_stream_new (stream_data, len, NULL, NULL);
stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream));
g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), byte_order);
/* Set flag to swap bytes if needed */
native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native);
/* set len to length of buffer cast to actual type */
switch (data_type)
{
case TEST_DATA_BYTE:
break;
case TEST_DATA_INT16:
case TEST_DATA_UINT16:
g_assert_cmpint (len % 2, ==, 0);
G_GNUC_FALLTHROUGH;
case TEST_DATA_INT32:
case TEST_DATA_UINT32:
g_assert_cmpint (len % 4, ==, 0);
G_GNUC_FALLTHROUGH;
case TEST_DATA_INT64:
case TEST_DATA_UINT64:
g_assert_cmpint (len % 8, ==, 0);
len /= 8;
break;
default:
g_assert_not_reached ();
break;
}
/* Write data to the file */
for (pos = 0; pos < len; pos++)
{
switch (data_type)
{
case TEST_DATA_BYTE:
res = g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (stream), buffer[pos], NULL, &error);
break;
case TEST_DATA_INT16:
res = g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (stream), ((gint16 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT16:
res = g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (stream), ((guint16 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_INT32:
res = g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (stream), ((gint32 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT32:
res = g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (stream), ((guint32 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_INT64:
res = g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (stream), ((gint64 *) buffer)[pos], NULL, &error);
break;
case TEST_DATA_UINT64:
res = g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (stream), ((guint64 *) buffer)[pos], NULL, &error);
break;
default:
g_assert_not_reached ();
break;
}
g_assert_no_error (error);
g_assert_cmpint (res, ==, TRUE);
}
/* Compare data back */
for (pos = 0; pos < len; pos++)
{
switch (data_type)
{
case TEST_DATA_BYTE:
/* swapping unnecessary */
g_assert_cmpint (buffer[pos], ==, stream_data[pos]);
break;
case TEST_DATA_UINT16:
if (swap)
g_assert_cmpint (GUINT16_SWAP_LE_BE (((guint16 *) buffer)[pos]), ==, ((guint16 *) stream_data)[pos]);
else
g_assert_cmpint (((guint16 *) buffer)[pos], ==, ((guint16 *) stream_data)[pos]);
break;
case TEST_DATA_INT16:
if (swap)
g_assert_cmpint ((gint16) GUINT16_SWAP_LE_BE (((gint16 *) buffer)[pos]), ==, ((gint16 *) stream_data)[pos]);
else
g_assert_cmpint (((gint16 *) buffer)[pos], ==, ((gint16 *) stream_data)[pos]);
break;
case TEST_DATA_UINT32:
if (swap)
g_assert_cmpint (GUINT32_SWAP_LE_BE (((guint32 *) buffer)[pos]), ==, ((guint32 *) stream_data)[pos]);
else
g_assert_cmpint (((guint32 *) buffer)[pos], ==, ((guint32 *) stream_data)[pos]);
break;
case TEST_DATA_INT32:
if (swap)
g_assert_cmpint ((gint32) GUINT32_SWAP_LE_BE (((gint32 *) buffer)[pos]), ==, ((gint32 *) stream_data)[pos]);
else
g_assert_cmpint (((gint32 *) buffer)[pos], ==, ((gint32 *) stream_data)[pos]);
break;
case TEST_DATA_UINT64:
if (swap)
g_assert_cmpint (GUINT64_SWAP_LE_BE (((guint64 *) buffer)[pos]), ==, ((guint64 *) stream_data)[pos]);
else
g_assert_cmpint (((guint64 *) buffer)[pos], ==, ((guint64 *) stream_data)[pos]);
break;
case TEST_DATA_INT64:
if (swap)
g_assert_cmpint ((gint64) GUINT64_SWAP_LE_BE (((gint64 *) buffer)[pos]), ==, ((gint64 *) stream_data)[pos]);
else
g_assert_cmpint (((gint64 *) buffer)[pos], ==, ((gint64 *) stream_data)[pos]);
break;
default:
g_assert_not_reached ();
break;
}
}
g_object_unref (base_stream);
g_object_unref (stream);
g_free (stream_data);
}
static void
test_read_int (void)
{
GRand *randomizer;
gpointer buffer;
int i;
randomizer = g_rand_new ();
buffer = g_malloc0(MAX_BYTES_BINARY);
/* Fill in some random data */
for (i = 0; i < MAX_BYTES_BINARY; i++)
{
guchar x = 0;
while (! x) x = (guchar)g_rand_int (randomizer);
*(guchar*)((guchar*)buffer + sizeof (guchar) * i) = x;
}
for (i = 0; i < 3; i++)
{
int j;
for (j = 0; j <= TEST_DATA_UINT64; j++)
test_data_array (buffer, MAX_BYTES_BINARY, j, i);
}
g_rand_free (randomizer);
g_free (buffer);
}
static void
test_seek (void)
{
GDataOutputStream *stream;
GMemoryOutputStream *base_stream;
GSeekable *seekable;
GError *error;
guchar *stream_data;
gsize len;
gboolean res;
len = 8;
/* create objects */
stream_data = g_malloc0 (len);
base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, NULL, NULL));
stream = g_data_output_stream_new (G_OUTPUT_STREAM (base_stream));
g_data_output_stream_set_byte_order (stream, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
seekable = G_SEEKABLE (stream);
g_assert (!g_seekable_can_truncate (seekable));
error = NULL;
/* Write */
g_assert_cmpint (g_seekable_tell (seekable), ==, 0);
res = g_data_output_stream_put_uint16 (stream, 0x0123, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_data_output_stream_put_uint16 (stream, 0x4567, NULL, NULL);
g_assert_cmpint (g_seekable_tell (seekable), ==, 4);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
/* Forward relative seek */
res = g_seekable_seek (seekable, 2, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 6);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
res = g_data_output_stream_put_uint16 (stream, 0x89AB, NULL, &error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 8);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
g_assert_cmpint (stream_data[4], ==, 0x00);
g_assert_cmpint (stream_data[5], ==, 0x00);
g_assert_cmpint (stream_data[6], ==, 0x89);
g_assert_cmpint (stream_data[7], ==, 0xAB);
/* Backward relative seek */
res = g_seekable_seek (seekable, -3, G_SEEK_CUR, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 5);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
res = g_data_output_stream_put_uint16 (stream, 0xCDEF, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 7);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
g_assert_cmpint (stream_data[4], ==, 0x00);
g_assert_cmpint (stream_data[5], ==, 0xCD);
g_assert_cmpint (stream_data[6], ==, 0xEF);
g_assert_cmpint (stream_data[7], ==, 0xAB);
/* From start */
res = g_seekable_seek (seekable, 4, G_SEEK_SET, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 4);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
res = g_data_output_stream_put_uint16 (stream, 0xFEDC, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 6);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
g_assert_cmpint (stream_data[4], ==, 0xFE);
g_assert_cmpint (stream_data[5], ==, 0xDC);
g_assert_cmpint (stream_data[6], ==, 0xEF);
g_assert_cmpint (stream_data[7], ==, 0xAB);
/* From end */
res = g_seekable_seek (seekable, -4, G_SEEK_END, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 4);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
res = g_data_output_stream_put_uint16 (stream, 0xBA87, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_seekable_tell (seekable), ==, 6);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 8);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
g_assert_cmpint (stream_data[4], ==, 0xBA);
g_assert_cmpint (stream_data[5], ==, 0x87);
g_assert_cmpint (stream_data[6], ==, 0xEF);
g_assert_cmpint (stream_data[7], ==, 0xAB);
g_object_unref (stream);
g_object_unref (base_stream);
g_free (stream_data);
}
static void
test_truncate (void)
{
GDataOutputStream *stream;
GMemoryOutputStream *base_stream;
GSeekable *seekable;
GError *error;
guchar *stream_data;
gsize len;
gboolean res;
len = 8;
/* Create objects */
stream_data = g_malloc0 (len);
base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, g_realloc, g_free));
stream = g_data_output_stream_new (G_OUTPUT_STREAM (base_stream));
g_data_output_stream_set_byte_order (stream, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
seekable = G_SEEKABLE (stream);
error = NULL;
g_assert (g_seekable_can_truncate (seekable));
/* Write */
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 0);
res = g_data_output_stream_put_uint16 (stream, 0x0123, NULL, &error);
g_assert_no_error (error);
g_assert (res);
res = g_data_output_stream_put_uint16 (stream, 0x4567, NULL, NULL);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
/* Truncate at position */
res = g_seekable_truncate (seekable, 4, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 4);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
/* Truncate beyond position */
res = g_seekable_truncate (seekable, 6, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 6);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 6);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_assert_cmpint (stream_data[2], ==, 0x45);
g_assert_cmpint (stream_data[3], ==, 0x67);
/* Truncate before position */
res = g_seekable_truncate (seekable, 2, NULL, &error);
g_assert_no_error (error);
g_assert (res);
g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 2);
g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 2);
stream_data = g_memory_output_stream_get_data (base_stream);
g_assert_cmpint (stream_data[0], ==, 0x01);
g_assert_cmpint (stream_data[1], ==, 0x23);
g_object_unref (stream);
g_object_unref (base_stream);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/data-output-stream/basic", test_basic);
g_test_add_func ("/data-output-stream/write-lines-LF", test_read_lines_LF);
g_test_add_func ("/data-output-stream/write-lines-CR", test_read_lines_CR);
g_test_add_func ("/data-output-stream/write-lines-CR-LF", test_read_lines_CR_LF);
g_test_add_func ("/data-output-stream/write-int", test_read_int);
g_test_add_func ("/data-output-stream/seek", test_seek);
g_test_add_func ("/data-output-stream/truncate", test_truncate);
return g_test_run();
}

449
gio/tests/dbus-appinfo.c Normal file
View file

@ -0,0 +1,449 @@
/*
* Copyright © 2013 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Ryan Lortie <desrt@desrt.ca>
*/
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
#include "gdbus-sessionbus.h"
static GDesktopAppInfo *appinfo;
static int current_state;
static gboolean saw_startup_id;
static gboolean requested_startup_id;
static GType test_app_launch_context_get_type (void);
typedef GAppLaunchContext TestAppLaunchContext;
typedef GAppLaunchContextClass TestAppLaunchContextClass;
G_DEFINE_TYPE (TestAppLaunchContext, test_app_launch_context, G_TYPE_APP_LAUNCH_CONTEXT)
static gchar *
test_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
GAppInfo *info,
GList *uris)
{
requested_startup_id = TRUE;
return g_strdup ("expected startup id");
}
static void
test_app_launch_context_init (TestAppLaunchContext *ctx)
{
}
static void
test_app_launch_context_class_init (GAppLaunchContextClass *class)
{
class->get_startup_notify_id = test_app_launch_context_get_startup_notify_id;
}
static GType test_application_get_type (void);
typedef GApplication TestApplication;
typedef GApplicationClass TestApplicationClass;
G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION)
static void
saw_action (const gchar *action)
{
/* This is the main driver of the test. It's a bit of a state
* machine.
*
* Each time some event arrives on the app, it calls here to report
* which event it was. The initial activation of the app is what
* starts everything in motion (starting from state 0). At each
* state, we assert that we receive the expected event, send the next
* event, then update the current_state variable so we do the correct
* thing next time.
*/
switch (current_state)
{
case 0: g_assert_cmpstr (action, ==, "activate");
/* Let's try another activation... */
g_app_info_launch (G_APP_INFO (appinfo), NULL, NULL, NULL);
current_state = 1; return; case 1: g_assert_cmpstr (action, ==, "activate");
/* Now let's try opening some files... */
{
GList *files;
files = g_list_prepend (NULL, g_file_new_for_uri ("file:///a/b"));
files = g_list_append (files, g_file_new_for_uri ("file:///c/d"));
g_app_info_launch (G_APP_INFO (appinfo), files, NULL, NULL);
g_list_free_full (files, g_object_unref);
}
current_state = 2; return; case 2: g_assert_cmpstr (action, ==, "open");
/* Now action activations... */
g_desktop_app_info_launch_action (appinfo, "frob", NULL);
current_state = 3; return; case 3: g_assert_cmpstr (action, ==, "frob");
g_desktop_app_info_launch_action (appinfo, "tweak", NULL);
current_state = 4; return; case 4: g_assert_cmpstr (action, ==, "tweak");
g_desktop_app_info_launch_action (appinfo, "twiddle", NULL);
current_state = 5; return; case 5: g_assert_cmpstr (action, ==, "twiddle");
/* Now launch the app with startup notification */
{
GAppLaunchContext *ctx;
g_assert (saw_startup_id == FALSE);
ctx = g_object_new (test_app_launch_context_get_type (), NULL);
g_app_info_launch (G_APP_INFO (appinfo), NULL, ctx, NULL);
g_assert (requested_startup_id);
requested_startup_id = FALSE;
g_object_unref (ctx);
}
current_state = 6; return; case 6: g_assert_cmpstr (action, ==, "activate"); g_assert (saw_startup_id);
saw_startup_id = FALSE;
/* Now do the same for an action */
{
GAppLaunchContext *ctx;
g_assert (saw_startup_id == FALSE);
ctx = g_object_new (test_app_launch_context_get_type (), NULL);
g_desktop_app_info_launch_action (appinfo, "frob", ctx);
g_assert (requested_startup_id);
requested_startup_id = FALSE;
g_object_unref (ctx);
}
current_state = 7; return; case 7: g_assert_cmpstr (action, ==, "frob"); g_assert (saw_startup_id);
saw_startup_id = FALSE;
/* Now quit... */
g_desktop_app_info_launch_action (appinfo, "quit", NULL);
current_state = 8; return; case 8: g_assert_not_reached ();
}
}
static void
test_application_frob (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_assert (parameter == NULL);
saw_action ("frob");
}
static void
test_application_tweak (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_assert (parameter == NULL);
saw_action ("tweak");
}
static void
test_application_twiddle (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
g_assert (parameter == NULL);
saw_action ("twiddle");
}
static void
test_application_quit (GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *application = user_data;
g_application_quit (application);
}
static const GActionEntry app_actions[] = {
{ "frob", test_application_frob, NULL, NULL, NULL, { 0 } },
{ "tweak", test_application_tweak, NULL, NULL, NULL, { 0 } },
{ "twiddle", test_application_twiddle, NULL, NULL, NULL, { 0 } },
{ "quit", test_application_quit, NULL, NULL, NULL, { 0 } }
};
static void
test_application_activate (GApplication *application)
{
/* Unbalanced, but that's OK because we will quit() */
g_application_hold (application);
saw_action ("activate");
}
static void
test_application_open (GApplication *application,
GFile **files,
gint n_files,
const gchar *hint)
{
GFile *f;
g_assert_cmpstr (hint, ==, "");
g_assert_cmpint (n_files, ==, 2);
f = g_file_new_for_uri ("file:///a/b");
g_assert (g_file_equal (files[0], f));
g_object_unref (f);
f = g_file_new_for_uri ("file:///c/d");
g_assert (g_file_equal (files[1], f));
g_object_unref (f);
saw_action ("open");
}
static void
test_application_startup (GApplication *application)
{
G_APPLICATION_CLASS (test_application_parent_class)
->startup (application);
g_action_map_add_action_entries (G_ACTION_MAP (application), app_actions, G_N_ELEMENTS (app_actions), application);
}
static void
test_application_before_emit (GApplication *application,
GVariant *platform_data)
{
const gchar *startup_id;
g_assert (!saw_startup_id);
if (!g_variant_lookup (platform_data, "desktop-startup-id", "&s", &startup_id))
return;
g_assert_cmpstr (startup_id, ==, "expected startup id");
saw_startup_id = TRUE;
}
static void
test_application_init (TestApplication *app)
{
}
static void
test_application_class_init (GApplicationClass *class)
{
class->before_emit = test_application_before_emit;
class->startup = test_application_startup;
class->activate = test_application_activate;
class->open = test_application_open;
}
static void
test_dbus_appinfo (void)
{
const gchar *argv[] = { "myapp", NULL };
TestApplication *app;
int status;
gchar *desktop_file = NULL;
desktop_file = g_test_build_filename (G_TEST_DIST,
"org.gtk.test.dbusappinfo.desktop",
NULL);
appinfo = g_desktop_app_info_new_from_filename (desktop_file);
g_assert (appinfo != NULL);
g_free (desktop_file);
app = g_object_new (test_application_get_type (),
"application-id", "org.gtk.test.dbusappinfo",
"flags", G_APPLICATION_HANDLES_OPEN,
NULL);
status = g_application_run (app, 1, (gchar **) argv);
g_assert_cmpint (status, ==, 0);
g_assert_cmpint (current_state, ==, 8);
g_object_unref (appinfo);
g_object_unref (app);
}
static void
on_flatpak_launch_uris_finish (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GApplication *app = user_data;
GError *error = NULL;
g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error);
g_assert_no_error (error);
g_application_release (app);
}
static void
on_flatpak_activate (GApplication *app,
gpointer user_data)
{
GDesktopAppInfo *flatpak_appinfo = user_data;
char *uri;
GList *uris;
/* The app will be released in on_flatpak_launch_uris_finish */
g_application_hold (app);
uri = g_filename_to_uri (g_desktop_app_info_get_filename (flatpak_appinfo), NULL, NULL);
g_assert_nonnull (uri);
uris = g_list_prepend (NULL, uri);
g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL,
NULL, on_flatpak_launch_uris_finish, app);
g_list_free (uris);
g_free (uri);
}
static void
on_flatpak_open (GApplication *app,
GFile **files,
gint n_files,
const char *hint)
{
GFile *f;
g_assert_cmpint (n_files, ==, 1);
g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
/* The file has been exported via the document portal */
f = g_file_new_for_uri ("file:///document-portal/document-id/org.gtk.test.dbusappinfo.flatpak.desktop");
g_assert_true (g_file_equal (files[0], f));
g_object_unref (f);
}
static void
test_flatpak_doc_export (void)
{
const gchar *argv[] = { "myapp", NULL };
gchar *desktop_file = NULL;
GDesktopAppInfo *flatpak_appinfo;
GApplication *app;
int status;
g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
desktop_file = g_test_build_filename (G_TEST_DIST,
"org.gtk.test.dbusappinfo.flatpak.desktop",
NULL);
flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
g_assert_nonnull (flatpak_appinfo);
g_free (desktop_file);
app = g_application_new ("org.gtk.test.dbusappinfo.flatpak",
G_APPLICATION_HANDLES_OPEN);
g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate),
flatpak_appinfo);
g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open), NULL);
status = g_application_run (app, 1, (gchar **) argv);
g_assert_cmpint (status, ==, 0);
g_object_unref (app);
g_object_unref (flatpak_appinfo);
}
static void
on_flatpak_launch_invalid_uri_finish (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GApplication *app = user_data;
GError *error = NULL;
g_app_info_launch_uris_finish (G_APP_INFO (object), result, &error);
g_assert_no_error (error);
g_application_release (app);
}
static void
on_flatpak_activate_invalid_uri (GApplication *app,
gpointer user_data)
{
GDesktopAppInfo *flatpak_appinfo = user_data;
GList *uris;
/* The app will be released in on_flatpak_launch_uris_finish */
g_application_hold (app);
uris = g_list_prepend (NULL, "file:///hopefully/an/invalid/path.desktop");
g_app_info_launch_uris_async (G_APP_INFO (flatpak_appinfo), uris, NULL,
NULL, on_flatpak_launch_invalid_uri_finish, app);
g_list_free (uris);
}
static void
on_flatpak_open_invalid_uri (GApplication *app,
GFile **files,
gint n_files,
const char *hint)
{
GFile *f;
g_assert_cmpint (n_files, ==, 1);
g_test_message ("on_flatpak_open received file '%s'", g_file_peek_path (files[0]));
/* The file has been exported via the document portal */
f = g_file_new_for_uri ("file:///hopefully/an/invalid/path.desktop");
g_assert_true (g_file_equal (files[0], f));
g_object_unref (f);
}
static void
test_flatpak_missing_doc_export (void)
{
const gchar *argv[] = { "myapp", NULL };
gchar *desktop_file = NULL;
GDesktopAppInfo *flatpak_appinfo;
GApplication *app;
int status;
g_test_summary ("Test that files launched via Flatpak apps are made available via the document portal.");
desktop_file = g_test_build_filename (G_TEST_DIST,
"org.gtk.test.dbusappinfo.flatpak.desktop",
NULL);
flatpak_appinfo = g_desktop_app_info_new_from_filename (desktop_file);
g_assert_nonnull (flatpak_appinfo);
app = g_application_new ("org.gtk.test.dbusappinfo.flatpak",
G_APPLICATION_HANDLES_OPEN);
g_signal_connect (app, "activate", G_CALLBACK (on_flatpak_activate_invalid_uri),
flatpak_appinfo);
g_signal_connect (app, "open", G_CALLBACK (on_flatpak_open_invalid_uri), NULL);
status = g_application_run (app, 1, (gchar **) argv);
g_assert_cmpint (status, ==, 0);
g_object_unref (app);
g_object_unref (flatpak_appinfo);
g_free (desktop_file);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/appinfo/dbusappinfo", test_dbus_appinfo);
g_test_add_func ("/appinfo/flatpak-doc-export", test_flatpak_doc_export);
g_test_add_func ("/appinfo/flatpak-missing-doc-export", test_flatpak_missing_doc_export);
return session_bus_run ();
}

78
gio/tests/dbus-launch.c Normal file
View file

@ -0,0 +1,78 @@
/*
* Mock version of dbus-launch, for gdbus-address-get-session test
*
* Copyright © 2015 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <glib.h>
#ifndef G_OS_UNIX
#error This is a Unix-specific test helper
#endif
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#define ME "GDBus mock version of dbus-launch"
static void
write_all (const void *ptr,
size_t len)
{
const char *p = ptr;
while (len > 0)
{
gssize done = write (STDOUT_FILENO, p, len);
int errsv = errno;
if (done == 0)
{
g_error ("%s: write: EOF", ME);
}
else if (done < 0)
{
if (errsv == EINTR)
continue;
g_error ("%s: write: %s", ME, g_strerror (errsv));
}
else
{
if (len < (size_t) done)
g_error ("%s: wrote too many bytes?", ME);
len -= done;
p += done;
}
}
}
int
main (int argc,
char *argv[])
{
pid_t pid = 0x2323;
long window_id = 0x42424242;
const char *addr = "hello:this=address-is-from-the,mock=dbus-launch";
write_all (addr, strlen (addr) + 1);
write_all (&pid, sizeof (pid));
write_all (&window_id, sizeof (window_id));
return 0;
}

17
gio/tests/de.po Normal file
View file

@ -0,0 +1,17 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: \n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
msgid "\"Unnamed\""
msgstr "\"Unbenannt\""
msgctxt "keyboard label"
msgid "\"BackSpace\""
msgstr "\"Löschen\""

View file

@ -0,0 +1,8 @@
# Doing this in a subdir, so we get it in the right build de/LC_MESSAGES subdir
# at least in cases where the build directory layout is mirrored.
test_mo = custom_target('test.mo',
input : ['../../de.po'],
output : ['test.mo'],
command : [msgfmt, '-o', '@OUTPUT@', '@INPUT@'])
test_mo_dir = meson.current_build_dir()

396
gio/tests/debugcontroller.c Normal file
View file

@ -0,0 +1,396 @@
/* GLib testing framework examples and tests
*
* Copyright © 2022 Endless OS Foundation, LLC
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Author: Philip Withnall <pwithnall@endlessos.org>
*/
#include <gio/gio.h>
#include <locale.h>
static void
test_dbus_basic (void)
{
GTestDBus *bus;
GDBusConnection *connection = NULL, *connection2 = NULL;
GDebugControllerDBus *controller = NULL;
gboolean old_value;
gboolean debug_enabled;
GError *local_error = NULL;
g_test_summary ("Smoketest for construction and setting of a #GDebugControllerDBus.");
/* Set up a test session bus and connection. */
bus = g_test_dbus_new (G_TEST_DBUS_NONE);
g_test_dbus_up (bus);
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
g_assert_no_error (local_error);
/* Create a controller for this process. */
controller = g_debug_controller_dbus_new (connection, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (controller);
g_assert_true (G_IS_DEBUG_CONTROLLER_DBUS (controller));
/* Try enabling and disabling debug output from within the process. */
old_value = g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller));
g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), TRUE);
g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)));
g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), FALSE);
g_assert_false (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)));
/* Reset the debug state and check using g_object_get(), to exercise that. */
g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), old_value);
g_object_get (G_OBJECT (controller),
"debug-enabled", &debug_enabled,
"connection", &connection2,
NULL);
g_assert_true (debug_enabled == old_value);
g_assert_true (connection2 == connection);
g_clear_object (&connection2);
g_debug_controller_dbus_stop (controller);
while (g_main_context_iteration (NULL, FALSE));
g_assert_finalize_object (controller);
g_clear_object (&connection);
g_test_dbus_down (bus);
g_clear_object (&bus);
}
static void
test_dbus_duplicate (void)
{
GTestDBus *bus;
GDBusConnection *connection = NULL;
GDebugControllerDBus *controller1 = NULL, *controller2 = NULL;
GError *local_error = NULL;
g_test_summary ("Test that creating a second #GDebugControllerDBus on the same D-Bus connection fails.");
/* Set up a test session bus and connection. */
bus = g_test_dbus_new (G_TEST_DBUS_NONE);
g_test_dbus_up (bus);
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
g_assert_no_error (local_error);
/* Create a controller for this process. */
controller1 = g_debug_controller_dbus_new (connection, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (controller1);
/* And try creating a second one. */
controller2 = g_debug_controller_dbus_new (connection, NULL, &local_error);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS);
g_assert_null (controller2);
g_clear_error (&local_error);
g_debug_controller_dbus_stop (controller1);
while (g_main_context_iteration (NULL, FALSE));
g_assert_finalize_object (controller1);
g_clear_object (&connection);
g_test_dbus_down (bus);
g_clear_object (&bus);
}
static void
async_result_cb (GObject *source_object,
GAsyncResult *result,
gpointer user_data)
{
GAsyncResult **result_out = user_data;
g_assert_null (*result_out);
*result_out = g_object_ref (result);
g_main_context_wakeup (g_main_context_get_thread_default ());
}
static gboolean
authorize_false_cb (GDebugControllerDBus *debug_controller,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
return FALSE;
}
static gboolean
authorize_true_cb (GDebugControllerDBus *debug_controller,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
return TRUE;
}
static void
notify_debug_enabled_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data)
{
guint *notify_count_out = user_data;
*notify_count_out = *notify_count_out + 1;
}
static void
properties_changed_cb (GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
const gchar *interface_name,
const gchar *signal_name,
GVariant *parameters,
gpointer user_data)
{
guint *properties_changed_count_out = user_data;
*properties_changed_count_out = *properties_changed_count_out + 1;
g_main_context_wakeup (g_main_context_get_thread_default ());
}
static void
test_dbus_properties (void)
{
GTestDBus *bus;
GDBusConnection *controller_connection = NULL;
GDBusConnection *remote_connection = NULL;
GDebugControllerDBus *controller = NULL;
gboolean old_value;
GAsyncResult *result = NULL;
GVariant *reply = NULL;
GVariant *debug_enabled_variant = NULL;
gboolean debug_enabled;
GError *local_error = NULL;
gulong handler_id;
gulong notify_id;
guint notify_count = 0;
guint properties_changed_id;
guint properties_changed_count = 0;
g_test_summary ("Test getting and setting properties on a #GDebugControllerDBus.");
/* Set up a test session bus and connection. Set up a separate second
* connection to simulate a remote peer. */
bus = g_test_dbus_new (G_TEST_DBUS_NONE);
g_test_dbus_up (bus);
controller_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &local_error);
g_assert_no_error (local_error);
remote_connection = g_dbus_connection_new_for_address_sync (g_test_dbus_get_bus_address (bus),
G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
NULL,
NULL,
&local_error);
g_assert_no_error (local_error);
/* Create a controller for this process. */
controller = g_debug_controller_dbus_new (controller_connection, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (controller);
g_assert_true (G_IS_DEBUG_CONTROLLER_DBUS (controller));
old_value = g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller));
notify_id = g_signal_connect (controller, "notify::debug-enabled", G_CALLBACK (notify_debug_enabled_cb), &notify_count);
properties_changed_id = g_dbus_connection_signal_subscribe (remote_connection,
g_dbus_connection_get_unique_name (controller_connection),
"org.freedesktop.DBus.Properties",
"PropertiesChanged",
"/org/gtk/Debugging",
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
properties_changed_cb,
&properties_changed_count,
NULL);
/* Get the debug status remotely. */
g_dbus_connection_call (remote_connection,
g_dbus_connection_get_unique_name (controller_connection),
"/org/gtk/Debugging",
"org.freedesktop.DBus.Properties",
"Get",
g_variant_new ("(ss)", "org.gtk.Debugging", "DebugEnabled"),
G_VARIANT_TYPE ("(v)"),
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
async_result_cb,
&result);
g_assert_no_error (local_error);
while (result == NULL)
g_main_context_iteration (NULL, TRUE);
reply = g_dbus_connection_call_finish (remote_connection, result, &local_error);
g_assert_no_error (local_error);
g_clear_object (&result);
g_variant_get (reply, "(v)", &debug_enabled_variant);
debug_enabled = g_variant_get_boolean (debug_enabled_variant);
g_assert_true (debug_enabled == old_value);
g_assert_cmpuint (notify_count, ==, 0);
g_assert_cmpuint (properties_changed_count, ==, 0);
g_clear_pointer (&debug_enabled_variant, g_variant_unref);
g_clear_pointer (&reply, g_variant_unref);
/* Set the debug status remotely. The first attempt should fail due to no
* authorisation handler being connected. The second should fail due to the
* now-connected handler returning %FALSE. The third attempt should
* succeed. */
g_dbus_connection_call (remote_connection,
g_dbus_connection_get_unique_name (controller_connection),
"/org/gtk/Debugging",
"org.gtk.Debugging",
"SetDebugEnabled",
g_variant_new ("(b)", !old_value),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
async_result_cb,
&result);
while (result == NULL)
g_main_context_iteration (NULL, TRUE);
reply = g_dbus_connection_call_finish (remote_connection, result, &local_error);
g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED);
g_clear_object (&result);
g_clear_error (&local_error);
g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value);
g_assert_cmpuint (notify_count, ==, 0);
g_assert_cmpuint (properties_changed_count, ==, 0);
g_clear_pointer (&debug_enabled_variant, g_variant_unref);
g_clear_pointer (&reply, g_variant_unref);
/* Attach an authorisation handler and try again. */
handler_id = g_signal_connect (controller, "authorize", G_CALLBACK (authorize_false_cb), NULL);
g_dbus_connection_call (remote_connection,
g_dbus_connection_get_unique_name (controller_connection),
"/org/gtk/Debugging",
"org.gtk.Debugging",
"SetDebugEnabled",
g_variant_new ("(b)", !old_value),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
async_result_cb,
&result);
while (result == NULL)
g_main_context_iteration (NULL, TRUE);
reply = g_dbus_connection_call_finish (remote_connection, result, &local_error);
g_assert_error (local_error, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED);
g_clear_object (&result);
g_clear_error (&local_error);
g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value);
g_assert_cmpuint (notify_count, ==, 0);
g_assert_cmpuint (properties_changed_count, ==, 0);
g_clear_pointer (&debug_enabled_variant, g_variant_unref);
g_clear_pointer (&reply, g_variant_unref);
g_signal_handler_disconnect (controller, handler_id);
handler_id = 0;
/* Attach another signal handler which will grant access, and try again. */
handler_id = g_signal_connect (controller, "authorize", G_CALLBACK (authorize_true_cb), NULL);
g_dbus_connection_call (remote_connection,
g_dbus_connection_get_unique_name (controller_connection),
"/org/gtk/Debugging",
"org.gtk.Debugging",
"SetDebugEnabled",
g_variant_new ("(b)", !old_value),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
async_result_cb,
&result);
while (result == NULL)
g_main_context_iteration (NULL, TRUE);
reply = g_dbus_connection_call_finish (remote_connection, result, &local_error);
g_assert_no_error (local_error);
g_clear_object (&result);
g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == !old_value);
g_assert_cmpuint (notify_count, ==, 1);
g_assert_cmpuint (properties_changed_count, ==, 1);
g_clear_pointer (&debug_enabled_variant, g_variant_unref);
g_clear_pointer (&reply, g_variant_unref);
g_signal_handler_disconnect (controller, handler_id);
handler_id = 0;
/* Set the debug status locally. */
g_debug_controller_set_debug_enabled (G_DEBUG_CONTROLLER (controller), old_value);
g_assert_true (g_debug_controller_get_debug_enabled (G_DEBUG_CONTROLLER (controller)) == old_value);
g_assert_cmpuint (notify_count, ==, 2);
while (properties_changed_count != 2)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpuint (properties_changed_count, ==, 2);
g_signal_handler_disconnect (controller, notify_id);
notify_id = 0;
g_dbus_connection_signal_unsubscribe (remote_connection, properties_changed_id);
properties_changed_id = 0;
g_debug_controller_dbus_stop (controller);
while (g_main_context_iteration (NULL, FALSE));
g_assert_finalize_object (controller);
g_clear_object (&controller_connection);
g_clear_object (&remote_connection);
g_test_dbus_down (bus);
g_clear_object (&bus);
}
int
main (int argc,
char *argv[])
{
setlocale (LC_ALL, "");
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/debug-controller/dbus/basic", test_dbus_basic);
g_test_add_func ("/debug-controller/dbus/duplicate", test_dbus_duplicate);
g_test_add_func ("/debug-controller/dbus/properties", test_dbus_properties);
return g_test_run ();
}

228
gio/tests/defaultvalue.c Normal file
View file

@ -0,0 +1,228 @@
/* GIO default value tests
* Copyright (C) 2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <gio/gio.h>
static void
check_property (const char *output,
GParamSpec *pspec,
GValue *value)
{
GValue default_value = G_VALUE_INIT;
char *v, *dv, *msg;
if (g_param_value_defaults (pspec, value))
return;
g_param_value_set_default (pspec, &default_value);
v = g_strdup_value_contents (value);
dv = g_strdup_value_contents (&default_value);
msg = g_strdup_printf ("%s %s.%s: %s != %s\n",
output,
g_type_name (pspec->owner_type),
pspec->name,
dv, v);
g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
g_free (msg);
g_free (v);
g_free (dv);
g_value_unset (&default_value);
}
static void
test_type (gconstpointer data)
{
GObjectClass *klass;
GObject *instance;
GParamSpec **pspecs;
guint n_pspecs, i;
GType type;
type = * (GType *) data;
if (g_type_is_a (type, G_TYPE_APP_INFO_MONITOR))
{
g_test_skip ("singleton");
return;
}
if (g_type_is_a (type, G_TYPE_BINDING) ||
g_type_is_a (type, G_TYPE_BUFFERED_INPUT_STREAM) ||
g_type_is_a (type, G_TYPE_BUFFERED_OUTPUT_STREAM) ||
g_type_is_a (type, G_TYPE_CHARSET_CONVERTER) ||
g_type_is_a (type, G_TYPE_DBUS_ACTION_GROUP) ||
g_type_is_a (type, G_TYPE_DBUS_CONNECTION) ||
g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_CLIENT) ||
g_type_is_a (type, G_TYPE_DBUS_OBJECT_MANAGER_SERVER) ||
g_type_is_a (type, G_TYPE_DBUS_PROXY) ||
g_type_is_a (type, G_TYPE_DBUS_SERVER) ||
g_type_is_a (type, G_TYPE_FILTER_OUTPUT_STREAM) ||
g_type_is_a (type, G_TYPE_FILTER_INPUT_STREAM) ||
g_type_is_a (type, G_TYPE_INET_ADDRESS) ||
g_type_is_a (type, G_TYPE_INET_SOCKET_ADDRESS) ||
g_type_is_a (type, G_TYPE_PROPERTY_ACTION) ||
g_type_is_a (type, G_TYPE_SETTINGS) ||
g_type_is_a (type, G_TYPE_SOCKET_CONNECTION) ||
g_type_is_a (type, G_TYPE_SIMPLE_IO_STREAM) ||
g_type_is_a (type, G_TYPE_THEMED_ICON) ||
FALSE)
{
g_test_skip ("mandatory construct params");
return;
}
if (g_type_is_a (type, G_TYPE_DBUS_MENU_MODEL) ||
g_type_is_a (type, G_TYPE_DBUS_METHOD_INVOCATION))
{
g_test_skip ("crash in finalize");
return;
}
if (g_type_is_a (type, G_TYPE_FILE_ENUMERATOR) ||
g_type_is_a (type, G_TYPE_FILE_IO_STREAM))
{
g_test_skip ("should be abstract");
return;
}
klass = g_type_class_ref (type);
instance = g_object_new (type, NULL);
if (G_IS_INITABLE (instance) &&
!g_initable_init (G_INITABLE (instance), NULL, NULL))
{
g_test_skip ("initialization failed");
g_object_unref (instance);
g_type_class_unref (klass);
return;
}
if (g_type_is_a (type, G_TYPE_INITIALLY_UNOWNED))
g_object_ref_sink (instance);
pspecs = g_object_class_list_properties (klass, &n_pspecs);
for (i = 0; i < n_pspecs; ++i)
{
GParamSpec *pspec = pspecs[i];
GValue value = G_VALUE_INIT;
if (pspec->owner_type != type)
continue;
if ((pspec->flags & G_PARAM_READABLE) == 0)
continue;
if (g_type_is_a (type, G_TYPE_APPLICATION) &&
(strcmp (pspec->name, "is-remote") == 0))
{
g_test_message ("skipping GApplication:is-remote");
continue;
}
if (g_type_is_a (type, G_TYPE_PROXY_ADDRESS_ENUMERATOR) &&
(strcmp (pspec->name, "proxy-resolver") == 0))
{
g_test_message ("skipping GProxyAddressEnumerator:proxy-resolver");
continue;
}
if (g_type_is_a (type, G_TYPE_SOCKET_CLIENT) &&
(strcmp (pspec->name, "proxy-resolver") == 0))
{
g_test_message ("skipping GSocketClient:proxy-resolver");
continue;
}
if (g_test_verbose ())
g_printerr ("Property %s.%s\n", g_type_name (pspec->owner_type), pspec->name);
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property (instance, pspec->name, &value);
check_property ("Property", pspec, &value);
g_value_unset (&value);
}
g_free (pspecs);
g_object_unref (instance);
g_type_class_unref (klass);
}
static GType *all_registered_types;
static const GType *
list_all_types (void)
{
if (!all_registered_types)
{
GType *tp;
all_registered_types = g_new0 (GType, 1000);
tp = all_registered_types;
#include "giotypefuncs.inc"
*tp = 0;
}
return all_registered_types;
}
int
main (int argc, char **argv)
{
const GType *otypes;
guint i;
GTestDBus *bus;
gint result;
g_setenv ("GIO_USE_VFS", "local", TRUE);
g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
g_test_init (&argc, &argv, NULL);
/* Create one test bus for all tests, as we have a lot of very small
* and quick tests.
*/
bus = g_test_dbus_new (G_TEST_DBUS_NONE);
g_test_dbus_up (bus);
otypes = list_all_types ();
for (i = 0; otypes[i]; i++)
{
gchar *testname;
if (!G_TYPE_IS_CLASSED (otypes[i]))
continue;
if (G_TYPE_IS_ABSTRACT (otypes[i]))
continue;
if (!g_type_is_a (otypes[i], G_TYPE_OBJECT))
continue;
testname = g_strdup_printf ("/Default Values/%s",
g_type_name (otypes[i]));
g_test_add_data_func (testname, &otypes[i], test_type);
g_free (testname);
}
result = g_test_run ();
g_test_dbus_down (bus);
g_object_unref (bus);
return result;
}

View file

@ -0,0 +1,836 @@
/*
* Copyright (C) 2008 Red Hat, Inc
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Matthias Clasen
*/
#include <locale.h>
#include <glib/glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static GAppInfo *
create_app_info (const char *name)
{
GError *error;
GAppInfo *info;
error = NULL;
info = g_app_info_create_from_commandline ("true blah",
name,
G_APP_INFO_CREATE_NONE,
&error);
g_assert_no_error (error);
/* this is necessary to ensure that the info is saved */
g_app_info_set_as_default_for_type (info, "application/x-blah", &error);
g_assert_no_error (error);
g_app_info_remove_supports_type (info, "application/x-blah", &error);
g_assert_no_error (error);
g_app_info_reset_type_associations ("application/x-blah");
return info;
}
static void
test_delete (void)
{
GAppInfo *info;
const char *id;
char *filename;
gboolean res;
info = create_app_info ("Blah");
id = g_app_info_get_id (info);
g_assert_nonnull (id);
filename = g_build_filename (g_get_user_data_dir (), "applications", id, NULL);
res = g_file_test (filename, G_FILE_TEST_EXISTS);
g_assert_true (res);
res = g_app_info_can_delete (info);
g_assert_true (res);
res = g_app_info_delete (info);
g_assert_true (res);
res = g_file_test (filename, G_FILE_TEST_EXISTS);
g_assert_false (res);
g_object_unref (info);
if (g_file_test ("/usr/share/applications/gedit.desktop", G_FILE_TEST_EXISTS))
{
info = (GAppInfo*)g_desktop_app_info_new_from_filename ("/usr/share/applications/gedit.desktop");
g_assert_nonnull (info);
res = g_app_info_can_delete (info);
g_assert_false (res);
res = g_app_info_delete (info);
g_assert_false (res);
}
g_free (filename);
}
static void
test_default (void)
{
GAppInfo *info, *info1, *info2, *info3;
GList *list;
GError *error = NULL;
info1 = create_app_info ("Blah1");
info2 = create_app_info ("Blah2");
info3 = create_app_info ("Blah3");
g_app_info_set_as_default_for_type (info1, "application/x-test", &error);
g_assert_no_error (error);
g_app_info_set_as_default_for_type (info2, "application/x-test", &error);
g_assert_no_error (error);
info = g_app_info_get_default_for_type ("application/x-test", FALSE);
g_assert_nonnull (info);
g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2));
g_object_unref (info);
/* now try adding something, but not setting as default */
g_app_info_add_supports_type (info3, "application/x-test", &error);
g_assert_no_error (error);
/* check that info2 is still default */
info = g_app_info_get_default_for_type ("application/x-test", FALSE);
g_assert_nonnull (info);
g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2));
g_object_unref (info);
/* now remove info1 again */
g_app_info_remove_supports_type (info1, "application/x-test", &error);
g_assert_no_error (error);
/* and make sure info2 is still default */
info = g_app_info_get_default_for_type ("application/x-test", FALSE);
g_assert_nonnull (info);
g_assert_cmpstr (g_app_info_get_id (info), ==, g_app_info_get_id (info2));
g_object_unref (info);
/* now clean it all up */
g_app_info_reset_type_associations ("application/x-test");
list = g_app_info_get_all_for_type ("application/x-test");
g_assert_null (list);
g_app_info_delete (info1);
g_app_info_delete (info2);
g_app_info_delete (info3);
g_object_unref (info1);
g_object_unref (info2);
g_object_unref (info3);
}
static void
test_fallback (void)
{
GAppInfo *info1, *info2, *app = NULL;
GList *apps, *recomm, *fallback, *list, *l, *m;
GError *error = NULL;
gint old_length;
info1 = create_app_info ("Test1");
info2 = create_app_info ("Test2");
g_assert_true (g_content_type_is_a ("text/x-python", "text/plain"));
apps = g_app_info_get_all_for_type ("text/x-python");
old_length = g_list_length (apps);
g_list_free_full (apps, g_object_unref);
g_app_info_add_supports_type (info1, "text/x-python", &error);
g_assert_no_error (error);
g_app_info_add_supports_type (info2, "text/plain", &error);
g_assert_no_error (error);
/* check that both apps are registered */
apps = g_app_info_get_all_for_type ("text/x-python");
g_assert_cmpint (g_list_length (apps), ==, old_length + 2);
/* check that Test1 is among the recommended apps */
recomm = g_app_info_get_recommended_for_type ("text/x-python");
g_assert_nonnull (recomm);
for (l = recomm; l; l = l->next)
{
app = l->data;
if (g_app_info_equal (info1, app))
break;
}
g_assert_nonnull (app);
g_assert_true (g_app_info_equal (info1, app));
/* and that Test2 is among the fallback apps */
fallback = g_app_info_get_fallback_for_type ("text/x-python");
g_assert_nonnull (fallback);
for (l = fallback; l; l = l->next)
{
app = l->data;
if (g_app_info_equal (info2, app))
break;
}
g_assert_cmpstr (g_app_info_get_name (app), ==, "Test2");
/* check that recomm + fallback = all applications */
list = g_list_concat (g_list_copy (recomm), g_list_copy (fallback));
g_assert_cmpuint (g_list_length (list), ==, g_list_length (apps));
for (l = list, m = apps; l != NULL && m != NULL; l = l->next, m = m->next)
{
g_assert_true (g_app_info_equal (l->data, m->data));
}
g_list_free (list);
g_list_free_full (apps, g_object_unref);
g_list_free_full (recomm, g_object_unref);
g_list_free_full (fallback, g_object_unref);
g_app_info_reset_type_associations ("text/x-python");
g_app_info_reset_type_associations ("text/plain");
g_app_info_delete (info1);
g_app_info_delete (info2);
g_object_unref (info1);
g_object_unref (info2);
}
static void
test_last_used (void)
{
GList *applications;
GAppInfo *info1, *info2, *default_app;
GError *error = NULL;
info1 = create_app_info ("Test1");
info2 = create_app_info ("Test2");
g_app_info_set_as_default_for_type (info1, "application/x-test", &error);
g_assert_no_error (error);
g_app_info_add_supports_type (info2, "application/x-test", &error);
g_assert_no_error (error);
applications = g_app_info_get_recommended_for_type ("application/x-test");
g_assert_cmpuint (g_list_length (applications), ==, 2);
/* the first should be the default app now */
g_assert_true (g_app_info_equal (g_list_nth_data (applications, 0), info1));
g_assert_true (g_app_info_equal (g_list_nth_data (applications, 1), info2));
g_list_free_full (applications, g_object_unref);
g_app_info_set_as_last_used_for_type (info2, "application/x-test", &error);
g_assert_no_error (error);
applications = g_app_info_get_recommended_for_type ("application/x-test");
g_assert_cmpuint (g_list_length (applications), ==, 2);
default_app = g_app_info_get_default_for_type ("application/x-test", FALSE);
g_assert_true (g_app_info_equal (default_app, info1));
/* the first should be the other app now */
g_assert_true (g_app_info_equal (g_list_nth_data (applications, 0), info2));
g_assert_true (g_app_info_equal (g_list_nth_data (applications, 1), info1));
g_list_free_full (applications, g_object_unref);
g_app_info_reset_type_associations ("application/x-test");
g_app_info_delete (info1);
g_app_info_delete (info2);
g_object_unref (info1);
g_object_unref (info2);
g_object_unref (default_app);
}
static void
test_extra_getters (void)
{
GDesktopAppInfo *appinfo;
const gchar *lang;
gchar *s;
gboolean b;
lang = setlocale (LC_ALL, NULL);
g_setenv ("LANGUAGE", "de_DE.UTF8", TRUE);
setlocale (LC_ALL, "");
appinfo = g_desktop_app_info_new_from_filename (g_test_get_filename (G_TEST_DIST, "appinfo-test-static.desktop", NULL));
g_assert_nonnull (appinfo);
g_assert_true (g_desktop_app_info_has_key (appinfo, "Terminal"));
g_assert_false (g_desktop_app_info_has_key (appinfo, "Bratwurst"));
s = g_desktop_app_info_get_string (appinfo, "StartupWMClass");
g_assert_cmpstr (s, ==, "appinfo-class");
g_free (s);
s = g_desktop_app_info_get_locale_string (appinfo, "X-JunkFood");
g_assert_cmpstr (s, ==, "Bratwurst");
g_free (s);
g_setenv ("LANGUAGE", "sv_SE.UTF8", TRUE);
setlocale (LC_ALL, "");
s = g_desktop_app_info_get_locale_string (appinfo, "X-JunkFood");
g_assert_cmpstr (s, ==, "Burger"); /* fallback */
g_free (s);
b = g_desktop_app_info_get_boolean (appinfo, "Terminal");
g_assert_true (b);
g_object_unref (appinfo);
g_setenv ("LANGUAGE", lang, TRUE);
setlocale (LC_ALL, "");
}
static void
wait_for_file (const gchar *want_this,
const gchar *but_not_this,
const gchar *or_this)
{
guint retries = 600;
/* I hate time-based conditions in tests, but this will wait up to one
* whole minute for "touch file" to finish running. I think it should
* be OK.
*
* 600 * 100ms = 60 seconds.
*/
while (access (want_this, F_OK) != 0)
{
g_usleep (100000); /* 100ms */
g_assert_cmpuint (retries, >, 0);
retries--;
}
g_assert_cmpuint (access (but_not_this, F_OK), !=, 0);
g_assert_cmpuint (access (or_this, F_OK), !=, 0);
unlink (want_this);
unlink (but_not_this);
unlink (or_this);
}
static void
test_actions (void)
{
const char *expected[] = { "frob", "tweak", "twiddle", "broken", NULL };
const gchar * const *actions;
GDesktopAppInfo *appinfo;
gchar *name;
appinfo = g_desktop_app_info_new_from_filename (g_test_get_filename (G_TEST_DIST, "appinfo-test-actions.desktop", NULL));
g_assert_nonnull (appinfo);
actions = g_desktop_app_info_list_actions (appinfo);
g_assert_cmpstrv (actions, expected);
name = g_desktop_app_info_get_action_name (appinfo, "frob");
g_assert_cmpstr (name, ==, "Frobnicate");
g_free (name);
name = g_desktop_app_info_get_action_name (appinfo, "tweak");
g_assert_cmpstr (name, ==, "Tweak");
g_free (name);
name = g_desktop_app_info_get_action_name (appinfo, "twiddle");
g_assert_cmpstr (name, ==, "Twiddle");
g_free (name);
name = g_desktop_app_info_get_action_name (appinfo, "broken");
g_assert_nonnull (name);
g_assert_true (g_utf8_validate (name, -1, NULL));
g_free (name);
unlink ("frob"); unlink ("tweak"); unlink ("twiddle");
g_desktop_app_info_launch_action (appinfo, "frob", NULL);
wait_for_file ("frob", "tweak", "twiddle");
g_desktop_app_info_launch_action (appinfo, "tweak", NULL);
wait_for_file ("tweak", "frob", "twiddle");
g_desktop_app_info_launch_action (appinfo, "twiddle", NULL);
wait_for_file ("twiddle", "frob", "tweak");
g_object_unref (appinfo);
}
static gchar *
run_apps (const gchar *command,
const gchar *arg,
gboolean with_usr,
gboolean with_home,
const gchar *locale_name,
const gchar *language,
const gchar *xdg_current_desktop)
{
gboolean success;
gchar **envp;
gchar **argv;
gint status;
gchar *out;
gchar *argv_str = NULL;
argv = g_new (gchar *, 4);
argv[0] = g_test_build_filename (G_TEST_BUILT, "apps", NULL);
argv[1] = g_strdup (command);
argv[2] = g_strdup (arg);
argv[3] = NULL;
envp = g_get_environ ();
if (with_usr)
{
gchar *tmp = g_test_build_filename (G_TEST_DIST, "desktop-files", "usr", NULL);
envp = g_environ_setenv (envp, "XDG_DATA_DIRS", tmp, TRUE);
g_free (tmp);
}
else
envp = g_environ_setenv (envp, "XDG_DATA_DIRS", "/does-not-exist", TRUE);
if (with_home)
{
gchar *tmp = g_test_build_filename (G_TEST_DIST, "desktop-files", "home", NULL);
envp = g_environ_setenv (envp, "XDG_DATA_HOME", tmp, TRUE);
g_free (tmp);
}
else
envp = g_environ_setenv (envp, "XDG_DATA_HOME", "/does-not-exist", TRUE);
if (locale_name)
envp = g_environ_setenv (envp, "LC_ALL", locale_name, TRUE);
else
envp = g_environ_setenv (envp, "LC_ALL", "C", TRUE);
if (language)
envp = g_environ_setenv (envp, "LANGUAGE", language, TRUE);
else
envp = g_environ_unsetenv (envp, "LANGUAGE");
if (xdg_current_desktop)
envp = g_environ_setenv (envp, "XDG_CURRENT_DESKTOP", xdg_current_desktop, TRUE);
else
envp = g_environ_unsetenv (envp, "XDG_CURRENT_DESKTOP");
envp = g_environ_setenv (envp, "G_MESSAGES_DEBUG", "", TRUE);
success = g_spawn_sync (NULL, argv, envp, 0, NULL, NULL, &out, NULL, &status, NULL);
g_assert_true (success);
g_assert_cmpuint (status, ==, 0);
argv_str = g_strjoinv (" ", argv);
g_test_message ("%s: `%s` returned: %s", G_STRFUNC, argv_str, out);
g_free (argv_str);
g_strfreev (envp);
g_strfreev (argv);
return out;
}
static void
assert_strings_equivalent (const gchar *expected,
const gchar *result)
{
gchar **expected_words;
gchar **result_words;
gint i, j;
expected_words = g_strsplit (expected, " ", 0);
result_words = g_strsplit_set (result, " \n", 0);
for (i = 0; expected_words[i]; i++)
{
for (j = 0; result_words[j]; j++)
if (g_str_equal (expected_words[i], result_words[j]))
goto got_it;
g_test_fail_printf ("Unable to find expected string '%s' in result '%s'", expected_words[i], result);
got_it:
continue;
}
g_assert_cmpint (g_strv_length (expected_words), ==, g_strv_length (result_words));
g_strfreev (expected_words);
g_strfreev (result_words);
}
static void
assert_list (const gchar *expected,
gboolean with_usr,
gboolean with_home,
const gchar *locale_name,
const gchar *language)
{
gchar *result;
result = run_apps ("list", NULL, with_usr, with_home, locale_name, language, NULL);
g_strchomp (result);
assert_strings_equivalent (expected, result);
g_free (result);
}
static void
assert_info (const gchar *desktop_id,
const gchar *expected,
gboolean with_usr,
gboolean with_home,
const gchar *locale_name,
const gchar *language)
{
gchar *result;
result = run_apps ("show-info", desktop_id, with_usr, with_home, locale_name, language, NULL);
g_assert_cmpstr (result, ==, expected);
g_free (result);
}
static void
assert_search (const gchar *search_string,
const gchar *expected,
gboolean with_usr,
gboolean with_home,
const gchar *locale_name,
const gchar *language)
{
gchar **expected_lines;
gchar **result_lines;
gchar *result;
gint i;
expected_lines = g_strsplit (expected, "\n", -1);
result = run_apps ("search", search_string, with_usr, with_home, locale_name, language, NULL);
result_lines = g_strsplit (result, "\n", -1);
g_assert_cmpint (g_strv_length (expected_lines), ==, g_strv_length (result_lines));
for (i = 0; expected_lines[i]; i++)
assert_strings_equivalent (expected_lines[i], result_lines[i]);
g_strfreev (expected_lines);
g_strfreev (result_lines);
g_free (result);
}
static void
assert_implementations (const gchar *interface,
const gchar *expected,
gboolean with_usr,
gboolean with_home)
{
gchar *result;
result = run_apps ("implementations", interface, with_usr, with_home, NULL, NULL, NULL);
g_strchomp (result);
assert_strings_equivalent (expected, result);
g_free (result);
}
#define ALL_USR_APPS "evince-previewer.desktop nautilus-classic.desktop gnome-font-viewer.desktop " \
"baobab.desktop yelp.desktop eog.desktop cheese.desktop org.gnome.clocks.desktop " \
"gnome-contacts.desktop kde4-kate.desktop gcr-prompter.desktop totem.desktop " \
"gnome-terminal.desktop nautilus-autorun-software.desktop gcr-viewer.desktop " \
"nautilus-connect-server.desktop kde4-dolphin.desktop gnome-music.desktop " \
"kde4-konqbrowser.desktop gucharmap.desktop kde4-okular.desktop nautilus.desktop " \
"gedit.desktop evince.desktop file-roller.desktop dconf-editor.desktop glade.desktop " \
"invalid-desktop.desktop"
#define HOME_APPS "epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb.desktop"
#define ALL_HOME_APPS HOME_APPS " eog.desktop"
static void
test_search (void)
{
assert_list ("", FALSE, FALSE, NULL, NULL);
assert_list (ALL_USR_APPS, TRUE, FALSE, NULL, NULL);
assert_list (ALL_HOME_APPS, FALSE, TRUE, NULL, NULL);
assert_list (ALL_USR_APPS " " HOME_APPS, TRUE, TRUE, NULL, NULL);
/* The user has "installed" their own version of eog.desktop which
* calls it "Eye of GNOME". Do some testing based on that.
*
* We should always find "Pictures" keyword no matter where we look.
*/
assert_search ("Picture", "eog.desktop\n", TRUE, TRUE, NULL, NULL);
assert_search ("Picture", "eog.desktop\n", TRUE, FALSE, NULL, NULL);
assert_search ("Picture", "eog.desktop\n", FALSE, TRUE, NULL, NULL);
assert_search ("Picture", "", FALSE, FALSE, NULL, NULL);
/* We should only find it called "eye of gnome" when using the user's
* directory.
*/
assert_search ("eye gnome", "", TRUE, FALSE, NULL, NULL);
assert_search ("eye gnome", "eog.desktop\n", FALSE, TRUE, NULL, NULL);
assert_search ("eye gnome", "eog.desktop\n", TRUE, TRUE, NULL, NULL);
/* We should only find it called "image viewer" when _not_ using the
* user's directory.
*/
assert_search ("image viewer", "eog.desktop\n", TRUE, FALSE, NULL, NULL);
assert_search ("image viewer", "", FALSE, TRUE, NULL, NULL);
assert_search ("image viewer", "", TRUE, TRUE, NULL, NULL);
/* There're "flatpak" apps (clocks) installed as well - they should *not*
* match the prefix command ("/bin/sh") in the Exec= line though.
*/
assert_search ("sh", "gnome-terminal.desktop\n", TRUE, FALSE, NULL, NULL);
/* "frobnicator.desktop" is ignored by get_all() because the binary is
* missing, but search should still find it (to avoid either stale results
* from the cache or expensive stat() calls for each potential result)
*/
assert_search ("frobni", "frobnicator.desktop\n", TRUE, FALSE, NULL, NULL);
/* Obvious multi-word search */
assert_search ("gno hel", "yelp.desktop\n", TRUE, TRUE, NULL, NULL);
/* Repeated search terms should do nothing... */
assert_search ("files file fil fi f", "nautilus.desktop\n"
"gedit.desktop\n", TRUE, TRUE, NULL, NULL);
/* "con" will match "connect" and "contacts" on name but dconf only on
* the "config" keyword
*/
assert_search ("con", "nautilus-connect-server.desktop gnome-contacts.desktop\n"
"dconf-editor.desktop\n", TRUE, TRUE, NULL, NULL);
/* "gnome" will match "eye of gnome" from the user's directory, plus
* matching "GNOME Clocks" X-GNOME-FullName. It's only a comment on
* yelp and gnome-contacts, though.
*/
assert_search ("gnome", "eog.desktop\n"
"org.gnome.clocks.desktop\n"
"yelp.desktop gnome-contacts.desktop\n", TRUE, TRUE, NULL, NULL);
/* eog has exec name 'false' in usr only */
assert_search ("false", "eog.desktop\n", TRUE, FALSE, NULL, NULL);
assert_search ("false", "", FALSE, TRUE, NULL, NULL);
assert_search ("false", "", TRUE, TRUE, NULL, NULL);
assert_search ("false", "", FALSE, FALSE, NULL, NULL);
/* make sure we only search the first component */
assert_search ("nonsearchable", "", TRUE, FALSE, NULL, NULL);
/* "gnome con" will match only gnome contacts; via the name for
* "contacts" and the comment for "gnome"
*/
assert_search ("gnome con", "gnome-contacts.desktop\n", TRUE, TRUE, NULL, NULL);
/* make sure we get the correct kde4- prefix on the application IDs
* from subdirectories
*/
assert_search ("konq", "kde4-konqbrowser.desktop\n", TRUE, TRUE, NULL, NULL);
assert_search ("kate", "kde4-kate.desktop\n", TRUE, TRUE, NULL, NULL);
/* make sure we can look up apps by name properly */
assert_info ("kde4-kate.desktop",
"kde4-kate.desktop\n"
"Kate\n"
"Kate\n"
"nil\n", TRUE, TRUE, NULL, NULL);
assert_info ("nautilus.desktop",
"nautilus.desktop\n"
"Files\n"
"Files\n"
"Access and organize files\n", TRUE, TRUE, NULL, NULL);
/* make sure localised searching works properly */
assert_search ("foliumi", "nautilus.desktop\n"
"kde4-konqbrowser.desktop\n"
"eog.desktop\n", TRUE, FALSE, "en_US.UTF-8", "eo");
/* the user's eog.desktop has no translations... */
assert_search ("foliumi", "nautilus.desktop\n"
"kde4-konqbrowser.desktop\n", TRUE, TRUE, "en_US.UTF-8", "eo");
}
static void
test_implements (void)
{
/* Make sure we can find our search providers... */
assert_implementations ("org.gnome.Shell.SearchProvider2",
"gnome-music.desktop gnome-contacts.desktop eog.desktop",
TRUE, FALSE);
/* And our image acquisition possibilities... */
assert_implementations ("org.freedesktop.ImageProvider",
"cheese.desktop",
TRUE, FALSE);
/* Make sure the user's eog is properly masking the system one */
assert_implementations ("org.gnome.Shell.SearchProvider2",
"gnome-music.desktop gnome-contacts.desktop",
TRUE, TRUE);
/* Make sure we get nothing if we have nothing */
assert_implementations ("org.gnome.Shell.SearchProvider2", "", FALSE, FALSE);
}
static void
assert_shown (const gchar *desktop_id,
gboolean expected,
const gchar *xdg_current_desktop)
{
gchar *result;
result = run_apps ("should-show", desktop_id, TRUE, TRUE, NULL, NULL, xdg_current_desktop);
g_assert_cmpstr (result, ==, expected ? "true\n" : "false\n");
g_free (result);
}
static void
test_show_in (void)
{
assert_shown ("gcr-prompter.desktop", FALSE, NULL);
assert_shown ("gcr-prompter.desktop", FALSE, "GNOME");
assert_shown ("gcr-prompter.desktop", FALSE, "KDE");
assert_shown ("gcr-prompter.desktop", FALSE, "GNOME:GNOME-Classic");
assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic:GNOME");
assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic");
assert_shown ("gcr-prompter.desktop", TRUE, "GNOME-Classic:KDE");
assert_shown ("gcr-prompter.desktop", TRUE, "KDE:GNOME-Classic");
assert_shown ("invalid-desktop.desktop", TRUE, "GNOME");
assert_shown ("invalid-desktop.desktop", FALSE, "../invalid/desktop");
assert_shown ("invalid-desktop.desktop", FALSE, "../invalid/desktop:../invalid/desktop");
}
static void
on_launch_started (GAppLaunchContext *context, GAppInfo *info, GVariant *platform_data, gpointer data)
{
gboolean *invoked = data;
g_assert_true (G_IS_APP_LAUNCH_CONTEXT (context));
g_assert_true (G_IS_APP_INFO (info));
/* Our default context doesn't fill in any platform data */
g_assert_null (platform_data);
g_assert_false (*invoked);
*invoked = TRUE;
}
/* Test g_desktop_app_info_launch_uris_as_manager() and
* g_desktop_app_info_launch_uris_as_manager_with_fds()
*/
static void
test_launch_as_manager (void)
{
GDesktopAppInfo *appinfo;
GError *error = NULL;
gboolean retval;
const gchar *path;
gboolean invoked = FALSE;
GAppLaunchContext *context;
if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0')
{
g_test_skip ("No DISPLAY. Skipping test.");
return;
}
path = g_test_get_filename (G_TEST_BUILT, "appinfo-test.desktop", NULL);
appinfo = g_desktop_app_info_new_from_filename (path);
if (appinfo == NULL)
{
g_test_skip ("appinfo-test binary not installed");
return;
}
context = g_app_launch_context_new ();
g_signal_connect (context, "launch-started",
G_CALLBACK (on_launch_started),
&invoked);
retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, context, 0,
NULL, NULL,
NULL, NULL,
&error);
g_assert_no_error (error);
g_assert_true (retval);
g_assert_true (invoked);
invoked = FALSE;
retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo,
NULL, context, 0,
NULL, NULL,
NULL, NULL,
-1, -1, -1,
&error);
g_assert_no_error (error);
g_assert_true (retval);
g_assert_true (invoked);
g_object_unref (appinfo);
g_assert_finalize_object (context);
}
/* Test if Desktop-File Id is correctly formed */
static void
test_id (void)
{
gchar *result;
result = run_apps ("default-for-type", "application/vnd.kde.okular-archive",
TRUE, FALSE, NULL, NULL, NULL);
g_assert_cmpstr (result, ==, "kde4-okular.desktop\n");
g_free (result);
}
int
main (int argc,
char *argv[])
{
/* While we use %G_TEST_OPTION_ISOLATE_DIRS to create temporary directories
* for each of the tests, we want to use the system MIME registry, assuming
* that it exists and correctly has shared-mime-info installed. */
g_content_type_set_mime_dirs (NULL);
g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
g_test_add_func ("/desktop-app-info/delete", test_delete);
g_test_add_func ("/desktop-app-info/default", test_default);
g_test_add_func ("/desktop-app-info/fallback", test_fallback);
g_test_add_func ("/desktop-app-info/lastused", test_last_used);
g_test_add_func ("/desktop-app-info/extra-getters", test_extra_getters);
g_test_add_func ("/desktop-app-info/actions", test_actions);
g_test_add_func ("/desktop-app-info/search", test_search);
g_test_add_func ("/desktop-app-info/implements", test_implements);
g_test_add_func ("/desktop-app-info/show-in", test_show_in);
g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager);
g_test_add_func ("/desktop-app-info/id", test_id);
return g_test_run ();
}

View file

@ -0,0 +1,11 @@
[Desktop Entry]
Name=Eye of GNOME
Exec=true %U
Icon=eog
StartupNotify=true
Terminal=false
Type=Application
Categories=GNOME;GTK;Graphics;2DGraphics;RasterGraphics;Viewer;
MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-gray;image/x-icb;image/x-ico;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/x-pcx;image/svg+xml;image/svg+xml-compressed;image/vnd.wap.wbmp;
# Extra keywords that can be used to search for eog in GNOME Shell and Unity
Keywords=Picture;Slideshow;Graphics;

View file

@ -0,0 +1,7 @@
[Desktop Entry]
Name=Weather for Toronto Island
Exec=true
StartupNotify=true
Terminal=false
Type=Application
StartupWMClass=epiphany-weather-for-toronto-island-9c6a4e022b17686306243dada811d550d25eb1fb

View file

@ -0,0 +1,39 @@
[Desktop Entry]
Name=Disk Usage Analyzer
Name[bn]=ি ি
Name[bn_IN]=ি ি
Name[ca]=Analitzador de l'ús dels discs
Name[ca@valencia]=Analitzador de l'ús dels discs
Name[en@shaw]=𐑛𐑦𐑕𐑒 𐑿𐑕𐑦𐑡 𐑨𐑯𐑩𐑤𐑲𐑟𐑻
Name[en_GB]=Disk Usage Analyser
Name[eo]=Diskuzada analizilo
Name[pt]=Analisador de Utilização do Disco
Name[pt_BR]=Analisador de uso de disco
Comment=Check folder sizes and available disk space
Comment[bn]= ি ি
Comment[bn_IN]= ি
Comment[ca]=Comprova la mida de les carpetes i l'espai disponible al disc
Comment[ca@valencia]=Comprova la mida de les carpetes i l'espai disponible al disc
Comment[en@shaw]=𐑗𐑧𐑒 𐑓𐑴𐑤𐑛𐑼 𐑕𐑲𐑟𐑩𐑟 𐑯 𐑩𐑝𐑱𐑤𐑩𐑚𐑩𐑤 𐑛𐑦𐑕𐑒 𐑕𐑐𐑱𐑕
Comment[en_GB]=Check folder sizes and available disk space
Comment[eo]=Kontroli dosierujajn grandojn kaj disponeblan diskmemoron
Comment[pt]=Verificar o tamanho das pastas e o espaço disponível em disco
Comment[pt_BR]=Verifique o tamanho de pastas e o espaço disponível em disco
Keywords=storage;space;cleanup;
Keywords[ca]=emmagatzemament;espai;neteja;
Keywords[ca@valencia]=emmagatzemament;espai;neteja;
Keywords[eo]=spaco;diskospaco;purigi;senrubigi;
Keywords[pt]=armazenamento;espaço;limpar;
Keywords[pt_BR]=armazenamento;espaço;limpeza;
Exec=true
Icon=baobab
Terminal=false
Type=Application
StartupNotify=true
MimeType=inode/directory;
Categories=GTK;GNOME;System;Filesystem;
NotShowIn=KDE;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-utils
X-GNOME-Bugzilla-Component=baobab
X-GNOME-Bugzilla-Version=3.10

View file

@ -0,0 +1,47 @@
[Desktop Entry]
Name=Cheese
Name[bn]=Cheese
Name[bn_IN]=Cheese
Name[ca]=Cheese
Name[ca@valencia]=Cheese
Name[en@shaw]=·𐑗𐑰𐑟
Name[en_GB]=Cheese
Name[eo]=Rideto
Name[pt]=Cheese
Name[pt_BR]=Cheese
X-GNOME-FullName=Cheese Webcam Booth
X-GNOME-FullName[bn]=Cheese
X-GNOME-FullName[bn_IN]=Cheese-
X-GNOME-FullName[ca]=Cabina de fotografia del Cheese
X-GNOME-FullName[ca@valencia]=Cabina de fotografia del Cheese
X-GNOME-FullName[en@shaw]=·𐑗𐑰𐑟 𐑢𐑧𐑚𐑒𐑨𐑥 𐑚𐑵𐑔
X-GNOME-FullName[en_GB]=Cheese Webcam Booth
X-GNOME-FullName[eo]=Rideto-Retkamerao-Budo
X-GNOME-FullName[pt]=Cabine Fotográfica Cheese
X-GNOME-FullName[pt_BR]=Cabine de webcam do Cheese
Comment=Take photos and videos with your webcam, with fun graphical effects
Comment[bn]= ি িি ি
Comment[bn_IN]= ি িি ি
Comment[ca]=Feu fotos i vídeos amb la càmera web, amb efectes gràfics divertits
Comment[ca@valencia]=Feu fotos i vídeos amb la càmera web, amb efectes gràfics divertits
Comment[en@shaw]=𐑑𐑱𐑒 𐑓𐑴𐑑𐑴𐑟 𐑯 𐑝𐑦𐑛𐑰𐑴𐑟 𐑢𐑦𐑞 𐑿𐑼 𐑢𐑧𐑚𐑒𐑨𐑥, 𐑢𐑦𐑞 𐑓𐑳𐑯 𐑜𐑮𐑨𐑓𐑦𐑒𐑩𐑤 𐑦𐑓𐑧𐑒𐑑𐑕
Comment[en_GB]=Take photos and videos with your webcam, with fun graphical effects
Comment[eo]=Fari fotaĵojn kaj videojn per via retkamerao, kun gajaj grafikaj efektoj
Comment[pt]=Tire fotografias e grave vídeos com a sua webcam, com engraçados efeitos gráficos
Comment[pt_BR]=Tire fotos e vídeos com sua webcam, com efeitos gráficos divertidos
Keywords=photo;video;webcam;
Keywords[ca]=foto;vídeo;càmera web;
Keywords[ca@valencia]=foto;vídeo;càmera web;
Keywords[pt]=foto;vídeo;webcam;
Keywords[pt_BR]=foto;fotos;vídeo;vídeos;webcam;
Exec=true
Terminal=false
Type=Application
StartupNotify=true
Icon=cheese
Categories=GNOME;AudioVideo;Video;Recorder;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=cheese
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.11.1
Implements=org.freedesktop.ImageProvider

View file

@ -0,0 +1,33 @@
[Desktop Entry]
Name=dconf Editor
Name[bn_IN]=dconf
Name[ca]=Editor del dconf
Name[ca@valencia]=Editor del dconf
Name[en_GB]=dconf Editor
Name[eo]=dconf Redaktilo
Name[pt]=Editor dconf
Name[pt_BR]=Editor do dconf
Comment=Directly edit your entire configuration database
Comment[bn_IN]= ি ি
Comment[ca]=Editeu directament la base de dades de configuració
Comment[ca@valencia]=Editeu directament la base de dades de configuració
Comment[en_GB]=Directly edit your entire configuration database
Comment[eo]=Rekte redakti vian totan agordan datumbazon
Comment[pt]=Edite diretamente toda a sua base de dados de configuração
Comment[pt_BR]=Edite diretamente seu banco de dados de configuração por inteiro
Keywords=settings;configuration;
Keywords[ca]=paràmetres;configuració;
Keywords[ca@valencia]=paràmetres;configuració;
Keywords[eo]=agordoj;
Keywords[pt]=definições;configuração;
Keywords[pt_BR]=ajustes;configuração;configurações;
Exec=true
Terminal=false
Type=Application
Icon=dconf-editor
StartupNotify=true
Categories=GNOME;GTK;System;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=dconf
X-GNOME-Bugzilla-Component=editor
X-GNOME-Bugzilla-Version=0.18.0

View file

@ -0,0 +1,44 @@
[Desktop Entry]
Name=Image Viewer
Name[bn]=ি
Name[bn_IN]=ি
Name[ca]=Visualitzador d'imatges
Name[ca@valencia]=Visualitzador d'imatges
Name[en@shaw]=𐑦𐑥𐑦𐑡 𐑝𐑿𐑼
Name[en_CA]=Image Viewer
Name[en_GB]=Image Viewer
Name[eo]=Bildomontrilo
Name[pt]=Visualizador de Imagens
Name[pt_BR]=Visualizador de imagens
Comment=Browse and rotate images
Comment[bn]=ি
Comment[bn_IN]=ি ি ি
Comment[ca]=Navegueu per imatges i gireu-les
Comment[ca@valencia]=Navegueu per imatges i gireu-les
Comment[en@shaw]=𐑚𐑮𐑬𐑟 𐑯 𐑮𐑴𐑑𐑱𐑑 𐑦𐑥𐑦𐑡𐑩𐑟
Comment[en_CA]=Browse and rotate images
Comment[en_GB]=Browse and rotate images
Comment[eo]=Foliumi kaj turni bildojn
Comment[pt]=Navegue e rode imagens
Comment[pt_BR]=Navegue e gire imagens
Exec=false --nonsearchable %U
Icon=eog
StartupNotify=true
Terminal=false
Type=Application
Categories=GNOME;GTK;Graphics;2DGraphics;RasterGraphics;Viewer;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=EOG
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.1
X-GNOME-DocPath=eog/eog.xml
MimeType=image/bmp;image/gif;image/jpeg;image/jpg;image/pjpeg;image/png;image/tiff;image/x-bmp;image/x-gray;image/x-icb;image/x-ico;image/x-png;image/x-portable-anymap;image/x-portable-bitmap;image/x-portable-graymap;image/x-portable-pixmap;image/x-xbitmap;image/x-xpixmap;image/x-pcx;image/svg+xml;image/svg+xml-compressed;image/vnd.wap.wbmp;
# Extra keywords that can be used to search for eog in GNOME Shell and Unity
Keywords=Picture;Slideshow;Graphics;
Keywords[ca]=Fotografia;Diapositives;Gràfics;
Keywords[ca@valencia]=Fotografia;Diapositives;Gràfics;
Keywords[en_GB]=Picture;Slideshow;Graphics;
Keywords[eo]=Bildo;Lumbildprezentado;Grafiko;
Keywords[pt]=Imagem;Apresentação;Gráficos;
Keywords[pt_BR]=Fotos;Apresentação de slides;Gráficos;
Implements=org.gnome.Shell.SearchProvider2

View file

@ -0,0 +1,28 @@
[Desktop Entry]
Name=Print Preview
Name[ca]=Previsualitza la impressió
Name[ca@valencia]=Previsualitza la impressió
Name[en_GB]=Print Preview
Name[eo]=Aspekto de la presotaĵo
Name[pt]=Antevisão de Impressão
Name[pt_BR]=Visualizar de impressão
Comment=Preview before printing
Comment[ca]=Previsualitza abans d'imprimir
Comment[ca@valencia]=Previsualitza abans d'imprimir
Comment[en_GB]=Preview before printing
Comment[eo]=Aspekti antaŭ presi
Comment[pt]=Antever antes de imprimir
Comment[pt_BR]=Visualize antes de imprimir
Exec=true %U
StartupNotify=true
Terminal=false
Type=Application
Icon=document-print-preview
NoDisplay=true
X-GNOME-DocPath=
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=evince
X-GNOME-Bugzilla-Component=BugBuddyBugs
X-GNOME-Bugzilla-Version=3.10.0
Categories=GNOME;GTK;Office;Viewer;Graphics;2DGraphics;VectorGraphics;
MimeType=application/pdf;application/x-bzpdf;application/x-gzpdf;application/x-xzpdf;image/tiff;application/x-cbr;application/x-cbz;application/x-cb7;application/x-cbt;application/oxps;application/vnd.ms-xpsdocument;

View file

@ -0,0 +1,42 @@
[Desktop Entry]
Name=Document Viewer
Name[bn]=ি
Name[bn_IN]=
Name[ca]=Visualitzador de documents
Name[ca@valencia]=Visualitzador de documents
Name[en@shaw]=𐑛𐑪𐑒𐑿𐑥𐑩𐑯𐑑 𐑝𐑿𐑼
Name[en_CA]=Document Viewer
Name[en_GB]=Document Viewer
Name[eo]=Dokumentmontrilo
Name[pt]=Visualizador de Documento
Name[pt_BR]=Visualizador de documentos
Comment=View multi-page documents
Comment[bn]= ি ি
Comment[bn_IN]=ি িি
Comment[ca]=Visualitzeu documents multipàgina
Comment[ca@valencia]=Visualitzeu documents multipàgina
Comment[en@shaw]=𐑝𐑿 𐑥𐑩𐑤𐑑𐑰-𐑐𐑱𐑡 𐑛𐑪𐑒𐑿𐑥𐑩𐑯𐑑𐑕
Comment[en_CA]=View multi-page documents
Comment[en_GB]=View multi-page documents
Comment[eo]=Montri mult-paĝajn dokumentojn
Comment[pt]=Visualizar documentos multipáginas
Comment[pt_BR]=Visualize documentos de múltiplas páginas
Keywords=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentation;
Keywords[ca]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentació;
Keywords[ca@valencia]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentació;
Keywords[en_GB]=pdf;ps;postscript;dvi;xps;djvu;tiff;document;presentation;
Keywords[eo]=pdf;ps;postscript;dvi;xps;djvu;tiff;dokumento;prezentaĵo;
Keywords[pt]=pdf;ps;postscript;dvi;xps;djvu;tiff;documento;apresentação;
Keywords[pt_BR]=pdf;ps;postscript;dvi;xps;djvu;tiff;documento;apresentação;
Exec=true %U
StartupNotify=true
Terminal=false
Type=Application
Icon=evince
X-GNOME-DocPath=
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=evince
X-GNOME-Bugzilla-Component=BugBuddyBugs
X-GNOME-Bugzilla-Version=3.10.0
Categories=GNOME;GTK;Office;Viewer;Graphics;2DGraphics;VectorGraphics;
MimeType=application/pdf;application/x-bzpdf;application/x-gzpdf;application/x-xzpdf;image/tiff;application/x-cbr;application/x-cbz;application/x-cb7;application/x-cbt;application/oxps;application/vnd.ms-xpsdocument;

View file

@ -0,0 +1,43 @@
[Desktop Entry]
Name=Archive Manager
Name[bn]=
Name[bn_IN]= ি
Name[ca]=Gestor d'arxius
Name[ca@valencia]=Gestor d'arxius
Name[en@shaw]=𐑸𐑒𐑲𐑝 𐑥𐑨𐑯𐑩𐑡𐑼
Name[en_CA]=Archive Manager
Name[en_GB]=Archive Manager
Name[eo]=Arkivo-administrilo
Name[pt]=Gestor de Arquivos
Name[pt_BR]=Gerenciador de pacotes
Comment=Create and modify an archive
Comment[bn]= ি ি
Comment[bn_IN]= ি ি
Comment[ca]=Crea i modifica un arxiu
Comment[ca@valencia]=Crea i modifica un arxiu
Comment[en@shaw]=𐑒𐑮𐑦𐑱𐑑 𐑯 𐑥𐑪𐑛𐑦𐑓𐑲 𐑩𐑯 𐑸𐑒𐑲𐑝
Comment[en_CA]=Create and modify an archive
Comment[en_GB]=Create and modify an archive
Comment[eo]=Krei kaj modifi arkivon
Comment[pt]=Criar e alterar um arquivo
Comment[pt_BR]=Crie e modifique um pacote
Keywords=zip;tar;extract;unpack;
Keywords[ca]=zip;tar;extreure;desampaquetar;
Keywords[ca@valencia]=zip;tar;extraure;desampaquetar;
Keywords[eo]=zip;tar;eltiri;malkompaktigi;malpaki;elpaki;
Keywords[pt]=zip;tar;extrair;desempacotar;
Keywords[pt_BR]=zip;tar;extrair;descompactar;
Exec=true %U
StartupNotify=true
Terminal=false
Type=Application
Icon=file-roller
Categories=GTK;GNOME;Utility;Archiving;Compression;
NotShowIn=KDE;
MimeType=application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lrzip;application/x-lrzip-compressed-tar;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-ms-wim;application/x-rar;application/x-rar-compressed;application/x-rpm;application/x-rzip;application/x-rzip-compressed-tar;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;application/x-archive;application/vnd.ms-cab-compressed;
X-GNOME-DocPath=file-roller/file-roller.xml
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=file-roller
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
X-GNOME-UsesNotifications=true

View file

@ -0,0 +1,9 @@
[Desktop Entry]
Name=Frobnicator
Comment=Frobnicate your life!
Exec=/does-not-exist
Icon=frobnicator
StartupNotify=true
Terminal=false
Type=Application
Categories=GNOME;GTK;Utilities

View file

@ -0,0 +1,19 @@
[Desktop Entry]
Name=Access Prompt
Name[ca]=Petició d'accés
Name[ca@valencia]=Petició d'accés
Name[en_GB]=Access Prompt
Name[pt]=Pedido de Acesso
Name[pt_BR]=Prompt de acesso
Comment=Unlock access to passwords and other secrets
Comment[ca]=Desbloca l'accés a les contrasenyes i altres secrets
Comment[ca@valencia]=Desbloca l'accés a les contrasenyes i altres secrets
Comment[en_GB]=Unlock access to passwords and other secrets
Comment[pt]=Destrancar acesso a senhas e outros segredos
Comment[pt_BR]=Destravar acesso a senhas e outros segredos
Icon=security-medium
Exec=true
Terminal=false
Type=Application
OnlyShowIn=GNOME-Classic
NotShowIn=GNOME

View file

@ -0,0 +1,10 @@
[Desktop Entry]
Name=View file
MimeType=application/pkcs12;application/pkcs12+pem;application/pkcs7-mime;application/pkcs7-mime+pem;application/pkcs8;application/pkcs8+pem;application/pkix-cert;application/pkix-cert+pem;application/pkix-crl;application/pkix-crl+pem;application/x-pem-file;application/x-pem-key;application/x-pkcs12;application/x-pkcs7-certificates;application/x-x509-ca-cert;application/x-x509-user-cert;application/pkcs10;application/pkcs10+pem;application/x-spkac;application/x-spkac+base64;
Exec=true
Type=Application
Terminal=false
NoDisplay=true
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-keyring
X-GNOME-Bugzilla-Component=gcr

View file

@ -0,0 +1,83 @@
[Desktop Entry]
Name=gedit
Name[bn]=িি
Name[bn_IN]=gedit
Name[ca]=gedit
Name[ca@valencia]=gedit
Name[en@shaw]=·𐑜𐑧𐑛𐑦𐑑
Name[en_CA]=gedit
Name[en_GB]=gedit
Name[eo]=Gedit
Name[pt]=gedit
Name[pt_BR]=gedit
GenericName=Text Editor
GenericName[bn]=
GenericName[bn_IN]= ি
GenericName[ca]=Editor de text
GenericName[ca@valencia]=Editor de text
GenericName[en@shaw]=𐑑𐑧𐑒𐑕𐑑 𐑧𐑛𐑦𐑑𐑼
GenericName[en_CA]=Text Editor
GenericName[en_GB]=Text Editor
GenericName[eo]=Tekstredaktilo
GenericName[pt]=Editor de Texto
GenericName[pt_BR]=Editor de texto
Comment=Edit text files
Comment[bn]=
Comment[bn_IN]=
Comment[ca]=Editeu fitxers de text
Comment[ca@valencia]=Editeu fitxers de text
Comment[en@shaw]=𐑧𐑛𐑦𐑑 𐑑𐑧𐑒𐑕𐑑 𐑓𐑲𐑤𐑟
Comment[en_CA]=Edit text files
Comment[en_GB]=Edit text files
Comment[eo]=Redakti tekstdosierojn
Comment[pt]=Editar ficheiros de texto
Comment[pt_BR]=Edite arquivos de texto
Exec=true
Terminal=false
Type=Application
StartupNotify=true
MimeType=text/plain;
Icon=accessories-text-editor
Categories=GNOME;GTK;Utility;TextEditor;
X-GNOME-DocPath=gedit/gedit.xml
X-GNOME-FullName=gedit Text Editor
X-GNOME-FullName[bn]=িি
X-GNOME-FullName[bn_IN]=gedit ি
X-GNOME-FullName[ca]=Editor de text gedit
X-GNOME-FullName[ca@valencia]=Editor de text gedit
X-GNOME-FullName[en@shaw]=·𐑜𐑧𐑛𐑦𐑑 𐑑𐑧𐑒𐑕𐑑 𐑧𐑛𐑦𐑑𐑼
X-GNOME-FullName[en_GB]=gedit Text Editor
X-GNOME-FullName[eo]=Gedit tekstredaktilo
X-GNOME-FullName[pt]=Editor de Texto gedit
X-GNOME-FullName[pt_BR]=Editor de texto gedit
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gedit
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
X-GNOME-Bugzilla-ExtraInfoScript=true
Actions=Window;Document;
Keywords=Text;Editor;
Keywords[ca]=Text;Editor;
Keywords[ca@valencia]=Text;Editor;
Keywords[pt]=Texto;Editor;
Keywords[pt_BR]=Texto;Editor;
[Desktop Action Window]
Name=Open a New Window
Name[bn_IN]=ি
Name[ca]=Obre una finestra nova
Name[ca@valencia]=Obri una finestra nova
Name[en_GB]=Open a New Window
Name[pt]=Abrir uma Nova Janela
Name[pt_BR]=Abrir uma nova janela
Exec=true
[Desktop Action Document]
Name=Open a New Document
Name[bn_IN]=
Name[ca]=Obre un document nou
Name[ca@valencia]=Obri un document nou
Name[en_GB]=Open a New Document
Name[pt]=Abrir um Novo Documento
Name[pt_BR]=Abrir um novo documento
Exec=true

View file

@ -0,0 +1,56 @@
[Desktop Entry]
Name=Glade
Name[bn]=Glade
Name[bn_IN]=Glade
Name[ca]=Glade
Name[ca@valencia]=Glade
Name[en@shaw]=·𐑜𐑤𐑱𐑛
Name[en_CA]=Glade
Name[en_GB]=Glade
Name[eo]=Glado
Name[pt]=Glade
Name[pt_BR]=Glade
GenericName=Interface Designer
GenericName[ca]=Dissenyador d'interfícies
GenericName[ca@valencia]=Dissenyador d'interfícies
GenericName[en@shaw]=𐑦𐑯𐑑𐑼𐑓𐑱𐑕 𐑛𐑩𐑟𐑲𐑯𐑼
GenericName[en_GB]=Interface Designer
GenericName[eo]=Interfaco-dizajnilo
GenericName[pt]=Desenhador de Interfaces
GenericName[pt_BR]=Construtor de interface
X-GNOME-FullName=Glade Interface Designer
X-GNOME-FullName[ca]=Dissenyador d'interfícies Glade
X-GNOME-FullName[ca@valencia]=Dissenyador d'interfícies Glade
X-GNOME-FullName[en@shaw]=·𐑜𐑤𐑱𐑛 𐑦𐑯𐑑𐑼𐑓𐑱𐑕 𐑛𐑩𐑟𐑲𐑯𐑼
X-GNOME-FullName[en_CA]=Glade Interface Designer
X-GNOME-FullName[en_GB]=Glade Interface Designer
X-GNOME-FullName[eo]=Uzantointerfaca dizajnilo Glado
X-GNOME-FullName[pt]=Designer de Interfaces Glade
X-GNOME-FullName[pt_BR]=Construtor de interfaces Glade
Comment=Create or open user interface designs for GTK+ applications
Comment[ca]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+
Comment[ca@valencia]=Creeu o obriu dissenys d'interfície d'usuari per a aplicacions GTK+
Comment[en@shaw]=𐑒𐑮𐑦𐑱𐑑 𐑹 𐑴𐑐𐑩𐑯 𐑿𐑟𐑼 𐑦𐑯𐑑𐑼𐑓𐑱𐑕 𐑛𐑩𐑟𐑲𐑯𐑟 𐑓𐑹 GTK+ 𐑩𐑐𐑤𐑦𐑒𐑱𐑕𐑩𐑯𐑟
Comment[en_CA]=Create or open user interface designs for GTK+ applications
Comment[en_GB]=Create or open user interface designs for GTK+ applications
Comment[eo]=Krei aŭ malfermi uzantointerfacan dizajnon por aplikaĵoj de GTK+
Comment[pt]=Criar ou abrir um desenho de interface de utilizador para aplicações GTK+
Comment[pt_BR]=Crie ou abra projetos de interface com o usuário para aplicativos GTK+
Keywords=GUI designer;user interface;ui builder;
Keywords[ca]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari;
Keywords[ca@valencia]=dissenyador d'interfícies d'usuari gràfiques;interfície d'usuari;constructor d'interfícies d'usuari;
Keywords[en_GB]=GUI designer;user interface;ui builder;
Keywords[pt]=criador IU;interface utilizador;interface gráfico;
Keywords[pt_BR]=Construtor de interface gráfica;Construtor de GUI;interface de usuário;construtor de interface;construtor de ui;
Exec=true
Terminal=false
StartupNotify=true
Type=Application
Icon=glade
Categories=GNOME;GTK;Development;GUIDesigner;
MimeType=application/x-glade;
X-GNOME-DocPath=glade/glade.xml
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=glade
X-GNOME-Bugzilla-Version=3.16.0
X-GNOME-Bugzilla-Component=general

View file

@ -0,0 +1,26 @@
[Desktop Entry]
Name=Contacts
Name[bn_IN]=িিি-
Name[ca]=Contactes
Name[ca@valencia]=Contactes
Name[en_CA]=Contacts
Name[en_GB]=Contacts
Name[eo]=Kontaktaro
Name[pt]=Contactos
Name[pt_BR]=Contatos
Comment=A contacts manager for GNOME
Keywords=friends;address book;
Keywords[bn_IN]=; ি ;
Keywords[ca]=amics;llibreta d'adreces;
Keywords[ca@valencia]=amics;llibreta d'adreces;
Keywords[eo]=amikoj;adreslibro;
Keywords[pt]=amigos;livro de endereços;
Keywords[pt_BR]=amigos;catálogo de endereços;
Icon=x-office-address-book
Exec=true
Terminal=false
Type=Application
StartupNotify=true
Categories=GNOME;GTK;Utility;
OnlyShowIn=GNOME;Unity;
Implements=org.gnome.Shell.SearchProvider2

View file

@ -0,0 +1,33 @@
[Desktop Entry]
Name=Font Viewer
Name[bn_IN]=
Name[ca]=Visualitzador de tipus de lletra
Name[ca@valencia]=Visualitzador de tipus de lletra
Name[en_GB]=Font Viewer
Name[eo]=Tipar-rigardilo
Name[pt]=Visualizador de Fontes
Name[pt_BR]=Visualizador de fontes
Comment=View fonts on your system
Comment[bn_IN]=ি ি
Comment[ca]=Visualitza tots els tipus de lletra del sistema
Comment[ca@valencia]=Visualitza tots els tipus de lletra del sistema
Comment[en_GB]=View fonts on your system
Comment[pt]=Visualize as fontes no seu sistema
Comment[pt_BR]=Ver fontes no seu sistema
Keywords=fonts;fontface;
Keywords[ca]=tipus de lletra;tipografia;
Keywords[ca@valencia]=tipus de lletra;tipografia;
Keywords[pt]=fontes;tipos de fonte;
Keywords[pt_BR]=fontes;tipo de fonte;tipo da fonte;
Icon=preferences-desktop-font
Exec=true %u
Terminal=false
Type=Application
StartupNotify=true
Categories=GTK;GNOME;Utility;
MimeType=application/x-font-ttf;application/x-font-pcf;application/x-font-type1;application/x-font-otf;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-font-viewer
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-OtherBinaries=gnome-thumbnail-font
X-GNOME-Bugzilla-Version=3.10.0

View file

@ -0,0 +1,23 @@
[Desktop Entry]
Name=Music
Name[ca]=Música
Name[en_GB]=Music
Name[pt]=Música
Name[pt_BR]=Músicas
GenericName=Music Player
GenericName[ca]=Reproductor de música
GenericName[en_GB]=Music Player
GenericName[pt]=Reprodutor de Música
GenericName[pt_BR]=Reprodutor de músicas
Comment=Play and organize your music collection
Comment[ca]=Reproduïu i organitzeu la col·lecció de música
Comment[en_GB]=Play and organise your music collection
Comment[pt]=Reproduz e organiza a sua coleção de media
Comment[pt_BR]=Reproduza e organize sua coleção de músicas
Icon=gnome-music
Exec=true
Terminal=false
Type=Application
Categories=GNOME;GTK;AudioVideo;Player;Audio;
StartupNotify=true
Implements=org.gnome.Shell.SearchProvider2

View file

@ -0,0 +1,39 @@
[Desktop Entry]
Name=Terminal
Name[bn]=ি
Name[bn_IN]=ি
Name[ca]=Terminal
Name[ca@valencia]=Terminal
Name[en@shaw]=𐑑𐑻𐑥𐑦𐑯𐑩𐑤
Name[en_CA]=Terminal
Name[en_GB]=Terminal
Name[eo]=Terminalo
Name[pt]=Consola
Name[pt_BR]=Terminal
Comment=Use the command line
Comment[bn]=
Comment[bn_IN]=
Comment[ca]=Obriu la línia d'ordres
Comment[ca@valencia]=Obriu la línia d'ordes
Comment[en@shaw]=𐑿𐑕 𐑞 𐑒𐑩𐑥𐑭𐑯𐑛 𐑤𐑲𐑯
Comment[en_CA]=Use the command line
Comment[en_GB]=Use the command line
Comment[eo]=Uzi la komandolinion
Comment[pt]=Utilizar a linha de comando
Comment[pt_BR]=Use a linha de comando
Keywords=shell;prompt;command;commandline;
Keywords[ca]=intèrpret d'ordres;indicador;ordre;línia d'ordres;
Keywords[ca@valencia]=intèrpret d'ordes;indicador;orde;línia d'ordes;
Keywords[en_GB]=shell;prompt;command;commandline;
Keywords[pt]=consola;linha;comando;terminal;
Keywords[pt_BR]=shell;prompt;comando;comandos;linha de comando;
Exec=true
Icon=utilities-terminal
Type=Application
X-GNOME-DocPath=gnome-terminal/index.html
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-terminal
X-GNOME-Bugzilla-Component=BugBuddyBugs
X-GNOME-Bugzilla-Version=3.10.1
Categories=GNOME;GTK;System;TerminalEmulator;
StartupNotify=true

View file

@ -0,0 +1,38 @@
[Desktop Entry]
Name=Character Map
Name[bn]=
Name[bn_IN]=
Name[ca]=Mapa de caràcters
Name[ca@valencia]=Mapa de caràcters
Name[en@shaw]=𐑒𐑸𐑩𐑒𐑑𐑼 𐑥𐑨𐑐
Name[en_CA]=Character Map
Name[en_GB]=Character Map
Name[eo]=Signotabelo
Name[pt]=Mapa de Carateres
Name[pt_BR]=Mapa de caracteres
Comment=Insert special characters into documents
Comment[bn]= ি
Comment[bn_IN]=ি ি ি
Comment[ca]=Inseriu caràcters especials en els documents
Comment[ca@valencia]=Inseriu caràcters especials en els documents
Comment[en@shaw]=𐑦𐑯𐑕𐑻𐑑 𐑕𐑐𐑧𐑖𐑩𐑤 𐑒𐑸𐑩𐑒𐑑𐑼𐑟 𐑦𐑯𐑑𐑫 𐑛𐑪𐑒𐑿𐑥𐑩𐑯𐑑𐑕
Comment[en_CA]=Insert special characters into documents
Comment[en_GB]=Insert special characters into documents
Comment[eo]=Enmeti specialajn signojn en dokumentojn
Comment[pt]=Inserir carateres especiais em documentos
Comment[pt_BR]=Insira caracteres especiais nos documentos
Keywords=font;unicode;
Keywords[ca]=tipus de lletra;unicode;
Keywords[ca@valencia]=tipus de lletra;unicode;
Keywords[pt]=fonte;unicode;
Keywords[pt_BR]=fonte;unicode;
Exec=true
Icon=accessories-character-map
Terminal=false
Type=Application
Categories=GNOME;GTK;Utility;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gucharmap
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
StartupNotify=true

View file

@ -0,0 +1,5 @@
[Desktop Entry]
Type=Application
Name=appinfo-test
OnlyShowIn=../invalid/desktop;GNOME
NotShowIn=ROX;

View file

@ -0,0 +1,27 @@
[Desktop Entry]
Name=Dolphin
Name[bn]=ি
Name[bn_IN]=Dolphin
Name[ca]=Dolphin
Name[ca@valencia]=Dolphin
Name[en_GB]=Dolphin
Name[eo]=Dolphin
Name[pt]=Dolphin
Name[pt_BR]=Dolphin
Exec=true %i -caption %c %u
Icon=system-file-manager
Type=Application
X-DocPath=dolphin/index.html
Categories=Qt;KDE;System;FileTools;FileManager;
GenericName=File Manager
GenericName[bn]=
GenericName[bn_IN]= ি
GenericName[ca]=Gestor de fitxers
GenericName[ca@valencia]=Gestor de fitxers
GenericName[en_GB]=File Manager
GenericName[eo]=Dosieradministrilo
GenericName[pt]=Gestor de Ficheiros
GenericName[pt_BR]=Gerenciador de arquivos
Terminal=false
MimeType=inode/directory;
InitialPreference=10

View file

@ -0,0 +1,26 @@
[Desktop Entry]
GenericName=Advanced Text Editor
GenericName[ca]=Editor de text avançat
GenericName[ca@valencia]=Editor de text avançat
GenericName[en_GB]=Advanced Text Editor
GenericName[pt]=Editor de Texto Avançado
GenericName[pt_BR]=Editor de textos avançado
Name=Kate
Name[ca]=Kate
Name[ca@valencia]=Kate
Name[en_GB]=Kate
Name[eo]=Kate
Name[pt]=Kate
Name[pt_BR]=Kate
MimeType=text/plain;
Exec=true -b %U
X-KDE-StartupNotify=true
X-KDE-HasTempFileOption=true
Icon=kate
X-DocPath=kate/index.html
Type=Application
Terminal=false
InitialPreference=9
X-DBUS-StartupType=Multi
X-DBUS-ServiceName=org.kde.kate
Categories=Qt;KDE;Utility;TextEditor;

View file

@ -0,0 +1,26 @@
[Desktop Entry]
Type=Application
Exec=true openProfile webbrowsing
Icon=konqueror
X-DocPath=konqueror/index.html
MimeType=x-scheme-handler/http;
Name=Konqueror
Name[bn]=
Name[bn_IN]=Konqueror
Name[ca]=Konqueror
Name[ca@valencia]=Konqueror
Name[en_GB]=Konqueror
Name[eo]=Konkeranto
Name[pt]=Konqueror
Name[pt_BR]=Konqueror
GenericName=Web Browser
GenericName[bn]=
GenericName[bn_IN]=
GenericName[ca]=Navegador web
GenericName[ca@valencia]=Navegador web
GenericName[en_GB]=Web Browser
GenericName[eo]=TTT-foliumilo
GenericName[pt]=Navegador Web
GenericName[pt_BR]=Navegador Web
Categories=Qt;KDE;Network;WebBrowser;

View file

@ -0,0 +1,23 @@
[Desktop Entry]
Terminal=false
Name=Okular
Name[ca]=Okular
Name[ca@valencia]=Okular
Name[en_GB]=Okular
Name[eo]=Okular
Name[pt]=Okular
Name[pt_BR]=Okular
GenericName=Document Viewer
GenericName[ca]=Visualitzador de documents
GenericName[ca@valencia]=Visualitzador de documents
GenericName[en_GB]=Document Viewer
GenericName[eo]=Dokumenta rigardilo
GenericName[pt]=Visualizador de Documentos
GenericName[pt_BR]=Visualizador de documentos
Exec=true %U %i -caption %c
Icon=okular
Type=Application
X-DocPath=okular/index.html
InitialPreference=7
Categories=Qt;KDE;Graphics;VectorGraphics;Viewer;
MimeType=application/vnd.kde.okular-archive;

View file

@ -0,0 +1,246 @@
[MIME Cache]
application/mxf=totem.desktop;
application/ogg=totem.desktop;
application/oxps=evince.desktop;evince-previewer.desktop;
application/pdf=evince.desktop;evince-previewer.desktop;
application/pkcs10=gcr-viewer.desktop;
application/pkcs10+pem=gcr-viewer.desktop;
application/pkcs12=gcr-viewer.desktop;
application/pkcs12+pem=gcr-viewer.desktop;
application/pkcs7-mime=gcr-viewer.desktop;
application/pkcs7-mime+pem=gcr-viewer.desktop;
application/pkcs8=gcr-viewer.desktop;
application/pkcs8+pem=gcr-viewer.desktop;
application/pkix-cert=gcr-viewer.desktop;
application/pkix-cert+pem=gcr-viewer.desktop;
application/pkix-crl=gcr-viewer.desktop;
application/pkix-crl+pem=gcr-viewer.desktop;
application/ram=totem.desktop;
application/sdp=totem.desktop;
application/smil=totem.desktop;
application/smil+xml=totem.desktop;
application/vnd.apple.mpegurl=totem.desktop;
application/vnd.kde.okular-archive=kde4-okular.desktop;
application/vnd.ms-cab-compressed=file-roller.desktop;
application/vnd.ms-wpl=totem.desktop;
application/vnd.ms-xpsdocument=evince.desktop;evince-previewer.desktop;
application/vnd.rn-realmedia=totem.desktop;
application/x-7z-compressed=file-roller.desktop;
application/x-7z-compressed-tar=file-roller.desktop;
application/x-ace=file-roller.desktop;
application/x-alz=file-roller.desktop;
application/x-ar=file-roller.desktop;
application/x-archive=file-roller.desktop;
application/x-arj=file-roller.desktop;
application/x-bzip=file-roller.desktop;
application/x-bzip-compressed-tar=file-roller.desktop;
application/x-bzip1=file-roller.desktop;
application/x-bzip1-compressed-tar=file-roller.desktop;
application/x-bzpdf=evince.desktop;evince-previewer.desktop;
application/x-cabinet=file-roller.desktop;
application/x-cb7=evince.desktop;evince-previewer.desktop;
application/x-cbr=evince.desktop;evince-previewer.desktop;file-roller.desktop;
application/x-cbt=evince.desktop;evince-previewer.desktop;
application/x-cbz=evince.desktop;evince-previewer.desktop;file-roller.desktop;
application/x-cd-image=file-roller.desktop;
application/x-compress=file-roller.desktop;
application/x-compressed-tar=file-roller.desktop;
application/x-cpio=file-roller.desktop;
application/x-deb=file-roller.desktop;
application/x-ear=file-roller.desktop;
application/x-extension-m4a=totem.desktop;
application/x-extension-mp4=totem.desktop;
application/x-flac=totem.desktop;
application/x-flash-video=totem.desktop;
application/x-font-otf=gnome-font-viewer.desktop;
application/x-font-pcf=gnome-font-viewer.desktop;
application/x-font-ttf=gnome-font-viewer.desktop;
application/x-font-type1=gnome-font-viewer.desktop;
application/x-glade=glade.desktop;
application/x-gnome-saved-search=nautilus.desktop;
application/x-gtar=file-roller.desktop;
application/x-gzip=file-roller.desktop;
application/x-gzpdf=evince.desktop;evince-previewer.desktop;
application/x-gzpostscript=file-roller.desktop;
application/x-java-archive=file-roller.desktop;
application/x-lha=file-roller.desktop;
application/x-lhz=file-roller.desktop;
application/x-lrzip=file-roller.desktop;
application/x-lrzip-compressed-tar=file-roller.desktop;
application/x-lzip=file-roller.desktop;
application/x-lzip-compressed-tar=file-roller.desktop;
application/x-lzma=file-roller.desktop;
application/x-lzma-compressed-tar=file-roller.desktop;
application/x-lzop=file-roller.desktop;
application/x-lzop-compressed-tar=file-roller.desktop;
application/x-matroska=totem.desktop;
application/x-ms-dos-executable=file-roller.desktop;
application/x-ms-wim=file-roller.desktop;
application/x-netshow-channel=totem.desktop;
application/x-ogg=totem.desktop;
application/x-pem-file=gcr-viewer.desktop;
application/x-pem-key=gcr-viewer.desktop;
application/x-pkcs12=gcr-viewer.desktop;
application/x-pkcs7-certificates=gcr-viewer.desktop;
application/x-quicktime-media-link=totem.desktop;
application/x-quicktimeplayer=totem.desktop;
application/x-rar=file-roller.desktop;
application/x-rar-compressed=file-roller.desktop;
application/x-rpm=file-roller.desktop;
application/x-rzip=file-roller.desktop;
application/x-rzip-compressed-tar=file-roller.desktop;
application/x-shorten=totem.desktop;
application/x-smil=totem.desktop;
application/x-spkac=gcr-viewer.desktop;
application/x-spkac+base64=gcr-viewer.desktop;
application/x-stuffit=file-roller.desktop;
application/x-tar=file-roller.desktop;
application/x-tarz=file-roller.desktop;
application/x-war=file-roller.desktop;
application/x-x509-ca-cert=gcr-viewer.desktop;
application/x-x509-user-cert=gcr-viewer.desktop;
application/x-xz=file-roller.desktop;
application/x-xz-compressed-tar=file-roller.desktop;
application/x-xzpdf=evince.desktop;evince-previewer.desktop;
application/x-zip=file-roller.desktop;
application/x-zip-compressed=file-roller.desktop;
application/x-zoo=file-roller.desktop;
application/xspf+xml=totem.desktop;
application/zip=file-roller.desktop;
audio/3gpp=totem.desktop;
audio/AMR=totem.desktop;
audio/AMR-WB=totem.desktop;
audio/ac3=totem.desktop;
audio/basic=totem.desktop;
audio/flac=totem.desktop;
audio/midi=totem.desktop;
audio/mp2=totem.desktop;
audio/mp4=totem.desktop;
audio/mpeg=totem.desktop;
audio/mpegurl=totem.desktop;
audio/ogg=totem.desktop;
audio/prs.sid=totem.desktop;
audio/vnd.rn-realaudio=totem.desktop;
audio/x-aiff=totem.desktop;
audio/x-ape=totem.desktop;
audio/x-flac=totem.desktop;
audio/x-gsm=totem.desktop;
audio/x-it=totem.desktop;
audio/x-m4a=totem.desktop;
audio/x-matroska=totem.desktop;
audio/x-mod=totem.desktop;
audio/x-mp3=totem.desktop;
audio/x-mpeg=totem.desktop;
audio/x-mpegurl=totem.desktop;
audio/x-ms-asf=totem.desktop;
audio/x-ms-asx=totem.desktop;
audio/x-ms-wax=totem.desktop;
audio/x-ms-wma=totem.desktop;
audio/x-musepack=totem.desktop;
audio/x-pn-aiff=totem.desktop;
audio/x-pn-au=totem.desktop;
audio/x-pn-realaudio=totem.desktop;
audio/x-pn-realaudio-plugin=totem.desktop;
audio/x-pn-wav=totem.desktop;
audio/x-pn-windows-acm=totem.desktop;
audio/x-real-audio=totem.desktop;
audio/x-realaudio=totem.desktop;
audio/x-s3m=totem.desktop;
audio/x-sbc=totem.desktop;
audio/x-scpls=totem.desktop;
audio/x-speex=totem.desktop;
audio/x-stm=totem.desktop;
audio/x-tta=totem.desktop;
audio/x-vorbis=totem.desktop;
audio/x-vorbis+ogg=totem.desktop;
audio/x-wav=totem.desktop;
audio/x-wavpack=totem.desktop;
audio/x-xm=totem.desktop;
image/bmp=eog.desktop;
image/gif=eog.desktop;
image/jpeg=eog.desktop;
image/jpg=eog.desktop;
image/pjpeg=eog.desktop;
image/png=eog.desktop;
image/svg+xml=eog.desktop;
image/svg+xml-compressed=eog.desktop;
image/tiff=eog.desktop;evince.desktop;evince-previewer.desktop;
image/vnd.rn-realpix=totem.desktop;
image/vnd.wap.wbmp=eog.desktop;
image/x-bmp=eog.desktop;
image/x-gray=eog.desktop;
image/x-icb=eog.desktop;
image/x-ico=eog.desktop;
image/x-pcx=eog.desktop;
image/x-pict=totem.desktop;
image/x-png=eog.desktop;
image/x-portable-anymap=eog.desktop;
image/x-portable-bitmap=eog.desktop;
image/x-portable-graymap=eog.desktop;
image/x-portable-pixmap=eog.desktop;
image/x-xbitmap=eog.desktop;
image/x-xpixmap=eog.desktop;
inode/directory=kde4-dolphin.desktop;baobab.desktop;nautilus.desktop;
misc/ultravox=totem.desktop;
text/google-video-pointer=totem.desktop;
text/plain=kde4-kate.desktop;gedit.desktop;
text/x-google-video-pointer=totem.desktop;
video/3gp=totem.desktop;
video/3gpp=totem.desktop;
video/divx=totem.desktop;
video/dv=totem.desktop;
video/fli=totem.desktop;
video/flv=totem.desktop;
video/mp2t=totem.desktop;
video/mp4=totem.desktop;
video/mp4v-es=totem.desktop;
video/mpeg=totem.desktop;
video/msvideo=totem.desktop;
video/ogg=totem.desktop;
video/quicktime=totem.desktop;
video/vivo=totem.desktop;
video/vnd.divx=totem.desktop;
video/vnd.mpegurl=totem.desktop;
video/vnd.rn-realvideo=totem.desktop;
video/vnd.vivo=totem.desktop;
video/webm=totem.desktop;
video/x-anim=totem.desktop;
video/x-avi=totem.desktop;
video/x-flc=totem.desktop;
video/x-fli=totem.desktop;
video/x-flic=totem.desktop;
video/x-flv=totem.desktop;
video/x-m4v=totem.desktop;
video/x-matroska=totem.desktop;
video/x-mpeg=totem.desktop;
video/x-mpeg2=totem.desktop;
video/x-ms-asf=totem.desktop;
video/x-ms-asx=totem.desktop;
video/x-ms-wm=totem.desktop;
video/x-ms-wmv=totem.desktop;
video/x-ms-wmx=totem.desktop;
video/x-ms-wvx=totem.desktop;
video/x-msvideo=totem.desktop;
video/x-nsv=totem.desktop;
video/x-ogm+ogg=totem.desktop;
video/x-theora+ogg=totem.desktop;
video/x-totem-stream=totem.desktop;
x-content/unix-software=nautilus-autorun-software.desktop;
x-content/video-dvd=totem.desktop;
x-content/video-svcd=totem.desktop;
x-content/video-vcd=totem.desktop;
x-scheme-handler/ghelp=yelp.desktop;
x-scheme-handler/help=yelp.desktop;
x-scheme-handler/http=kde4-konqbrowser.desktop;
x-scheme-handler/icy=totem.desktop;
x-scheme-handler/icyx=totem.desktop;
x-scheme-handler/info=yelp.desktop;
x-scheme-handler/man=yelp.desktop;
x-scheme-handler/mms=totem.desktop;
x-scheme-handler/mmsh=totem.desktop;
x-scheme-handler/net=totem.desktop;
x-scheme-handler/pnm=totem.desktop;
x-scheme-handler/rtmp=totem.desktop;
x-scheme-handler/rtp=totem.desktop;
x-scheme-handler/rtsp=totem.desktop;
x-scheme-handler/uvox=totem.desktop;

View file

@ -0,0 +1,19 @@
[Desktop Entry]
Name=Run Software
Name[ca]=Executa programari
Name[ca@valencia]=Executa programari
Name[en_GB]=Run Software
Name[eo]=Lanĉi programaron
Name[pt]=Executar Aplicação
Name[pt_BR]=Executar software
Exec=true %u
Icon=application-x-executable
NoDisplay=true
Terminal=false
StartupNotify=true
Type=Application
MimeType=x-content/unix-software;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=nautilus
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0

View file

@ -0,0 +1,15 @@
[Desktop Entry]
Type=Application
Name=Desktop Icons
Comment=Classic session desktop file for desktop icons
Exec=true --no-default-window --force-desktop
OnlyShowIn=GNOME;
NoDisplay=true
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=nautilus
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
X-GNOME-Autostart-Phase=Desktop
X-GNOME-Autostart-Notify=true
X-GNOME-AutoRestart=true
X-GNOME-Provides=filemanager

View file

@ -0,0 +1,22 @@
[Desktop Entry]
Name=Connect to Server
Name[bn]=
Name[bn_IN]=
Name[ca]=Connecta't al servidor
Name[ca@valencia]=Connecta't al servidor
Name[en@shaw]=𐑒𐑩𐑯𐑧𐑒𐑑 𐑑 𐑕𐑻𐑝𐑼
Name[en_CA]=Connect to Server
Name[en_GB]=Connect to Server
Name[eo]=Konekti al servilo
Name[pt]=Ligar-se a Servidores
Name[pt_BR]=Conectar ao servidor
Exec=true
Icon=applications-internet
NoDisplay=true
Terminal=false
StartupNotify=true
Type=Application
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=nautilus
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0

View file

@ -0,0 +1,39 @@
[Desktop Entry]
Name=Files
Name[bn]=
Name[ca]=Fitxers
Name[ca@valencia]=Fitxers
Name[en_CA]=Files
Name[en_GB]=Files
Name[eo]=Dosieroj
Name[pt]=Ficheiros
Name[pt_BR]=Arquivos
Comment=Access and organize files
Comment[bn]=
Comment[ca]=Organitzeu i accediu a fitxers
Comment[ca@valencia]=Organitzeu i accediu a fitxers
Comment[en_CA]=Access and organize files
Comment[en_GB]=Access and organise files
Comment[eo]=Atingi kaj organizi dosierojn
Comment[pt]=Aceder e organizar ficheiros
Comment[pt_BR]=Acesse e organize arquivos
Keywords=folder;manager;explore;disk;filesystem;
Keywords[ca]=carpeta;gestor;explora;disc;sistema de fitxers;
Keywords[ca@valencia]=carpeta;gestor;explora;disc;sistema de fitxers;
Keywords[en_GB]=folder;manager;explore;disk;filesystem;
Keywords[eo]=dosierujo;administrilo;foliumi;esplori;disko;dosiersistemo;
Keywords[pt]=pasta;gestor;explorar;disco;sistema;ficheiros;
Keywords[pt_BR]=pasta;gerenciador;explorar;disco;sistema de arquivos;
Exec=true --new-window %U
Icon=system-file-manager
Terminal=false
Type=Application
StartupNotify=true
OnlyShowIn=GNOME;Unity;
Categories=GNOME;GTK;Utility;Core;FileManager;
MimeType=inode/directory;application/x-gnome-saved-search;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=nautilus
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
X-GNOME-UsesNotifications=true

View file

@ -0,0 +1,404 @@
[Desktop Entry]
Name[af]=Horlosies
Name[an]=Reloches
Name[ar]=الساعات
Name[as]=
Name[be]=Гадзіннікі
Name[bg]=Часовници
Name[bn_IN]=ি
Name[bs]=Satovi
Name[ca]=Rellotges
Name[ca@valencia]=Rellotges
Name[cs]=Hodiny
Name[da]=Ure
Name[de]=Uhren
Name[el]=Ρολόγια
Name[en_GB]=Clocks
Name[eo]=Horloĝoj
Name[es]=Relojes
Name[et]=Kell
Name[eu]=Ordulariak
Name[fa]=ساعتها
Name[fi]=Kellot
Name[fr]=Horloges
Name[fur]=Orlois
Name[ga]=Cloig
Name[gd]=Uaireadairean
Name[gl]=Reloxos
Name[gu]=િ
Name[he]=שעונים
Name[hi]=
Name[hr]=Satovi
Name[hu]=Órák
Name[id]=Jam
Name[is]=Klukkur
Name[it]=Orologi
Name[ja]=
Name[kk]=Сағаттар
Name[ko]=
Name[kn]=ಿ
Name[lt]=Laikrodžiai
Name[lv]=Pulksteņi
Name[ml]=
Name[mr]=
Name[nb]=Klokker
Name[ne]=ि
Name[nl]=Klok
Name[oc]=Relòtges
Name[or]=ି
Name[pa]=
Name[pl]=Zegar
Name[pt]=Relógios
Name[pt_BR]=Relógios
Name[ro]=Ceasuri
Name[ru]=Часы
Name[sk]=Hodiny
Name[sl]=Ure
Name[sr]=Сатови
Name[sr@latin]=Satovi
Name[sv]=Klockor
Name[ta]=ி
Name[te]=ి
Name[tg]=Соатҳо
Name[th]=
Name[tr]=Saatler
Name[uk]=Годинники
Name[vi]=Đng h
Name[zh_CN]=
Name[zh_HK]=
Name[zh_TW]=
Name[ug]=سائەتلەر
Name=Clocks
GenericName[af]=Horlosies
GenericName[an]=Reloches
GenericName[ar]=الساعات
GenericName[as]=
GenericName[be]=Гадзіннікі
GenericName[bg]=Часовници
GenericName[bn_IN]=ি
GenericName[bs]=Satovi
GenericName[ca]=Rellotges
GenericName[ca@valencia]=Rellotges
GenericName[cs]=Hodiny
GenericName[da]=Ure
GenericName[de]=Uhren
GenericName[el]=Ρολόγια
GenericName[en_GB]=Clocks
GenericName[eo]=Horloĝoj
GenericName[es]=Relojes
GenericName[et]=Kell
GenericName[eu]=Ordulariak
GenericName[fa]=ساعتها
GenericName[fi]=Kellot
GenericName[fr]=Horloges
GenericName[fur]=Orlois
GenericName[ga]=Cloig
GenericName[gd]=Uaireadairean
GenericName[gl]=Reloxos
GenericName[gu]=િ
GenericName[he]=שעונים
GenericName[hi]=
GenericName[hr]=Satovi
GenericName[hu]=Órák
GenericName[id]=Jam
GenericName[is]=Klukkur
GenericName[it]=Orologi
GenericName[ja]=
GenericName[kk]=Сағаттар
GenericName[ko]=
GenericName[kn]=ಿ
GenericName[lt]=Laikrodžiai
GenericName[lv]=Pulksteņi
GenericName[ml]=
GenericName[mr]=
GenericName[nb]=Klokker
GenericName[ne]=ि
GenericName[nl]=Klok
GenericName[oc]=Relòtges
GenericName[or]=ି
GenericName[pa]=
GenericName[pl]=Zegar
GenericName[pt]=Relógios
GenericName[pt_BR]=Relógios
GenericName[ro]=Ceasuri
GenericName[ru]=Часы
GenericName[sk]=Hodiny
GenericName[sl]=Ure
GenericName[sr]=Сатови
GenericName[sr@latin]=Satovi
GenericName[sv]=Klockor
GenericName[ta]=ி
GenericName[te]=ి
GenericName[tg]=Соатҳо
GenericName[th]=
GenericName[tr]=Saatler
GenericName[uk]=Годинники
GenericName[vi]=Đng h
GenericName[zh_CN]=
GenericName[zh_HK]=
GenericName[zh_TW]=
GenericName[ug]=سائەتلەر
GenericName=Clocks
X-GNOME-FullName[af]=GNOME Horlosies
X-GNOME-FullName[an]=Reloches d'o GNOME
X-GNOME-FullName[ar]=ساعات جنوم
X-GNOME-FullName[as]=GNOME
X-GNOME-FullName[be]=Гадзіннікі GNOME
X-GNOME-FullName[bg]=Часовници
X-GNOME-FullName[bn_IN]=GNOME ি
X-GNOME-FullName[bs]=GNOME satovi
X-GNOME-FullName[ca]=Rellotges del GNOME
X-GNOME-FullName[ca@valencia]=Rellotges del GNOME
X-GNOME-FullName[cs]=Hodiny GNOME
X-GNOME-FullName[da]=GNOME Ure
X-GNOME-FullName[de]=GNOME-Uhren
X-GNOME-FullName[el]=Ρολόγια GNOME
X-GNOME-FullName[en_GB]=GNOME Clocks
X-GNOME-FullName[eo]=GNOME-horloĝoj
X-GNOME-FullName[es]=Relojes de GNOME
X-GNOME-FullName[et]=GNOME kell
X-GNOME-FullName[eu]=GNOMEren ordulariak
X-GNOME-FullName[fa]=ساعتهای گنوم
X-GNOME-FullName[fi]=Gnomen kellot
X-GNOME-FullName[fr]=Horloges de GNOME
X-GNOME-FullName[fur]=Orlois par GNOME
X-GNOME-FullName[ga]=Cloig GNOME
X-GNOME-FullName[gd]=Uaireadairean GNOME
X-GNOME-FullName[gl]=Reloxos de GNOME
X-GNOME-FullName[gu]=GNOME િ
X-GNOME-FullName[he]=שעונים מבית GNOME
X-GNOME-FullName[hi]=
X-GNOME-FullName[hr]=GNOME satovi
X-GNOME-FullName[hu]=GNOME órák
X-GNOME-FullName[id]=Jam GNOME
X-GNOME-FullName[is]=GNOME Klukkur
X-GNOME-FullName[it]=Orologi per GNOME
X-GNOME-FullName[ja]=GNOME Clocks
X-GNOME-FullName[kk]=GNOME сағаттары
X-GNOME-FullName[ko]=
X-GNOME-FullName[kn]=GNOME
X-GNOME-FullName[lt]=GNOME laikrodžiai
X-GNOME-FullName[lv]=GNOME pulksteņi
X-GNOME-FullName[ml]=
X-GNOME-FullName[mr]=GNOME
X-GNOME-FullName[nb]=GNOME klokker
X-GNOME-FullName[ne]=ि
X-GNOME-FullName[nl]=Gnome Klok
X-GNOME-FullName[oc]=Relòtges GNOME
X-GNOME-FullName[or]=GNOME ି
X-GNOME-FullName[pa]=
X-GNOME-FullName[pl]=Zegar GNOME
X-GNOME-FullName[pt]=Relógios GNOME
X-GNOME-FullName[pt_BR]=Relógios do GNOME
X-GNOME-FullName[ro]=Ceasuri GNOME
X-GNOME-FullName[ru]=Часы GNOME
X-GNOME-FullName[sk]=Hodiny prostredia GNOME
X-GNOME-FullName[sl]=Gnomeove ure
X-GNOME-FullName[sr]=Гномови сатови
X-GNOME-FullName[sr@latin]=Gnomovi satovi
X-GNOME-FullName[sv]=GNOME Klockor
X-GNOME-FullName[ta]= ி
X-GNOME-FullName[te]= ి
X-GNOME-FullName[tg]=Соатҳои GNOME
X-GNOME-FullName[th]= GNOME
X-GNOME-FullName[tr]=GNOME Saatleri
X-GNOME-FullName[vi]=Đng h GNOME
X-GNOME-FullName[zh_CN]=GNOME
X-GNOME-FullName[zh_HK]=GNOME Clocks
X-GNOME-FullName[zh_TW]=GNOME
X-GNOME-FullName[ug]=گىنوم سائەتلىرى
X-GNOME-FullName=GNOME Clocks
Comment[af]=Horlosies vir wêreldtyd, plus wekkers, stophorlosie en 'n tydteller
Comment[an]=Reloches d'horas mundials, amás d'alarmas, cronometro y un temporizador
Comment[ar]=ساعات لتوقيتات العالم، مع منبه ومُؤقّت وساعة إيقاف.
Comment[as]=ি , ,
Comment[be]=Гадзіннікі для адсочвання часу ў розных кутках свету, з будзільнікам, таймерам і секундамерам
Comment[bg]=Часовници за различни градове, аларми, хронометър и отброяване
Comment[bn_IN]=িি, , ি
Comment[bs]=Satovi za svjetsko vrijeme, plus alarmi, štoperica i tajmer
Comment[ca]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
Comment[ca@valencia]=Rellotges de tot el món, a més d'alarmes, de cronòmetres i de temporitzadors
Comment[cs]=Hodiny s časy ve světě, budíkem, stopkami a odpočtem
Comment[da]=Verdensur plus alarmer, stopur og et minutur
Comment[de]=Uhren für die Weltzeit mit Alarm, Stoppuhr und einem Timer
Comment[el]=Ρολόγια για παγκόσμιες ώρες, για ειδοποιήσεις, με χρονόμετρο και αντίστροφη μέτρηση
Comment[en_GB]=Clocks for world times, plus alarms, stopwatch and a timer
Comment[eo]=Horloĝoj por mondaj horoj, plus alarmoj, kronometro kaj minutatoro
Comment[es]=Relojes de horas mundiales, además de alarmas, cronómetro y un temporizador
Comment[et]=Kell maailmaajaga, alarmide, stopperi ja taimeriga
Comment[eu]=Ordulariak munduko orduetarako, gehi alarmak, kronometroa eta tenporizadorea
Comment[fa]=ساعتهایی برای زمانها در دنیا، با اضافهی زنگ هشدار، کرنومتر و زمانسنج
Comment[fi]=Kellot eri puolille maailmaa, hälytykset, sekuntikello ja ajastin
Comment[fr]=Des horloges pour connaître lheure dans le monde, régler des alarmes, chronométrer ou lancer un décompte
Comment[fur]=Orlois par i fûs oraris tal mont, sveis, cronometri e un timer
Comment[gd]=Uaireadairean airson àm an t-saoghail le caismeachdan, stad-uaireadair s tìmear
Comment[gl]=Reloxos para todo o mundo, ademais de alarmas, cronómetro e un temporizador
Comment[gu]=િ , , િ
Comment[he]=שעונים לזמנים שונים ברחבי העולם לרבות התרעות, שעון עצר וקוצב זמן
Comment[hi]=ि , , ि ि
Comment[hr]=Satovi sa svjetskim vremenima, uključujući alarme, štopericu i odbrojavanje vremena
Comment[hu]=Világidő, figyelmeztetés, stopper és időzítő
Comment[id]=Jam untuk waktu dunia, alarm, stopwatch dan penghitung waktu
Comment[is]=Klukkur á ýmsum stöðum, vekjaraklukkur, skeiðklukka og niðurteljari.
Comment[it]=Orologi per i fusi orari nel mondo, sveglie, cronometro e un timer
Comment[ja]=
Comment[kk]=Дүниежүзілік уақыттары үшін сағаттар, құрамында тағы оятқыш, секундтар өлшегіші және таймері бар
Comment[ko]= , , ,
Comment[kn]= ಿ, ಿಿ, ಿ ಿಿ ಿ
Comment[lt]=Pasaulio laikų laikrodžiai, taip pat žadintuvai, chronometras ir laikmatis
Comment[lv]=Pulksteņi pasaules laikiem, kā arī modinātājs, hronometrs un taimeris
Comment[ml]=ി ി , , , ി
Comment[mr]=ि , ,
Comment[nb]=Klokker med verdenstid, alarm, stoppeklokke og nedtelling
Comment[nl]=Wereldklok, wekker, stopwatch en timer
Comment[oc]=De relòtges per conéisser l'ora dins lo mond, reglar d'alarmas, cronometrar o aviar un descompte
Comment[or]=ି ି, ି ,
Comment[pa]= , ,
Comment[pl]=Zegar światowy, budzik, stoper i minutnik
Comment[pt]=Relógios com as horas do mundo, alarmes, cronómetros e um temporizador
Comment[pt_BR]=Relógios para horários mundiais além de alarmes, cronômetro e um temporizador
Comment[ro]=Ora în lume, alarme, cronometru și temporizator
Comment[ru]=Часы мирового времени, а также будильник, секундомер и таймер
Comment[sk]=Hodiny svetového času, budík, stopky a časovač
Comment[sl]=Ure za prikazovanje svetovnega časa, alarmi, štoparica in časomer
Comment[sr]=Сатови за светска времена, будилници, штоперица и одбројавач
Comment[sr@latin]=Satovi za svetska vremena, budilnici, štoperica i odbrojavač
Comment[sv]=Klockor för världstider, alarm, stoppur och en timer
Comment[ta]= , ி ி, ி ி, ி ி
Comment[te]= ,, ిి ి
Comment[tg]=Соат барои вақти ҷаҳон, аз ҷумла истифодаи ҳушдорҳо, сонияшумор ва вақтсанҷ
Comment[th]=, ,
Comment[tr]=Dünya saatleri, alarmlar, kronometre ve zaman ölçer
Comment[vi]=Đng h thế gii, kèm báo thc và đo gi
Comment[zh_CN]=
Comment[zh_HK]=
Comment[zh_TW]=
Comment[ug]=دۇنيا ۋاقىتلىرى، قوڭغۇراقلىق سائەت، ۋاقىت ئۆلچىگۈچ
Comment=Clocks for world times, plus alarms, stopwatch and a timer
Keywords[af]=time;timer;alarm;world clock;stopwatch;time zone;tyd;tydteller;wekker;wêreldtyd;stophorlosie;tydsone;tydhou;
Keywords[an]=Hora;Temporizador;Alarma;Hora mundial;Cronometro;Zona horaria;
Keywords[ar]=وقت;موقت;منبه;ساعة عالمية;ساعة إيقاف;منطقة زمنية;
Keywords[as]=time;timer;alarm;world clock;stopwatch;time zone;
Keywords[be]=час;таймер;гадзіннік;будзільнік;сусветны гадзіннік;секундамер;часавы пояс;
Keywords[bg]=време;обратно;отброяване;напомняне;аларма;часовник;секундомер;пояс;хронометър;time;timer;alarm;world clock;stopwatch;time zone;
Keywords[bn_IN]=;;;িি;; ;
Keywords[bs]=vrijeme;tajmer;alarm;svjetski sat;štoperica;vremenska zona;
Keywords[ca]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
Keywords[ca@valencia]=temps;temporitzador;alarma;rellotge global;cronòmetre;zona horària;
Keywords[cs]=čas;časovač;minutka;odpočet;budík;buzení;světový čas;stopky;časové pásmo;
Keywords[da]=tid;timer;minutur;alarm;vækkeur;verdensur;stopur;ur;tidszone;klokken;
Keywords[de]=Zeit;Uhrzeit;Alarm;Weltuhr;Stoppuhr;Zeitzone;
Keywords[el]=χρόνος;χρονόμετρο;ξυπνητήρι;παγκόσμιο ρολόι;χρονόμετρο;ώρα ζώνης;time;timer;alarm;world clock;stopwatch;time zone;
Keywords[en_GB]=time;timer;alarm;world clock;stopwatch;time zone;
Keywords[eo]=horo;minutatoro;alarmo;monda horloĝo;kronometro;horzono;
Keywords[es]=Hora;Temporizador;Alarma;Hora mundial;Cronómetro;Zona horaria;
Keywords[et]=aeg;kell;kuupäev;taimer;alarm;äratus;maailmakell;stopper;ajavöönd;ajatsoon;
Keywords[eu]=ordua;tenporizadorea;alarma;munduko ordulariak;kronometroa;ordu-zona;
Keywords[fa]=time;timer;alarm;world clock;stopwatch;time zone;زمان;زمانسنج;زنگ;ساعت جهانی;منطقه زمانی;
Keywords[fi]=time;timer;alarm;world clock;stopwatch;time zone;aika;ajastin;hälytys;maailmankello;aikavyöhyke;
Keywords[fr]=heure;minuterie;décompte;alarme;horloge mondiale;chronomètre;fuseau horaire;
Keywords[fur]=ore;orari;timp;orloi;cronometri;fûs orari;svee;alarme;
Keywords[gd]=time;timer;alarm;world clock;stopwatch;time zone;àm;ùine;tìmear;uaireadair an t-saoghail;uaireadair;saoghal;cleoc;gleoc;stad-uaireadair;roinn-tìde;
Keywords[gl]=tempo;temporizador;alarma;reloxo mundial;reloxo de parada;fuso horario;
Keywords[gu]=;;;િ િ;;;
Keywords[he]=זמן;שעה;טיימר;קוצב זמן;שעון עולמי;שעון עצר;סטופר;אזור זמן;שעון;
Keywords[hi]=; ;;ि ; ; ;
Keywords[hr]=vrijeme;odbrojavanje;alarm;svjetski sat;štoperica;vremenska zona;
Keywords[hu]=idő;időzítő;riasztás;világóra;stopper;időzóna;
Keywords[id]=time;timer;alarm;world clock;stopwatch;time zone;jam;waktu;
Keywords[is]=tími;heimsklukka;vekjari;skeiðklukka;niðurteljari;tímabelti;
Keywords[it]=ora;orario;tempo;orologio;cronometro;fuso orario;sveglia;allarme;
Keywords[ja]=time;timer;alarm;world clock;stopwatch;time zone;;;;;;;;;;;
Keywords[kk]=time;timer;alarm;world clock;stopwatch;time zone;уақыт;таймер;оятқыш;дүниежүзі сағаты;секундтар өлшегіші;уақыт белдеуі;
Keywords[ko]=time;;timer;;alarm;;world clock; ;stopwatch;;time zone;;
Keywords[kn]=;;; ಿ;; ;
Keywords[lt]=laikas;laikmatis;žadintuvas;pasaulio laikrodis;chronometras;laiko juosta;
Keywords[lv]=laiks;taimeris;modinātājs;pasaules pulkstenis;hronometrs;laika zona;signāls;
Keywords[ml]=time;timer;alarm;world clock;stopwatch;time zone;
Keywords[mr]=;;;ि ;; ;
Keywords[nb]=tid;nedtelling;alarm;verdensklokke;stoppeklokke;tidssone;
Keywords[nl]=time;timer;alarm;world clock;stopwatch;time zone;klok;tijd;wekker;wereldtijd;wereldklok;tijdzone;
Keywords[oc]=ora;minutariá;descompte;alarma;relòtge mondiala;cronomètre;fus orari;
Keywords[or]=; ;;ି ; ; ;
Keywords[pa]=;;;; ;; ; ;;;ਿ;;;
Keywords[pl]=czas;minutnik;timer;budzik;alarm;zegar światowy;stoper;strefa czasowa;
Keywords[pt]=horas;temporizador;alarme;relógio mundial;cronómetro;fuso horário;
Keywords[pt_BR]=hora;temporizador;alarme;relógio mundial;cronômetro;fuso horário;
Keywords[ro]=timp;temporizator;fus orar;cronometru;alarmă;time;timer;alarm;world clock;stopwatch;time zone;
Keywords[ru]=время;таймер;будильник;мировое время;часовой пояс;
Keywords[sk]=čas;časovač;budík;svetový čas;stopky;časová zóna;
Keywords[sl]=čas;časomer;alarm;svetovne ure;štoparica;časovni pas;
Keywords[sr]=време;одбројавач;аларм;будилник;светски сат;штоперица;временска зона;
Keywords[sr@latin]=vreme;odbrojavač;alarm;budilnik;svetski sat;štoperica;vremenska zona;
Keywords[sv]=tid;timer;alarm:världsklocka;världsur;stoppur;tidszon;
Keywords[ta]=; ி;ி; ி;ி ி;ி;
Keywords[te]=;;; ి;;;
Keywords[tg]=вақт;вақтсанҷ;ҳушдор;соати ҷаҳон;сонияшумор;минтақаи вақт;
Keywords[th]=;;;;;;
Keywords[tr]=saat;zaman;geri sayım;alarm;dünya saatleri;kronometre;saat dilimi;
Keywords[vi]=time;thi;gian;thoi;timer;hn;gi;hen;gio;alarm;world clock;đng;h;dong;ho;stopwatch;time zone;múi;mui;bm;
Keywords[zh_CN]=time;timer;alarm;world clock;stopwatch;time zone;;;;;;;
Keywords[zh_HK]=time;timer;alarm;world clock;stopwatch;time zone;;;;;;;;
Keywords[zh_TW]=time;timer;alarm;world clock;stopwatch;time zone;;;;;;;;;
Keywords[ug]=time;timer;alarm;world clock;stopwatch;time zone;ۋاقىت;ئۆلچىگۈچ;قوڭغۇراق;دۇنيا سائىتى;ۋاقىت رايونى;
Keywords=time;timer;alarm;world clock;stopwatch;time zone;
# GDesktopAppInfo requires that the command exists, so use /bin/sh
# rather than /usr/bin/flatpak, since that's guaranteed to exist on
# all test systems (in particular CI machines).
Exec=/bin/sh run --branch=stable --arch=x86_64 --command=gnome-clocks org.gnome.clocks
Icon=org.gnome.clocks
Terminal=false
Type=Application
Categories=GNOME;GTK;Utility;Clock;
StartupNotify=true
DBusActivatable=true
X-GNOME-UsesNotifications=true
X-Geoclue-Reason[af]=Laat wêreldhorlosies toe om vir jou tydsone vertoon te word.
X-Geoclue-Reason[ar]=يتيح عرض الساعات العالمية في منطقة الزمنية الحالية.
X-Geoclue-Reason[be]=Дазваляе паказваць сусветныя гадзіннікі для вашага часавога пояса.
X-Geoclue-Reason[ca]=Permet que els rellotges del món es mostrin a la vostra zona horària.
X-Geoclue-Reason[ca@valencia]=Permet que els rellotges del món es mostren a la vostra zona horària.
X-Geoclue-Reason[cs]=Umožňuje zobrazit světové časy pro vaše časová pásma.
X-Geoclue-Reason[da]=Lader verdensure blive vist for din tidszone.
X-Geoclue-Reason[de]=Ermöglicht die Anzeige von Weltuhren für Ihre Zeitzone.
X-Geoclue-Reason[el]=Επιτρέπει την εμφάνιση των παγκόσμιων ρολογιών για την ζώνη ώρας σας.
X-Geoclue-Reason[en_GB]=Allows world clocks to be displayed for your time zone.
X-Geoclue-Reason[es]=Permite a los relojes del mundo mostrarse para su zona horaria.
X-Geoclue-Reason[eu]=Munduko ordulariak zure ordu-zonan bistaratzea baimentzen du.
X-Geoclue-Reason[fa]=اجازه میدهد تا ساعتهای جهانی برای منطقه زمانی شما نمایش داده شود.
X-Geoclue-Reason[fi]=Mahdollistaa maailmankellojen esityksen aikavyöhykkeellesi.
X-Geoclue-Reason[fr]=Permet dafficher des horloges mondiales selon votre fuseau horaire.
X-Geoclue-Reason[fur]=Al permet di mostrâ orlois di dut il mont pal tô fûs orari.
X-Geoclue-Reason[gd]=Leigidh seo leat uaireadairean an t-saoghail a shealltainn airson na roinn-tìde agad.
X-Geoclue-Reason[gl]=Permítelle mostrar reloxos do mundio para o seu fuso horario.
X-Geoclue-Reason[he]=מאפשר הצגת שעונים מסביב לעולם עבור אזור הזמן שלך.
X-Geoclue-Reason[hr]=Dopušta svjetskim satovima prikaz u vašoj vremenskoj zoni.
X-Geoclue-Reason[hu]=Világórák megjelenítése az időzónájához.
X-Geoclue-Reason[id]=Mengijinkan jam dunia ditampilkan untuk zona waktu Anda.
X-Geoclue-Reason[is]=Gerir kleift að birta klukku fyrir staðinn þar sem þú ert.
X-Geoclue-Reason[it]=Consente di visualizzare orologi per il proprio fuso orario.
X-Geoclue-Reason[ja]=
X-Geoclue-Reason[kk]=Сіздің уақыт белдеуіңіз үшін дүниежүзілік сағаттарды көрсетуді мүмкін етеді.
X-Geoclue-Reason[ko]= .
X-Geoclue-Reason[lt]=Leidžia rodyti pasaulio laikrodžius jūsų laiko zonai.
X-Geoclue-Reason[lv]=Ļauj parādīt pasaules pulksteņus jūsu laika joslai.
X-Geoclue-Reason[ml]= ി ി ിി ി.
X-Geoclue-Reason[nb]=Tillat visning av verdensklokker for din tidssone.
X-Geoclue-Reason[nl]=Uw tijdzone kan worden weergegeven in de wereldklok.
X-Geoclue-Reason[pa]= ਿ ਿ
X-Geoclue-Reason[pl]=Umożliwia wyświetlanie zegara dla strefy czasowej użytkownika.
X-Geoclue-Reason[pt]=Permite que o relógio mundial apresente o seu fuso horário.
X-Geoclue-Reason[pt_BR]=Permite que relógios mundiais sejam exibidos para o seu fuso horário.
X-Geoclue-Reason[ru]=Позволяет отображать мировые часы для вашего часового пояса.
X-Geoclue-Reason[sk]=Umožňuje zobrazenie svetových hodín pre vašu časovú zónu.
X-Geoclue-Reason[sl]=Dovoli prikaz svetovnih časov za trenutno časovno območje.
X-Geoclue-Reason[sr]=Допустите да светски сатови буду приказани за вашу временску зону.
X-Geoclue-Reason[sr@latin]=Dopustite da svetski satovi budu prikazani za vašu vremensku zonu.
X-Geoclue-Reason[sv]=Låter världsklockor visas för din tidszon.
X-Geoclue-Reason[th]=
X-Geoclue-Reason[tr]=Saat diliminiz için dünya saatlerinin gösterilmesine olanak tanır.
X-Geoclue-Reason[vi]=Cho phép các đng h thế gii hin th cho múi gi ca bn.
X-Geoclue-Reason[zh_CN]=
X-Geoclue-Reason[zh_TW]=
X-Geoclue-Reason=Allows world clocks to be displayed for your time zone.
X-Flatpak=org.gnome.clocks

View file

@ -0,0 +1,36 @@
[Desktop Entry]
Name=Videos
Name[bn]=িি
Name[bn_IN]=িি
Name[ca]=Vídeos
Name[ca@valencia]=Vídeos
Name[en@shaw]=𐑝𐑦𐑛𐑰𐑴𐑟
Name[en_GB]=Videos
Name[pt]=Vídeos
Name[pt_BR]=Vídeos
Comment=Play movies
Comment[ca]=Reprodueix pel·lícules
Comment[ca@valencia]=Reprodueix pel·lícules
Comment[en_GB]=Play movies
Comment[pt]=Reproduzir filmes
Comment[pt_BR]=Reproduzir filmes
Keywords=Video;Movie;Film;Clip;Series;Player;DVD;TV;Disc;
Keywords[ca]=Vídeo;Pel·lícula;Film;Clip;Sèries;Reproductor;DVD;TV;Disc;
Keywords[ca@valencia]=Vídeo;Pel·lícula;Film;Clip;Sèries;Reproductor;DVD;TV;Disc;
Keywords[en_GB]=Video;Movie;Film;Clip;Series;Player;DVD;TV;Disc;
Keywords[pt]=Vídeo;Filme;Clip;Séries;Reprodutor;DVD;TV;Disc;
Keywords[pt_BR]=Vídeo;Filme;Clipe;Série;Reprodutor;DVD;TV;Disco;
Exec=true %U
Icon=totem
Terminal=false
Type=Application
Categories=GTK;GNOME;AudioVideo;Player;Video;
X-GNOME-DocPath=totem/totem.xml
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=totem
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.1
X-GNOME-Bugzilla-OtherBinaries=totem-video-thumbnailer;totem-audio-preview;
X-GNOME-Bugzilla-ExtraInfoScript=true
StartupNotify=true
MimeType=application/mxf;application/ogg;application/ram;application/sdp;application/smil;application/smil+xml;application/vnd.apple.mpegurl;application/vnd.ms-wpl;application/vnd.rn-realmedia;application/x-extension-m4a;application/x-extension-mp4;application/x-flac;application/x-flash-video;application/x-matroska;application/x-netshow-channel;application/x-ogg;application/x-quicktime-media-link;application/x-quicktimeplayer;application/x-shorten;application/x-smil;application/xspf+xml;audio/3gpp;audio/ac3;audio/AMR;audio/AMR-WB;audio/basic;audio/flac;audio/midi;audio/mp2;audio/mp4;audio/mpeg;audio/mpegurl;audio/ogg;audio/prs.sid;audio/vnd.rn-realaudio;audio/x-aiff;audio/x-ape;audio/x-flac;audio/x-gsm;audio/x-it;audio/x-m4a;audio/x-matroska;audio/x-mod;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-asf;audio/x-ms-asx;audio/x-ms-wax;audio/x-ms-wma;audio/x-musepack;audio/x-pn-aiff;audio/x-pn-au;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-pn-wav;audio/x-pn-windows-acm;audio/x-realaudio;audio/x-real-audio;audio/x-s3m;audio/x-sbc;audio/x-scpls;audio/x-speex;audio/x-stm;audio/x-tta;audio/x-wav;audio/x-wavpack;audio/x-vorbis;audio/x-vorbis+ogg;audio/x-xm;image/vnd.rn-realpix;image/x-pict;misc/ultravox;text/google-video-pointer;text/x-google-video-pointer;video/3gp;video/3gpp;video/dv;video/divx;video/fli;video/flv;video/mp2t;video/mp4;video/mp4v-es;video/mpeg;video/msvideo;video/ogg;video/quicktime;video/vivo;video/vnd.divx;video/vnd.mpegurl;video/vnd.rn-realvideo;video/vnd.vivo;video/webm;video/x-anim;video/x-avi;video/x-flc;video/x-fli;video/x-flic;video/x-flv;video/x-m4v;video/x-matroska;video/x-mpeg;video/x-mpeg2;video/x-ms-asf;video/x-ms-asx;video/x-msvideo;video/x-ms-wm;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvx;video/x-nsv;video/x-ogm+ogg;video/x-theora+ogg;video/x-totem-stream;x-content/video-dvd;x-content/video-vcd;x-content/video-svcd;x-scheme-handler/pnm;x-scheme-handler/mms;x-scheme-handler/net;x-scheme-handler/rtp;x-scheme-handler/rtmp;x-scheme-handler/rtsp;x-scheme-handler/mmsh;x-scheme-handler/uvox;x-scheme-handler/icy;x-scheme-handler/icyx;

View file

@ -0,0 +1,39 @@
[Desktop Entry]
Name=Help
Name[bn]=
Name[bn_IN]=
Name[ca]=Ajuda
Name[ca@valencia]=Ajuda
Name[en_CA]=Help
Name[en_GB]=Help
Name[eo]=Helpo
Name[pt]=Ajuda
Name[pt_BR]=Ajuda
Comment=Get help with GNOME
Comment[bn]=GNOME ি
Comment[bn_IN]=GNOME
Comment[ca]=Obtingueu ajuda per al GNOME
Comment[ca@valencia]=Obtingueu ajuda per al GNOME
Comment[en_CA]=Get help with GNOME
Comment[en_GB]=Get help with GNOME
Comment[eo]=Ricevi helpon pri GNOME
Comment[pt]=Obtenha ajuda com o GNOME
Comment[pt_BR]=Obtenha ajuda sobre o GNOME
Keywords=documentation;information;manual;
Keywords[ca]=documentació;informació;manual;
Keywords[ca@valencia]=documentació;informació;manual;
Keywords[eo]=dokumentado;informo;manlibro;gvidilo;
Keywords[pt]=documentação;informação;manual;
Keywords[pt_BR]=documentação;informação;informações;manual;
OnlyShowIn=GNOME;Unity;
Exec=true %u
Icon=help-browser
StartupNotify=true
Terminal=false
Type=Application
Categories=GNOME;GTK;Core;Documentation;Utility;
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=Yelp
X-GNOME-Bugzilla-Component=general
X-GNOME-Bugzilla-Version=3.10.0
MimeType=x-scheme-handler/ghelp;x-scheme-handler/help;x-scheme-handler/info;x-scheme-handler/man;

70
gio/tests/echo-server.c Normal file
View file

@ -0,0 +1,70 @@
#include <gio/gio.h>
#include <string.h>
#define MESSAGE "Welcome to the echo service!\n"
int port = 7777;
static GOptionEntry cmd_entries[] = {
{"port", 'p', 0, G_OPTION_ARG_INT, &port,
"Local port to bind to", NULL},
G_OPTION_ENTRY_NULL
};
static gboolean
handler (GThreadedSocketService *service,
GSocketConnection *connection,
GSocketListener *listener,
gpointer user_data)
{
GOutputStream *out;
GInputStream *in;
char buffer[1024];
gssize size;
out = g_io_stream_get_output_stream (G_IO_STREAM (connection));
in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
g_output_stream_write_all (out, MESSAGE, strlen (MESSAGE),
NULL, NULL, NULL);
while (0 < (size = g_input_stream_read (in, buffer,
sizeof buffer, NULL, NULL)))
g_output_stream_write (out, buffer, size, NULL, NULL);
return TRUE;
}
int
main (int argc, char *argv[])
{
GSocketService *service;
GOptionContext *context;
GError *error = NULL;
context = g_option_context_new (" - Test GSocket server stuff");
g_option_context_add_main_entries (context, cmd_entries, NULL);
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
service = g_threaded_socket_service_new (10);
if (!g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service),
port,
NULL,
&error))
{
g_printerr ("%s: %s\n", argv[0], error->message);
return 1;
}
g_print ("Echo service listening on port %d\n", port);
g_signal_connect (service, "run", G_CALLBACK (handler), NULL);
g_main_loop_run (g_main_loop_new (NULL, FALSE));
g_assert_not_reached ();
}

0
gio/tests/empty.txt Normal file
View file

View file

@ -0,0 +1,18 @@
/*** BEGIN comment ***/
<!-- @comment@ -->
/*** END comment ***/
/*** BEGIN file-header ***/
<schemalist>
/*** END file-header ***/
/*** BEGIN value-header ***/
<@type@ id='org.gtk.test.@EnumName@'>
/*** END value-header ***/
/*** BEGIN value-production ***/
<value nick='@valuenick@' value='@valuenum@'/>
/*** END value-production ***/
/*** BEGIN value-tail ***/
</@type@>
/*** END value-tail ***/
/*** BEGIN file-tail ***/
</schemalist>
/*** END file-tail ***/

View file

@ -0,0 +1,144 @@
/*
* Copyright (C) 2019 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: James Henstridge <james.henstridge@canonical.com>
*/
/* A stub implementation of xdg-document-portal covering enough to
* support g_document_portal_add_documents */
#include <glib.h>
#include <gio/gio.h>
#include <gio/gunixfdlist.h>
#include "fake-document-portal-generated.h"
static gboolean
on_handle_get_mount_point (FakeDocuments *object,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
fake_documents_complete_get_mount_point (object,
invocation,
"/document-portal");
return TRUE;
}
static gboolean
on_handle_add_full (FakeDocuments *object,
GDBusMethodInvocation *invocation,
GUnixFDList *o_path_fds,
guint flags,
const gchar *app_id,
const gchar * const *permissions,
gpointer user_data)
{
const gchar **doc_ids = NULL;
GVariant *extra_out = NULL;
gsize length, i;
if (o_path_fds != NULL)
length = g_unix_fd_list_get_length (o_path_fds);
else
length = 0;
doc_ids = g_new0 (const gchar *, length + 1 /* NULL terminator */);
for (i = 0; i < length; i++)
{
doc_ids[i] = "document-id";
}
extra_out = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0);
fake_documents_complete_add_full (object,
invocation,
NULL,
doc_ids,
extra_out);
g_free (doc_ids);
return TRUE;
}
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
FakeDocuments *interface;
GError *error = NULL;
g_test_message ("Acquired a message bus connection");
interface = fake_documents_skeleton_new ();
g_signal_connect (interface,
"handle-get-mount-point",
G_CALLBACK (on_handle_get_mount_point),
NULL);
g_signal_connect (interface,
"handle-add-full",
G_CALLBACK (on_handle_add_full),
NULL);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface),
connection,
"/org/freedesktop/portal/documents",
&error);
g_assert_no_error (error);
}
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
g_test_message ("Acquired the name %s", name);
}
static void
on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
g_test_message ("Lost the name %s", name);
}
gint
main (gint argc, gchar *argv[])
{
GMainLoop *loop;
guint id;
loop = g_main_loop_new (NULL, FALSE);
id = g_bus_own_name (G_BUS_TYPE_SESSION,
"org.freedesktop.portal.Documents",
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
loop,
NULL);
g_main_loop_run (loop);
g_bus_unown_name (id);
g_main_loop_unref (loop);
return 0;
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (C) 2021 Frederic Martinsons
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Frederic Martinsons <frederic.martinsons@gmail.com>
*/
/* A dummy service which just own a dbus name and implement a method to quit*/
#include <gio/gio.h>
#include <glib.h>
static GDBusNodeInfo *introspection_data = NULL;
static GMainLoop *loop = NULL;
static const gchar introspection_xml[] =
"<node>"
" <interface name='org.gtk.GDBus.FakeService'>"
" <method name='Quit'/>"
" </interface>"
"</node>";
static void
incoming_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
if (g_strcmp0 (method_name, "Quit") == 0)
{
g_dbus_method_invocation_return_value (invocation, NULL);
g_main_loop_quit (loop);
}
}
static const GDBusInterfaceVTable interface_vtable = {
incoming_method_call,
NULL,
NULL,
{ 0 }
};
static void
on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
guint registration_id;
GError *error = NULL;
g_test_message ("Acquired a message bus connection");
registration_id = g_dbus_connection_register_object (connection,
"/org/gtk/GDBus/FakeService",
introspection_data->interfaces[0],
&interface_vtable,
NULL, /* user_data */
NULL, /* user_data_free_func */
&error);
g_assert_no_error (error);
g_assert (registration_id > 0);
}
static void
on_name_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
g_test_message ("Acquired the name %s", name);
}
static void
on_name_lost (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
g_test_message ("Lost the name %s", name);
}
gint
main (gint argc, gchar *argv[])
{
guint id;
loop = g_main_loop_new (NULL, FALSE);
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL);
id = g_bus_own_name (G_BUS_TYPE_SESSION,
"org.gtk.GDBus.FakeService",
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
G_BUS_NAME_OWNER_FLAGS_REPLACE,
on_bus_acquired,
on_name_acquired,
on_name_lost,
loop,
NULL);
g_main_loop_run (loop);
g_bus_unown_name (id);
g_main_loop_unref (loop);
g_dbus_node_info_unref (introspection_data);
return 0;
}

3160
gio/tests/file.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,162 @@
#include <gio/gio.h>
static void
test_exact (void)
{
const char *exact_matches[] = {
"*",
"a::*",
"a::*,b::*",
"a::a,a::b",
"a::a,a::b,b::*"
};
GFileAttributeMatcher *matcher;
char *s;
guint i;
for (i = 0; i < G_N_ELEMENTS (exact_matches); i++)
{
matcher = g_file_attribute_matcher_new (exact_matches[i]);
s = g_file_attribute_matcher_to_string (matcher);
g_assert_cmpstr (exact_matches[i], ==, s);
g_free (s);
g_file_attribute_matcher_unref (matcher);
}
}
static void
test_equality (void)
{
struct {
const char *expected;
const char *actual;
} equals[] = {
/* star makes everything else go away */
{ "*", "*,*" },
{ "*", "*,a::*" },
{ "*", "*,a::b" },
{ "*", "a::*,*" },
{ "*", "a::b,*" },
{ "*", "a::b,*,a::*" },
/* a::* makes a::<anything> go away */
{ "a::*", "a::*,a::*" },
{ "a::*", "a::*,a::b" },
{ "a::*", "a::b,a::*" },
{ "a::*", "a::b,a::*,a::c" },
/* a::b does not allow duplicates */
{ "a::b", "a::b,a::b" },
{ "a::b,a::c", "a::b,a::c,a::b" },
/* stuff gets ordered in registration order */
{ "a::b,a::c", "a::c,a::b" },
{ "a::*,b::*", "b::*,a::*" },
};
GFileAttributeMatcher *matcher;
char *s;
guint i;
for (i = 0; i < G_N_ELEMENTS (equals); i++)
{
matcher = g_file_attribute_matcher_new (equals[i].actual);
s = g_file_attribute_matcher_to_string (matcher);
g_assert_cmpstr (equals[i].expected, ==, s);
g_free (s);
g_file_attribute_matcher_unref (matcher);
}
}
static void
test_subtract (void)
{
struct {
const char *attributes;
const char *subtract;
const char *result;
} subtractions[] = {
/* * subtracts everything */
{ "*", "*", NULL },
{ "a::*", "*", NULL },
{ "a::b", "*", NULL },
{ "a::b,a::c", "*", NULL },
{ "a::*,b::*", "*", NULL },
{ "a::*,b::c", "*", NULL },
{ "a::b,b::*", "*", NULL },
{ "a::b,b::c", "*", NULL },
{ "a::b,a::c,b::*", "*", NULL },
{ "a::b,a::c,b::c", "*", NULL },
/* a::* subtracts all a's */
{ "*", "a::*", "*" },
{ "a::*", "a::*", NULL },
{ "a::b", "a::*", NULL },
{ "a::b,a::c", "a::*", NULL },
{ "a::*,b::*", "a::*", "b::*" },
{ "a::*,b::c", "a::*", "b::c" },
{ "a::b,b::*", "a::*", "b::*" },
{ "a::b,b::c", "a::*", "b::c" },
{ "a::b,a::c,b::*", "a::*", "b::*" },
{ "a::b,a::c,b::c", "a::*", "b::c" },
/* a::b subtracts exactly that */
{ "*", "a::b", "*" },
{ "a::*", "a::b", "a::*" },
{ "a::b", "a::b", NULL },
{ "a::b,a::c", "a::b", "a::c" },
{ "a::*,b::*", "a::b", "a::*,b::*" },
{ "a::*,b::c", "a::b", "a::*,b::c" },
{ "a::b,b::*", "a::b", "b::*" },
{ "a::b,b::c", "a::b", "b::c" },
{ "a::b,a::c,b::*", "a::b", "a::c,b::*" },
{ "a::b,a::c,b::c", "a::b", "a::c,b::c" },
/* a::b,b::* subtracts both of those */
{ "*", "a::b,b::*", "*" },
{ "a::*", "a::b,b::*", "a::*" },
{ "a::b", "a::b,b::*", NULL },
{ "a::b,a::c", "a::b,b::*", "a::c" },
{ "a::*,b::*", "a::b,b::*", "a::*" },
{ "a::*,b::c", "a::b,b::*", "a::*" },
{ "a::b,b::*", "a::b,b::*", NULL },
{ "a::b,b::c", "a::b,b::*", NULL },
{ "a::b,a::c,b::*", "a::b,b::*", "a::c" },
{ "a::b,a::c,b::c", "a::b,b::*", "a::c" },
/* a::b,b::c should work, too */
{ "*", "a::b,b::c", "*" },
{ "a::*", "a::b,b::c", "a::*" },
{ "a::b", "a::b,b::c", NULL },
{ "a::b,a::c", "a::b,b::c", "a::c" },
{ "a::*,b::*", "a::b,b::c", "a::*,b::*" },
{ "a::*,b::c", "a::b,b::c", "a::*" },
{ "a::b,b::*", "a::b,b::c", "b::*" },
{ "a::b,b::c", "a::b,b::c", NULL },
{ "a::b,a::c,b::*", "a::b,b::c", "a::c,b::*" },
{ "a::b,a::c,b::c", "a::b,b::c", "a::c" },
};
GFileAttributeMatcher *matcher, *subtract, *result;
char *s;
guint i;
for (i = 0; i < G_N_ELEMENTS (subtractions); i++)
{
matcher = g_file_attribute_matcher_new (subtractions[i].attributes);
subtract = g_file_attribute_matcher_new (subtractions[i].subtract);
result = g_file_attribute_matcher_subtract (matcher, subtract);
s = g_file_attribute_matcher_to_string (result);
g_assert_cmpstr (subtractions[i].result, ==, s);
g_free (s);
g_file_attribute_matcher_unref (matcher);
g_file_attribute_matcher_unref (subtract);
g_file_attribute_matcher_unref (result);
}
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/fileattributematcher/exact", test_exact);
g_test_add_func ("/fileattributematcher/equality", test_equality);
g_test_add_func ("/fileattributematcher/subtract", test_subtract);
return g_test_run ();
}

269
gio/tests/filter-cat.c Normal file
View file

@ -0,0 +1,269 @@
/* GIO - GLib Input, Output and Streaming Library
*
* Copyright (C) 2009 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include <stdio.h>
#include <locale.h>
#include <errno.h>
#include <glib.h>
#include <gio/gio.h>
#ifdef G_OS_UNIX
#include <unistd.h>
#endif
#ifdef G_OS_WIN32
#include <io.h>
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#endif
static gchar **locations = NULL;
static char *from_charset = NULL;
static char *to_charset = NULL;
static gboolean decompress = FALSE;
static gboolean compress = FALSE;
static gboolean gzip = FALSE;
static gboolean fallback = FALSE;
static GOptionEntry entries[] = {
{"decompress", 0, 0, G_OPTION_ARG_NONE, &decompress, "decompress", NULL},
{"compress", 0, 0, G_OPTION_ARG_NONE, &compress, "compress", NULL},
{"gzip", 0, 0, G_OPTION_ARG_NONE, &gzip, "use gzip format", NULL},
{"from-charset", 0, 0, G_OPTION_ARG_STRING, &from_charset, "from charset", NULL},
{"to-charset", 0, 0, G_OPTION_ARG_STRING, &to_charset, "to charset", NULL},
{"fallback", 0, 0, G_OPTION_ARG_NONE, &fallback, "use fallback", NULL},
{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &locations, "locations", NULL},
G_OPTION_ENTRY_NULL
};
static void
decompressor_file_info_notify_cb (GZlibDecompressor *decompressor,
GParamSpec *pspec,
gpointer data)
{
GFileInfo *file_info;
const gchar *filename;
file_info = g_zlib_decompressor_get_file_info (decompressor);
if (file_info == NULL)
return;
filename = g_file_info_get_name (file_info);
if (filename)
g_printerr ("Decompressor filename: %s\n", filename);
}
static void
cat (GFile * file)
{
GInputStream *in;
char buffer[1024 * 8 + 1];
char *p;
gssize res;
gboolean close_res;
GError *error;
GConverter *conv;
GCharsetConverter *cconv = NULL;
error = NULL;
in = (GInputStream *) g_file_read (file, NULL, &error);
if (in == NULL)
{
/* Translators: the first %s is the program name, the second one */
/* is the URI of the file, the third is the error message. */
g_printerr ("%s: %s: error opening file: %s\n",
g_get_prgname (), g_file_get_uri (file), error->message);
g_error_free (error);
return;
}
if (decompress)
{
GInputStream *old;
conv = (GConverter *)g_zlib_decompressor_new (gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB);
old = in;
in = (GInputStream *) g_converter_input_stream_new (in, conv);
g_signal_connect (conv, "notify::file-info", G_CALLBACK (decompressor_file_info_notify_cb), NULL);
g_object_unref (conv);
g_object_unref (old);
}
if (from_charset && to_charset)
{
cconv = g_charset_converter_new (to_charset, from_charset, &error);
conv = (GConverter *)cconv;
if (conv)
{
GInputStream *old;
g_charset_converter_set_use_fallback (cconv, fallback);
old = in;
in = (GInputStream *) g_converter_input_stream_new (in, conv);
g_object_unref (conv);
g_object_unref (old);
}
else
{
g_printerr ("%s: Can't convert between charsets: %s\n",
g_get_prgname (), error->message);
}
}
if (compress)
{
GInputStream *old;
GFileInfo *in_file_info;
in_file_info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_NAME ","
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
NULL,
&error);
if (in_file_info == NULL)
{
g_printerr ("%s: %s: error reading file info: %s\n",
g_get_prgname (), g_file_get_uri (file), error->message);
g_error_free (error);
return;
}
conv = (GConverter *)g_zlib_compressor_new(gzip?G_ZLIB_COMPRESSOR_FORMAT_GZIP:G_ZLIB_COMPRESSOR_FORMAT_ZLIB, -1);
g_zlib_compressor_set_file_info (G_ZLIB_COMPRESSOR (conv), in_file_info);
old = in;
in = (GInputStream *) g_converter_input_stream_new (in, conv);
g_object_unref (conv);
g_object_unref (old);
g_object_unref (in_file_info);
}
while (1)
{
res =
g_input_stream_read (in, buffer, sizeof (buffer) - 1, NULL, &error);
if (res > 0)
{
gssize written;
p = buffer;
while (res > 0)
{
written = write (STDOUT_FILENO, p, res);
if (written == -1 && errno != EINTR)
{
/* Translators: the first %s is the program name, the */
/* second one is the URI of the file. */
g_printerr ("%s: %s, error writing to stdout",
g_get_prgname (), g_file_get_uri (file));
goto out;
}
res -= written;
p += written;
}
}
else if (res < 0)
{
g_printerr ("%s: %s: error reading: %s\n",
g_get_prgname (), g_file_get_uri (file),
error->message);
g_error_free (error);
error = NULL;
break;
}
else if (res == 0)
break;
}
out:
close_res = g_input_stream_close (in, NULL, &error);
if (!close_res)
{
g_printerr ("%s: %s:error closing: %s\n",
g_get_prgname (), g_file_get_uri (file), error->message);
g_error_free (error);
}
if (cconv != NULL && fallback)
{
guint num = g_charset_converter_get_num_fallbacks (cconv);
if (num > 0)
g_printerr ("Number of fallback errors: %u\n", num);
}
}
int
main (int argc, char *argv[])
{
GError *error = NULL;
GOptionContext *context = NULL;
GFile *file;
int i;
context =
g_option_context_new ("LOCATION... - concatenate LOCATIONS "
"to standard output.");
g_option_context_set_summary (context, "filter files");
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
g_option_context_parse (context, &argc, &argv, &error);
g_option_context_free (context);
if (error != NULL)
{
g_printerr ("Error parsing commandline options: %s\n", error->message);
g_printerr ("\n");
g_printerr ("Try \"%s --help\" for more information.",
g_get_prgname ());
g_printerr ("\n");
g_error_free(error);
return 1;
}
if (!locations)
{
g_printerr ("%s: missing locations", g_get_prgname ());
g_printerr ("\n");
g_printerr ("Try \"%s --help\" for more information.",
g_get_prgname ());
g_printerr ("\n");
return 1;
}
i = 0;
do
{
file = g_file_new_for_commandline_arg (locations[i]);
cat (file);
g_object_unref (file);
}
while (locations[++i] != NULL);
return 0;
}

391
gio/tests/filter-streams.c Normal file
View file

@ -0,0 +1,391 @@
/*
* Copyright © 2009 Codethink Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*
* Author: Ryan Lortie <desrt@desrt.ca>
*/
#include <string.h>
#include <glib/glib.h>
#include <gio/gio.h>
/* GFilterInputStream and GFilterOutputStream are abstract, so define
* minimal subclasses for testing. (This used to use
* GBufferedInputStream and GBufferedOutputStream, but those have
* their own test program, and they override some methods, meaning the
* core filter stream functionality wasn't getting fully tested.)
*/
GType test_filter_input_stream_get_type (void);
GType test_filter_output_stream_get_type (void);
#define TEST_TYPE_FILTER_INPUT_STREAM (test_filter_input_stream_get_type ())
#define TEST_FILTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_INPUT_STREAM, TestFilterInputStream))
#define TEST_TYPE_FILTER_OUTPUT_STREAM (test_filter_output_stream_get_type ())
#define TEST_FILTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_OUTPUT_STREAM, TestFilterOutputStream))
typedef GFilterInputStream TestFilterInputStream;
typedef GFilterInputStreamClass TestFilterInputStreamClass;
typedef GFilterOutputStream TestFilterOutputStream;
typedef GFilterOutputStreamClass TestFilterOutputStreamClass;
G_DEFINE_TYPE (TestFilterInputStream, test_filter_input_stream, G_TYPE_FILTER_INPUT_STREAM)
G_DEFINE_TYPE (TestFilterOutputStream, test_filter_output_stream, G_TYPE_FILTER_OUTPUT_STREAM)
static void
test_filter_input_stream_init (TestFilterInputStream *stream)
{
}
static void
test_filter_input_stream_class_init (TestFilterInputStreamClass *klass)
{
}
static void
test_filter_output_stream_init (TestFilterOutputStream *stream)
{
}
static void
test_filter_output_stream_class_init (TestFilterOutputStreamClass *klass)
{
}
/* Now the tests */
static void
test_input_filter (void)
{
GInputStream *base, *f1, *f2, *s;
gboolean close_base;
gchar buf[1024];
GError *error = NULL;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=568394");
base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
"base-stream", base,
"close-base-stream", FALSE,
NULL);
f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
"base-stream", base,
NULL);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f1));
g_assert (!g_input_stream_is_closed (f2));
g_object_get (f1,
"close-base-stream", &close_base,
"base-stream", &s,
NULL);
g_assert (!close_base);
g_assert (s == base);
g_object_unref (s);
g_object_unref (f1);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
g_input_stream_skip (f2, 3, NULL, &error);
g_assert_no_error (error);
memset (buf, 0, 1024);
g_input_stream_read_all (f2, buf, 1024, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (buf, ==, "defghijk");
g_object_unref (f2);
g_assert (g_input_stream_is_closed (base));
g_object_unref (base);
}
static void
test_output_filter (void)
{
GOutputStream *base, *f1, *f2;
base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
"base-stream", base,
"close-base-stream", FALSE,
NULL);
f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
"base-stream", base,
NULL);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f1));
g_assert (!g_output_stream_is_closed (f2));
g_object_unref (f1);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
g_object_unref (f2);
g_assert (g_output_stream_is_closed (base));
g_object_unref (base);
}
gpointer expected_obj;
gpointer expected_data;
gboolean callback_happened;
GMainLoop *loop;
static void
return_result_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GAsyncResult **ret = user_data;
*ret = g_object_ref (result);
g_main_loop_quit (loop);
}
static void
in_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
g_assert (object == expected_obj);
g_assert (user_data == expected_data);
g_assert (callback_happened == FALSE);
g_input_stream_close_finish (expected_obj, result, &error);
g_assert (error == NULL);
callback_happened = TRUE;
g_main_loop_quit (loop);
}
static void
test_input_async (void)
{
GInputStream *base, *f1, *f2;
char buf[20];
GAsyncResult *result = NULL;
GError *error = NULL;
loop = g_main_loop_new (NULL, FALSE);
base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyz", -1, NULL);
f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
"base-stream", base,
"close-base-stream", FALSE,
NULL);
f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
"base-stream", base,
NULL);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
memset (buf, 0, sizeof (buf));
g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
g_main_loop_run (loop);
g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 10);
g_assert_cmpstr (buf, ==, "abcdefghij");
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 10);
g_input_stream_skip_async (f2, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
g_main_loop_run (loop);
g_assert_cmpint (g_input_stream_skip_finish (f2, result, &error), ==, 10);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 20);
memset (buf, 0, sizeof (buf));
g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
g_main_loop_run (loop);
g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 6);
g_assert_cmpstr (buf, ==, "uvwxyz");
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f1));
g_assert (!g_input_stream_is_closed (f2));
expected_obj = f1;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_input_stream_close_async (f1, 0, NULL, in_cb, expected_data);
g_assert (callback_happened == FALSE);
g_main_loop_run (loop);
g_assert (callback_happened == TRUE);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f1);
g_assert (!g_input_stream_is_closed (base));
g_assert (!g_input_stream_is_closed (f2));
expected_obj = f2;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_input_stream_close_async (f2, 0, NULL, in_cb, expected_data);
g_assert (callback_happened == FALSE);
g_main_loop_run (loop);
g_assert (callback_happened == TRUE);
g_assert (g_input_stream_is_closed (base));
g_assert (g_input_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f2);
g_assert (g_input_stream_is_closed (base));
g_object_unref (base);
g_main_loop_unref (loop);
}
static void
out_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
GError *error = NULL;
g_assert (object == expected_obj);
g_assert (user_data == expected_data);
g_assert (callback_happened == FALSE);
g_output_stream_close_finish (expected_obj, result, &error);
g_assert (error == NULL);
callback_happened = TRUE;
g_main_loop_quit (loop);
}
static void
test_output_async (void)
{
GOutputStream *base, *f1, *f2;
GAsyncResult *result = NULL;
GError *error = NULL;
loop = g_main_loop_new (NULL, FALSE);
base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
"base-stream", base,
"close-base-stream", FALSE,
NULL);
f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
"base-stream", base,
NULL);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
g_output_stream_write_async (f1, "abcdefghijklm", 13, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
g_main_loop_run (loop);
g_assert_cmpint (g_output_stream_write_finish (f1, result, &error), ==, 13);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 13);
g_output_stream_write_async (f2, "nopqrstuvwxyz", 13, G_PRIORITY_DEFAULT,
NULL, return_result_cb, &result);
g_main_loop_run (loop);
g_assert_cmpint (g_output_stream_write_finish (f2, result, &error), ==, 13);
g_assert_no_error (error);
g_clear_object (&result);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 26);
g_output_stream_write (base, "\0", 1, NULL, &error);
g_assert_no_error (error);
g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrstuvwxyz");
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f1));
g_assert (!g_output_stream_is_closed (f2));
expected_obj = f1;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_output_stream_close_async (f1, 0, NULL, out_cb, expected_data);
g_assert (callback_happened == FALSE);
g_main_loop_run (loop);
g_assert (callback_happened == TRUE);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f1);
g_assert (!g_output_stream_is_closed (base));
g_assert (!g_output_stream_is_closed (f2));
expected_obj = f2;
expected_data = g_malloc (20);
callback_happened = FALSE;
g_output_stream_close_async (f2, 0, NULL, out_cb, expected_data);
g_assert (callback_happened == FALSE);
g_main_loop_run (loop);
g_assert (callback_happened == TRUE);
g_assert (g_output_stream_is_closed (base));
g_assert (g_output_stream_is_closed (f2));
g_free (expected_data);
g_object_unref (f2);
g_assert (g_output_stream_is_closed (base));
g_object_unref (base);
g_main_loop_unref (loop);
}
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/filter-stream/input", test_input_filter);
g_test_add_func ("/filter-stream/output", test_output_filter);
g_test_add_func ("/filter-stream/async-input", test_input_async);
g_test_add_func ("/filter-stream/async-output", test_output_async);
return g_test_run();
}

View file

@ -0,0 +1,273 @@
/* Testcase for bug in GIO function g_file_query_filesystem_info()
* Author: Nelson Benítez León
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <errno.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <gio/gunixmounts.h>
static gboolean
run (GError **error,
const gchar *argv0,
...)
{
GPtrArray *args;
const gchar *arg;
va_list ap;
GSubprocess *subprocess;
gchar *command_line = NULL;
gboolean success;
args = g_ptr_array_new ();
va_start (ap, argv0);
g_ptr_array_add (args, (gchar *) argv0);
while ((arg = va_arg (ap, const gchar *)))
g_ptr_array_add (args, (gchar *) arg);
g_ptr_array_add (args, NULL);
va_end (ap);
command_line = g_strjoinv (" ", (gchar **) args->pdata);
g_test_message ("Running command `%s`", command_line);
g_free (command_line);
subprocess = g_subprocess_newv ((const gchar * const *) args->pdata, G_SUBPROCESS_FLAGS_NONE, error);
g_ptr_array_free (args, TRUE);
if (subprocess == NULL)
return FALSE;
success = g_subprocess_wait_check (subprocess, NULL, error);
g_object_unref (subprocess);
return success;
}
static void
assert_remove (const gchar *file)
{
if (g_remove (file) != 0)
g_error ("failed to remove %s: %s", file, g_strerror (errno));
}
static gboolean
fuse_module_loaded (void)
{
char *contents = NULL;
gboolean ret;
if (!g_file_get_contents ("/proc/modules", &contents, NULL, NULL) ||
contents == NULL)
{
g_free (contents);
return FALSE;
}
ret = (strstr (contents, "\nfuse ") != NULL);
g_free (contents);
return ret;
}
static void
test_filesystem_readonly (gconstpointer with_mount_monitor)
{
GFileInfo *file_info;
GFile *mounted_file;
GUnixMountMonitor *mount_monitor = NULL;
gchar *bindfs, *fusermount;
gchar *curdir, *dir_to_mount, *dir_mountpoint;
gchar *file_in_mount, *file_in_mountpoint;
GError *error = NULL;
/* installed by package 'bindfs' in Fedora */
bindfs = g_find_program_in_path ("bindfs");
/* installed by package 'fuse' in Fedora */
fusermount = g_find_program_in_path ("fusermount");
if (bindfs == NULL || fusermount == NULL)
{
/* We need these because "mount --bind" requires root privileges */
g_test_skip ("'bindfs' and 'fusermount' commands are needed to run this test");
g_free (fusermount);
g_free (bindfs);
return;
}
/* If the fuse module is loaded but there's no /dev/fuse, then we're
* we're probably in a rootless container and won't be able to
* use bindfs to run our tests */
if (fuse_module_loaded () &&
!g_file_test ("/dev/fuse", G_FILE_TEST_EXISTS))
{
g_test_skip ("fuse support is needed to run this test (rootless container?)");
g_free (fusermount);
g_free (bindfs);
return;
}
curdir = g_get_current_dir ();
dir_to_mount = g_strdup_printf ("%s/dir_bindfs_to_mount", curdir);
file_in_mount = g_strdup_printf ("%s/example.txt", dir_to_mount);
dir_mountpoint = g_strdup_printf ("%s/dir_bindfs_mountpoint", curdir);
g_mkdir (dir_to_mount, 0777);
g_mkdir (dir_mountpoint, 0777);
if (! g_file_set_contents (file_in_mount, "Example", -1, NULL))
{
g_test_skip ("Failed to create file needed to proceed further with the test");
g_free (dir_mountpoint);
g_free (file_in_mount);
g_free (dir_to_mount);
g_free (curdir);
g_free (fusermount);
g_free (bindfs);
return;
}
if (with_mount_monitor)
mount_monitor = g_unix_mount_monitor_get ();
/* Use bindfs, which does not need root privileges, to mount the contents of one dir
* into another dir (and do the mount as readonly as per passed '-o ro' option) */
if (!run (&error, bindfs, "-n", "-o", "ro", dir_to_mount, dir_mountpoint, NULL))
{
gchar *skip_message = g_strdup_printf ("Failed to run bindfs to set up test: %s", error->message);
g_test_skip (skip_message);
g_free (skip_message);
g_clear_error (&error);
g_clear_object (&mount_monitor);
g_free (dir_mountpoint);
g_free (file_in_mount);
g_free (dir_to_mount);
g_free (curdir);
g_free (fusermount);
g_free (bindfs);
return;
}
/* Let's check now, that the file is in indeed in a readonly filesystem */
file_in_mountpoint = g_strdup_printf ("%s/example.txt", dir_mountpoint);
mounted_file = g_file_new_for_path (file_in_mountpoint);
if (with_mount_monitor)
{
/* Let UnixMountMonitor process its 'mounts-changed'
* signal triggered by mount operation above */
while (g_main_context_iteration (NULL, FALSE));
}
file_info = g_file_query_filesystem_info (mounted_file,
G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, NULL, &error);
g_assert_no_error (error);
g_assert_nonnull (file_info);
if (! g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY))
{
g_test_skip ("Failed to create readonly file needed to proceed further with the test");
g_clear_object (&file_info);
g_clear_object (&mounted_file);
g_free (file_in_mountpoint);
g_clear_object (&mount_monitor);
g_free (dir_mountpoint);
g_free (file_in_mount);
g_free (dir_to_mount);
g_free (curdir);
g_free (fusermount);
g_free (bindfs);
return;
}
/* Now we unmount, and mount again but this time rw (not readonly) */
run (&error, fusermount, "-z", "-u", dir_mountpoint, NULL);
g_assert_no_error (error);
run (&error, bindfs, "-n", dir_to_mount, dir_mountpoint, NULL);
g_assert_no_error (error);
if (with_mount_monitor)
{
/* Let UnixMountMonitor process its 'mounts-changed' signal
* triggered by mount/umount operations above */
while (g_main_context_iteration (NULL, FALSE));
}
/* Now let's test if GIO will report the new filesystem state */
g_clear_object (&file_info);
g_clear_object (&mounted_file);
mounted_file = g_file_new_for_path (file_in_mountpoint);
file_info = g_file_query_filesystem_info (mounted_file,
G_FILE_ATTRIBUTE_FILESYSTEM_READONLY, NULL, &error);
g_assert_no_error (error);
g_assert_nonnull (file_info);
g_assert_false (g_file_info_get_attribute_boolean (file_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY));
/* Clean up */
g_clear_object (&mount_monitor);
g_clear_object (&file_info);
g_clear_object (&mounted_file);
run (&error, fusermount, "-z", "-u", dir_mountpoint, NULL);
g_assert_no_error (error);
assert_remove (file_in_mount);
assert_remove (dir_to_mount);
assert_remove (dir_mountpoint);
g_free (bindfs);
g_free (fusermount);
g_free (curdir);
g_free (dir_to_mount);
g_free (dir_mountpoint);
g_free (file_in_mount);
g_free (file_in_mountpoint);
}
int
main (int argc, char *argv[])
{
/* To avoid unnecessary D-Bus calls, see http://goo.gl/ir56j2 */
g_setenv ("GIO_USE_VFS", "local", FALSE);
g_test_init (&argc, &argv, NULL);
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=787731");
g_test_add_data_func ("/g-file-info-filesystem-readonly/test-fs-ro",
GINT_TO_POINTER (FALSE), test_filesystem_readonly);
/* This second test is using a running GUnixMountMonitor, so the calls to:
* g_unix_mount_get(&time_read) - To fill the time_read parameter
* g_unix_mounts_changed_since()
*
* made from inside g_file_query_filesystem_info() will use the mount_poller_time
* from the monitoring of /proc/self/mountinfo , while in the previous test new
* created timestamps are returned from those g_unix_mount* functions. */
g_test_add_data_func ("/g-file-info-filesystem-readonly/test-fs-ro-with-mount-monitor",
GINT_TO_POINTER (TRUE), test_filesystem_readonly);
return g_test_run ();
}

908
gio/tests/g-file-info.c Normal file
View file

@ -0,0 +1,908 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include "config.h"
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#ifdef G_OS_WIN32
#include <stdio.h>
#include <glib/gstdio.h>
#include <windows.h>
#include <shlobj.h>
#include <io.h> /* for _get_osfhandle */
#endif
#define TEST_NAME "Prilis zlutoucky kun"
#define TEST_DISPLAY_NAME "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"
#define TEST_SIZE 0xFFFFFFF0
static void
test_assigned_values (GFileInfo *info)
{
const char *name, *display_name, *mistake;
guint64 size;
GFileType type;
/* Test for attributes presence */
g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME));
g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME));
g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME));
/* Retrieve data back and compare */
name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME);
display_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
mistake = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
type = g_file_info_get_file_type (info);
g_assert_cmpstr (name, ==, TEST_NAME);
g_assert_cmpstr (display_name, ==, TEST_DISPLAY_NAME);
g_assert_null (mistake);
g_assert_cmpint (size, ==, TEST_SIZE);
g_assert_cmpstr (name, ==, g_file_info_get_name (info));
g_assert_cmpstr (display_name, ==, g_file_info_get_display_name (info));
g_assert_cmpint (size, ==, g_file_info_get_size (info) );
g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY);
}
static void
test_g_file_info (void)
{
GFileInfo *info;
GFileInfo *info_dup;
GFileInfo *info_copy;
char **attr_list;
GFileAttributeMatcher *matcher;
info = g_file_info_new ();
/* Test for empty instance */
attr_list = g_file_info_list_attributes (info, NULL);
g_assert_nonnull (attr_list);
g_assert_null (*attr_list);
g_strfreev (attr_list);
g_file_info_set_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME);
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, TEST_DISPLAY_NAME);
g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE, TEST_SIZE);
g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
/* The attr list should not be empty now */
attr_list = g_file_info_list_attributes (info, NULL);
g_assert_nonnull (attr_list);
g_assert_nonnull (*attr_list);
g_strfreev (attr_list);
test_assigned_values (info);
/* Test dups */
info_dup = g_file_info_dup (info);
g_assert_nonnull (info_dup);
test_assigned_values (info_dup);
info_copy = g_file_info_new ();
g_file_info_copy_into (info_dup, info_copy);
g_assert_nonnull (info_copy);
test_assigned_values (info_copy);
/* Test remove attribute */
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
g_file_info_set_attribute_int32 (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 10);
g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INT32);
g_assert_cmpint (g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), !=, G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
g_file_info_remove_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INVALID);
matcher = g_file_attribute_matcher_new (G_FILE_ATTRIBUTE_STANDARD_NAME ","
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
g_assert_true (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME));
g_assert_false (g_file_attribute_matcher_matches_only (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME));
g_assert_false (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_file_info_set_attribute_mask (info, matcher);
g_file_attribute_matcher_unref (matcher);
g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME));
g_object_unref (info);
g_object_unref (info_dup);
g_object_unref (info_copy);
}
static void
test_g_file_info_modification_time (void)
{
GFile *file = NULL;
GFileIOStream *io_stream = NULL;
GFileInfo *info = NULL;
GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL;
GTimeSpan ts;
GError *error = NULL;
g_test_summary ("Test that getting the modification time of a file works.");
file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
g_assert_no_error (error);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
/* Check the modification time is retrievable. */
dt = g_file_info_get_modification_date_time (info);
g_assert_nonnull (dt);
/* Try again with microsecond precision. */
g_clear_object (&info);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
dt_usecs = g_file_info_get_modification_date_time (info);
g_assert_nonnull (dt_usecs);
ts = g_date_time_difference (dt_usecs, dt);
g_assert_cmpint (ts, >=, 0);
g_assert_cmpint (ts, <, G_USEC_PER_SEC);
/* Try round-tripping the modification time. */
dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
g_file_info_set_modification_date_time (info, dt_new);
dt_new_usecs = g_file_info_get_modification_date_time (info);
ts = g_date_time_difference (dt_new_usecs, dt_new);
g_assert_cmpint (ts, ==, 0);
/* Clean up. */
g_clear_object (&io_stream);
g_file_delete (file, NULL, NULL);
g_clear_object (&file);
g_clear_object (&info);
g_date_time_unref (dt);
g_date_time_unref (dt_usecs);
g_date_time_unref (dt_new);
g_date_time_unref (dt_new_usecs);
}
static void
test_g_file_info_access_time (void)
{
GFile *file = NULL;
GFileIOStream *io_stream = NULL;
GFileInfo *info = NULL;
GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
*dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
GTimeSpan ts;
GError *error = NULL;
g_test_summary ("Test that getting the access time of a file works.");
file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
g_assert_no_error (error);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_ACCESS,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
/* Check the access time is retrievable. */
dt = g_file_info_get_access_date_time (info);
g_assert_nonnull (dt);
/* Try again with microsecond precision. */
g_clear_object (&info);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
dt_usecs = g_file_info_get_access_date_time (info);
g_assert_nonnull (dt_usecs);
ts = g_date_time_difference (dt_usecs, dt);
g_assert_cmpint (ts, >, 0);
g_assert_cmpint (ts, <, G_USEC_PER_SEC);
/* Try round-tripping the access time. */
dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
g_file_info_set_access_date_time (info, dt_new);
dt_new_usecs = g_file_info_get_access_date_time (info);
ts = g_date_time_difference (dt_new_usecs, dt_new);
g_assert_cmpint (ts, ==, 0);
// try with a negative timestamp
dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
g_file_info_set_access_date_time (info, dt_before_epoch);
dt_before_epoch_returned = g_file_info_get_access_date_time (info);
ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
g_assert_cmpint (ts, ==, 0);
/* Clean up. */
g_clear_object (&io_stream);
g_file_delete (file, NULL, NULL);
g_clear_object (&file);
g_clear_object (&info);
g_date_time_unref (dt);
g_date_time_unref (dt_usecs);
g_date_time_unref (dt_new);
g_date_time_unref (dt_new_usecs);
g_date_time_unref (dt_before_epoch);
g_date_time_unref (dt_before_epoch_returned);
}
static void
test_g_file_info_creation_time (void)
{
GFile *file = NULL;
GFileIOStream *io_stream = NULL;
GFileInfo *info = NULL;
GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
*dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
GTimeSpan ts;
GError *error = NULL;
g_test_summary ("Test that getting the creation time of a file works.");
file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
g_assert_no_error (error);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_CREATED,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
/* Check the creation time is retrievable. */
dt = g_file_info_get_creation_date_time (info);
if (!dt)
{
g_test_skip ("Skipping testing creation time as its not supported by the kernel");
g_file_delete (file, NULL, NULL);
g_clear_object (&file);
g_clear_object (&info);
return;
}
/* Try again with microsecond precision. */
g_clear_object (&info);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, &error);
g_assert_no_error (error);
dt_usecs = g_file_info_get_creation_date_time (info);
g_assert_nonnull (dt_usecs);
ts = g_date_time_difference (dt_usecs, dt);
g_assert_cmpint (ts, >, 0);
g_assert_cmpint (ts, <, G_USEC_PER_SEC);
/* Try round-tripping the creation time. */
dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
g_file_info_set_creation_date_time (info, dt_new);
dt_new_usecs = g_file_info_get_creation_date_time (info);
ts = g_date_time_difference (dt_new_usecs, dt_new);
g_assert_cmpint (ts, ==, 0);
// try with a negative timestamp
dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
g_file_info_set_creation_date_time (info, dt_before_epoch);
dt_before_epoch_returned = g_file_info_get_creation_date_time (info);
ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
g_assert_cmpint (ts, ==, 0);
/* Clean up. */
g_clear_object (&io_stream);
g_file_delete (file, NULL, NULL);
g_clear_object (&file);
g_clear_object (&info);
g_date_time_unref (dt);
g_date_time_unref (dt_usecs);
g_date_time_unref (dt_new);
g_date_time_unref (dt_new_usecs);
g_date_time_unref (dt_before_epoch);
g_date_time_unref (dt_before_epoch_returned);
}
#ifdef G_OS_WIN32
static void
test_internal_enhanced_stdio (void)
{
char *p0, *p1, *ps;
gboolean try_sparse;
gchar *tmp_dir_root;
wchar_t *tmp_dir_root_w;
gchar *c;
DWORD fsflags;
FILE *f;
SYSTEMTIME st;
FILETIME ft;
HANDLE h;
GStatBuf statbuf_p0, statbuf_p1, statbuf_ps;
GFile *gf_p0, *gf_p1, *gf_ps;
GFileInfo *fi_p0, *fi_p1, *fi_ps;
guint64 size_p0, alsize_p0, size_ps, alsize_ps;
const gchar *id_p0;
const gchar *id_p1;
guint64 time_p0;
gchar *tmp_dir;
wchar_t *programdata_dir_w;
wchar_t *users_dir_w;
static const GUID folder_id_programdata =
{ 0x62AB5D82, 0xFDC1, 0x4DC3, { 0xA9, 0xDD, 0x07, 0x0D, 0x1D, 0x49, 0x5D, 0x97 } };
static const GUID folder_id_users =
{ 0x0762D272, 0xC50A, 0x4BB0, { 0xA3, 0x82, 0x69, 0x7D, 0xCD, 0x72, 0x9B, 0x80 } };
GDateTime *dt = NULL, *dt2 = NULL;
GTimeSpan ts;
/* Just before SYSTEMTIME limit (Jan 1 30827) */
const gint64 one_sec_before_systemtime_limit = 910670515199;
gboolean retval;
GError *local_error = NULL;
programdata_dir_w = NULL;
SHGetKnownFolderPath (&folder_id_programdata, 0, NULL, &programdata_dir_w);
users_dir_w = NULL;
SHGetKnownFolderPath (&folder_id_users, 0, NULL, &users_dir_w);
if (programdata_dir_w != NULL && users_dir_w != NULL)
{
gchar *programdata;
gchar *users_dir;
gchar *allusers;
gchar *commondata;
GFile *gf_programdata, *gf_allusers, *gf_commondata;
GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target, *fi_commondata, *fi_commondata_target;
GFileType ft_allusers;
GFileType ft_allusers_target;
GFileType ft_programdata;
GFileType ft_commondata;
gboolean allusers_is_symlink;
gboolean commondata_is_symlink;
gboolean commondata_is_mount_point;
guint32 allusers_reparse_tag;
guint32 commondata_reparse_tag;
const gchar *id_allusers;
const gchar *id_allusers_target;
const gchar *id_commondata_target;
const gchar *id_programdata;
const gchar *allusers_target;
const gchar *commondata_target;
/* C:/ProgramData */
programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL);
g_assert_nonnull (programdata);
/* C:/Users */
users_dir = g_utf16_to_utf8 (users_dir_w, -1, NULL, NULL, NULL);
g_assert_nonnull (users_dir);
/* "C:/Users/All Users" is a known directory symlink
* for "C:/ProgramData".
*/
allusers = g_build_filename (users_dir, "All Users", NULL);
/* "C:/Users/All Users/Application Data" is a known
* junction for "C:/ProgramData"
*/
commondata = g_build_filename (allusers, "Application Data", NULL);
/* We don't test g_stat() and g_lstat() on these directories,
* because it is pointless - there's no way to tell that these
* functions behave correctly in this case
* (st_ino is useless, so we can't tell apart g_stat() and g_lstat()
* results; st_mode is also useless as it does not support S_ISLNK;
* and these directories have no interesting properties other
* than [not] being symlinks).
*/
gf_programdata = g_file_new_for_path (programdata);
gf_allusers = g_file_new_for_path (allusers);
gf_commondata = g_file_new_for_path (commondata);
fi_programdata = g_file_query_info (gf_programdata,
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
fi_allusers_target = g_file_query_info (gf_allusers,
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
fi_allusers = g_file_query_info (gf_allusers,
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, NULL);
fi_commondata = g_file_query_info (gf_commondata,
G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT ","
G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, NULL);
fi_commondata_target = g_file_query_info (gf_commondata,
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE));
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
ft_allusers = g_file_info_get_file_type (fi_allusers);
ft_allusers_target = g_file_info_get_file_type (fi_allusers_target);
ft_programdata = g_file_info_get_file_type (fi_programdata);
ft_commondata = g_file_info_get_file_type (fi_commondata);
g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_DIRECTORY);
g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY);
g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY);
g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_DIRECTORY);
allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
commondata_is_symlink = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
commondata_is_mount_point = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT);
commondata_reparse_tag = g_file_info_get_attribute_uint32 (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
g_assert_true (allusers_is_symlink);
g_assert_cmpuint (allusers_reparse_tag, ==, IO_REPARSE_TAG_SYMLINK);
g_assert_true (commondata_is_symlink);
g_assert_true (commondata_is_mount_point);
g_assert_cmpuint (commondata_reparse_tag, ==, IO_REPARSE_TAG_MOUNT_POINT);
id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE);
id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE);
id_commondata_target = g_file_info_get_attribute_string (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE);
id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE);
g_assert_cmpstr (id_allusers_target, ==, id_programdata);
g_assert_cmpstr (id_commondata_target, ==, id_programdata);
g_assert_cmpstr (id_allusers, !=, id_programdata);
allusers_target = g_file_info_get_symlink_target (fi_allusers);
g_assert_true (g_str_has_suffix (allusers_target, "ProgramData"));
commondata_target = g_file_info_get_symlink_target (fi_commondata);
g_assert_true (g_str_has_suffix (commondata_target, "ProgramData"));
g_object_unref (fi_allusers);
g_object_unref (fi_allusers_target);
g_object_unref (fi_commondata);
g_object_unref (fi_commondata_target);
g_object_unref (fi_programdata);
g_object_unref (gf_allusers);
g_object_unref (gf_commondata);
g_object_unref (gf_programdata);
g_free (allusers);
g_free (commondata);
g_free (users_dir);
g_free (programdata);
}
if (programdata_dir_w)
CoTaskMemFree (programdata_dir_w);
if (users_dir_w)
CoTaskMemFree (users_dir_w);
tmp_dir = g_dir_make_tmp ("glib_stdio_testXXXXXX", NULL);
g_assert_nonnull (tmp_dir);
/* Technically, this isn't necessary - we already assume NTFS, because of
* symlink support, and NTFS also supports sparse files. Still, given
* the amount of unusual I/O APIs called in this test, checking for
* sparse file support of the filesystem where temp directory is
* doesn't seem to be out of place.
*/
try_sparse = FALSE;
tmp_dir_root = g_strdup (tmp_dir);
/* We need "C:\\" or "C:/", with a trailing [back]slash */
for (c = tmp_dir_root; c && c[0] && c[1]; c++)
if (c[0] == ':')
{
c[2] = '\0';
break;
}
tmp_dir_root_w = g_utf8_to_utf16 (tmp_dir_root, -1, NULL, NULL, NULL);
g_assert_nonnull (tmp_dir_root_w);
g_free (tmp_dir_root);
g_assert_true (GetVolumeInformationW (tmp_dir_root_w, NULL, 0, NULL, NULL, &fsflags, NULL, 0));
g_free (tmp_dir_root_w);
try_sparse = (fsflags & FILE_SUPPORTS_SPARSE_FILES) == FILE_SUPPORTS_SPARSE_FILES;
p0 = g_build_filename (tmp_dir, "zool", NULL);
p1 = g_build_filename (tmp_dir, "looz", NULL);
ps = g_build_filename (tmp_dir, "sparse", NULL);
if (try_sparse)
{
FILE_SET_SPARSE_BUFFER ssb;
FILE_ZERO_DATA_INFORMATION zdi;
g_remove (ps);
f = g_fopen (ps, "wb");
g_assert_nonnull (f);
h = (HANDLE) _get_osfhandle (fileno (f));
g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
ssb.SetSparse = TRUE;
g_assert_true (DeviceIoControl (h,
FSCTL_SET_SPARSE,
&ssb, sizeof (ssb),
NULL, 0, NULL, NULL));
/* Make it a sparse file that starts with 4GBs of zeros */
zdi.FileOffset.QuadPart = 0;
zdi.BeyondFinalZero.QuadPart = 0xFFFFFFFFULL + 1;
g_assert_true (DeviceIoControl (h,
FSCTL_SET_ZERO_DATA,
&zdi, sizeof (zdi),
NULL, 0, NULL, NULL));
/* Let's not keep this seemingly 4GB monster around
* longer than we absolutely need to. Do all operations
* without assertions, then remove the file immediately.
*/
_fseeki64 (f, 0xFFFFFFFFULL, SEEK_SET);
fprintf (f, "Hello 4GB World!");
fflush (f);
fclose (f);
memset (&statbuf_ps, 0, sizeof (statbuf_ps));
g_stat (ps, &statbuf_ps);
gf_ps = g_file_new_for_path (ps);
fi_ps = g_file_query_info (gf_ps,
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
g_remove (ps);
g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE);
alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
/* allocated size should small (usually - size of the FS cluster,
* let's assume it's less than 1 gigabyte),
* size should be more than 4 gigabytes,
* st_size should not exceed its 0xFFFFFFFF 32-bit limit,
* and should be nonzero (this also detects a failed g_stat() earlier).
*/
g_assert_cmpuint (alsize_ps, <, 0x40000000);
g_assert_cmpuint (size_ps, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
g_assert_cmpuint (statbuf_ps.st_size, >, 0);
#if defined(_WIN64)
g_assert_cmpuint (statbuf_ps.st_size, ==, G_GUINT64_CONSTANT (0x10000000f));
#else
g_assert_cmpuint (statbuf_ps.st_size, <=, 0xFFFFFFFF);
#endif
g_object_unref (fi_ps);
g_object_unref (gf_ps);
}
/* Wa-a-ay past 02/07/2106 @ 6:28am (UTC),
* which is the date corresponding to 0xFFFFFFFF + 1.
* This is easier to check than Y2038 (0x80000000 + 1),
* since there's no need to worry about signedness this way.
*/
st.wYear = 2106;
st.wMonth = 2;
st.wDay = 9;
st.wHour = 0;
st.wMinute = 0;
st.wSecond = 0;
st.wMilliseconds = 0;
g_assert_true (SystemTimeToFileTime (&st, &ft));
f = g_fopen (p0, "w");
g_assert_nonnull (f);
h = (HANDLE) _get_osfhandle (fileno (f));
g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
fprintf (f, "1");
fflush (f);
g_assert_true (SetFileTime (h, &ft, &ft, &ft));
fclose (f);
f = g_fopen (p1, "w");
g_assert_nonnull (f);
fclose (f);
memset (&statbuf_p0, 0, sizeof (statbuf_p0));
memset (&statbuf_p1, 0, sizeof (statbuf_p1));
g_assert_cmpint (g_stat (p0, &statbuf_p0), ==, 0);
g_assert_cmpint (g_stat (p1, &statbuf_p1), ==, 0);
gf_p0 = g_file_new_for_path (p0);
gf_p1 = g_file_new_for_path (p1);
fi_p0 = g_file_query_info (gf_p0,
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
fi_p1 = g_file_query_info (gf_p1,
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
G_FILE_ATTRIBUTE_ID_FILE ","
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED));
g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC));
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE));
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE));
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED));
g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC));
size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE);
alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
/* size should be 1, allocated size should be something else
* (could be 0 or the size of the FS cluster, but never 1).
*/
g_assert_cmpuint (size_p0, ==, statbuf_p0.st_size);
g_assert_cmpuint (size_p0, ==, 1);
g_assert_cmpuint (alsize_p0, !=, size_p0);
id_p0 = g_file_info_get_attribute_string (fi_p0, G_FILE_ATTRIBUTE_ID_FILE);
id_p1 = g_file_info_get_attribute_string (fi_p1, G_FILE_ATTRIBUTE_ID_FILE);
/* st_ino from W32 stat() is useless for file identification.
* It will be either 0, or it will be the same for both files.
*/
g_assert_cmpint (statbuf_p0.st_ino, ==, statbuf_p1.st_ino);
g_assert_cmpstr (id_p0, !=, id_p1);
time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED);
/* Check that GFileInfo doesn't suffer from Y2106 problem.
* Don't check stat(), as its contents may vary depending on
* the host platform architecture
* (time fields are 32-bit on 32-bit Windows,
* and 64-bit on 64-bit Windows, usually),
* so it *can* pass this test in some cases.
*/
g_assert_cmpuint (time_p0, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
dt = g_file_info_get_modification_date_time (fi_p0);
g_assert_nonnull (dt);
dt2 = g_date_time_add (dt, G_USEC_PER_SEC / 100 * 200);
g_object_unref (fi_p0);
fi_p0 = g_file_info_new ();
g_file_info_set_modification_date_time (fi_p0, dt2);
g_assert_true (g_file_set_attributes_from_info (gf_p0,
fi_p0,
G_FILE_QUERY_INFO_NONE,
NULL,
NULL));
g_date_time_unref (dt2);
g_object_unref (fi_p0);
fi_p0 = g_file_query_info (gf_p0,
G_FILE_ATTRIBUTE_TIME_MODIFIED ","
G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
G_FILE_QUERY_INFO_NONE,
NULL, NULL);
dt2 = g_file_info_get_modification_date_time (fi_p0);
ts = g_date_time_difference (dt2, dt);
g_assert_cmpint (ts, >, 0);
g_assert_cmpint (ts, <, G_USEC_PER_SEC / 100 * 300);
g_date_time_unref (dt);
g_date_time_unref (dt2);
g_file_info_set_attribute_uint64 (fi_p0,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
one_sec_before_systemtime_limit);
g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0);
g_assert_true (g_file_set_attributes_from_info (gf_p0,
fi_p0,
G_FILE_QUERY_INFO_NONE,
NULL,
NULL));
g_file_info_set_attribute_uint64 (fi_p0,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
one_sec_before_systemtime_limit + G_USEC_PER_SEC * 2);
g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0);
retval = g_file_set_attributes_from_info (gf_p0,
fi_p0,
G_FILE_QUERY_INFO_NONE,
NULL,
&local_error);
g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
g_assert_false (retval);
g_clear_error (&local_error);
g_object_unref (fi_p0);
g_object_unref (fi_p1);
g_object_unref (gf_p0);
g_object_unref (gf_p1);
g_remove (p0);
g_remove (p1);
g_free (p0);
g_free (p1);
g_rmdir (tmp_dir);
}
#endif
static void
test_xattrs (void)
{
GFile *file = NULL;
GFileIOStream *stream = NULL;
GFileInfo *file_info0 = NULL, *file_info1 = NULL;
GError *local_error = NULL;
g_test_summary ("Test setting and getting escaped xattrs");
/* Create a temporary file; no need to write anything to it. */
file = g_file_new_tmp ("g-file-info-test-xattrs-XXXXXX", &stream, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (file);
g_io_stream_close (G_IO_STREAM (stream), NULL, NULL);
g_object_unref (stream);
/* Check the existing xattrs. */
file_info0 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (file_info0);
/* Set some new xattrs, with escaping and some embedded nuls. */
g_file_info_set_attribute_string (file_info0, "xattr::escaped", "hello\\x82\\x80\\xbd");
g_file_info_set_attribute_string (file_info0, "xattr::string", "hi there");
g_file_info_set_attribute_string (file_info0, "xattr::embedded-nul", "hi\\x00there");
g_file_set_attributes_from_info (file, file_info0, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
g_object_unref (file_info0);
if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
{
g_test_skip ("xattrs not supported on this file system");
g_clear_error (&local_error);
}
else
{
g_assert_no_error (local_error);
/* Check they were set properly. */
file_info1 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
g_assert_no_error (local_error);
g_assert_nonnull (file_info1);
g_assert_true (g_file_info_has_namespace (file_info1, "xattr"));
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::escaped"), ==, "hello\\x82\\x80\\xbd");
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::string"), ==, "hi there");
g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::embedded-nul"), ==, "hi\\x00there");
g_object_unref (file_info1);
}
/* Tidy up. */
g_file_delete (file, NULL, NULL);
g_object_unref (file);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info);
g_test_add_func ("/g-file-info/test_g_file_info/modification-time", test_g_file_info_modification_time);
g_test_add_func ("/g-file-info/test_g_file_info/access-time", test_g_file_info_access_time);
g_test_add_func ("/g-file-info/test_g_file_info/creation-time", test_g_file_info_creation_time);
#ifdef G_OS_WIN32
g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio);
#endif
g_test_add_func ("/g-file-info/xattrs", test_xattrs);
return g_test_run();
}

537
gio/tests/g-file.c Normal file
View file

@ -0,0 +1,537 @@
/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Authors: Tomas Bzatek <tbzatek@redhat.com>
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
struct TestPathsWithOper {
const char *path1;
gboolean equal;
gboolean use_uri;
const char *path2;
const char *path3;
};
/* TODO:
* - test on Windows
*
**/
static void
test_g_file_new_null (void)
{
const char *paths[] = {"/",
"/tmp///",
"/non-existent-file",
"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88",
NULL
};
const char *uris[] = {"file:///",
"file:///tmp///",
"non-existent-uri:///some-dir/",
"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88",
NULL
};
GFile *file = NULL;
int i = 0;
while (paths[i])
{
file = g_file_new_for_path (paths[i++]);
g_assert (file != NULL);
g_object_unref (file);
}
i = 0;
while (uris[i])
{
file = g_file_new_for_uri (uris[i++]);
g_assert (file != NULL);
g_object_unref(file);
}
}
static gboolean
compare_two_files (const gboolean use_uri, const char *path1, const char *path2)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
gboolean equal;
if (use_uri)
{
file1 = g_file_new_for_uri (path1);
file2 = g_file_new_for_uri (path2);
}
else
{
file1 = g_file_new_for_path (path1);
file2 = g_file_new_for_path (path2);
}
g_assert (file1 != NULL);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
return equal;
}
static void
test_g_file_new_for_path (void)
{
const struct TestPathsWithOper cmp_paths[] =
{
{"/", TRUE, 0, "/./", NULL },
{"//", TRUE, 0, "//", NULL },
{"//", TRUE, 0, "//./", NULL },
{"/", TRUE, 0, "/.//", NULL },
{"/", TRUE, 0, "/././", NULL },
{"/tmp", TRUE, 0, "/tmp/d/../", NULL },
{"/", TRUE, 0, "/somedir/../", NULL },
{"/", FALSE, 0, "/somedir/.../", NULL },
{"//tmp/dir1", TRUE, 0, "//tmp/dir1", NULL },
{"/tmp/dir1", TRUE, 0, "///tmp/dir1", NULL },
{"/tmp/dir1", TRUE, 0, "////tmp/dir1", NULL },
{"/tmp/dir1", TRUE, 0, "/tmp/./dir1", NULL },
{"/tmp/dir1", TRUE, 0, "/tmp//dir1", NULL },
{"/tmp/dir1", TRUE, 0, "/tmp///dir1///", NULL },
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, 0, "/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", NULL }
};
guint i;
for (i = 0; i < G_N_ELEMENTS (cmp_paths); i++)
{
gboolean equal = compare_two_files (FALSE, cmp_paths[i].path1, cmp_paths[i].path2);
g_assert_cmpint (equal, ==, cmp_paths[i].equal);
}
}
static void
test_g_file_new_for_uri (void)
{
const struct TestPathsWithOper cmp_uris[] = {
{"file:///", TRUE, 0, "file:///./", NULL },
{"file:////", TRUE, 0, "file:////", NULL },
{"file:////", TRUE, 0, "file:////./", NULL },
{"file:///", TRUE, 0, "file:///.//", NULL },
{"file:///", TRUE, 0, "file:///././", NULL },
{"file:///tmp", TRUE, 0, "file:///tmp/d/../", NULL },
{"file:///", TRUE, 0, "file:///somedir/../", NULL },
{"file:///", FALSE, 0, "file:///somedir/.../", NULL },
{"file:////tmp/dir1", TRUE, 0, "file:////tmp/dir1", NULL },
{"file:///tmp/dir1", TRUE, 0, "file:///tmp/./dir1", NULL },
{"file:///tmp/dir1", TRUE, 0, "file:///tmp//dir1", NULL },
{"file:///tmp/dir1", TRUE, 0, "file:///tmp///dir1///", NULL },
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, 0, "file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", NULL }
};
guint i;
for (i = 0; i < G_N_ELEMENTS (cmp_uris); i++)
{
gboolean equal = compare_two_files (TRUE, cmp_uris[i].path1, cmp_uris[i].path2);
g_assert_cmpint (equal, ==, cmp_uris[i].equal);
}
}
static gboolean
dup_equals (const gboolean use_uri, const char *path)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
gboolean equal;
if (use_uri)
file1 = g_file_new_for_uri (path);
else
file1 = g_file_new_for_path (path);
g_assert (file1 != NULL);
file2 = g_file_dup (file1);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
return equal;
}
static void
test_g_file_dup (void)
{
const struct TestPathsWithOper dup_paths[] =
{
{"/", 0, FALSE, "", NULL },
{"file:///", 0, TRUE, "", NULL },
{"totalnonsense", 0, FALSE, "", NULL },
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "", NULL },
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", 0, TRUE, "", NULL },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (dup_paths); i++)
{
gboolean equal = dup_equals (dup_paths[i].use_uri, dup_paths[i].path1);
g_assert (equal == TRUE);
}
}
static gboolean
parse_check_utf8 (const gboolean use_uri, const char *path, const char *result_parse_name)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
char *parsed_name;
gboolean is_utf8_valid;
gboolean equal;
if (use_uri)
file1 = g_file_new_for_uri (path);
else
file1 = g_file_new_for_path (path);
g_assert (file1 != NULL);
parsed_name = g_file_get_parse_name (file1);
g_assert (parsed_name != NULL);
/* UTF-8 validation */
is_utf8_valid = g_utf8_validate (parsed_name, -1, NULL);
g_assert (is_utf8_valid == TRUE);
if (result_parse_name)
g_assert_cmpstr (parsed_name, ==, result_parse_name);
file2 = g_file_parse_name (parsed_name);
g_assert (file2 != NULL);
equal = g_file_equal (file1, file2);
g_object_unref (file1);
g_object_unref (file2);
g_free (parsed_name);
return equal;
}
static void
test_g_file_get_parse_name_utf8 (void)
{
const struct TestPathsWithOper strings[] =
{
{G_DIR_SEPARATOR_S, 0, FALSE, G_DIR_SEPARATOR_S, NULL },
{"file:///", 0, TRUE, G_DIR_SEPARATOR_S, NULL },
{"totalnonsense", 0, FALSE, NULL, NULL },
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, NULL, NULL /* Depends on local file encoding */},
{"file:///invalid%08/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, TRUE, "file:///invalid%08/UTF-8%20p\xc5\x99\xc3\xadli\xc5\xa1%20\xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd%20k\xc5\xaf\xc5\x88", NULL },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (strings); i++)
{
gboolean equal = parse_check_utf8 (strings[i].use_uri, strings[i].path1, strings[i].path2);
g_assert (equal == TRUE);
}
}
static char *
resolve_arg (const gboolean is_uri_only, const char *arg)
{
GFile *file1 = NULL;
char *uri = NULL;
char *path = NULL;
char *s = NULL;
file1 = g_file_new_for_commandline_arg (arg);
g_assert (file1 != NULL);
/* Test if we get URI string */
uri = g_file_get_uri (file1);
g_assert_cmpstr (uri, !=, NULL);
g_printerr ("%s\n",uri);
/* Test if we get correct value of the local path */
path = g_file_get_path (file1);
if (is_uri_only)
g_assert_cmpstr (path, ==, NULL);
else
g_assert (g_path_is_absolute (path) == TRUE);
/* Get the URI scheme and compare it with expected one */
s = g_file_get_uri_scheme (file1);
g_object_unref (file1);
g_free (uri);
g_free (path);
return s;
}
static void
test_g_file_new_for_commandline_arg (void)
{
/* TestPathsWithOper.use_uri represents IsURIOnly here */
const struct TestPathsWithOper arg_data[] =
{
{"./", 0, FALSE, "file", NULL },
{"../", 0, FALSE, "file", NULL },
{"/tmp", 0, FALSE, "file", NULL },
{"//UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", 0, FALSE, "file", NULL },
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", 0, FALSE, "file", NULL },
#if 0
{"http://www.gtk.org/", 0, TRUE, "http", NULL },
{"ftp://user:pass@ftp.gimp.org/", 0, TRUE, "ftp", NULL },
#endif
};
GFile *file;
char *resolved;
char *cwd;
guint i;
for (i = 0; i < G_N_ELEMENTS (arg_data); i++)
{
char *s = resolve_arg (arg_data[i].use_uri, arg_data[i].path1);
g_assert_cmpstr (s, ==, arg_data[i].path2);
g_free (s);
}
/* Manual test for getting correct cwd */
file = g_file_new_for_commandline_arg ("./");
resolved = g_file_get_path (file);
cwd = g_get_current_dir ();
g_assert_cmpstr (resolved, ==, cwd);
g_object_unref (file);
g_free (resolved);
g_free (cwd);
}
static char*
get_relative_path (const gboolean use_uri, const gboolean should_have_prefix, const char *dir1, const char *dir2)
{
GFile *file1 = NULL;
GFile *file2 = NULL;
GFile *file3 = NULL;
gboolean has_prefix = FALSE;
char *relative_path = NULL;
if (use_uri)
{
file1 = g_file_new_for_uri (dir1);
file2 = g_file_new_for_uri (dir2);
}
else
{
file1 = g_file_new_for_path (dir1);
file2 = g_file_new_for_path (dir2);
}
g_assert (file1 != NULL);
g_assert (file2 != NULL);
has_prefix = g_file_has_prefix (file2, file1);
g_printerr ("%s %s\n", dir1, dir2);
g_assert (has_prefix == should_have_prefix);
relative_path = g_file_get_relative_path (file1, file2);
if (should_have_prefix)
{
g_assert (relative_path != NULL);
file3 = g_file_resolve_relative_path (file1, relative_path);
g_assert (g_file_equal (file2, file3) == TRUE);
}
if (file1)
g_object_unref (file1);
if (file2)
g_object_unref (file2);
if (file3)
g_object_unref (file3);
return relative_path;
}
static void
test_g_file_has_prefix (void)
{
/* TestPathsWithOper.equal represents here if the dir belongs to the directory structure */
const struct TestPathsWithOper dirs[] =
{
/* path1 equal uri path2 path3 */
{"/dir1", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"/dir1", TRUE, FALSE, "/dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"/dir1/", TRUE, FALSE, "/dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"/tmp/", FALSE, FALSE, "/something/", NULL},
{"/dir1/dir2", FALSE, FALSE, "/dir1/", NULL},
{"//dir1/new", TRUE, FALSE, "//dir1/new/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", TRUE, FALSE, "/dir/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/dir2", "dir2"},
{"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3/", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"file:///dir1", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"file:///dir1/", TRUE, TRUE, "file:///dir1/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"file:///tmp/", FALSE, TRUE, "file:///something/", NULL},
{"file:///dir1/dir2", FALSE, TRUE, "file:///dir1/", NULL},
{"file:////dir1/new", TRUE, TRUE, "file:////dir1/new/dir2/dir3", "dir2" G_DIR_SEPARATOR_S "dir3"},
{"file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88", TRUE, TRUE, "file:///dir/UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/dir2", "dir2"},
#if 0
{"dav://www.gtk.org/plan/", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "meetings/20071218.txt"},
{"dav://www.gtk.org/plan/meetings", TRUE, TRUE, "dav://www.gtk.org/plan/meetings/20071218.txt", "20071218.txt"},
#endif
};
guint i;
for (i = 0; i < G_N_ELEMENTS (dirs); i++)
{
char *s = get_relative_path (dirs[i].use_uri, dirs[i].equal, dirs[i].path1, dirs[i].path2);
if (dirs[i].equal)
g_assert_cmpstr (s, ==, dirs[i].path3);
g_free (s);
}
}
static void
roundtrip_parent_child (const gboolean use_uri, const gboolean under_root_descending,
const char *path, const char *dir_holder)
{
GFile *files[6] = {NULL};
guint i;
if (use_uri)
{
files[0] = g_file_new_for_uri (path);
files[1] = g_file_new_for_uri (path);
}
else
{
files[0] = g_file_new_for_path (path);
files[1] = g_file_new_for_path (path);
}
g_assert (files[0] != NULL);
g_assert (files[1] != NULL);
files[2] = g_file_get_child (files[1], dir_holder);
g_assert (files[2] != NULL);
files[3] = g_file_get_parent (files[2]);
g_assert (files[3] != NULL);
g_assert (g_file_equal (files[3], files[0]) == TRUE);
files[4] = g_file_get_parent (files[3]);
/* Don't go lower beyond the root */
if (under_root_descending)
g_assert (files[4] == NULL);
else
{
g_assert (files[4] != NULL);
files[5] = g_file_get_child (files[4], dir_holder);
g_assert (files[5] != NULL);
g_assert (g_file_equal (files[5], files[0]) == TRUE);
}
for (i = 0; i < G_N_ELEMENTS (files); i++)
{
if (files[i])
g_object_unref (files[i]);
}
}
static void
test_g_file_get_parent_child (void)
{
const struct TestPathsWithOper paths[] =
{
/* path root_desc uri dir_holder */
{"/dir1/dir", FALSE, FALSE, "dir", NULL },
{"/dir", FALSE, FALSE, "dir", NULL },
{"/", TRUE, FALSE, "dir", NULL },
{"/UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88/", FALSE, FALSE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL },
{"file:///dir1/dir", FALSE, TRUE, "dir", NULL },
{"file:///dir", FALSE, TRUE, "dir", NULL },
{"file:///", TRUE, TRUE, "dir", NULL },
{"file:///UTF-8%20p%C5%99%C3%ADli%C5%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%BD%20k%C5%AF%C5%88/", FALSE, TRUE, "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88", NULL },
{"dav://www.gtk.org/plan/meetings", FALSE, TRUE, "meetings", NULL },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (paths); i++)
roundtrip_parent_child (paths[i].use_uri, paths[i].equal, paths[i].path1, paths[i].path2);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
/* Testing whether g_file_new_for_path() or g_file_new_for_uri() always returns non-NULL result */
g_test_add_func ("/g-file/test_g_file_new_null", test_g_file_new_null);
/* Testing whether the g_file_new_for_path() correctly canonicalizes strings and two files equals (g_file_equal()) */
g_test_add_func ("/g-file/test_g_file_new_for_path", test_g_file_new_for_path);
/* Testing whether the g_file_new_for_uri() correctly canonicalizes strings and two files equals (g_file_equal()) */
g_test_add_func ("/g-file/test_g_file_new_for_uri", test_g_file_new_for_uri);
/* Testing g_file_dup() equals original file via g_file_equal() */
g_test_add_func ("/g-file/test_g_file_dup", test_g_file_dup);
/* Testing g_file_get_parse_name() to return correct UTF-8 string */
g_test_add_func ("/g-file/test_g_file_get_parse_name_utf8", test_g_file_get_parse_name_utf8);
/* Testing g_file_new_for_commandline_arg() for correct relavive path resolution and correct path/URI guess */
g_test_add_func ("/g-file/test_g_file_new_for_commandline_arg", test_g_file_new_for_commandline_arg);
/* Testing g_file_has_prefix(), g_file_get_relative_path() and g_file_resolve_relative_path() to return and process correct relative paths */
g_test_add_func ("/g-file/test_g_file_has_prefix", test_g_file_has_prefix);
/* Testing g_file_get_parent() and g_file_get_child() */
g_test_add_func ("/g-file/test_g_file_get_parent_child", test_g_file_get_parent_child);
return g_test_run();
}

622
gio/tests/g-icon.c Normal file
View file

@ -0,0 +1,622 @@
/* GLib testing framework examples and tests
*
* Copyright (C) 2008 Red Hat, Inc.
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*
* Authors: David Zeuthen <davidz@redhat.com>
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_g_icon_to_string (void)
{
GIcon *icon;
GIcon *icon2;
GIcon *icon3;
GIcon *icon4;
GIcon *icon5;
GEmblem *emblem1;
GEmblem *emblem2;
const char *uri;
GFile *location;
char *data;
GError *error;
gint origin;
GIcon *i;
GFile *file;
error = NULL;
/* check that GFileIcon and GThemedIcon serialize to the encoding specified */
uri = "file:///some/native/path/to/an/icon.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
g_object_get (icon, "file", &file, NULL);
g_assert (file == location);
g_object_unref (file);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "some" G_DIR_SEPARATOR_S "native" G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "an" G_DIR_SEPARATOR_S "icon.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
uri = "file:///some/native/path/to/an/icon with spaces.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "some" G_DIR_SEPARATOR_S "native" G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "an" G_DIR_SEPARATOR_S "icon with spaces.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
uri = "sftp:///some/non-native/path/to/an/icon.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#if 0
uri = "sftp:///some/non-native/path/to/an/icon with spaces.png";
location = g_file_new_for_uri (uri);
icon = g_file_icon_new (location);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///some/non-native/path/to/an/icon%20with%20spaces.png");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#endif
icon = g_themed_icon_new_with_default_fallbacks ("some-icon-symbolic");
g_themed_icon_append_name (G_THEMED_ICON (icon), "some-other-icon");
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, ". GThemedIcon "
"some-icon-symbolic some-symbolic some-other-icon some-other some "
"some-icon some-other-icon-symbolic some-other-symbolic");
g_free (data);
g_object_unref (icon);
icon = g_themed_icon_new ("network-server");
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "network-server");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new_with_default_fallbacks ("network-server");
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, ". GThemedIcon network-server network network-server-symbolic network-symbolic");
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
/* Check that we can serialize from well-known specified formats */
icon = g_icon_new_for_string ("network-server%", &error);
g_assert_no_error (error);
icon2 = g_themed_icon_new ("network-server%");
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
icon = g_icon_new_for_string ("/path/to/somewhere.png", &error);
g_assert_no_error (error);
location = g_file_new_for_commandline_arg ("/path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
icon = g_icon_new_for_string ("/path/to/somewhere with whitespace.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, G_DIR_SEPARATOR_S "path" G_DIR_SEPARATOR_S "to" G_DIR_SEPARATOR_S "somewhere with whitespace.png");
g_free (data);
location = g_file_new_for_commandline_arg ("/path/to/somewhere with whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
location = g_file_new_for_commandline_arg ("/path/to/somewhere%20with%20whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (!g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
g_object_unref (icon);
icon = g_icon_new_for_string ("sftp:///path/to/somewhere.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere.png");
g_free (data);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
#if 0
icon = g_icon_new_for_string ("sftp:///path/to/somewhere with whitespace.png", &error);
g_assert_no_error (error);
data = g_icon_to_string (icon);
g_assert_cmpstr (data, ==, "sftp:///path/to/somewhere%20with%20whitespace.png");
g_free (data);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere with whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere%20with%20whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
g_object_unref (icon);
#endif
/* Check that GThemedIcon serialization works */
icon = g_themed_icon_new ("network-server");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new ("icon name with whitespace");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new_with_default_fallbacks ("network-server-xyz");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon, icon2));
g_free (data);
g_object_unref (icon);
g_object_unref (icon2);
/* Check that GEmblemedIcon serialization works */
icon = g_themed_icon_new ("face-smirk");
icon2 = g_themed_icon_new ("emblem-important");
g_themed_icon_append_name (G_THEMED_ICON (icon2), "emblem-shared");
location = g_file_new_for_uri ("file:///some/path/somewhere.png");
icon3 = g_file_icon_new (location);
g_object_unref (location);
emblem1 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_DEVICE);
emblem2 = g_emblem_new_with_origin (icon3, G_EMBLEM_ORIGIN_LIVEMETADATA);
icon4 = g_emblemed_icon_new (icon, emblem1);
g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2);
data = g_icon_to_string (icon4);
icon5 = g_icon_new_for_string (data, &error);
g_assert_no_error (error);
g_assert (g_icon_equal (icon4, icon5));
g_object_get (emblem1, "origin", &origin, "icon", &i, NULL);
g_assert (origin == G_EMBLEM_ORIGIN_DEVICE);
g_assert (i == icon2);
g_object_unref (i);
g_object_unref (emblem1);
g_object_unref (emblem2);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
g_object_unref (icon5);
g_free (data);
}
static void
test_g_icon_serialize (void)
{
GIcon *icon;
GIcon *icon2;
GIcon *icon3;
GIcon *icon4;
GIcon *icon5;
GEmblem *emblem1;
GEmblem *emblem2;
GFile *location;
GVariant *data;
gint origin;
GIcon *i;
/* Check that we can deserialize from well-known specified formats */
data = g_variant_new_string ("network-server%");
icon = g_icon_deserialize (g_variant_ref_sink (data));
g_variant_unref (data);
icon2 = g_themed_icon_new ("network-server%");
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
data = g_variant_new_string ("/path/to/somewhere.png");
icon = g_icon_deserialize (g_variant_ref_sink (data));
g_variant_unref (data);
location = g_file_new_for_commandline_arg ("/path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
data = g_variant_new_string ("/path/to/somewhere with whitespace.png");
icon = g_icon_deserialize (g_variant_ref_sink (data));
g_variant_unref (data);
location = g_file_new_for_commandline_arg ("/path/to/somewhere with whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
location = g_file_new_for_commandline_arg ("/path/to/somewhere%20with%20whitespace.png");
icon2 = g_file_icon_new (location);
g_assert (!g_icon_equal (icon, icon2));
g_object_unref (location);
g_object_unref (icon2);
g_object_unref (icon);
data = g_variant_new_string ("sftp:///path/to/somewhere.png");
icon = g_icon_deserialize (g_variant_ref_sink (data));
g_variant_unref (data);
location = g_file_new_for_commandline_arg ("sftp:///path/to/somewhere.png");
icon2 = g_file_icon_new (location);
g_assert (g_icon_equal (icon, icon2));
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (location);
/* Check that GThemedIcon serialization works */
icon = g_themed_icon_new ("network-server");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_serialize (icon);
icon2 = g_icon_deserialize (data);
g_assert (g_icon_equal (icon, icon2));
g_variant_unref (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new ("icon name with whitespace");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_serialize (icon);
icon2 = g_icon_deserialize (data);
g_assert (g_icon_equal (icon, icon2));
g_variant_unref (data);
g_object_unref (icon);
g_object_unref (icon2);
icon = g_themed_icon_new_with_default_fallbacks ("network-server-xyz");
g_themed_icon_append_name (G_THEMED_ICON (icon), "computer");
data = g_icon_serialize (icon);
icon2 = g_icon_deserialize (data);
g_assert (g_icon_equal (icon, icon2));
g_variant_unref (data);
g_object_unref (icon);
g_object_unref (icon2);
/* Check that GEmblemedIcon serialization works */
icon = g_themed_icon_new ("face-smirk");
icon2 = g_themed_icon_new ("emblem-important");
g_themed_icon_append_name (G_THEMED_ICON (icon2), "emblem-shared");
location = g_file_new_for_uri ("file:///some/path/somewhere.png");
icon3 = g_file_icon_new (location);
g_object_unref (location);
emblem1 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_DEVICE);
emblem2 = g_emblem_new_with_origin (icon3, G_EMBLEM_ORIGIN_LIVEMETADATA);
icon4 = g_emblemed_icon_new (icon, emblem1);
g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2);
data = g_icon_serialize (icon4);
icon5 = g_icon_deserialize (data);
g_assert (g_icon_equal (icon4, icon5));
g_object_get (emblem1, "origin", &origin, "icon", &i, NULL);
g_assert (origin == G_EMBLEM_ORIGIN_DEVICE);
g_assert (i == icon2);
g_object_unref (i);
g_object_unref (emblem1);
g_object_unref (emblem2);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
g_object_unref (icon5);
g_variant_unref (data);
}
static void
test_themed_icon (void)
{
GIcon *icon1, *icon2, *icon3, *icon4;
const gchar *const *names;
const gchar *names2[] = { "first-symbolic", "testicon", "last", NULL };
gchar *str;
gboolean fallbacks;
GVariant *variant;
icon1 = g_themed_icon_new ("testicon");
g_object_get (icon1, "use-default-fallbacks", &fallbacks, NULL);
g_assert (!fallbacks);
names = g_themed_icon_get_names (G_THEMED_ICON (icon1));
g_assert_cmpint (g_strv_length ((gchar **)names), ==, 2);
g_assert_cmpstr (names[0], ==, "testicon");
g_assert_cmpstr (names[1], ==, "testicon-symbolic");
g_themed_icon_prepend_name (G_THEMED_ICON (icon1), "first-symbolic");
g_themed_icon_append_name (G_THEMED_ICON (icon1), "last");
names = g_themed_icon_get_names (G_THEMED_ICON (icon1));
g_assert_cmpint (g_strv_length ((gchar **)names), ==, 6);
g_assert_cmpstr (names[0], ==, "first-symbolic");
g_assert_cmpstr (names[1], ==, "testicon");
g_assert_cmpstr (names[2], ==, "last");
g_assert_cmpstr (names[3], ==, "first");
g_assert_cmpstr (names[4], ==, "testicon-symbolic");
g_assert_cmpstr (names[5], ==, "last-symbolic");
g_assert_cmpuint (g_icon_hash (icon1), ==, 1812785139);
icon2 = g_themed_icon_new_from_names ((gchar**)names2, -1);
g_assert (g_icon_equal (icon1, icon2));
str = g_icon_to_string (icon2);
icon3 = g_icon_new_for_string (str, NULL);
g_assert (g_icon_equal (icon2, icon3));
g_free (str);
variant = g_icon_serialize (icon3);
icon4 = g_icon_deserialize (variant);
g_assert (g_icon_equal (icon3, icon4));
g_assert (g_icon_hash (icon3) == g_icon_hash (icon4));
g_variant_unref (variant);
g_object_unref (icon1);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
}
static void
test_emblemed_icon (void)
{
GIcon *icon;
GIcon *icon1, *icon2, *icon3, *icon4, *icon5;
GEmblem *emblem, *emblem1, *emblem2;
GList *emblems;
GVariant *variant;
icon1 = g_themed_icon_new ("testicon");
icon2 = g_themed_icon_new ("testemblem");
emblem1 = g_emblem_new (icon2);
emblem2 = g_emblem_new_with_origin (icon2, G_EMBLEM_ORIGIN_TAG);
icon3 = g_emblemed_icon_new (icon1, emblem1);
emblems = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon3));
g_assert_cmpint (g_list_length (emblems), ==, 1);
g_assert (g_emblemed_icon_get_icon (G_EMBLEMED_ICON (icon3)) == icon1);
icon4 = g_emblemed_icon_new (icon1, emblem1);
g_emblemed_icon_add_emblem (G_EMBLEMED_ICON (icon4), emblem2);
emblems = g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon4));
g_assert_cmpint (g_list_length (emblems), ==, 2);
g_assert (!g_icon_equal (icon3, icon4));
variant = g_icon_serialize (icon4);
icon5 = g_icon_deserialize (variant);
g_assert (g_icon_equal (icon4, icon5));
g_assert (g_icon_hash (icon4) == g_icon_hash (icon5));
g_variant_unref (variant);
emblem = emblems->data;
g_assert (g_emblem_get_icon (emblem) == icon2);
g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_UNKNOWN);
emblem = emblems->next->data;
g_assert (g_emblem_get_icon (emblem) == icon2);
g_assert (g_emblem_get_origin (emblem) == G_EMBLEM_ORIGIN_TAG);
g_emblemed_icon_clear_emblems (G_EMBLEMED_ICON (icon4));
g_assert (g_emblemed_icon_get_emblems (G_EMBLEMED_ICON (icon4)) == NULL);
g_assert (g_icon_hash (icon4) != g_icon_hash (icon2));
g_object_get (icon4, "gicon", &icon, NULL);
g_assert (icon == icon1);
g_object_unref (icon);
g_object_unref (icon1);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
g_object_unref (icon5);
g_object_unref (emblem1);
g_object_unref (emblem2);
}
static void
load_cb (GObject *source_object,
GAsyncResult *res,
gpointer data)
{
GLoadableIcon *icon = G_LOADABLE_ICON (source_object);
GMainLoop *loop = data;
GError *error = NULL;
GInputStream *stream;
stream = g_loadable_icon_load_finish (icon, res, NULL, &error);
g_assert_no_error (error);
g_assert (G_IS_INPUT_STREAM (stream));
g_object_unref (stream);
g_main_loop_quit (loop);
}
static void
loadable_icon_tests (GLoadableIcon *icon)
{
GError *error = NULL;
GInputStream *stream;
GMainLoop *loop;
stream = g_loadable_icon_load (icon, 20, NULL, NULL, &error);
g_assert_no_error (error);
g_assert (G_IS_INPUT_STREAM (stream));
g_object_unref (stream);
loop = g_main_loop_new (NULL, FALSE);
g_loadable_icon_load_async (icon, 20, NULL, load_cb, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
static void
test_file_icon (void)
{
GFile *file;
GIcon *icon;
GIcon *icon2;
GIcon *icon3;
GIcon *icon4;
gchar *str;
GVariant *variant;
file = g_file_new_for_path (g_test_get_filename (G_TEST_DIST, "g-icon.c", NULL));
icon = g_file_icon_new (file);
g_object_unref (file);
loadable_icon_tests (G_LOADABLE_ICON (icon));
str = g_icon_to_string (icon);
icon2 = g_icon_new_for_string (str, NULL);
g_assert (g_icon_equal (icon, icon2));
g_free (str);
file = g_file_new_for_path ("/\1\2\3/\244");
icon4 = g_file_icon_new (file);
variant = g_icon_serialize (icon4);
icon3 = g_icon_deserialize (variant);
g_assert (g_icon_equal (icon4, icon3));
g_assert (g_icon_hash (icon4) == g_icon_hash (icon3));
g_variant_unref (variant);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (icon3);
g_object_unref (icon4);
g_object_unref (file);
}
static void
test_bytes_icon (void)
{
GBytes *bytes;
GBytes *bytes2;
GIcon *icon;
GIcon *icon2;
GIcon *icon3;
GVariant *variant;
const gchar *data = "1234567890987654321";
bytes = g_bytes_new_static (data, strlen (data));
icon = g_bytes_icon_new (bytes);
icon2 = g_bytes_icon_new (bytes);
g_assert (g_bytes_icon_get_bytes (G_BYTES_ICON (icon)) == bytes);
g_assert (g_icon_equal (icon, icon2));
g_assert (g_icon_hash (icon) == g_icon_hash (icon2));
g_object_get (icon, "bytes", &bytes2, NULL);
g_assert (bytes == bytes2);
g_bytes_unref (bytes2);
variant = g_icon_serialize (icon);
icon3 = g_icon_deserialize (variant);
g_assert (g_icon_equal (icon, icon3));
g_assert (g_icon_hash (icon) == g_icon_hash (icon3));
loadable_icon_tests (G_LOADABLE_ICON (icon));
g_variant_unref (variant);
g_object_unref (icon);
g_object_unref (icon2);
g_object_unref (icon3);
g_bytes_unref (bytes);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/icons/to-string", test_g_icon_to_string);
g_test_add_func ("/icons/serialize", test_g_icon_serialize);
g_test_add_func ("/icons/themed", test_themed_icon);
g_test_add_func ("/icons/emblemed", test_emblemed_icon);
g_test_add_func ("/icons/file", test_file_icon);
g_test_add_func ("/icons/bytes", test_bytes_icon);
return g_test_run();
}

View file

@ -0,0 +1,122 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
activate (GApplication *application)
{
g_application_hold (application);
g_print ("activated\n");
g_application_release (application);
}
static void
activate_action (GAction *action,
GVariant *parameter,
gpointer data)
{
GApplication *application = G_APPLICATION (data);
g_application_hold (application);
g_print ("action %s activated\n", g_action_get_name (action));
g_application_release (application);
}
static void
activate_toggle_action (GSimpleAction *action,
GVariant *parameter,
gpointer data)
{
GApplication *application = G_APPLICATION (data);
GVariant *state;
gboolean b;
g_print ("action %s activated\n", g_action_get_name (G_ACTION (action)));
g_application_hold (application);
state = g_action_get_state (G_ACTION (action));
b = g_variant_get_boolean (state);
g_variant_unref (state);
g_simple_action_set_state (action, g_variant_new_boolean (!b));
g_print ("state change %d -> %d\n", b, !b);
g_application_release (application);
}
static void
add_actions (GApplication *app)
{
GSimpleAction *action;
action = g_simple_action_new ("simple-action", NULL);
g_signal_connect (action, "activate", G_CALLBACK (activate_action), app);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action));
g_object_unref (action);
action = g_simple_action_new_stateful ("toggle-action", NULL,
g_variant_new_boolean (FALSE));
g_signal_connect (action, "activate", G_CALLBACK (activate_toggle_action), app);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION (action));
g_object_unref (action);
}
static void
describe_and_activate_action (GActionGroup *group,
const gchar *name)
{
const GVariantType *param_type;
GVariant *state;
gboolean enabled;
gchar *tmp;
param_type = g_action_group_get_action_parameter_type (group, name);
state = g_action_group_get_action_state (group, name);
enabled = g_action_group_get_action_enabled (group, name);
g_print ("action name: %s\n", name);
tmp = param_type ? g_variant_type_dup_string (param_type) : NULL;
g_print ("parameter type: %s\n", tmp ? tmp : "<none>");
g_free (tmp);
g_print ("state type: %s\n",
state ? g_variant_get_type_string (state) : "<none>");
tmp = state ? g_variant_print (state, FALSE) : NULL;
g_print ("state: %s\n", tmp ? tmp : "<none>");
g_free (tmp);
g_print ("enabled: %s\n", enabled ? "true" : "false");
if (state != NULL)
g_variant_unref (state);
g_action_group_activate_action (group, name, NULL);
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
app = g_application_new ("org.gtk.TestApplication", 0);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
g_application_set_inactivity_timeout (app, 10000);
add_actions (app);
if (argc > 1 && strcmp (argv[1], "--simple-action") == 0)
{
g_application_register (app, NULL, NULL);
describe_and_activate_action (G_ACTION_GROUP (app), "simple-action");
exit (0);
}
else if (argc > 1 && strcmp (argv[1], "--toggle-action") == 0)
{
g_application_register (app, NULL, NULL);
describe_and_activate_action (G_ACTION_GROUP (app), "toggle-action");
exit (0);
}
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}

View file

@ -0,0 +1,43 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static int
command_line (GApplication *application,
GApplicationCommandLine *cmdline)
{
gchar **argv;
gint argc;
gint i;
argv = g_application_command_line_get_arguments (cmdline, &argc);
g_application_command_line_print (cmdline,
"This text is written back\n"
"to stdout of the caller\n");
for (i = 0; i < argc; i++)
g_print ("argument %d: %s\n", i, argv[i]);
g_strfreev (argv);
return 0;
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
app = g_application_new ("org.gtk.TestApplication",
G_APPLICATION_HANDLES_COMMAND_LINE);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
g_application_set_inactivity_timeout (app, 10000);
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}

View file

@ -0,0 +1,106 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static int
command_line (GApplication *application,
GApplicationCommandLine *cmdline)
{
gchar **argv;
gint argc;
gint i;
argv = g_application_command_line_get_arguments (cmdline, &argc);
for (i = 0; i < argc; i++)
g_print ("handling argument %s remotely\n", argv[i]);
g_strfreev (argv);
return 0;
}
static gboolean
test_local_cmdline (GApplication *application,
gchar ***arguments,
gint *exit_status)
{
gint i, j;
gchar **argv;
argv = *arguments;
i = 1;
while (argv[i])
{
if (g_str_has_prefix (argv[i], "--local-"))
{
g_print ("handling argument %s locally\n", argv[i]);
g_free (argv[i]);
for (j = i; argv[j]; j++)
argv[j] = argv[j + 1];
}
else
{
g_print ("not handling argument %s locally\n", argv[i]);
i++;
}
}
*exit_status = 0;
return FALSE;
}
typedef GApplication TestApplication;
typedef GApplicationClass TestApplicationClass;
static GType test_application_get_type (void);
G_DEFINE_TYPE (TestApplication, test_application, G_TYPE_APPLICATION)
static void
test_application_finalize (GObject *object)
{
G_OBJECT_CLASS (test_application_parent_class)->finalize (object);
}
static void
test_application_init (TestApplication *app)
{
}
static void
test_application_class_init (TestApplicationClass *class)
{
G_OBJECT_CLASS (class)->finalize = test_application_finalize;
G_APPLICATION_CLASS (class)->local_command_line = test_local_cmdline;
}
static GApplication *
test_application_new (const gchar *application_id,
GApplicationFlags flags)
{
g_return_val_if_fail (g_application_id_is_valid (application_id), NULL);
return g_object_new (test_application_get_type (),
"application-id", application_id,
"flags", flags,
NULL);
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
app = test_application_new ("org.gtk.TestApplication", 0);
g_application_set_inactivity_timeout (app, 10000);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}

View file

@ -0,0 +1,106 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static gboolean
my_cmdline_handler (gpointer data)
{
GApplicationCommandLine *cmdline = data;
gchar **args;
gchar **argv;
gint argc;
gint arg1;
gboolean arg2;
gboolean help;
GOptionContext *context;
GOptionEntry entries[] = {
{ "arg1", 0, 0, G_OPTION_ARG_INT, &arg1, NULL, NULL },
{ "arg2", 0, 0, G_OPTION_ARG_NONE, &arg2, NULL, NULL },
{ "help", '?', 0, G_OPTION_ARG_NONE, &help, NULL, NULL },
G_OPTION_ENTRY_NULL
};
GError *error;
gint i;
args = g_application_command_line_get_arguments (cmdline, &argc);
/* We have to make an extra copy of the array, since g_option_context_parse()
* assumes that it can remove strings from the array without freeing them.
*/
argv = g_new (gchar*, argc + 1);
for (i = 0; i <= argc; i++)
argv[i] = args[i];
context = g_option_context_new (NULL);
g_option_context_set_help_enabled (context, FALSE);
g_option_context_add_main_entries (context, entries, NULL);
arg1 = 0;
arg2 = FALSE;
help = FALSE;
error = NULL;
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_application_command_line_printerr (cmdline, "%s\n", error->message);
g_error_free (error);
g_application_command_line_set_exit_status (cmdline, 1);
}
else if (help)
{
gchar *text;
text = g_option_context_get_help (context, FALSE, NULL);
g_application_command_line_print (cmdline, "%s", text);
g_free (text);
}
else
{
g_application_command_line_print (cmdline, "arg1 is %d and arg2 is %s\n",
arg1, arg2 ? "TRUE" : "FALSE");
g_application_command_line_set_exit_status (cmdline, 0);
}
g_free (argv);
g_strfreev (args);
g_option_context_free (context);
/* we are done handling this commandline */
g_object_unref (cmdline);
return G_SOURCE_REMOVE;
}
static int
command_line (GApplication *application,
GApplicationCommandLine *cmdline)
{
/* keep the application running until we are done with this commandline */
g_application_hold (application);
g_object_set_data_full (G_OBJECT (cmdline),
"application", application,
(GDestroyNotify)g_application_release);
g_object_ref (cmdline);
g_idle_add (my_cmdline_handler, cmdline);
return 0;
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
app = g_application_new ("org.gtk.TestApplication",
G_APPLICATION_HANDLES_COMMAND_LINE);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
g_application_set_inactivity_timeout (app, 10000);
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}

View file

@ -0,0 +1,85 @@
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static gint
handle_local_options (GApplication *application,
GVariantDict *options,
gpointer user_data)
{
guint32 count;
/* Deal (locally) with version option */
if (g_variant_dict_lookup (options, "version", "b", &count))
{
g_print ("This is example-cmdline4, version 1.2.3\n");
return EXIT_SUCCESS;
}
return -1;
}
static gint
command_line (GApplication *application,
GApplicationCommandLine *cmdline,
gpointer user_data)
{
guint32 count;
GVariantDict *options = g_application_command_line_get_options_dict (cmdline);
/* Deal with arg option */
if (g_variant_dict_lookup (options, "flag", "b", &count))
{
g_application_command_line_print (cmdline, "flag is set\n");
}
return EXIT_SUCCESS;
}
int
main (int argc, char **argv)
{
GApplication *app;
int status;
GOptionEntry entries[] = {
/* A version flag option, to be handled locally */
{ "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "Show the application version", NULL },
/* A dummy flag option, to be handled in primary */
{ "flag", 'f', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, NULL, "A flag argument", NULL },
G_OPTION_ENTRY_NULL
};
app = g_application_new ("org.gtk.TestApplication",
G_APPLICATION_HANDLES_COMMAND_LINE);
g_application_add_main_option_entries (app, entries);
g_application_set_option_context_parameter_string (app, "- a simple command line example");
g_application_set_option_context_summary (app,
"Summary:\n"
"This is a simple command line --help example.");
g_application_set_option_context_description (app,
"Description:\n"
"This example illustrates the use of "
"g_application command line --help functionalities "
"(parameter string, summary, description). "
"It does nothing at all except displaying information "
"when invoked with --help argument...\n");
g_signal_connect (app, "handle-local-options", G_CALLBACK (handle_local_options), NULL);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
/* This application does absolutely nothing, except if a command line is given */
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}

Some files were not shown because too many files have changed in this diff Show more