tests: Mock libfeedback

Copied from libfeedback as of 2e081602f627505e566cc0bdb6cd96c7642d8b65
and adjusted for our mocking needs.

The mocked library will be LD_PRELOADED for the moment,
but further changes to the build should allow us to simply link
to it in the future.
This commit is contained in:
Evangelos Ribeiro Tzaras
2022-09-19 18:50:53 +02:00
parent b4887fa68a
commit 280527d7a7
10 changed files with 587 additions and 155 deletions

View File

@@ -0,0 +1,49 @@
/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */
#include "lfb-enums.h"
#include "lfb-event.h"
#define C_ENUM(v) ((gint) v)
#define C_FLAGS(v) ((guint) v)
/* enumerations from "lfb-event.h" */
GType
lfb_event_state_get_type (void)
{
static gsize gtype_id = 0;
static const GEnumValue values[] = {
{ C_ENUM(LFB_EVENT_STATE_ERRORED), "LFB_EVENT_STATE_ERRORED", "errored" },
{ C_ENUM(LFB_EVENT_STATE_NONE), "LFB_EVENT_STATE_NONE", "none" },
{ C_ENUM(LFB_EVENT_STATE_RUNNING), "LFB_EVENT_STATE_RUNNING", "running" },
{ C_ENUM(LFB_EVENT_STATE_ENDED), "LFB_EVENT_STATE_ENDED", "ended" },
{ 0, NULL, NULL }
};
if (g_once_init_enter (&gtype_id)) {
GType new_type = g_enum_register_static (g_intern_static_string ("LfbEventState"), values);
g_once_init_leave (&gtype_id, new_type);
}
return (GType) gtype_id;
}
GType
lfb_event_end_reason_get_type (void)
{
static gsize gtype_id = 0;
static const GEnumValue values[] = {
{ C_ENUM(LFB_EVENT_END_REASON_NOT_FOUND), "LFB_EVENT_END_REASON_NOT_FOUND", "not-found" },
{ C_ENUM(LFB_EVENT_END_REASON_NATURAL), "LFB_EVENT_END_REASON_NATURAL", "natural" },
{ C_ENUM(LFB_EVENT_END_REASON_EXPIRED), "LFB_EVENT_END_REASON_EXPIRED", "expired" },
{ C_ENUM(LFB_EVENT_END_REASON_EXPLICIT), "LFB_EVENT_END_REASON_EXPLICIT", "explicit" },
{ 0, NULL, NULL }
};
if (g_once_init_enter (&gtype_id)) {
GType new_type = g_enum_register_static (g_intern_static_string ("LfbEventEndReason"), values);
g_once_init_leave (&gtype_id, new_type);
}
return (GType) gtype_id;
}
/* Generated data ends here */

View File

@@ -0,0 +1,24 @@
/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */
#pragma once
#include <glib-object.h>
G_BEGIN_DECLS
/* enumerations from "lfb-event.h" */
GType lfb_event_state_get_type (void);
#define LFB_TYPE_EVENT_STATE (lfb_event_state_get_type())
GType lfb_event_end_reason_get_type (void);
#define LFB_TYPE_EVENT_END_REASON (lfb_event_end_reason_get_type())
G_END_DECLS
/* Generated data ends here */

348
tests/mock/lfb/lfb-event.c Normal file
View File

@@ -0,0 +1,348 @@
/*
* Copyright (C) 2020 Purism SPC
* SPDX-License-Identifier: LGPL-2.1+
* Author: Guido Günther <agx@sigxcpu.org>
*/
#include "lfb-event.h"
#include "lfb-enums.h"
#include <gio/gio.h>
gboolean success = TRUE;
guint interval_timeout_ms = 50;
enum {
PROP_0,
PROP_EVENT,
PROP_TIMEOUT,
PROP_STATE,
PROP_END_REASON,
PROP_FEEDBACK_PROFILE,
PROP_LAST_PROP,
};
static GParamSpec *props[PROP_LAST_PROP];
enum {
SIGNAL_FEEDBACK_ENDED,
N_SIGNALS,
};
static guint signals[N_SIGNALS];
typedef struct _LfbEvent {
GObject parent;
char *event;
gint timeout;
gchar *profile;
guint id;
LfbEventState state;
gint end_reason;
gulong handler_id;
} LfbEvent;
G_DEFINE_TYPE (LfbEvent, lfb_event, G_TYPE_OBJECT);
typedef struct _LpfAsyncData {
LfbEvent *event;
GTask *task;
} LpfAsyncData;
static void
lfb_event_set_state (LfbEvent *self, LfbEventState state)
{
if (self->state == state)
return;
self->state = state;
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_STATE]);
}
static void
lfb_event_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
LfbEvent *self = LFB_EVENT (object);
switch (property_id) {
case PROP_EVENT:
g_free (self->event);
self->event = g_value_dup_string (value);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_EVENT]);
break;
case PROP_TIMEOUT:
lfb_event_set_timeout (self, g_value_get_int (value));
break;
case PROP_FEEDBACK_PROFILE:
lfb_event_set_feedback_profile (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
lfb_event_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
LfbEvent *self = LFB_EVENT (object);
switch (property_id) {
case PROP_EVENT:
g_value_set_string (value, self->event);
break;
case PROP_TIMEOUT:
g_value_set_int (value, self->timeout);
break;
case PROP_FEEDBACK_PROFILE:
g_value_set_string (value, self->profile);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
lfb_event_finalize (GObject *object)
{
LfbEvent *self = LFB_EVENT (object);
/* Signal handler is disconnected automatically due to g_signal_connect_object */
self->handler_id = 0;
g_clear_pointer (&self->event, g_free);
g_clear_pointer (&self->profile, g_free);
G_OBJECT_CLASS (lfb_event_parent_class)->finalize (object);
}
static void
lfb_event_class_init (LfbEventClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->set_property = lfb_event_set_property;
object_class->get_property = lfb_event_get_property;
object_class->finalize = lfb_event_finalize;
props[PROP_EVENT] =
g_param_spec_string (
"event",
"Event",
"The name of the event triggering the feedback",
NULL,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PROP_TIMEOUT] =
g_param_spec_int (
"timeout",
"Timeout",
"When the event should timeout",
-1, G_MAXINT, -1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
props[PROP_STATE] =
g_param_spec_enum (
"state",
"State",
"The event's state",
LFB_TYPE_EVENT_STATE,
LFB_EVENT_END_REASON_NATURAL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
props[PROP_END_REASON] =
g_param_spec_enum (
"end-reason",
"End reason",
"The reason why the feedbacks ended",
LFB_TYPE_EVENT_END_REASON,
LFB_EVENT_END_REASON_NATURAL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
props[PROP_FEEDBACK_PROFILE] =
g_param_spec_string (
"feedback-profile",
"Feedback profile",
"Feedback profile to use for this event",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY);
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
signals[SIGNAL_FEEDBACK_ENDED] = g_signal_new ("feedback-ended",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL,
NULL,
G_TYPE_NONE,
0);
}
static void
lfb_event_init (LfbEvent *self)
{
self->timeout = -1;
self->state = LFB_EVENT_STATE_NONE;
self->end_reason = LFB_EVENT_END_REASON_NATURAL;
}
LfbEvent *
lfb_event_new (const char *event)
{
return g_object_new (LFB_TYPE_EVENT, "event", event, NULL);
}
/* mock libfeedback functions */
static gboolean
on_mock_timeout (gpointer user_data)
{
GTask *task;
GCancellable *cancellable;
if (!G_IS_TASK (user_data))
return G_SOURCE_REMOVE;
task = G_TASK (user_data);
cancellable = g_task_get_cancellable (task);
if (!g_cancellable_is_cancelled (cancellable))
g_task_return_boolean (task, TRUE);
return G_SOURCE_REMOVE;
}
static gboolean
on_check_task_cancelled (gpointer user_data)
{
GTask *task;
LfbEvent *event;
LfbEventState state;
if (!G_IS_TASK (user_data))
return G_SOURCE_REMOVE;
task = G_TASK (user_data);
event = g_task_get_source_object (task);
state = GPOINTER_TO_INT (g_task_get_task_data (task));
lfb_event_set_state (event, success ? state : LFB_EVENT_STATE_ERRORED);
if (g_task_get_completed (task) || g_task_return_error_if_cancelled (task)) {
g_object_unref (task);
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}
void
lfb_event_trigger_feedback_async (LfbEvent *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
g_return_if_fail (LFB_IS_EVENT (self));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, GINT_TO_POINTER (LFB_EVENT_STATE_RUNNING), NULL);
g_timeout_add (interval_timeout_ms, on_mock_timeout, task);
g_idle_add (G_SOURCE_FUNC (on_check_task_cancelled), task);
}
gboolean
lfb_event_trigger_feedback_finish (LfbEvent *self,
GAsyncResult *res,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
return success;
}
gboolean
lfb_event_end_feedback_finish (LfbEvent *self,
GAsyncResult *res,
GError **error)
{
g_return_val_if_fail (g_task_is_valid (res, self), FALSE);
return success;
}
void
lfb_event_end_feedback_async (LfbEvent *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
g_return_if_fail (LFB_IS_EVENT (self));
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, GINT_TO_POINTER (LFB_EVENT_STATE_ENDED), NULL);
g_timeout_add (interval_timeout_ms, on_mock_timeout, task);
g_idle_add (G_SOURCE_FUNC (on_check_task_cancelled), task);
}
void
lfb_event_set_timeout (LfbEvent *self, gint timeout)
{
g_return_if_fail (LFB_IS_EVENT (self));
if (self->timeout == timeout)
return;
self->timeout = timeout;
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TIMEOUT]);
}
gint
lfb_event_get_timeout (LfbEvent *self)
{
g_return_val_if_fail (LFB_IS_EVENT (self), -1);
return self->timeout;
}
LfbEventState
lfb_event_get_state (LfbEvent *self)
{
g_return_val_if_fail (LFB_IS_EVENT (self), LFB_EVENT_STATE_NONE);
return self->state;
}
void
lfb_event_set_feedback_profile (LfbEvent *self, const gchar *profile)
{
g_return_if_fail (LFB_IS_EVENT (self));
if (!g_strcmp0 (self->profile, profile))
return;
g_free (self->profile);
self->profile = g_strdup (profile);
g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FEEDBACK_PROFILE]);
}
char *
lfb_event_get_feedback_profile (LfbEvent *self)
{
g_return_val_if_fail (LFB_IS_EVENT (self), NULL);
return g_strdup (self->profile);
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2020 Purism SPC
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <gio/gio.h>
#include <glib-object.h>
G_BEGIN_DECLS
/* values used for mocking */
extern gboolean success;
extern guint interval_timeout_ms;
typedef enum _LfbEventState {
LFB_EVENT_STATE_ERRORED = -1,
LFB_EVENT_STATE_NONE = 0,
LFB_EVENT_STATE_RUNNING = 1,
LFB_EVENT_STATE_ENDED = 2,
} LfbEventState;
typedef enum _LfbEventEndReason {
LFB_EVENT_END_REASON_NOT_FOUND = -1,
LFB_EVENT_END_REASON_NATURAL = 0,
LFB_EVENT_END_REASON_EXPIRED = 1,
LFB_EVENT_END_REASON_EXPLICIT = 2,
} LfbEventEndReason;
#define LFB_TYPE_EVENT (lfb_event_get_type())
G_DECLARE_FINAL_TYPE (LfbEvent, lfb_event, LFB, EVENT, GObject)
LfbEvent* lfb_event_new (const char *event);
void lfb_event_trigger_feedback_async (LfbEvent *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean lfb_event_trigger_feedback_finish (LfbEvent *self,
GAsyncResult *res,
GError **error);
void lfb_event_end_feedback_async (LfbEvent *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean lfb_event_end_feedback_finish (LfbEvent *self,
GAsyncResult *res,
GError **error);
void lfb_event_set_timeout (LfbEvent *self, gint timeout);
gint lfb_event_get_timeout (LfbEvent *self);
void lfb_event_set_feedback_profile (LfbEvent *self, const char *profile);
char *lfb_event_get_feedback_profile (LfbEvent *self);
LfbEventState lfb_event_get_state (LfbEvent *self);
G_END_DECLS

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2020 Purism SPC
* SPDX-License-Identifier: LGPL-2.1+
* Author: Guido Günther <agx@sigxcpu.org>
*/
#include "libfeedback.h"
static gboolean _initted;
gboolean
lfb_init (const gchar *app_id, GError **error)
{
_initted = TRUE;
g_debug ("libfeedback mock library initialized");
return TRUE;
}
void
lfb_uninit (void)
{
_initted = FALSE;
}
gboolean
lfb_is_initted (void)
{
return _initted;
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (C) 2020 Purism SPC
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#pragma once
#include <glib.h>
G_BEGIN_DECLS
#include "lfb-enums.h"
#include "lfb-event.h"
gboolean lfb_init (const gchar *app_id, GError **error);
void lfb_uninit (void);
gboolean lfb_is_initted (void);
G_END_DECLS

View File

@@ -0,0 +1,52 @@
libfeedback_libdir = get_option('libdir')
libfeedback_link_args = []
libfeedback_symbols_file = 'libfeedback.syms'
lfb_enum_headers = files([
'lfb-event.h',
])
libfeedback_headers = [
'libfeedback.h',
'lfb-event.h',
]
libfeedback_sources = [
'lfb-enums.c',
libfeedback_headers,
'libfeedback.c',
'lfb-event.c',
]
gio = dependency('gio-2.0', version: '>=2.50.0')
glib = dependency('glib-2.0', version: '>=2.50.0')
gobject = dependency('gobject-2.0', version: '>=2.50.0')
libfeedback_deps = [
gio,
glib,
gobject,
]
libfeedback_c_args = [
'-DG_LOG_DOMAIN="libfeedback"',
]
libtype = 'shared_library'
libfeedback = build_target(
'feedback-0',
libfeedback_sources,
soversion : 0,
c_args : libfeedback_c_args,
dependencies : libfeedback_deps,
link_args : [],
install : false,
target_type : libtype,
)
libfeedback_inc = include_directories('.')
libfeedback_dep = declare_dependency(
link_with : libfeedback,
dependencies: libfeedback_deps,
include_directories : libfeedback_inc,
)

1
tests/mock/meson.build Normal file
View File

@@ -0,0 +1 @@
subdir('lfb')