diff --git a/src/fbd-feedback-theme.c b/src/fbd-feedback-theme.c index 6fe8109..f6dd8e0 100644 --- a/src/fbd-feedback-theme.c +++ b/src/fbd-feedback-theme.c @@ -319,3 +319,41 @@ fbd_feedback_theme_lookup_feedback (FbdFeedbackTheme *self, g_debug ("No feedback for event %s", fbd_event_get_event (event)); return feedbacks; } + + +/** + * fbd_feedback_theme_update: + * @self: The feedback theme that should be updated + * @new: The feedback theme we want to take profiles and feedbacks new + * + * Merges two feedback themes. Feedbacks and profiles are read new + * the `new` theme. If feedback already exists in the same profile + * of `self` it is overwritten with the feedback in `new`. + */ +void +fbd_feedback_theme_update (FbdFeedbackTheme *self, FbdFeedbackTheme *new) +{ + GHashTableIter iter; + const char *profile_name; + FbdFeedbackProfile *profile; + + g_return_if_fail (FBD_IS_FEEDBACK_THEME (self)); + g_return_if_fail (FBD_IS_FEEDBACK_THEME (new)); + + fbd_feedback_theme_set_name (self, fbd_feedback_theme_get_name (new)); + + g_hash_table_iter_init (&iter, new->profiles); + while (g_hash_table_iter_next (&iter, (gpointer)&profile_name, (gpointer)&profile)) { + FbdFeedbackProfile *current; + + current = g_hash_table_lookup (self->profiles, profile_name); + if (current == NULL) { + current = fbd_feedback_profile_new (profile_name); + g_hash_table_insert (self->profiles, + g_strdup (profile_name), + current); + } + + fbd_feedback_profile_update (current, profile); + } +} diff --git a/src/fbd-feedback-theme.h b/src/fbd-feedback-theme.h index f9ed3ff..ddddc46 100644 --- a/src/fbd-feedback-theme.h +++ b/src/fbd-feedback-theme.h @@ -21,8 +21,10 @@ G_DECLARE_FINAL_TYPE (FbdFeedbackTheme, fbd_feedback_theme, FBD, FEEDBACK_THEME, FbdFeedbackTheme *fbd_feedback_theme_new (const char *name); FbdFeedbackTheme *fbd_feedback_theme_new_from_data (const gchar *data, GError **error); FbdFeedbackTheme *fbd_feedback_theme_new_from_file (const gchar *filename, GError **error); +void fbd_feedback_theme_update (FbdFeedbackTheme *self, FbdFeedbackTheme *from); const char *fbd_feedback_theme_get_name (FbdFeedbackTheme *self); +void fbd_feedback_theme_set_name (FbdFeedbackTheme *self, const char *name); void fbd_feedback_theme_add_profile (FbdFeedbackTheme *self, FbdFeedbackProfile *profile); FbdFeedbackProfile *fbd_feedback_theme_get_profile (FbdFeedbackTheme *self, const char *name); diff --git a/tests/data/parent/base.json b/tests/data/parent/base.json new file mode 100644 index 0000000..650d625 --- /dev/null +++ b/tests/data/parent/base.json @@ -0,0 +1,30 @@ +{ + "name" : "base", + "profiles" : [ + { + "name" : "full", + "feedbacks" : [ + { + "type" : "Dummy", + "event-name" : "test-dummy-00", + "duration" : 0x01 + }, + { + "type" : "Dummy", + "event-name" : "test-dummy-01", + "duration" : 0x02 + } + ] + }, + { + "name" : "quiet", + "feedbacks" : [ + { + "type" : "Dummy", + "event-name" : "test-dummy-00", + "duration" : 0x03 + } + ] + } + ] +} diff --git a/tests/data/parent/test.json b/tests/data/parent/test.json new file mode 100644 index 0000000..60f863e --- /dev/null +++ b/tests/data/parent/test.json @@ -0,0 +1,40 @@ +{ + "name" : "test", + "profiles" : [ + { + "name" : "full", + "feedbacks" : [ + { + "type" : "Dummy", + "event-name" : "test-dummy-00", + "duration" : 0x10 + }, + { + "type" : "Dummy", + "event-name" : "test-dummy-10", + "duration" : 0x20 + } + ] + }, + { + "name" : "quiet", + "feedbacks" : [ + { + "type" : "Dummy", + "event-name" : "test-dummy-10", + "duration" : 0x30 + } + ] + }, + { + "name" : "silent", + "feedbacks" : [ + { + "type" : "Dummy", + "event-name" : "test-dummy-10", + "duration" : 0x40 + } + ] + } + ] +} diff --git a/tests/meson.build b/tests/meson.build index d9905f5..85b1d7e 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -53,7 +53,8 @@ endforeach if get_option('daemon') test_fbd_cflags = [ - '-DTEST_APP_ID="org.sigxcpu.feedbackd_test"', + '-DTEST_APP_ID="org.sigxcpu.feedbackd_test"', + '-DTEST_DATA_DIR="@0@"'.format(join_paths(meson.current_source_dir(), 'data')), ] test_fbd_link_args = [ diff --git a/tests/test-fbd-feedback-theme.c b/tests/test-fbd-feedback-theme.c index 3e04551..421b4a2 100644 --- a/tests/test-fbd-feedback-theme.c +++ b/tests/test-fbd-feedback-theme.c @@ -116,6 +116,71 @@ test_fbd_feedback_theme_parse (void) fbd_feedback_profile_get_name (profile)); } + +static void +test_fbd_feedback_theme_update (void) +{ + g_autoptr (GError) err = NULL; + FbdFeedbackTheme *theme, *from; + FbdFeedbackProfile *profile; + FbdFeedbackBase *fb; + const char *name; + + /* test-dummy-1x feedbacks */ + from = fbd_feedback_theme_new_from_file (TEST_DATA_DIR "/parent/test.json", &err); + g_assert_no_error (err); + g_assert_true (FBD_IS_FEEDBACK_THEME (from)); + + /* test-dummy-0{0,1} feedbacks */ + theme = fbd_feedback_theme_new_from_file (TEST_DATA_DIR "/parent/base.json", &err); + g_assert_no_error (err); + g_assert_true (FBD_IS_FEEDBACK_THEME (theme)); + + name = fbd_feedback_theme_get_name (from); + g_assert_cmpstr ("test", ==, name); + + name = fbd_feedback_theme_get_name (theme); + g_assert_cmpstr ("base", ==, name); + + /* `theme` is lacking "silent" while `from` has it */ + profile = fbd_feedback_theme_get_profile (theme, "silent"); + g_assert_null (profile); + profile = fbd_feedback_theme_get_profile (from, "silent"); + g_assert_true (FBD_IS_FEEDBACK_PROFILE(profile)); + + fbd_feedback_theme_update (theme, from); + + /* After merging `theme` has a silent profile too */ + profile = fbd_feedback_theme_get_profile (theme, "silent"); + g_assert_true (FBD_IS_FEEDBACK_PROFILE(profile)); + g_assert_cmpstr ("silent", ==, fbd_feedback_profile_get_name (profile)); + + /* Name updated */ + name = fbd_feedback_theme_get_name (theme); + g_assert_cmpstr ("test", ==, name); + + /* test-dummy-10 added */ + profile = fbd_feedback_theme_get_profile (theme, "full"); + fb = fbd_feedback_profile_get_feedback (profile, "test-dummy-10"); + g_assert_cmpstr ("test-dummy-10", ==, fbd_feedback_get_event_name (fb)); + profile = fbd_feedback_theme_get_profile (theme, "quiet"); + fb = fbd_feedback_profile_get_feedback (profile, "test-dummy-10"); + g_assert_cmpstr ("test-dummy-10", ==, fbd_feedback_get_event_name (fb)); + profile = fbd_feedback_theme_get_profile (theme, "silent"); + fb = fbd_feedback_profile_get_feedback (profile, "test-dummy-10"); + g_assert_cmpstr ("test-dummy-10", ==, fbd_feedback_get_event_name (fb)); + + /* test-dummy-00 updated */ + profile = fbd_feedback_theme_get_profile (theme, "full"); + fb = fbd_feedback_profile_get_feedback (profile, "test-dummy-00"); + g_assert_cmpstr ("test-dummy-00", ==, fbd_feedback_get_event_name (fb)); + g_assert_cmpint (fbd_feedback_dummy_get_duration (FBD_FEEDBACK_DUMMY (fb)), ==, 0x10); + + g_assert_finalize_object (from); + g_assert_finalize_object (theme); +} + + gint main (gint argc, gchar *argv[]) { @@ -124,6 +189,7 @@ main (gint argc, gchar *argv[]) g_test_add_func("/feedbackd/fbd/feedback-theme/name", test_fbd_feedback_theme_name); g_test_add_func("/feedbackd/fbd/feedback-theme/profiles", test_fbd_feedback_theme_profiles); g_test_add_func("/feedbackd/fbd/feedback-theme/parse", test_fbd_feedback_theme_parse); + g_test_add_func("/feedbackd/fbd/feedback-theme/update", test_fbd_feedback_theme_update); return g_test_run(); }