/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 *  Copyright (C) 2008  Kouhei Sutou <kou@cozmixng.org>
 *
 *  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 3 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 "kz-test-utils.h"
#include "src/bookmarks/kz-bookmark.h"
#include "src/bookmarks/kz-bookmarks-enum-types.h"

static gchar *base_dir = NULL;
const gchar *
kz_test_get_base_dir (void)
{
    const gchar *dir;

    if (base_dir)
        return base_dir;

    dir = g_getenv("BASE_DIR");
    if (!dir)
        dir = ".";

    if (g_path_is_absolute(dir)) {
        base_dir = g_strdup(dir);
    } else {
        gchar *current_dir;

        current_dir = g_get_current_dir();
        base_dir = g_build_filename(current_dir, dir, NULL);
        g_free(current_dir);
    }

    return base_dir;
}

gboolean
kz_test_equal_bookmark (KzBookmark *expected, KzBookmark *actual)
{
    GParamSpec **expected_param_specs, **actual_param_specs;
    GObjectClass *expected_object_class;
    GObjectClass *actual_object_class;
    guint i, n_expected_properties, n_actual_properties;

    if (G_OBJECT_TYPE(expected) != G_OBJECT_TYPE(actual))
        return FALSE;

    expected_object_class = G_OBJECT_CLASS(KZ_BOOKMARK_GET_CLASS(expected));
    actual_object_class = G_OBJECT_CLASS(KZ_BOOKMARK_GET_CLASS(actual));

    expected_param_specs = g_object_class_list_properties(expected_object_class,
                                                          &n_expected_properties);
    actual_param_specs = g_object_class_list_properties(actual_object_class,
                                                        &n_actual_properties);
    cut_take_memory(expected_param_specs);
    cut_take_memory(actual_param_specs);

    if (n_expected_properties != n_actual_properties)
        return FALSE;

    for (i = 0; i < n_expected_properties; i++) {
        GParamSpec *actual_param_spec;
        GValue expected_value = {0}, actual_value = {0};
        actual_param_spec = g_object_class_find_property(actual_object_class,
                                                         expected_param_specs[i]->name);
        if (!actual_param_spec)
            return FALSE;
        g_value_init(&expected_value, expected_param_specs[i]->value_type);
        g_value_init(&actual_value, expected_param_specs[i]->value_type);
        g_object_get_property(G_OBJECT(expected), expected_param_specs[i]->name,
                              &expected_value);
        g_object_get_property(G_OBJECT(expected), expected_param_specs[i]->name,
                              &actual_value);
        if (!gcut_value_equal(&expected_value, &actual_value))
            return FALSE;
    }
    return TRUE;
}

void
kz_assert_equal_bookmark_helper (KzBookmark *expected,
                                 KzBookmark *actual,
                                 const gchar *expression_expected,
                                 const gchar *expression_actual)
{
    if (kz_test_equal_bookmark(expected, actual)) {
        cut_test_pass();
    } else {
        gchar *inspected_expected, *inspected_actual;
        const gchar *message;

        inspected_expected = gcut_object_inspect(G_OBJECT(expected));
        inspected_actual = gcut_object_inspect(G_OBJECT(actual));
        message = cut_take_printf("<%s> == <%s>\n"
                                  "expected: <%s>\n"
                                  "  actual: <%s>",
                                  expression_expected, expression_actual,
                                  inspected_expected,
                                  inspected_actual);
        if (expected && actual)
            message = cut_append_diff(message,
                                      inspected_expected, inspected_actual);
        g_free(inspected_expected);
        g_free(inspected_actual);
        cut_test_fail(message);
    }
}


/*
vi:ts=4:nowrap:ai:expandtab:sw=4
*/
