2021-07-26 21:10:46 +02:00
|
|
|
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
|
|
|
// SPDX-FileCopyrightText: 2021 Emmanuele Bassi
|
|
|
|
|
|
|
|
|
|
#include <glib-object.h>
|
|
|
|
|
|
2023-04-13 16:39:37 +02:00
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
GTypeInterface g_iface;
|
|
|
|
|
} TestInterfaceInterface;
|
|
|
|
|
|
|
|
|
|
GType test_interface_get_type (void);
|
|
|
|
|
#define TEST_TYPE_INTERFACE test_interface_get_type ()
|
|
|
|
|
G_DEFINE_INTERFACE (TestInterface, test_interface, G_TYPE_INVALID)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_interface_default_init (TestInterfaceInterface *iface)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_type_flags_interface (void)
|
|
|
|
|
{
|
|
|
|
|
g_assert_false (G_TYPE_IS_ABSTRACT (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_ABSTRACT));
|
|
|
|
|
|
|
|
|
|
g_assert_false (G_TYPE_IS_CLASSED (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_CLASSED));
|
|
|
|
|
|
|
|
|
|
g_assert_false (G_TYPE_IS_DEEP_DERIVABLE (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DEEP_DERIVABLE));
|
|
|
|
|
|
|
|
|
|
g_assert_true (G_TYPE_IS_DERIVABLE (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_true (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_DERIVABLE));
|
|
|
|
|
|
|
|
|
|
g_assert_false (G_TYPE_IS_FINAL (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_FINAL));
|
|
|
|
|
|
|
|
|
|
g_assert_false (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_INTERFACE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_INTERFACE, G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 21:10:46 +02:00
|
|
|
|
#define TEST_TYPE_FINAL (test_final_get_type())
|
|
|
|
|
G_DECLARE_FINAL_TYPE (TestFinal, test_final, TEST, FINAL, GObject)
|
|
|
|
|
|
|
|
|
|
struct _TestFinal
|
|
|
|
|
{
|
|
|
|
|
GObject parent_instance;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _TestFinalClass
|
|
|
|
|
{
|
|
|
|
|
GObjectClass parent_class;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_FINAL_TYPE (TestFinal, test_final, G_TYPE_OBJECT)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_final_class_init (TestFinalClass *klass)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_final_init (TestFinal *self)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define TEST_TYPE_FINAL2 (test_final2_get_type())
|
|
|
|
|
G_DECLARE_FINAL_TYPE (TestFinal2, test_final2, TEST, FINAL2, TestFinal)
|
|
|
|
|
|
|
|
|
|
struct _TestFinal2
|
|
|
|
|
{
|
|
|
|
|
TestFinal parent_instance;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _TestFinal2Class
|
|
|
|
|
{
|
|
|
|
|
TestFinalClass parent_class;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (TestFinal2, test_final2, TEST_TYPE_FINAL)
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_final2_class_init (TestFinal2Class *klass)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_final2_init (TestFinal2 *self)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* test_type_flags_final: Check that trying to derive from a final class
|
|
|
|
|
* will result in a warning from the type system
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
test_type_flags_final (void)
|
|
|
|
|
{
|
|
|
|
|
GType final2_type;
|
|
|
|
|
|
2022-12-12 18:00:10 +01:00
|
|
|
|
g_assert_true (G_TYPE_IS_FINAL (TEST_TYPE_FINAL));
|
|
|
|
|
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_FINAL));
|
|
|
|
|
g_assert_true (G_TYPE_IS_CLASSED (TEST_TYPE_FINAL));
|
|
|
|
|
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_CLASSED));
|
|
|
|
|
g_assert_true (G_TYPE_IS_INSTANTIATABLE (TEST_TYPE_FINAL));
|
|
|
|
|
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL, G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
g_assert_true (g_type_test_flags (TEST_TYPE_FINAL,
|
|
|
|
|
G_TYPE_FLAG_FINAL |
|
|
|
|
|
G_TYPE_FLAG_CLASSED |
|
|
|
|
|
G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
g_assert_false (g_type_test_flags (TEST_TYPE_FINAL,
|
|
|
|
|
G_TYPE_FLAG_FINAL |
|
|
|
|
|
G_TYPE_FLAG_CLASSED |
|
|
|
|
|
G_TYPE_FLAG_DEPRECATED |
|
|
|
|
|
G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
|
2021-07-26 21:10:46 +02:00
|
|
|
|
/* This is the message we print out when registering the type */
|
2022-08-04 01:35:33 +02:00
|
|
|
|
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
|
2021-07-26 21:10:46 +02:00
|
|
|
|
"*cannot derive*");
|
|
|
|
|
|
|
|
|
|
/* This is the message when we fail to return from the GOnce init
|
|
|
|
|
* block within the test_final2_get_type() function
|
|
|
|
|
*/
|
|
|
|
|
g_test_expect_message ("GLib", G_LOG_LEVEL_CRITICAL,
|
2023-09-12 10:26:21 +02:00
|
|
|
|
"*g_once_init_leave_pointer: assertion*");
|
2021-07-26 21:10:46 +02:00
|
|
|
|
|
|
|
|
|
final2_type = TEST_TYPE_FINAL2;
|
|
|
|
|
g_assert_true (final2_type == G_TYPE_INVALID);
|
|
|
|
|
|
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-21 02:04:01 +02:00
|
|
|
|
#define TEST_TYPE_DEPRECATED (test_deprecated_get_type())
|
|
|
|
|
G_DECLARE_FINAL_TYPE (TestDeprecated, test_deprecated, TEST, DEPRECATED, GObject)
|
|
|
|
|
|
|
|
|
|
struct _TestDeprecated
|
|
|
|
|
{
|
|
|
|
|
GObject parent_instance;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _TestDeprecatedClass
|
|
|
|
|
{
|
|
|
|
|
GObjectClass parent_class;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE_EXTENDED (TestDeprecated, test_deprecated, G_TYPE_OBJECT, G_TYPE_FLAG_FINAL | G_TYPE_FLAG_DEPRECATED, {})
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_deprecated_class_init (TestDeprecatedClass *klass)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
test_deprecated_init (TestDeprecated *self)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-12 18:00:10 +01:00
|
|
|
|
static void
|
|
|
|
|
test_type_flags_final_instance_check (void)
|
|
|
|
|
{
|
|
|
|
|
TestFinal *final;
|
|
|
|
|
|
|
|
|
|
final = g_object_new (TEST_TYPE_FINAL, NULL);
|
|
|
|
|
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
|
|
|
|
|
TEST_TYPE_FINAL));
|
|
|
|
|
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
|
|
|
|
|
TEST_TYPE_DEPRECATED));
|
|
|
|
|
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) final,
|
|
|
|
|
G_TYPE_OBJECT));
|
2022-12-21 20:16:10 +01:00
|
|
|
|
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) final,
|
|
|
|
|
G_TYPE_INVALID));
|
2022-12-12 18:00:10 +01:00
|
|
|
|
|
|
|
|
|
g_clear_object (&final);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-21 02:04:01 +02:00
|
|
|
|
static void
|
|
|
|
|
test_type_flags_deprecated (void)
|
|
|
|
|
{
|
|
|
|
|
GType deprecated_type;
|
|
|
|
|
GObject *deprecated_object = NULL;
|
|
|
|
|
|
|
|
|
|
g_test_summary ("Test that trying to instantiate a deprecated type results in a warning.");
|
|
|
|
|
|
|
|
|
|
/* This is the message we print out when registering the type */
|
|
|
|
|
g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_WARNING,
|
|
|
|
|
"*The type TestDeprecated is deprecated and shouldn’t be used any more*");
|
|
|
|
|
|
|
|
|
|
/* The type itself should not be considered invalid. */
|
|
|
|
|
deprecated_type = TEST_TYPE_DEPRECATED;
|
|
|
|
|
g_assert_false (deprecated_type == G_TYPE_INVALID);
|
|
|
|
|
g_assert_true (G_TYPE_IS_DEPRECATED (deprecated_type));
|
|
|
|
|
|
2022-12-12 18:00:10 +01:00
|
|
|
|
g_assert_true (G_TYPE_IS_FINAL (deprecated_type));
|
|
|
|
|
g_assert_true (g_type_test_flags (deprecated_type, G_TYPE_FLAG_FINAL));
|
|
|
|
|
|
|
|
|
|
g_assert_true (g_type_test_flags (deprecated_type,
|
|
|
|
|
G_TYPE_FLAG_DEPRECATED |
|
|
|
|
|
G_TYPE_FLAG_CLASSED |
|
|
|
|
|
G_TYPE_FLAG_FINAL |
|
|
|
|
|
G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
g_assert_false (g_type_test_flags (deprecated_type,
|
|
|
|
|
G_TYPE_FLAG_DEPRECATED |
|
|
|
|
|
G_TYPE_FLAG_CLASSED |
|
|
|
|
|
G_TYPE_FLAG_FINAL |
|
|
|
|
|
G_TYPE_FLAG_ABSTRACT |
|
|
|
|
|
G_TYPE_FLAG_INSTANTIATABLE));
|
|
|
|
|
|
2022-10-21 02:04:01 +02:00
|
|
|
|
/* Instantiating it should work, but emit a warning. */
|
|
|
|
|
deprecated_object = g_object_new (deprecated_type, NULL);
|
|
|
|
|
g_assert_nonnull (deprecated_object);
|
|
|
|
|
|
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
|
|
|
|
|
|
g_object_unref (deprecated_object);
|
|
|
|
|
|
|
|
|
|
/* Instantiating it again should not emit a second warning. */
|
|
|
|
|
deprecated_object = g_object_new (deprecated_type, NULL);
|
|
|
|
|
g_assert_nonnull (deprecated_object);
|
|
|
|
|
|
2022-12-12 18:00:10 +01:00
|
|
|
|
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
|
|
|
|
|
TEST_TYPE_DEPRECATED));
|
|
|
|
|
g_assert_true (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
|
|
|
|
|
G_TYPE_OBJECT));
|
|
|
|
|
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
|
|
|
|
|
TEST_TYPE_FINAL));
|
2022-12-21 20:16:10 +01:00
|
|
|
|
g_assert_false (g_type_check_instance_is_a ((GTypeInstance *) deprecated_object,
|
|
|
|
|
G_TYPE_INVALID));
|
2022-12-12 18:00:10 +01:00
|
|
|
|
|
2022-10-21 02:04:01 +02:00
|
|
|
|
g_test_assert_expected_messages ();
|
|
|
|
|
|
|
|
|
|
g_object_unref (deprecated_object);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 21:10:46 +02:00
|
|
|
|
int
|
|
|
|
|
main (int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
g_test_init (&argc, &argv, NULL);
|
|
|
|
|
|
2022-11-12 21:56:53 +01:00
|
|
|
|
g_setenv ("G_ENABLE_DIAGNOSTIC", "1", TRUE);
|
|
|
|
|
|
2023-04-13 16:39:37 +02:00
|
|
|
|
g_test_add_func ("/type/flags/interface", test_type_flags_interface);
|
2021-07-26 21:10:46 +02:00
|
|
|
|
g_test_add_func ("/type/flags/final", test_type_flags_final);
|
2022-12-12 18:00:10 +01:00
|
|
|
|
g_test_add_func ("/type/flags/final/instance-check", test_type_flags_final_instance_check);
|
2022-10-21 02:04:01 +02:00
|
|
|
|
g_test_add_func ("/type/flags/deprecated", test_type_flags_deprecated);
|
2021-07-26 21:10:46 +02:00
|
|
|
|
|
|
|
|
|
return g_test_run ();
|
|
|
|
|
}
|