mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 10:08:56 +01:00 
			
		
		
		
	Some applications (eg., gnome-photos) really want a large thumbnail, if one can be created. Simply falling back to a smaller one (probably created by an old nautilus), without giving the application a chance to create a bigger thumbnail, is undesirable because they will appear fuzzy. Therefore, at separate attribute sets for all the thumbnail sizes that are supported in the spec: normal/large/x-large/xx-large. The old attribute will now return by default the biggest available, as it used to be, but also including the x-large and xx-large cases. Co-Authored-by: Marco Trevisan <mail@3v1n0.net> Fixes: #621
		
			
				
	
	
		
			621 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			621 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Unit tests for GFile thumbnails
 | 
						|
 * GIO - GLib Input, Output and Streaming Library
 | 
						|
 *
 | 
						|
 * Copyright (C) 2022 Marco Trevisan
 | 
						|
 *
 | 
						|
 * SPDX-License-Identifier: LGPL-2.1-or-later
 | 
						|
 *
 | 
						|
 * 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: Marco Trevisan <marco.trevisan@canonical.com>
 | 
						|
 */
 | 
						|
 | 
						|
#include <gio/gio.h>
 | 
						|
 | 
						|
#define THUMBNAIL_FAIL_SIZE "fail"
 | 
						|
 | 
						|
#define THUMBNAILS_ATTRIBS ( \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_PATH "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XXLARGE "," \
 | 
						|
  G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE "," \
 | 
						|
)
 | 
						|
 | 
						|
/* Must be kept in order, for priority */
 | 
						|
static const char * SIZES_NAMES[] = {
 | 
						|
  "normal",
 | 
						|
  "large",
 | 
						|
  "x-large",
 | 
						|
  "xx-large",
 | 
						|
};
 | 
						|
 | 
						|
static GFile *
 | 
						|
get_thumbnail_src_file (const gchar *name)
 | 
						|
{
 | 
						|
  const gchar *thumbnail_path;
 | 
						|
  thumbnail_path = g_test_get_filename (G_TEST_DIST, "thumbnails",
 | 
						|
                                        name, NULL);
 | 
						|
 | 
						|
  g_assert_true (g_file_test (thumbnail_path, G_FILE_TEST_IS_REGULAR));
 | 
						|
 | 
						|
  return g_file_new_for_path (thumbnail_path);
 | 
						|
}
 | 
						|
 | 
						|
static gchar *
 | 
						|
get_thumbnail_basename (GFile *source)
 | 
						|
{
 | 
						|
  GChecksum *checksum;
 | 
						|
  gchar *uri = g_file_get_uri (source);
 | 
						|
  gchar *basename;
 | 
						|
 | 
						|
  checksum = g_checksum_new (G_CHECKSUM_MD5);
 | 
						|
  g_checksum_update (checksum, (const guchar *) uri, strlen (uri));
 | 
						|
 | 
						|
  basename = g_strconcat (g_checksum_get_string (checksum), ".png", NULL);
 | 
						|
 | 
						|
  g_checksum_free (checksum);
 | 
						|
  g_free (uri);
 | 
						|
 | 
						|
  return basename;
 | 
						|
}
 | 
						|
 | 
						|
static GFile *
 | 
						|
get_expected_thumbnail_file (GFile       *source,
 | 
						|
                             const gchar *size)
 | 
						|
{
 | 
						|
  GFile *file;
 | 
						|
  gchar *basename;
 | 
						|
 | 
						|
  basename = get_thumbnail_basename (source);
 | 
						|
  file = g_file_new_build_filename (g_get_user_cache_dir (),
 | 
						|
                                    "thumbnails",
 | 
						|
                                    size,
 | 
						|
                                    basename,
 | 
						|
                                    NULL);
 | 
						|
  g_free (basename);
 | 
						|
  return file;
 | 
						|
}
 | 
						|
 | 
						|
static GFile *
 | 
						|
get_failed_thumbnail_file (GFile *source)
 | 
						|
{
 | 
						|
  GFile *file;
 | 
						|
  gchar *basename;
 | 
						|
 | 
						|
  basename = get_thumbnail_basename (source);
 | 
						|
  file = g_file_new_build_filename (g_get_user_cache_dir (),
 | 
						|
                                    "thumbnails", THUMBNAIL_FAIL_SIZE,
 | 
						|
                                    "gnome-thumbnail-factory",
 | 
						|
                                    basename,
 | 
						|
                                    NULL);
 | 
						|
  g_free (basename);
 | 
						|
  return file;
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
check_thumbnail_exists (GFile       *source,
 | 
						|
                         const gchar *size)
 | 
						|
{
 | 
						|
  GFile *thumbnail;
 | 
						|
  gboolean ret;
 | 
						|
 | 
						|
  thumbnail = get_expected_thumbnail_file (source, size);
 | 
						|
  g_assert_nonnull (thumbnail);
 | 
						|
 | 
						|
  ret = g_file_query_exists (thumbnail, NULL);
 | 
						|
  g_clear_object (&thumbnail);
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
check_failed_thumbnail_exists (GFile *source)
 | 
						|
{
 | 
						|
  GFile *thumbnail;
 | 
						|
  gboolean ret;
 | 
						|
 | 
						|
  thumbnail = get_failed_thumbnail_file (source);
 | 
						|
  g_assert_nonnull (thumbnail);
 | 
						|
 | 
						|
  ret = g_file_query_exists (thumbnail, NULL);
 | 
						|
  g_clear_object (&thumbnail);
 | 
						|
 | 
						|
  return ret;
 | 
						|
}
 | 
						|
 | 
						|
static GFile *
 | 
						|
create_thumbnail (GFile       *source,
 | 
						|
                  const gchar *size)
 | 
						|
{
 | 
						|
  GFile *thumbnail;
 | 
						|
  GFile *thumbnail_dir;
 | 
						|
  GError *error = NULL;
 | 
						|
  gchar *thumbnail_path;
 | 
						|
 | 
						|
  /* TODO: This is just a stub implementation to create a fake thumbnail file
 | 
						|
   * We should implement a real thumbnail generator, but we don't care here.
 | 
						|
   */
 | 
						|
 | 
						|
  if (!size || g_strcmp0 (size, THUMBNAIL_FAIL_SIZE) == 0)
 | 
						|
    thumbnail = get_failed_thumbnail_file (source);
 | 
						|
  else
 | 
						|
    thumbnail = get_expected_thumbnail_file (source, size);
 | 
						|
 | 
						|
  thumbnail_dir = g_file_get_parent (thumbnail);
 | 
						|
 | 
						|
  if (!g_file_query_exists (thumbnail_dir, NULL))
 | 
						|
    {
 | 
						|
      g_file_make_directory_with_parents (thumbnail_dir, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
      g_clear_error (&error);
 | 
						|
    }
 | 
						|
 | 
						|
  g_file_copy (source, thumbnail, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_true (g_file_query_exists (thumbnail, NULL));
 | 
						|
  thumbnail_path = g_file_get_path (thumbnail);
 | 
						|
  g_test_message ("Created test thumbnail at %s", thumbnail_path);
 | 
						|
 | 
						|
  g_clear_object (&thumbnail_dir);
 | 
						|
  g_clear_error (&error);
 | 
						|
  g_free (thumbnail_path);
 | 
						|
 | 
						|
  return thumbnail;
 | 
						|
}
 | 
						|
 | 
						|
static GFile *
 | 
						|
create_thumbnail_from_test_file (const gchar  *source_name,
 | 
						|
                                 const gchar  *size,
 | 
						|
                                 GFile       **out_source)
 | 
						|
{
 | 
						|
  GFile *thumbnail;
 | 
						|
  GFile *source = get_thumbnail_src_file (source_name);
 | 
						|
 | 
						|
  thumbnail = create_thumbnail (source, size);
 | 
						|
 | 
						|
  if (!size || g_strcmp0 (size, THUMBNAIL_FAIL_SIZE) == 0)
 | 
						|
    {
 | 
						|
      g_assert_true (check_failed_thumbnail_exists (source));
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      g_assert_false (check_failed_thumbnail_exists (source));
 | 
						|
      g_assert_true (check_thumbnail_exists (source, size));
 | 
						|
    }
 | 
						|
 | 
						|
  if (out_source)
 | 
						|
    *out_source = g_steal_pointer (&source);
 | 
						|
 | 
						|
  g_clear_object (&source);
 | 
						|
 | 
						|
  return thumbnail;
 | 
						|
}
 | 
						|
 | 
						|
static gboolean
 | 
						|
get_size_attributes (const char   *size,
 | 
						|
                     const gchar **path,
 | 
						|
                     const gchar **is_valid,
 | 
						|
                     const gchar **failed)
 | 
						|
{
 | 
						|
  if (g_str_equal (size, "normal"))
 | 
						|
    {
 | 
						|
      *path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL;
 | 
						|
      *is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL;
 | 
						|
      *failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL;
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  else if (g_str_equal (size, "large"))
 | 
						|
    {
 | 
						|
      *path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE;
 | 
						|
      *is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE;
 | 
						|
      *failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE;
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  else if (g_str_equal (size, "x-large"))
 | 
						|
    {
 | 
						|
      *path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE;
 | 
						|
      *is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE;
 | 
						|
      *failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE;
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
  else if (g_str_equal (size, "xx-large"))
 | 
						|
    {
 | 
						|
      *path = G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE;
 | 
						|
      *is_valid = G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE;
 | 
						|
      *failed = G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XXLARGE;
 | 
						|
      return TRUE;
 | 
						|
    }
 | 
						|
 | 
						|
  *path = NULL;
 | 
						|
  *is_valid = NULL;
 | 
						|
  *failed = NULL;
 | 
						|
 | 
						|
  return FALSE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
test_valid_thumbnail_size (gconstpointer data)
 | 
						|
{
 | 
						|
  GFile *source;
 | 
						|
  GFile *thumbnail;
 | 
						|
  GFile *f;
 | 
						|
  GError *error = NULL;
 | 
						|
  GFileInfo *info;
 | 
						|
  const gchar *size = data;
 | 
						|
  const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
 | 
						|
  thumbnail = create_thumbnail_from_test_file ("valid.png", size, &source);
 | 
						|
  info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
 | 
						|
                            NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_cmpstr (
 | 
						|
    g_file_peek_path (f),
 | 
						|
    ==,
 | 
						|
    g_file_peek_path (thumbnail)
 | 
						|
  );
 | 
						|
  g_clear_object (&f);
 | 
						|
 | 
						|
  /* TODO: We can't really test this without having a proper thumbnail created
 | 
						|
  g_assert_true (
 | 
						|
     g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  */
 | 
						|
 | 
						|
  g_assert_true (get_size_attributes (size, &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, path_attr));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
  f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
 | 
						|
  g_assert_cmpstr (
 | 
						|
    g_file_info_get_attribute_byte_string (info, path_attr),
 | 
						|
    ==,
 | 
						|
    g_file_peek_path (thumbnail)
 | 
						|
  );
 | 
						|
  g_clear_object (&f);
 | 
						|
 | 
						|
  /* TODO: We can't really test this without having a proper thumbnail created
 | 
						|
  g_assert_true (g_file_info_get_attribute_boolean (info, is_valid_attr));
 | 
						|
  */
 | 
						|
 | 
						|
  g_clear_object (&source);
 | 
						|
  g_clear_object (&thumbnail);
 | 
						|
  g_clear_error (&error);
 | 
						|
  g_clear_object (&info);
 | 
						|
  g_clear_object (&f);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
test_unknown_thumbnail_size (gconstpointer data)
 | 
						|
{
 | 
						|
  GFile *source;
 | 
						|
  GFile *thumbnail;
 | 
						|
  GError *error = NULL;
 | 
						|
  GFileInfo *info;
 | 
						|
  const gchar *size = data;
 | 
						|
 | 
						|
  thumbnail = create_thumbnail_from_test_file ("valid.png", size, &source);
 | 
						|
  info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
 | 
						|
                            NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_NORMAL));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_NORMAL));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_NORMAL));
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_LARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_LARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_LARGE));
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XLARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XLARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED_XLARGE));
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH_XXLARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID_XXLARGE));
 | 
						|
 | 
						|
  g_clear_object (&source);
 | 
						|
  g_clear_object (&thumbnail);
 | 
						|
  g_clear_error (&error);
 | 
						|
  g_clear_object (&info);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
test_failed_thumbnail (void)
 | 
						|
{
 | 
						|
  GFile *source;
 | 
						|
  GFile *thumbnail;
 | 
						|
  GError *error = NULL;
 | 
						|
  GFileInfo *info;
 | 
						|
 | 
						|
  thumbnail = create_thumbnail_from_test_file ("valid.png", NULL, &source);
 | 
						|
  info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
 | 
						|
                            NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_assert_false (
 | 
						|
     g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_true (
 | 
						|
     g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_clear_object (&source);
 | 
						|
  g_clear_object (&thumbnail);
 | 
						|
  g_clear_error (&error);
 | 
						|
  g_clear_object (&info);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
test_thumbnails_size_priority (void)
 | 
						|
{
 | 
						|
  GPtrArray *sized_thumbnails;
 | 
						|
  GError *error = NULL;
 | 
						|
  GFileInfo *info;
 | 
						|
  GFile *source;
 | 
						|
  GFile *failed_thumbnail;
 | 
						|
  gsize i;
 | 
						|
 | 
						|
  failed_thumbnail = create_thumbnail_from_test_file ("valid.png", NULL, &source);
 | 
						|
  sized_thumbnails = g_ptr_array_new_with_free_func (g_object_unref);
 | 
						|
 | 
						|
  /* Checking that each thumbnail with higher priority override the previous */
 | 
						|
  for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
 | 
						|
    {
 | 
						|
      GFile *thumbnail = create_thumbnail (source, SIZES_NAMES[i]);
 | 
						|
      const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
      GFile *f;
 | 
						|
 | 
						|
      g_ptr_array_add (sized_thumbnails, thumbnail);
 | 
						|
 | 
						|
      info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
 | 
						|
                               G_FILE_QUERY_INFO_NONE, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
      f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
      g_assert_cmpstr (
 | 
						|
        g_file_peek_path (f),
 | 
						|
        ==,
 | 
						|
        g_file_peek_path (thumbnail)
 | 
						|
      );
 | 
						|
      g_clear_object (&f);
 | 
						|
 | 
						|
      g_assert_true (get_size_attributes (SIZES_NAMES[i],
 | 
						|
                     &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, path_attr));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
      f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
 | 
						|
      g_assert_cmpstr (
 | 
						|
        g_file_peek_path (f),
 | 
						|
        ==,
 | 
						|
        g_file_peek_path (thumbnail)
 | 
						|
      );
 | 
						|
 | 
						|
      g_clear_object (&info);
 | 
						|
      g_clear_object (&f);
 | 
						|
    }
 | 
						|
 | 
						|
  g_assert_cmpuint (sized_thumbnails->len, ==, G_N_ELEMENTS (SIZES_NAMES));
 | 
						|
 | 
						|
  /* Ensuring we can access to all the thumbnails by explicit size request */
 | 
						|
  for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
 | 
						|
    {
 | 
						|
      GFile *thumbnail = g_ptr_array_index (sized_thumbnails, i);
 | 
						|
      const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
      GFile *f;
 | 
						|
 | 
						|
      info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
 | 
						|
                                G_FILE_QUERY_INFO_NONE, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      g_assert_true (get_size_attributes (SIZES_NAMES[i],
 | 
						|
                     &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, path_attr));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
      f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
 | 
						|
      g_assert_cmpstr (
 | 
						|
        g_file_peek_path (f),
 | 
						|
        ==,
 | 
						|
        g_file_peek_path (thumbnail)
 | 
						|
      );
 | 
						|
      g_clear_object (&f);
 | 
						|
 | 
						|
      g_clear_object (&info);
 | 
						|
    }
 | 
						|
 | 
						|
  /* Now removing them in the inverse order, to check this again */
 | 
						|
  for (i = G_N_ELEMENTS (SIZES_NAMES); i > 1; i--)
 | 
						|
    {
 | 
						|
      GFile *thumbnail = g_ptr_array_index (sized_thumbnails, i - 1);
 | 
						|
      GFile *less_priority_thumbnail = g_ptr_array_index (sized_thumbnails, i - 2);
 | 
						|
      const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
      GFile *f;
 | 
						|
 | 
						|
      g_file_delete (thumbnail, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
 | 
						|
                                G_FILE_QUERY_INFO_NONE, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
      f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
      g_assert_cmpstr (
 | 
						|
        g_file_peek_path (f),
 | 
						|
        ==,
 | 
						|
        g_file_peek_path (less_priority_thumbnail)
 | 
						|
      );
 | 
						|
      g_clear_object (&f);
 | 
						|
 | 
						|
      g_assert_true (get_size_attributes (SIZES_NAMES[i-2],
 | 
						|
                     &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, path_attr));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
      f = g_file_new_for_path (g_file_info_get_attribute_byte_string (info, path_attr));
 | 
						|
      g_assert_cmpstr (
 | 
						|
        g_file_peek_path (f),
 | 
						|
        ==,
 | 
						|
        g_file_peek_path (less_priority_thumbnail)
 | 
						|
      );
 | 
						|
 | 
						|
      g_clear_object (&info);
 | 
						|
      g_clear_object (&f);
 | 
						|
    }
 | 
						|
 | 
						|
  /* And now let's remove the last valid one, so that failed should have priority */
 | 
						|
  g_file_delete (G_FILE (g_ptr_array_index (sized_thumbnails, 0)), NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
 | 
						|
                            NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_assert_false (
 | 
						|
     g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_true (
 | 
						|
     g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_clear_object (&info);
 | 
						|
 | 
						|
  /* And check if we get the failed state for all explicit requests */
 | 
						|
  for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
 | 
						|
    {
 | 
						|
      const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
 | 
						|
      info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
 | 
						|
                                G_FILE_QUERY_INFO_NONE, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      g_assert_true (get_size_attributes (SIZES_NAMES[i],
 | 
						|
                     &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, path_attr));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
      g_assert_true (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
      g_assert_false (g_file_info_get_attribute_boolean (info, is_valid_attr));
 | 
						|
      g_assert_true (g_file_info_get_attribute_boolean (info, failed_attr));
 | 
						|
 | 
						|
      g_clear_object (&info);
 | 
						|
    }
 | 
						|
 | 
						|
  /* Removing the failed thumbnail too, so no thumbnail should be available */
 | 
						|
  g_file_delete (failed_thumbnail, NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  info = g_file_query_info (source, THUMBNAILS_ATTRIBS, G_FILE_QUERY_INFO_NONE,
 | 
						|
                            NULL, &error);
 | 
						|
  g_assert_no_error (error);
 | 
						|
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_PATH));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAIL_IS_VALID));
 | 
						|
  g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_THUMBNAILING_FAILED));
 | 
						|
 | 
						|
  g_clear_object (&info);
 | 
						|
 | 
						|
  for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
 | 
						|
    {
 | 
						|
      const gchar *path_attr, *failed_attr, *is_valid_attr;
 | 
						|
 | 
						|
      info = g_file_query_info (source, THUMBNAILS_ATTRIBS,
 | 
						|
                                G_FILE_QUERY_INFO_NONE, NULL, &error);
 | 
						|
      g_assert_no_error (error);
 | 
						|
 | 
						|
      g_assert_true (get_size_attributes (SIZES_NAMES[i],
 | 
						|
                     &path_attr, &is_valid_attr, &failed_attr));
 | 
						|
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, path_attr));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, is_valid_attr));
 | 
						|
      g_assert_false (g_file_info_has_attribute (info, failed_attr));
 | 
						|
 | 
						|
      g_clear_object (&info);
 | 
						|
    }
 | 
						|
 | 
						|
  g_clear_object (&source);
 | 
						|
  g_clear_pointer (&sized_thumbnails, g_ptr_array_unref);
 | 
						|
  g_clear_object (&failed_thumbnail);
 | 
						|
  g_clear_error (&error);
 | 
						|
  g_clear_object (&info);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
int
 | 
						|
main (int   argc,
 | 
						|
      char *argv[])
 | 
						|
{
 | 
						|
  gsize i;
 | 
						|
 | 
						|
  g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
 | 
						|
 | 
						|
  for (i = 0; i < G_N_ELEMENTS (SIZES_NAMES); i++)
 | 
						|
    {
 | 
						|
      gchar *test_path;
 | 
						|
 | 
						|
      test_path = g_strconcat ("/file-thumbnail/valid/", SIZES_NAMES[i], NULL);
 | 
						|
      g_test_add_data_func (test_path, SIZES_NAMES[i], test_valid_thumbnail_size);
 | 
						|
      g_free (test_path);
 | 
						|
    }
 | 
						|
 | 
						|
  g_test_add_data_func ("/file-thumbnail/unknown/super-large", "super-large", test_unknown_thumbnail_size);
 | 
						|
  g_test_add_func ("/file-thumbnail/fail", test_failed_thumbnail);
 | 
						|
  g_test_add_func ("/file-thumbnail/size-priority", test_thumbnails_size_priority);
 | 
						|
 | 
						|
  return g_test_run ();
 | 
						|
}
 |