From 65b8e1a13ad1bc4bc9edcf280ebb28f9779a7a1b Mon Sep 17 00:00:00 2001 From: Fabian Orccon Date: Fri, 21 Apr 2017 17:31:30 -0500 Subject: engine: add peas_engine_create_extension_with_properties() Adds an introspectable variant of peas_engine_create_extension(). Fixes #8 --- libpeas/peas-engine.c | 81 +++++++++++++++++++++ libpeas/peas-engine.h | 9 +++ tests/libpeas/testing/testing-extension.c | 115 ++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) diff --git a/libpeas/peas-engine.c b/libpeas/peas-engine.c index de0b3c4..9ed5af5 100644 --- a/libpeas/peas-engine.c +++ b/libpeas/peas-engine.c @@ -1353,6 +1353,87 @@ peas_engine_create_extensionv (PeasEngine *engine, } G_GNUC_END_IGNORE_DEPRECATIONS +/** + * peas_engine_create_extension_with_properties: (rename-to peas_engine_create_extension) + * @engine: A #PeasEngine. + * @info: A loaded #PeasPluginInfo. + * @extension_type: The implemented extension #GType. + * @n_properties: the length of the @prop_names and @prop_values array. + * @prop_names: (array length=n_properties): an array of property names. + * @prop_values: (array length=n_properties): an array of property values. + * + * If the plugin identified by @info implements the @extension_type, + * then this function will return a new instance of this implementation, + * wrapped in a new #PeasExtension instance. Otherwise, it will return %NULL. + * + * Since libpeas 1.22, @extension_type can be an Abstract #GType + * and not just an Interface #GType. + * + * See peas_engine_create_extension() for more information. + * + * Returns: (transfer full): a new instance of #PeasExtension wrapping + * the @extension_type instance, or %NULL. + * + * Since: 1.24 + */ +PeasExtension * +peas_engine_create_extension_with_properties (PeasEngine *engine, + PeasPluginInfo *info, + GType extension_type, + guint n_properties, + const gchar **prop_names, + const GValue *prop_values) +{ +G_GNUC_BEGIN_IGNORE_DEPRECATIONS + + PeasPluginLoader *loader; + PeasExtension *extension; + GParameter *parameters = NULL; + + g_return_val_if_fail (PEAS_IS_ENGINE (engine), NULL); + g_return_val_if_fail (info != NULL, NULL); + g_return_val_if_fail (G_TYPE_IS_INTERFACE (extension_type) || + G_TYPE_IS_ABSTRACT (extension_type), NULL); + g_return_val_if_fail (peas_plugin_info_is_loaded (info), NULL); + g_return_val_if_fail (n_properties == 0 || prop_names != NULL, NULL); + g_return_val_if_fail (n_properties == 0 || prop_values != NULL, NULL); + + if (n_properties > 0) + { + parameters = g_new (GParameter, n_properties); + if (!peas_utils_properties_array_to_parameter_list (extension_type, + n_properties, + prop_names, + prop_values, + parameters)) + { + /* Already warned */ + g_free (parameters); + return NULL; + } + } + + loader = get_plugin_loader (engine, info->loader_id); + extension = peas_plugin_loader_create_extension (loader, info, extension_type, + n_properties, parameters); + + while (n_properties-- > 0) + g_value_unset (¶meters[n_properties].value); + g_free (parameters); + + if (!G_TYPE_CHECK_INSTANCE_TYPE (extension, extension_type)) + { + g_warning ("Plugin '%s' does not provide a '%s' extension", + peas_plugin_info_get_module_name (info), + g_type_name (extension_type)); + return NULL; + } + + return extension; + +G_GNUC_END_IGNORE_DEPRECATIONS +} + /** * peas_engine_create_extension_valist: (skip) * @engine: A #PeasEngine. diff --git a/libpeas/peas-engine.h b/libpeas/peas-engine.h index 8ccab1d..42a7b03 100644 --- a/libpeas/peas-engine.h +++ b/libpeas/peas-engine.h @@ -136,6 +136,15 @@ PeasExtension *peas_engine_create_extensionv (PeasEngine *engine, GParameter *parameters); G_GNUC_END_IGNORE_DEPRECATIONS +PEAS_AVAILABLE_IN_1_24 +PeasExtension *peas_engine_create_extension_with_properties + (PeasEngine *engine, + PeasPluginInfo *info, + GType extension_type, + guint n_properties, + const gchar **prop_names, + const GValue *prop_values); + PEAS_AVAILABLE_IN_ALL PeasExtension *peas_engine_create_extension_valist (PeasEngine *engine, diff --git a/tests/libpeas/testing/testing-extension.c b/tests/libpeas/testing/testing-extension.c index e00588b..122c274 100644 --- a/tests/libpeas/testing/testing-extension.c +++ b/tests/libpeas/testing/testing-extension.c @@ -144,6 +144,49 @@ test_extension_create_valid (PeasEngine *engine, g_object_unref (extension); } +static void +test_extension_create_valid_without_properties (PeasEngine *engine, + PeasPluginInfo *info) +{ + PeasExtension *extension; + + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_CALLABLE, + 0, NULL, NULL); + + g_assert (PEAS_IS_EXTENSION (extension)); + g_assert (INTROSPECTION_IS_CALLABLE (extension)); + + g_object_unref (extension); +} + +static void +test_extension_create_valid_with_properties (PeasEngine *engine, + PeasPluginInfo *info) +{ + PeasExtension *extension; + IntrospectionAbstract *abstract; + GValue prop_values[1] = { G_VALUE_INIT }; + const gchar *prop_names[1] = { "abstract-property" }; + + g_assert (peas_engine_load_plugin (engine, info)); + + g_value_init (&prop_values[0], G_TYPE_INT); + g_value_set_int (&prop_values[0], 47); + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_ABSTRACT, + G_N_ELEMENTS (prop_values), + prop_names, + prop_values); + abstract = INTROSPECTION_ABSTRACT (extension); + g_assert_cmpint (introspection_abstract_get_value (abstract), ==, 47); + + g_object_unref (extension); + g_value_unset (&prop_values[0]); +} + static void test_extension_create_invalid (PeasEngine *engine, PeasPluginInfo *info) @@ -186,6 +229,72 @@ test_extension_create_invalid (PeasEngine *engine, g_assert (!PEAS_IS_EXTENSION (extension)); } +static void +test_extension_create_invalid_with_properties (PeasEngine *engine, + PeasPluginInfo *info) +{ + PeasExtension *extension; + GValue prop_values[1] = { G_VALUE_INIT }; + const gchar *prop_names[1] = { NULL }; + GValue prop_values2[1] = { G_VALUE_INIT }; + const gchar *prop_names2[1] = { "does-not-exist" }; + + g_value_init (&prop_values[0], G_TYPE_STRING); + g_value_set_string (&prop_values[0], "foo"); + + testing_util_push_log_hook ("*assertion*G_TYPE_IS_INTERFACE*failed"); + testing_util_push_log_hook ("*does not provide a 'IntrospectionUnimplemented' extension"); + testing_util_push_log_hook ("*property name*should not be NULL."); + testing_util_push_log_hook ("*property value*should*initialized GValue."); + testing_util_push_log_hook ("*assertion*peas_plugin_info_is_loaded*failed"); + + /* Invalid GType */ + extension = peas_engine_create_extension_with_properties (engine, info, + G_TYPE_INVALID, 0, + NULL, NULL); + g_assert (!PEAS_IS_EXTENSION (extension)); + + /* GObject but not a GInterface */ + extension = peas_engine_create_extension_with_properties (engine, info, + PEAS_TYPE_ENGINE, 0, + NULL, NULL); + g_assert (!PEAS_IS_EXTENSION (extension)); + + /* Does not implement this GType */ + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_UNIMPLEMENTED, + 0, NULL, NULL); + g_assert (!PEAS_IS_EXTENSION (extension)); + + /* Interface has a NULL property name*/ + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_CALLABLE, + G_N_ELEMENTS (prop_names2), + prop_names, prop_values); + g_assert (!PEAS_IS_EXTENSION (extension)); + + /* Interface has a not initialiazed GValue */ + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_CALLABLE, + G_N_ELEMENTS (prop_names2), + prop_names2, prop_values2); + g_assert (!PEAS_IS_EXTENSION (extension)); + + /* Not loaded */ + g_assert (peas_engine_unload_plugin (engine, info)); + extension = + peas_engine_create_extension_with_properties (engine, info, + INTROSPECTION_TYPE_CALLABLE, + 0, NULL, NULL); + g_assert (!PEAS_IS_EXTENSION (extension)); + + g_value_unset (&prop_values[0]); + +} + static void test_extension_create_with_prerequisite (PeasEngine *engine, PeasPluginInfo *info) @@ -573,7 +682,13 @@ testing_extension_basic (const gchar *loader_) _EXTENSION_TEST (loader, "provides-invalid", provides_invalid); _EXTENSION_TEST (loader, "create-valid", create_valid); + _EXTENSION_TEST (loader, "create-valid-without-properties", + create_valid_without_properties); + _EXTENSION_TEST (loader, "create-valid-with-properties", + create_valid_with_properties); _EXTENSION_TEST (loader, "create-invalid", create_invalid); + _EXTENSION_TEST (loader, "create-invalid-with-properties", + create_invalid_with_properties); _EXTENSION_TEST (loader, "create-with-prerequisite", create_with_prerequisite); _EXTENSION_TEST (loader, "reload", reload); -- cgit v1.2.1