From e1c348b96e368df0b566292fc3560e3d4b5e70c6 Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Wed, 26 Jan 2022 02:15:52 +0000 Subject: [PATCH] tc_replica_get_task --- .../src/bindings_tests/replica.c | 78 +++++++++++++++++++ integration-tests/src/bindings_tests/task.c | 23 ------ lib/src/replica.rs | 22 +++++- lib/taskchampion.h | 8 ++ 4 files changed, 107 insertions(+), 24 deletions(-) diff --git a/integration-tests/src/bindings_tests/replica.c b/integration-tests/src/bindings_tests/replica.c index 613b15666..756c9acfe 100644 --- a/integration-tests/src/bindings_tests/replica.c +++ b/integration-tests/src/bindings_tests/replica.c @@ -29,11 +29,89 @@ static void test_replica_undo_empty(void) { tc_replica_free(rep); } +// creating a task succeeds and the resulting task looks good +static void test_replica_task_creation(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + + TCTask *task = tc_replica_new_task( + rep, + TC_STATUS_PENDING, + tc_string_borrow("my task")); + TEST_ASSERT_NOT_NULL(task); + + TCUuid uuid = tc_task_get_uuid(task); + TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); + + TCString *desc = tc_task_get_description(task); + TEST_ASSERT_NOT_NULL(desc); + TEST_ASSERT_EQUAL_STRING("my task", tc_string_content(desc)); + tc_string_free(desc); + + tc_task_free(task); + + // get the task again and verify it + task = tc_replica_get_task(rep, uuid); + TEST_ASSERT_NOT_NULL(task); + TEST_ASSERT_EQUAL_MEMORY(uuid.bytes, tc_task_get_uuid(task).bytes, sizeof(uuid.bytes)); + TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); + + tc_task_free(task); + + tc_replica_free(rep); +} + +// importing a task succeeds and the resulting task looks good +static void test_replica_task_import(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + + TCUuid uuid; + TEST_ASSERT_TRUE(tc_uuid_from_str(tc_string_borrow("23cb25e0-5d1a-4932-8131-594ac6d3a843"), &uuid)); + TCTask *task = tc_replica_import_task_with_uuid(rep, uuid); + TEST_ASSERT_NOT_NULL(task); + + TEST_ASSERT_EQUAL_MEMORY(uuid.bytes, tc_task_get_uuid(task).bytes, sizeof(uuid.bytes)); + TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); + + TCString *desc = tc_task_get_description(task); + TEST_ASSERT_NOT_NULL(desc); + TEST_ASSERT_EQUAL_STRING("", tc_string_content(desc)); // default value + tc_string_free(desc); + + tc_task_free(task); + + // get the task again and verify it + task = tc_replica_get_task(rep, uuid); + TEST_ASSERT_NOT_NULL(task); + TEST_ASSERT_EQUAL_MEMORY(uuid.bytes, tc_task_get_uuid(task).bytes, sizeof(uuid.bytes)); + TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); + + tc_task_free(task); + + tc_replica_free(rep); +} + +// importing a task succeeds and the resulting task looks good +static void test_replica_get_task_not_found(void) { + TCReplica *rep = tc_replica_new_in_memory(); + TEST_ASSERT_NULL(tc_replica_error(rep)); + + TCUuid uuid; + TEST_ASSERT_TRUE(tc_uuid_from_str(tc_string_borrow("23cb25e0-5d1a-4932-8131-594ac6d3a843"), &uuid)); + TCTask *task = tc_replica_get_task(rep, uuid); + TEST_ASSERT_NULL(task); + TEST_ASSERT_NULL(tc_replica_error(rep)); +} + int replica_tests(void) { UNITY_BEGIN(); // each test case above should be named here, in order. RUN_TEST(test_replica_creation); RUN_TEST(test_replica_creation_disk); RUN_TEST(test_replica_undo_empty); + RUN_TEST(test_replica_task_creation); + RUN_TEST(test_replica_task_import); + RUN_TEST(test_replica_get_task_not_found); return UNITY_END(); } diff --git a/integration-tests/src/bindings_tests/task.c b/integration-tests/src/bindings_tests/task.c index bd9e14f4b..b0bbc4117 100644 --- a/integration-tests/src/bindings_tests/task.c +++ b/integration-tests/src/bindings_tests/task.c @@ -26,32 +26,9 @@ static void test_task_creation(void) { tc_replica_free(rep); } -// importing a task succeeds and the resulting task looks good -static void test_task_import(void) { - TCReplica *rep = tc_replica_new_in_memory(); - TEST_ASSERT_NULL(tc_replica_error(rep)); - - TCUuid uuid; - TEST_ASSERT_TRUE(tc_uuid_from_str(tc_string_borrow("23cb25e0-5d1a-4932-8131-594ac6d3a843"), &uuid)); - TCTask *task = tc_replica_import_task_with_uuid(rep, uuid); - TEST_ASSERT_NOT_NULL(task); - - TEST_ASSERT_EQUAL(TC_STATUS_PENDING, tc_task_get_status(task)); - - TCString *desc = tc_task_get_description(task); - TEST_ASSERT_NOT_NULL(desc); - TEST_ASSERT_EQUAL_STRING("", tc_string_content(desc)); // default value - tc_string_free(desc); - - tc_task_free(task); - - tc_replica_free(rep); -} - int task_tests(void) { UNITY_BEGIN(); // each test case above should be named here, in order. RUN_TEST(test_task_creation); - RUN_TEST(test_task_import); return UNITY_END(); } diff --git a/lib/src/replica.rs b/lib/src/replica.rs index f77612b41..6bb89b209 100644 --- a/lib/src/replica.rs +++ b/lib/src/replica.rs @@ -27,6 +27,7 @@ where F: FnOnce(&mut Replica) -> anyhow::Result, { let rep: &'a mut TCReplica = rep_ref(rep); + rep.error = None; match f(&mut rep.inner) { Ok(v) => v, Err(e) => { @@ -83,7 +84,26 @@ pub extern "C" fn tc_replica_new_on_disk<'a>( // TODO: tc_replica_all_tasks // TODO: tc_replica_all_task_uuids // TODO: tc_replica_working_set -// TODO: tc_replica_get_task + +/// Get an existing task by its UUID. +/// +/// Returns NULL when the task does not exist, and on error. Consult tc_replica_error +/// to distinguish the two conditions. +#[no_mangle] +pub extern "C" fn tc_replica_get_task(rep: *mut TCReplica, uuid: TCUuid) -> *mut TCTask { + wrap( + rep, + |rep| { + let uuid: Uuid = uuid.into(); + if let Some(task) = rep.get_task(uuid)? { + Ok(TCTask::as_ptr(task)) + } else { + Ok(std::ptr::null_mut()) + } + }, + std::ptr::null_mut(), + ) +} /// Create a new task. The task must not already exist. /// diff --git a/lib/taskchampion.h b/lib/taskchampion.h index a82ef49a3..466e98994 100644 --- a/lib/taskchampion.h +++ b/lib/taskchampion.h @@ -84,6 +84,14 @@ struct TCReplica *tc_replica_new_in_memory(void); */ struct TCReplica *tc_replica_new_on_disk(struct TCString *path, struct TCString **error_out); +/** + * Get an existing task by its UUID. + * + * Returns NULL when the task does not exist, and on error. Consult tc_replica_error + * to distinguish the two conditions. + */ +struct TCTask *tc_replica_get_task(struct TCReplica *rep, struct TCUuid uuid); + /** * Create a new task. The task must not already exist. *