automerge/automerge-c/test/ammapput_tests.c
Jason Kankiewicz 5128d1926d Replaced the verb "set" with the verb "put" within
the names of the source files for unit test suites.
2022-04-20 01:00:49 -06:00

190 lines
8.1 KiB
C

#include <float.h>
#include <limits.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
/* third-party */
#include <cmocka.h>
/* local */
#include "group_state.h"
#include "macro_utils.h"
#define test_AMmapPut(suffix) test_AMmapPut ## suffix
#define static_void_test_AMmapPut(suffix, member, scalar_value) \
static void test_AMmapPut ## suffix(void **state) { \
GroupState* group_state = *state; \
AMresult* res = AMmapPut ## suffix( \
group_state->doc, \
AM_ROOT, \
#suffix, \
scalar_value \
); \
if (AMresultStatus(res) != AM_STATUS_OK) { \
fail_msg("%s", AMerrorMessage(res)); \
} \
assert_int_equal(AMresultSize(res), 0); \
AMvalue value = AMresultValue(res, 0); \
assert_int_equal(value.tag, AM_VALUE_NOTHING); \
AMfreeResult(res); \
res = AMmapGet(group_state->doc, AM_ROOT, #suffix); \
if (AMresultStatus(res) != AM_STATUS_OK) { \
fail_msg("%s", AMerrorMessage(res)); \
} \
assert_int_equal(AMresultSize(res), 1); \
value = AMresultValue(res, 0); \
assert_int_equal(value.tag, AMvalue_discriminant(#suffix)); \
assert_true(value.member == scalar_value); \
AMfreeResult(res); \
}
#define test_AMmapPutObject(label) test_AMmapPutObject_ ## label
#define static_void_test_AMmapPutObject(label) \
static void test_AMmapPutObject_ ## label(void **state) { \
GroupState* group_state = *state; \
AMresult* res = AMmapPutObject( \
group_state->doc, \
AM_ROOT, \
#label, \
AMobjType_tag(#label) \
); \
if (AMresultStatus(res) != AM_STATUS_OK) { \
fail_msg("%s", AMerrorMessage(res)); \
} \
assert_int_equal(AMresultSize(res), 1); \
AMvalue value = AMresultValue(res, 0); \
assert_int_equal(value.tag, AM_VALUE_OBJ_ID); \
/** \
* \note The `AMresult` struct can be deallocated immediately when its \
* value is a pointer to an opaque struct because its lifetime \
* is tied to the `AMdoc` struct instead. \
*/ \
AMfreeResult(res); \
assert_non_null(value.obj_id); \
assert_int_equal(AMobjSize(group_state->doc, value.obj_id), 0); \
AMfreeObjId(group_state->doc, value.obj_id); \
}
static void test_AMmapPutBytes(void **state) {
static char const* const KEY = "Bytes";
static uint8_t const BYTES_VALUE[] = {INT8_MIN, INT8_MAX / 2, INT8_MAX};
static size_t const BYTES_SIZE = sizeof(BYTES_VALUE) / sizeof(uint8_t);
GroupState* group_state = *state;
AMresult* res = AMmapPutBytes(
group_state->doc,
AM_ROOT,
KEY,
BYTES_VALUE,
BYTES_SIZE
);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 0);
AMvalue value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_NOTHING);
AMfreeResult(res);
res = AMmapGet(group_state->doc, AM_ROOT, KEY);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 1);
value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_BYTES);
assert_int_equal(value.bytes.count, BYTES_SIZE);
assert_memory_equal(value.bytes.src, BYTES_VALUE, BYTES_SIZE);
AMfreeResult(res);
}
static_void_test_AMmapPut(Counter, counter, INT64_MAX)
static_void_test_AMmapPut(F64, f64, DBL_MAX)
static_void_test_AMmapPut(Int, int_, INT64_MAX)
static void test_AMmapPutNull(void **state) {
static char const* const KEY = "Null";
GroupState* group_state = *state;
AMresult* res = AMmapPutNull(group_state->doc, AM_ROOT, KEY);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 0);
AMvalue value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_NOTHING);
AMfreeResult(res);
res = AMmapGet(group_state->doc, AM_ROOT, KEY);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 1);
value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_NULL);
AMfreeResult(res);
}
static_void_test_AMmapPutObject(List)
static_void_test_AMmapPutObject(Map)
static_void_test_AMmapPutObject(Text)
static void test_AMmapPutStr(void **state) {
static char const* const KEY = "Str";
static char const* const STR_VALUE = "Hello, world!";
size_t const STR_LEN = strlen(STR_VALUE);
GroupState* group_state = *state;
AMresult* res = AMmapPutStr(
group_state->doc,
AM_ROOT,
KEY,
STR_VALUE
);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 0);
AMvalue value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_NOTHING);
AMfreeResult(res);
res = AMmapGet(group_state->doc, AM_ROOT, KEY);
if (AMresultStatus(res) != AM_STATUS_OK) {
fail_msg("%s", AMerrorMessage(res));
}
assert_int_equal(AMresultSize(res), 1);
value = AMresultValue(res, 0);
assert_int_equal(value.tag, AM_VALUE_STR);
assert_int_equal(strlen(value.str), STR_LEN);
assert_memory_equal(value.str, STR_VALUE, STR_LEN + 1);
AMfreeResult(res);
}
static_void_test_AMmapPut(Timestamp, timestamp, INT64_MAX)
static_void_test_AMmapPut(Uint, uint, UINT64_MAX)
int run_AMmapPut_tests(void) {
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_AMmapPutBytes),
cmocka_unit_test(test_AMmapPut(Counter)),
cmocka_unit_test(test_AMmapPut(F64)),
cmocka_unit_test(test_AMmapPut(Int)),
cmocka_unit_test(test_AMmapPutNull),
cmocka_unit_test(test_AMmapPutObject(List)),
cmocka_unit_test(test_AMmapPutObject(Map)),
cmocka_unit_test(test_AMmapPutObject(Text)),
cmocka_unit_test(test_AMmapPutStr),
cmocka_unit_test(test_AMmapPut(Timestamp)),
cmocka_unit_test(test_AMmapPut(Uint)),
};
return cmocka_run_group_tests(tests, group_setup, group_teardown);
}