diff --git a/src/driver-test.c b/src/driver-test.c index b511ef46..3e72c18c 100644 --- a/src/driver-test.c +++ b/src/driver-test.c @@ -37,6 +37,24 @@ static const struct ratbag_id test_table[] = { { }, }; +static int +test_has_capability(const struct ratbag_device *device, + enum ratbag_device_capability cap) +{ + switch (cap) { + case RATBAG_DEVICE_CAP_NONE: + abort(); + break; + case RATBAG_DEVICE_CAP_SWITCHABLE_RESOLUTION: + case RATBAG_DEVICE_CAP_BUTTON_KEY: + case RATBAG_DEVICE_CAP_BUTTON_MACROS: + return (device->num_profiles > 1); + default: + return 0; + } + return 0; +} + static void test_read_profile(struct ratbag_profile *profile, unsigned int index) { @@ -65,6 +83,14 @@ test_read_profile(struct ratbag_profile *profile, unsigned int index) profile->is_default = p->dflt; } +static int +test_write_profile(struct ratbag_profile *profile) +{ + /* check if the device is still valid */ + assert(ratbag_get_drv_data(profile->device) != NULL); + return 0; +} + static int test_probe(struct ratbag_device *device, const struct ratbag_id id) { @@ -103,9 +129,9 @@ struct ratbag_driver test_driver = { .probe = test_probe, .remove = test_remove, .read_profile = test_read_profile, - .write_profile = NULL, + .write_profile = test_write_profile, .set_active_profile = NULL, - .has_capability = NULL, + .has_capability = test_has_capability, .read_button = NULL, .write_button = NULL, .write_resolution_dpi = NULL, diff --git a/test/test-device.c b/test/test-device.c index 2638ad75..0d0b3ff7 100644 --- a/test/test-device.c +++ b/test/test-device.c @@ -398,6 +398,45 @@ START_TEST(device_resolutions_num_0) } END_TEST +START_TEST(device_freed_before_profile) +{ + struct ratbag *r; + struct ratbag_device *d; + struct ratbag_profile *p; + int is_active, rc; + int device_freed_count = 0; + + struct ratbag_test_device td = sane_device; + + td.destroyed_data = &device_freed_count; + td.profiles[0].active = false; + td.profiles[1].active = true; + + r = ratbag_create_context(&abort_iface, NULL); + d = ratbag_device_new_test_device(r, &td); + ck_assert(d != NULL); + + p = ratbag_device_get_profile_by_index(d, 0); + ck_assert(p != NULL); + is_active = ratbag_profile_is_active(p); + ck_assert_int_eq(is_active, 0); + + d = ratbag_device_unref(d); + /* a ref to d is still kept through p, so d can not be NULL */ + ck_assert(d != NULL); + + rc = ratbag_profile_set_active(p); + ck_assert_int_eq(rc, 0); + + is_active = ratbag_profile_is_active(p); + ck_assert_int_eq(is_active, 1); + + p = ratbag_profile_unref(p); + ratbag_unref(r); + ck_assert_int_eq(device_freed_count, 1); +} +END_TEST + static Suite * test_context_suite(void) { @@ -416,6 +455,7 @@ test_context_suite(void) tcase_add_test(tc, device_profiles_num_0); tcase_add_test(tc, device_profiles_multiple_active); tcase_add_test(tc, device_profiles_get_invalid); + tcase_add_test(tc, device_freed_before_profile); suite_add_tcase(s, tc); tc = tcase_create("resolutions");