2023-10-16 18:20:08 +07:00

7726 lines
202 KiB
C

/*
* SPDX-License-Identifier: ISC
*
* Copyright (C) 2017-2021 Michael Drake <tlsa@netsurf-browser.org>
*/
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <cyaml/cyaml.h>
#include "../../src/data.h"
#include "ttest.h"
#include "test.h"
/** Macro to squash unused variable compiler warnings. */
#define UNUSED(_x) ((void)(_x))
/** Helper macro to count bytes of YAML input data. */
#define YAML_LEN(_y) (sizeof(_y) - 1)
/**
* Unit test context data.
*/
typedef struct test_data {
cyaml_data_t **data;
unsigned *seq_count;
const struct cyaml_config *config;
const struct cyaml_schema_value *schema;
} test_data_t;
/**
* Common clean up function to free data loaded by tests.
*
* \param[in] data The unit test context data.
*/
static void cyaml_cleanup(void *data)
{
struct test_data *td = data;
unsigned seq_count = 0;
if (td->seq_count != NULL) {
seq_count = *(td->seq_count);
}
if (td->data != NULL) {
cyaml_free(td->config, td->schema, *(td->data), seq_count);
}
}
/**
* Test loading a positive signed integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int_pos(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int value = 90;
static const unsigned char yaml[] =
"test_int: 90\n";
struct target_struct {
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_int != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a negative signed integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int_neg(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int value = -77;
static const unsigned char yaml[] =
"test_int: -77\n";
struct target_struct {
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_int != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a positive signed integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int_pos_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int value = 90;
static const unsigned char yaml[] =
"test_int: 90\n";
struct target_struct {
int *test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT_PTR("test_int", CYAML_FLAG_POINTER,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_int != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a negative signed integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int_neg_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int value = -77;
static const unsigned char yaml[] =
"test_int: -77\n";
struct target_struct {
int *test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT_PTR("test_int", CYAML_FLAG_POINTER,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_int != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an unsigned integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_uint(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
unsigned value = 9999;
static const unsigned char yaml[] =
"test_uint: 9999\n";
struct target_struct {
unsigned test_value_uint;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_UINT("test_uint", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_uint),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_uint != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to an unsigned integer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_uint_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
unsigned value = 9999;
static const unsigned char yaml[] =
"test_uint: 9999\n";
struct target_struct {
unsigned *test_value_uint;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_UINT_PTR("test_uint", CYAML_FLAG_POINTER,
struct target_struct, test_value_uint),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_uint != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a float.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_float(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
float value = 3.14159f;
static const unsigned char yaml[] =
"test_fp: 3.14159\n";
struct target_struct {
float test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT("test_fp", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %f, got: %f",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a float.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_float_underflow(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
float value = 1.55331e-40f;
static const unsigned char yaml[] =
"test_fp: 1.55331e-40\n";
struct target_struct {
float test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT("test_fp", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %e, got: %e",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a pointer to float.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_float_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
float value = 3.14159f;
static const unsigned char yaml[] =
"test_fp: 3.14159\n";
struct target_struct {
float *test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT_PTR("test_fp", CYAML_FLAG_POINTER,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %lf, got: %lf",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a double.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_double(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
double value = 3.14159;
static const unsigned char yaml[] =
"test_fp: 3.14159\n";
struct target_struct {
double test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT("test_fp", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %lf, got: %lf",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a double.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_double_underflow(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
double value = 1.79769e+308;
static const unsigned char yaml[] =
"test_fp: 1.79769e+309\n";
struct target_struct {
double test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT("test_fp", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
value *= 10;
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %lf, got: %lf",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a floating point value as a pointer to double.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_double_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
double value = 3.14159;
static const unsigned char yaml[] =
"test_fp: 3.14159\n";
struct target_struct {
double *test_value_fp;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLOAT_PTR("test_fp", CYAML_FLAG_POINTER,
struct target_struct, test_value_fp),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_fp != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %lf, got: %lf",
value, data_tgt->test_value_fp);
}
return ttest_pass(&tc);
}
/**
* Test loading a boolean value (true).
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bool_true(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool value = true;
static const unsigned char yaml[] =
"test_bool: true\n";
struct target_struct {
unsigned test_value_bool;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BOOL("test_bool", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_bool),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_bool != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a boolean value (false).
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bool_false(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool value = false;
static const unsigned char yaml[] =
"test_bool: false\n";
struct target_struct {
unsigned test_value_bool;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BOOL("test_bool", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_bool),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_bool != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a boolean value (true).
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bool_true_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool value = true;
static const unsigned char yaml[] =
"test_bool: true\n";
struct target_struct {
unsigned *test_value_bool;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BOOL_PTR("test_bool", CYAML_FLAG_POINTER,
struct target_struct, test_value_bool),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_bool != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a boolean value (false).
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bool_false_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool value = false;
static const unsigned char yaml[] =
"test_bool: false\n";
struct target_struct {
unsigned *test_value_bool;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BOOL_PTR("test_bool", CYAML_FLAG_POINTER,
struct target_struct, test_value_bool),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_bool != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an enumeration.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_enum(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST,
TEST_ENUM_SECOND,
TEST_ENUM_THIRD,
TEST_ENUM__COUNT,
} value = TEST_ENUM_SECOND;
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
[TEST_ENUM_FIRST] = { "first", 0 },
[TEST_ENUM_SECOND] = { "second", 1 },
[TEST_ENUM_THIRD] = { "third", 2 },
};
static const unsigned char yaml[] =
"test_enum: second\n";
struct target_struct {
enum test_enum test_value_enum;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_ENUM("test_enum", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_enum,
strings, TEST_ENUM__COUNT),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_enum != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to an enumeration.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_enum_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST,
TEST_ENUM_SECOND,
TEST_ENUM_THIRD,
TEST_ENUM__COUNT,
} value = TEST_ENUM_SECOND;
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
[TEST_ENUM_FIRST] = { "first", 0 },
[TEST_ENUM_SECOND] = { "second", 1 },
[TEST_ENUM_THIRD] = { "third", 2 },
};
static const unsigned char yaml[] =
"test_enum: second\n";
struct target_struct {
enum test_enum *test_value_enum;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_ENUM_PTR("test_enum", CYAML_FLAG_POINTER,
struct target_struct, test_value_enum,
strings, TEST_ENUM__COUNT),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_enum != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a sparse enumeration.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_enum_sparse(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST = 3,
TEST_ENUM_SECOND = 77,
TEST_ENUM_THIRD = 183,
TEST_ENUM_FOURTH = 9900,
} value = TEST_ENUM_SECOND;
static const cyaml_strval_t strings[] = {
{ "first", TEST_ENUM_FIRST },
{ "second", TEST_ENUM_SECOND },
{ "third", TEST_ENUM_THIRD },
{ "fourth", TEST_ENUM_FOURTH },
};
static const unsigned char yaml[] =
"test_enum: second\n";
struct target_struct {
enum test_enum test_value_enum;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_ENUM("test_enum", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_enum,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_enum != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an enumeration with numerical fallback.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_enum_fallback(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST = 3,
TEST_ENUM_SECOND = 77,
TEST_ENUM_THIRD = 183,
TEST_ENUM_FOURTH = 9900,
} value = TEST_ENUM_SECOND;
static const cyaml_strval_t strings[] = {
{ "first", TEST_ENUM_FIRST },
{ "second", TEST_ENUM_SECOND },
{ "third", TEST_ENUM_THIRD },
{ "fourth", TEST_ENUM_FOURTH },
};
static const unsigned char yaml[] =
"test_enum: 77\n";
struct target_struct {
enum test_enum test_value_enum;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_ENUM("test_enum", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_enum,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_enum != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a string to a character array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_string(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *value = "Hello World!";
static const unsigned char yaml[] =
"test_string: Hello World!\n";
struct target_struct {
char test_value_string[50];
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING("test_string", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_string, 0),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, value) != 0) {
fprintf(stderr, "expected: %s\n", value);
for (unsigned i = 0; i < strlen(value) + 1; i++) {
fprintf(stderr, "%2.2x ", value[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, " got: %s\n", data_tgt->test_value_string);
for (unsigned i = 0; i < sizeof(data_tgt->test_value_string); i++) {
fprintf(stderr, "%2.2x ", value[i]);
}
fprintf(stderr, "\n");
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a string to an allocated char pointer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_string_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *value = "null";
static const unsigned char yaml[] =
"test_string: null\n";
struct target_struct {
char * test_value_string;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, value) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an empty string to an allocated char pointer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_string_ptr_empty(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *value = "";
static const unsigned char yaml[] =
"test_string:\n";
struct target_struct {
char * test_value_string;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, value) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a null string to an allocated nullable char pointer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_string_ptr_null_str(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *value = NULL;
static const unsigned char yaml[] =
"test_string: null\n";
struct target_struct {
char * test_value_string;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("test_string",
CYAML_FLAG_POINTER_NULL_STR,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_string != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an empty string to an allocated nullable char pointer.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_string_ptr_null_empty(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *value = NULL;
static const unsigned char yaml[] =
"test_string:\n";
struct target_struct {
char * test_value_string;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER_NULL,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_string != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an ignored value with descendants.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_ignore_deep(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"ignore:\n"
" foo: bar\n"
" bar:\n"
" - 1\n"
" - 2\n";
struct target_struct {
bool foo;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("ignore", CYAML_FLAG_DEFAULT),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->foo != false) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading an ignored value.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_ignore_scalar(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"ignore: foo\n";
struct target_struct {
bool foo;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("ignore", CYAML_FLAG_DEFAULT),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->foo != false) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a flag word.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_flags(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 1),
TEST_FLAGS_THIRD = (1 << 2),
TEST_FLAGS_FOURTH = (1 << 3),
TEST_FLAGS_FIFTH = (1 << 4),
TEST_FLAGS_SIXTH = (1 << 5),
} value = TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH | 1024;
static const cyaml_strval_t strings[] = {
{ "none", TEST_FLAGS_NONE },
{ "first", TEST_FLAGS_FIRST },
{ "second", TEST_FLAGS_SECOND },
{ "third", TEST_FLAGS_THIRD },
{ "fourth", TEST_FLAGS_FOURTH },
{ "fifth", TEST_FLAGS_FIFTH },
{ "sixth", TEST_FLAGS_SIXTH },
};
static const unsigned char yaml[] =
"test_flags:\n"
" - second\n"
" - fifth\n"
" - 1024\n";
struct target_struct {
enum test_flags test_value_flags;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLAGS("test_flags", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_flags,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_flags != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_flags);
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a flag word.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_flags_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 1),
TEST_FLAGS_THIRD = (1 << 2),
TEST_FLAGS_FOURTH = (1 << 3),
TEST_FLAGS_FIFTH = (1 << 4),
TEST_FLAGS_SIXTH = (1 << 5),
} value = TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH | 1024;
static const cyaml_strval_t strings[] = {
{ "none", TEST_FLAGS_NONE },
{ "first", TEST_FLAGS_FIRST },
{ "second", TEST_FLAGS_SECOND },
{ "third", TEST_FLAGS_THIRD },
{ "fourth", TEST_FLAGS_FOURTH },
{ "fifth", TEST_FLAGS_FIFTH },
{ "sixth", TEST_FLAGS_SIXTH },
};
static const unsigned char yaml[] =
"test_flags:\n"
" - second\n"
" - fifth\n"
" - 1024\n";
struct target_struct {
enum test_flags *test_value_flags;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLAGS_PTR("test_flags", CYAML_FLAG_POINTER,
struct target_struct, test_value_flags,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_flags != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_flags);
}
return ttest_pass(&tc);
}
/**
* Test loading an empty flag word.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_flags_empty(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 1),
TEST_FLAGS_THIRD = (1 << 2),
TEST_FLAGS_FOURTH = (1 << 3),
TEST_FLAGS_FIFTH = (1 << 4),
TEST_FLAGS_SIXTH = (1 << 5),
} value = TEST_FLAGS_NONE;
static const cyaml_strval_t strings[] = {
{ "none", TEST_FLAGS_NONE },
{ "first", TEST_FLAGS_FIRST },
{ "second", TEST_FLAGS_SECOND },
{ "third", TEST_FLAGS_THIRD },
{ "fourth", TEST_FLAGS_FOURTH },
{ "fifth", TEST_FLAGS_FIFTH },
{ "sixth", TEST_FLAGS_SIXTH },
};
static const unsigned char yaml[] =
"test_flags: []\n";
struct target_struct {
enum test_flags test_value_flags;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLAGS("test_flags", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_flags,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_flags != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_flags);
}
return ttest_pass(&tc);
}
/**
* Test loading a sparse flag word.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_flags_sparse(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 4),
TEST_FLAGS_THIRD = (1 << 7),
TEST_FLAGS_FOURTH = (1 << 11),
TEST_FLAGS_FIFTH = (1 << 14),
TEST_FLAGS_SIXTH = (1 << 20),
} value = TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH;
static const cyaml_strval_t strings[] = {
{ "none", TEST_FLAGS_NONE },
{ "first", TEST_FLAGS_FIRST },
{ "second", TEST_FLAGS_SECOND },
{ "third", TEST_FLAGS_THIRD },
{ "fourth", TEST_FLAGS_FOURTH },
{ "fifth", TEST_FLAGS_FIFTH },
{ "sixth", TEST_FLAGS_SIXTH },
};
static const unsigned char yaml[] =
"test_flags:\n"
" - second\n"
" - fifth\n";
struct target_struct {
enum test_flags test_value_flags;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_FLAGS("test_flags", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_flags,
strings, CYAML_ARRAY_LEN(strings)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_flags != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_flags);
}
return ttest_pass(&tc);
}
/**
* Test loading a bitfield.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bitfield(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
uint64_t value = 0xFFFFFFFFFFFFFFFFu;
static const cyaml_bitdef_t bitvals[] = {
{ .name = "a", .offset = 0, .bits = 3 },
{ .name = "b", .offset = 3, .bits = 7 },
{ .name = "c", .offset = 10, .bits = 32 },
{ .name = "d", .offset = 42, .bits = 8 },
{ .name = "e", .offset = 50, .bits = 14 },
};
static const unsigned char yaml[] =
"test_bitfield:\n"
" a: 0x7\n"
" b: 0x7f\n"
" c: 0xffffffff\n"
" d: 0xff\n"
" e: 0x3fff\n";
struct target_struct {
uint64_t test_value_bitfield;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BITFIELD("test_bitfield", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_bitfield,
bitvals, CYAML_ARRAY_LEN(bitvals)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_bitfield != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_bitfield);
}
return ttest_pass(&tc);
}
/**
* Test loading a pointer to a bitfield.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_bitfield_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
uint64_t value = 0xFFFFFFFFFFFFFFFFu;
static const cyaml_bitdef_t bitvals[] = {
{ .name = "a", .offset = 0, .bits = 3 },
{ .name = "b", .offset = 3, .bits = 7 },
{ .name = "c", .offset = 10, .bits = 32 },
{ .name = "d", .offset = 42, .bits = 8 },
{ .name = "e", .offset = 50, .bits = 14 },
};
static const unsigned char yaml[] =
"test_bitfield:\n"
" a: 0x7\n"
" b: 0x7f\n"
" c: 0xffffffff\n"
" d: 0xff\n"
" e: 0x3fff\n";
struct target_struct {
uint64_t *test_value_bitfield;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_BITFIELD_PTR("test_bitfield", CYAML_FLAG_POINTER,
struct target_struct, test_value_bitfield,
bitvals, CYAML_ARRAY_LEN(bitvals)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt->test_value_bitfield != value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: 0x%x, got: 0x%x\n",
value, data_tgt->test_value_bitfield);
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping, to an internal structure.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_mapping(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} value;
static const unsigned char yaml[] =
"mapping:\n"
" a: 123\n"
" b: 9999\n";
struct target_struct {
struct value_s test_value_mapping;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_MAPPING("mapping", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_mapping,
test_mapping_schema),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
memset(&value, 0, sizeof(value));
value.a = 123;
value.b = 9999;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (memcmp(&data_tgt->test_value_mapping, &value, sizeof(value)) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping, to an allocated structure.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_mapping_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} value;
static const unsigned char yaml[] =
"mapping:\n"
" a: 123\n"
" b: 9999\n";
struct target_struct {
struct value_s *test_value_mapping;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_MAPPING_PTR("mapping", CYAML_FLAG_POINTER,
struct target_struct, test_value_mapping,
test_mapping_schema),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
memset(&value, 0, sizeof(value));
value.a = 123;
value.b = 9999;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (memcmp(data_tgt->test_value_mapping, &value, sizeof(value)) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers into an int[].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of enums into an enum test_enum[].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_enum(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST,
TEST_ENUM_SECOND,
TEST_ENUM_THIRD,
TEST_ENUM__COUNT,
} ref[] = { TEST_ENUM_FIRST, TEST_ENUM_SECOND, TEST_ENUM_THIRD };
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
[TEST_ENUM_FIRST] = { "first", 0 },
[TEST_ENUM_SECOND] = { "second", 1 },
[TEST_ENUM_THIRD] = { "third", 2 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - first\n"
" - second\n"
" - third\n";
struct target_struct {
enum test_enum seq[CYAML_ARRAY_LEN(ref)];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_ENUM(CYAML_FLAG_DEFAULT,
*(data_tgt->seq), strings, TEST_ENUM__COUNT),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of unsigned integers into an unsigned[].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_uint(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
unsigned ref[] = { 99999, 99998, 99997, 99996, 99995, 99994 };
static const unsigned char yaml[] =
"sequence:\n"
" - 99999\n"
" - 99998\n"
" - 99997\n"
" - 99996\n"
" - 99995\n"
" - 99994\n";
struct target_struct {
unsigned seq[CYAML_ARRAY_LEN(ref)];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of boolean values into an bool[].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_bool(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool ref[] = { true, false, true, false, true, false, true, false };
static const unsigned char yaml[] =
"sequence:\n"
" - true\n"
" - false\n"
" - yes\n"
" - no\n"
" - enable\n"
" - disable\n"
" - 1\n"
" - 0\n";
struct target_struct {
bool seq[CYAML_ARRAY_LEN(ref)];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_BOOL(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of flag sequences into an array of flag words.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_flags(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 1),
TEST_FLAGS_THIRD = (1 << 2),
TEST_FLAGS_FOURTH = (1 << 3),
TEST_FLAGS_FIFTH = (1 << 4),
TEST_FLAGS_SIXTH = (1 << 5),
} ref[3] = {
TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH | 1024,
TEST_FLAGS_FIRST,
TEST_FLAGS_FOURTH | TEST_FLAGS_SIXTH
};
#define TEST_FLAGS__COUNT 6
static const cyaml_strval_t strings[TEST_FLAGS__COUNT] = {
{ "first", (1 << 0) },
{ "second", (1 << 1) },
{ "third", (1 << 2) },
{ "fourth", (1 << 3) },
{ "fifth", (1 << 4) },
{ "sixth", (1 << 5) },
};
static const unsigned char yaml[] =
"sequence:\n"
" - - second\n"
" - fifth\n"
" - 1024\n"
" - - first\n"
" - - fourth\n"
" - sixth\n";
struct target_struct {
enum test_flags seq[3];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_FLAGS(CYAML_FLAG_DEFAULT, *(data_tgt->seq),
strings, TEST_FLAGS__COUNT),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(data_tgt->seq)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of strings into an array of char[7].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_string(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *ref[] = {
"This",
"is",
"merely",
"a",
"test",
};
static const unsigned char yaml[] =
"sequence:\n"
" - This\n"
" - is\n"
" - merely\n"
" - a\n"
" - test\n";
struct target_struct {
char seq[5][7];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_DEFAULT, *(data_tgt->seq), 0, 6),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (strcmp(data_tgt->seq[i], ref[i]) != 0) {
return ttest_fail(&tc, "Incorrect value (i=%u)", i);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of strings into an array of allocated strings.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_string_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *ref[] = {
"This",
"is",
"merely",
"a",
"test",
};
static const unsigned char yaml[] =
"sequence:\n"
" - This\n"
" - is\n"
" - merely\n"
" - a\n"
" - test\n";
struct target_struct {
char *seq[5];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, *(data_tgt->seq),
0, CYAML_UNLIMITED),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (strcmp(data_tgt->seq[i], ref[i]) != 0) {
return ttest_fail(&tc, "Incorrect value (i=%u)", i);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of mappings into an array of structures.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_mapping(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} ref[3];
static const unsigned char yaml[] =
"sequence:\n"
" - a: 123\n"
" b: 9999\n"
" - a: 4000\n"
" b: 62000\n"
" - a: 1\n"
" b: 765\n";
struct target_struct {
struct value_s seq[3];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT,
struct value_s, test_mapping_schema),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(data_tgt->seq)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
memset(ref, 0, sizeof(ref));
ref[0].a = 123;
ref[0].b = 9999;
ref[1].a = 4000;
ref[1].b = 62000;
ref[2].a = 1;
ref[2].b = 765;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
if (memcmp(data_tgt->seq, ref, sizeof(ref)) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of mappings into an array of pointers to structs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_mapping_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} ref[3] = {
{ .a = 123, .b = 9999, },
{ .a = 4000, .b = 62000, },
{ .a = 1, .b = 765, },
};
static const unsigned char yaml[] =
"sequence:\n"
" - a: 123\n"
" b: 9999\n"
" - a: 4000\n"
" b: 62000\n"
" - a: 1\n"
" b: 765\n";
struct target_struct {
struct value_s *seq[3];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct value_s, test_mapping_schema),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(data_tgt->seq)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (ref[i].a != data_tgt->seq[i]->a) {
return ttest_fail(&tc, "Incorrect value");
}
if (ref[i].b != data_tgt->seq[i]->b) {
return ttest_fail(&tc, "Incorrect value");
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of int into int[4][3].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_sequence_fixed_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int seq[4][3];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, **(data_tgt->seq)),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_DEFAULT, **(data_tgt->seq),
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j][i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j][i], ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of int into int*[4].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_sequence_fixed_ptr_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int *seq[4];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, **(data_tgt->seq)),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_POINTER, **(data_tgt->seq),
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j][i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j][i], ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of int into one-dimensional int[].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_sequence_fixed_flat_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int seq[12];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_DEFAULT, int,
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
{
.key = "sequence",
.value = {
.type = CYAML_SEQUENCE,
.flags = CYAML_FLAG_DEFAULT,
.data_size = sizeof(int[3]),
.sequence = {
.entry = &entry_schema,
.min = 0,
.max = CYAML_UNLIMITED,
}
},
.data_offset = offsetof(struct target_struct, seq),
.count_size = sizeof(data_tgt->seq_count),
.count_offset = offsetof(struct target_struct, seq_count),
},
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
/* Note: count is count of entries of the outer sequence entries,
* so, 4, not 12. */
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j * CYAML_ARRAY_LEN(*ref) + i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j * CYAML_ARRAY_LEN(*ref) + i],
ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers to allocated int* array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of enums to allocated enum test_enum* array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_enum(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST,
TEST_ENUM_SECOND,
TEST_ENUM_THIRD,
TEST_ENUM__COUNT,
} ref[] = { TEST_ENUM_FIRST, TEST_ENUM_SECOND, TEST_ENUM_THIRD };
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
[TEST_ENUM_FIRST] = { "first", 0 },
[TEST_ENUM_SECOND] = { "second", 1 },
[TEST_ENUM_THIRD] = { "third", 2 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - first\n"
" - second\n"
" - third\n";
struct target_struct {
enum test_enum *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_ENUM(CYAML_FLAG_DEFAULT,
*(data_tgt->seq), strings, TEST_ENUM__COUNT),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of unsigned integers to allocated unsigned* array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_uint(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
unsigned ref[] = { 99999, 99998, 99997, 99996, 99995, 99994 };
static const unsigned char yaml[] =
"sequence:\n"
" - 99999\n"
" - 99998\n"
" - 99997\n"
" - 99996\n"
" - 99995\n"
" - 99994\n";
struct target_struct {
unsigned *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of boolean values to allocated bool* array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_bool(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
bool ref[] = { true, false, true, false, true, false, true, false };
static const unsigned char yaml[] =
"sequence:\n"
" - true\n"
" - false\n"
" - yes\n"
" - no\n"
" - enable\n"
" - disable\n"
" - 1\n"
" - 0\n";
struct target_struct {
bool *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_BOOL(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of flag sequences to allocated flag words array.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_flags(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_flags {
TEST_FLAGS_NONE = 0,
TEST_FLAGS_FIRST = (1 << 0),
TEST_FLAGS_SECOND = (1 << 1),
TEST_FLAGS_THIRD = (1 << 2),
TEST_FLAGS_FOURTH = (1 << 3),
TEST_FLAGS_FIFTH = (1 << 4),
TEST_FLAGS_SIXTH = (1 << 5),
} ref[3] = {
TEST_FLAGS_SECOND | TEST_FLAGS_FIFTH | 1024,
TEST_FLAGS_FIRST,
TEST_FLAGS_FOURTH | TEST_FLAGS_SIXTH
};
#define TEST_FLAGS__COUNT 6
static const cyaml_strval_t strings[TEST_FLAGS__COUNT] = {
{ "first", (1 << 0) },
{ "second", (1 << 1) },
{ "third", (1 << 2) },
{ "fourth", (1 << 3) },
{ "fifth", (1 << 4) },
{ "sixth", (1 << 5) },
};
static const unsigned char yaml[] =
"sequence:\n"
" - - second\n"
" - fifth\n"
" - 1024\n"
" - - first\n"
" - - fourth\n"
" - sixth\n";
struct target_struct {
enum test_flags *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_FLAGS(CYAML_FLAG_DEFAULT, *(data_tgt->seq),
strings, TEST_FLAGS__COUNT),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of strings to allocated array of char[7].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_string(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *ref[] = {
"This",
"is",
"merely",
"a",
"test",
};
static const unsigned char yaml[] =
"sequence:\n"
" - This\n"
" - is\n"
" - merely\n"
" - a\n"
" - test\n";
struct target_struct {
char (*seq)[7];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_DEFAULT, *(data_tgt->seq), 0, 6),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (strcmp(data_tgt->seq[i], ref[i]) != 0) {
return ttest_fail(&tc, "Incorrect value (i=%u)", i);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of strings to allocated array of
* allocated strings.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_string_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *ref[] = {
"This",
"is",
"merely",
"a",
"test",
};
static const unsigned char yaml[] =
"sequence:\n"
" - This\n"
" - is\n"
" - merely\n"
" - a\n"
" - test\n";
struct target_struct {
char **seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, *(data_tgt->seq),
0, CYAML_UNLIMITED),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (strcmp(data_tgt->seq[i], ref[i]) != 0) {
return ttest_fail(&tc, "Incorrect value (i=%u)", i);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of mappings to allocated array mapping structs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_mapping(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} ref[3] = {
{ .a = 123, .b = 9999, },
{ .a = 4000, .b = 62000, },
{ .a = 1, .b = 765, },
};
static const unsigned char yaml[] =
"sequence:\n"
" - a: 123\n"
" b: 9999\n"
" - a: 4000\n"
" b: 62000\n"
" - a: 1\n"
" b: 765\n";
struct target_struct {
struct value_s *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_DEFAULT,
struct value_s, test_mapping_schema),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (ref[i].a != data_tgt->seq[i].a) {
return ttest_fail(&tc, "Incorrect value");
}
if (ref[i].b != data_tgt->seq[i].b) {
return ttest_fail(&tc, "Incorrect value");
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of mappings to allocated array of pointers to
* mapping structs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_mapping_ptr(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct value_s {
short a;
long b;
} ref[3] = {
{ .a = 123, .b = 9999, },
{ .a = 4000, .b = 62000, },
{ .a = 1, .b = 765, },
};
static const unsigned char yaml[] =
"sequence:\n"
" - a: 123\n"
" b: 9999\n"
" - a: 4000\n"
" b: 62000\n"
" - a: 1\n"
" b: 765\n";
struct target_struct {
struct value_s **seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_field test_mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT, struct value_s, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT, struct value_s, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct value_s, test_mapping_schema),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (ref[i].a != data_tgt->seq[i]->a) {
return ttest_fail(&tc, "Incorrect value");
}
if (ref[i].b != data_tgt->seq[i]->b) {
return ttest_fail(&tc, "Incorrect value");
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of integers to allocated array
* of int[3].
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_sequence_fixed_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int (*seq)[3];
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_DEFAULT, int,
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j][i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j][i], ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of integers to allocated array
* of allocated arrays of integers.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_sequence_fixed_ptr_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int **seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_POINTER, int,
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_POINTER,
struct target_struct, seq, &entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j][i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j][i], ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of sequences of integers a one-dimensional allocated
* array of integers.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_ptr_sequence_fixed_flat_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[4][3] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
{ 10, 11, 12 },
};
static const unsigned char yaml[] =
"sequence:\n"
" - [ 1, 2, 3 ]\n"
" - [ 4, 5, 6 ]\n"
" - [ 7, 8, 9 ]\n"
" - [ 10, 11, 12 ]\n";
struct target_struct {
int *seq;
uint32_t seq_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema_int = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_SEQUENCE_FIXED(
CYAML_FLAG_DEFAULT, int,
&entry_schema_int, CYAML_ARRAY_LEN(*ref)),
};
static const struct cyaml_schema_field mapping_schema[] = {
{
.key = "sequence",
.value = {
.type = CYAML_SEQUENCE,
.flags = CYAML_FLAG_POINTER,
.data_size = sizeof(int[3]),
.sequence = {
.entry = &entry_schema,
.min = 0,
.max = CYAML_UNLIMITED,
}
},
.data_offset = offsetof(struct target_struct, seq),
.count_size = sizeof(data_tgt->seq_count),
.count_offset = offsetof(struct target_struct, seq_count),
},
CYAML_FIELD_END,
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
/* Note: count is count of entries of the outer sequence entries,
* so, 4, not 12. */
if (CYAML_ARRAY_LEN(ref) != data_tgt->seq_count) {
return ttest_fail(&tc, "Incorrect sequence count: "
"expected %u, got %u",
CYAML_ARRAY_LEN(ref), data_tgt->seq_count);
}
for (unsigned j = 0; j < CYAML_ARRAY_LEN(ref); j++) {
for (unsigned i = 0; i < CYAML_ARRAY_LEN(*ref); i++) {
if (data_tgt->seq[j * CYAML_ARRAY_LEN(*ref) + i] != ref[j][i]) {
return ttest_fail(&tc,
"Incorrect value "
"(i=%u, j=%u): "
"got: %i, expected: %i", i, j,
data_tgt->seq[j * CYAML_ARRAY_LEN(*ref) + i],
ref[j][i]);
}
}
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int8_limit_neg(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = 127;
static const unsigned char yaml[] =
"val: 127\n";
struct target_struct {
int8_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi8", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int8_limit_pos(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = -128;
static const unsigned char yaml[] =
"val: -128\n";
struct target_struct {
int8_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi8", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int16_limit_neg(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = -32768;
static const unsigned char yaml[] =
"val: -32768\n";
struct target_struct {
int16_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi16", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int16_limit_pos(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = 32767;
static const unsigned char yaml[] =
"val: 32767\n";
struct target_struct {
int16_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi16", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int32_limit_neg(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = -2147483648;
static const unsigned char yaml[] =
"val: -2147483648\n";
struct target_struct {
int32_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi32", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int32_limit_pos(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = 2147483647;
static const unsigned char yaml[] =
"val: 2147483647\n";
struct target_struct {
int32_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi32", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int64_limit_neg(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = -9223372036854775807ll;
static const unsigned char yaml[] =
"val: -9223372036854775807\n";
struct target_struct {
int64_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi64", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test integer limit.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_int64_limit_pos(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int64_t value = 9223372036854775807;
static const unsigned char yaml[] =
"val: 9223372036854775807\n";
struct target_struct {
int64_t val;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("val", CYAML_FLAG_DEFAULT,
struct target_struct, val),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->val != value) {
return ttest_fail(&tc, "Incorrect value "
"(got %"PRIi64", expecting %"PRIi64")",
data_tgt->val, value);
}
return ttest_pass(&tc);
}
/**
* Test loading sequence of pointers to integer values with NULLs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_sequence_null_str_values_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const int expected[] = {
777, 6, 5, 4, 3, 2, 1, 0,
};
static const bool expected_nulls[] = {
false, false, false, true, false, false, true, false,
};
static const unsigned char yaml[] =
"- 777\n"
"- 6\n"
"- 5\n"
"- ~\n"
"- 3\n"
"- 2\n"
"- null\n"
"- 0\n";
int **value = NULL;
unsigned count = 0;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_POINTER_NULL_STR, **value)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, *value,
&entry_schema, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.seq_count = &count,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, &count);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (count != CYAML_ARRAY_LEN(expected)) {
return ttest_fail(&tc, "Unexpected sequence count.");
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(expected); i ++) {
if (expected_nulls[i]) {
if (value[i] != NULL) {
return ttest_fail(&tc, "Expected NULL.");
}
continue;
} else {
if (value[i] == NULL) {
return ttest_fail(&tc, "Unexpected NULL.");
}
if ((*(value)[i]) != expected[i]) {
return ttest_fail(&tc, "Bad value.");
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading sequence of pointers to integer values with NULLs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_sequence_null_values_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const int expected[] = {
777, 6, 5, 4, 3, 2, 1, 0,
};
static const bool expected_nulls[] = {
false, false, false, true, false, false, true, false,
};
static const unsigned char yaml[] =
"- 777\n"
"- 6\n"
"- 5\n"
"- \n"
"- 3\n"
"- 2\n"
"- \n"
"- 0\n";
int **value = NULL;
unsigned count = 0;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_POINTER_NULL, **value)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, *value,
&entry_schema, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.seq_count = &count,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, &count);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (count != CYAML_ARRAY_LEN(expected)) {
return ttest_fail(&tc, "Unexpected sequence count.");
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(expected); i ++) {
if (expected_nulls[i]) {
if (value[i] != NULL) {
return ttest_fail(&tc, "Expected NULL.");
}
continue;
} else {
if (value[i] == NULL) {
return ttest_fail(&tc, "Unexpected NULL.");
}
if ((*(value)[i]) != expected[i]) {
return ttest_fail(&tc, "Bad value.");
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading sequence of pointers to integer values with NULLs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_sequence_null_str_values_uint(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned int expected[] = {
7, 6, 5555, 4, 3, 2, 1, 0,
};
static const bool expected_nulls[] = {
false, true, false, true, false, false, true, false,
};
static const unsigned char yaml[] =
"- 7\n"
"- \n"
"- 5555\n"
"- Null\n"
"- 3\n"
"- 2\n"
"- NULL\n"
"- 0\n";
unsigned int **value = NULL;
unsigned count = 0;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_POINTER_NULL_STR,
**value)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, *value,
&entry_schema, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.seq_count = &count,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, &count);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (count != CYAML_ARRAY_LEN(expected)) {
return ttest_fail(&tc, "Unexpected sequence count.");
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(expected); i ++) {
if (expected_nulls[i]) {
if (value[i] != NULL) {
return ttest_fail(&tc, "Expected NULL.");
}
continue;
} else {
if (value[i] == NULL) {
return ttest_fail(&tc, "Unexpected NULL.");
}
if ((*(value)[i]) != expected[i]) {
return ttest_fail(&tc, "Bad value.");
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading sequence of pointers to mapping values with NULLs.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_sequence_null_str_values_mapping(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct entry_value {
int a;
int b;
};
static const struct entry_value expected[] = {
{ .a = 7 },
{ .a = 6 },
{ .a = 5555 },
{ .a = 4 },
{ .a = 3 },
{ .b = 2 },
{ .a = 1 },
{ .a = 0 },
};
static const bool expected_nulls[] = {
false, true, false, true, false, false, true, false,
};
static const unsigned char yaml[] =
"- a: 7\n"
"- \n"
"- a: 5555\n"
"- Null\n"
"- a: 3\n"
"- b: 2\n"
"- NULL\n"
"- a: 0\n";
struct entry_value **value = NULL;
unsigned count = 0;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_OPTIONAL,
struct entry_value, a),
CYAML_FIELD_INT("b", CYAML_FLAG_OPTIONAL,
struct entry_value, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER_NULL_STR,
**value, mapping_schema)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, *value,
&entry_schema, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.seq_count = &count,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, &count);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (count != CYAML_ARRAY_LEN(expected)) {
return ttest_fail(&tc, "Unexpected sequence count.");
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(expected); i ++) {
if (expected_nulls[i]) {
if (value[i] != NULL) {
return ttest_fail(&tc, "Expected NULL.");
}
continue;
} else {
if (value[i] == NULL) {
return ttest_fail(&tc, "Unexpected NULL.");
}
if (memcmp(&(*(value)[i]), &expected[i],
sizeof(**value)) != 0) {
return ttest_fail(&tc, "Bad value.");
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 1 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_1(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[1];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 2 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_2(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[2];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 3 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_3(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[3];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 4 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_4(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[4];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 5 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_5(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[5];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 6 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_6(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[6];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 7 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_7(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[7];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence of integers with 8 byte sequence count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_entry_sequence_count_8(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int ref[] = { 1, 1, 2, 3, 5, 8 };
static const unsigned char yaml[] =
"sequence:\n"
" - 1\n"
" - 1\n"
" - 2\n"
" - 3\n"
" - 5\n"
" - 8\n";
struct target_struct {
int seq[CYAML_ARRAY_LEN(ref)];
uint8_t seq_count[8];
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, *(data_tgt->seq)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("sequence", CYAML_FLAG_DEFAULT,
struct target_struct, seq, &entry_schema,
0, CYAML_ARRAY_LEN(ref)),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != cyaml_data_read(sizeof(data_tgt->seq_count),
data_tgt->seq_count, &err)) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->seq[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->seq[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading with schema with scalar top level type.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_schema_top_level_scalar(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"7\n";
int *value = NULL;
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_INT(CYAML_FLAG_POINTER, int)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
if (*value != 7) {
return ttest_fail(&tc, "Bad value.");
}
return ttest_pass(&tc);
}
/**
* Test loading with schema with string top level type.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_schema_top_level_string(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"Hello\n";
char *value = NULL;
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, int, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
if (strcmp(value, "Hello") != 0) {
return ttest_fail(&tc, "Bad value.");
}
return ttest_pass(&tc);
}
/**
* Test loading with schema with sequence_fixed top level type.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_schema_top_level_sequence(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"- 7\n"
"- 6\n"
"- 5\n";
int *value = NULL;
unsigned count = 0;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE(CYAML_FLAG_POINTER, int,
&entry_schema, 0, CYAML_UNLIMITED)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.seq_count = &count,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, &count);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (count != 3) {
return ttest_fail(&tc, "Unexpected sequence count.");
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
if ((value[0] != 7) && (value[1] != 6) && (value[2] != 5)) {
return ttest_fail(&tc, "Bad value.");
}
return ttest_pass(&tc);
}
/**
* Test loading with schema with sequence_fixed top level type.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_schema_top_level_sequence_fixed(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
static const unsigned char yaml[] =
"- 7\n"
"- 6\n"
"- 5\n";
int *value = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int)
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_SEQUENCE_FIXED(CYAML_FLAG_POINTER, int,
&entry_schema, 3)
};
test_data_t td = {
.data = (cyaml_data_t **) &value,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &value, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (value == NULL) {
return ttest_fail(&tc, "Data NULL on success.");
}
if ((value[0] != 7) && (value[1] != 6) && (value[2] != 5)) {
return ttest_fail(&tc, "Bad value.");
}
return ttest_pass(&tc);
}
/**
* Test loading a stream with more than one document.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_multiple_documents_ignored(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
} data = {
.a = 9,
};
static const unsigned char yaml[] =
"a: 9\n"
"---\n"
"b: foo\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping multiple fields.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_with_multiple_fields(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"a: 9\n"
"b: 90\n"
"c: 900\n"
"d: 9000\n"
"e: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("a", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("c", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("d", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("e", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with optional fields.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_with_optional_fields(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
long values[] = { 4, 3, 2, 1 };
const struct target_struct {
char *a;
char b[10];
int c;
long d[4];
long *e;
unsigned e_count;
char *f;
char *g;
char h[10];
int i;
long j[4];
long *k;
unsigned k_count;
bool l;
} data = {
.a = (char *) "Hello",
.b = "World!",
.c = 0,
.d = { 0, 0, 0, 0 },
.e = values,
.f = (char *) "Required!",
.g = NULL,
.h = "\0",
.i = 9876,
.j = { 1, 2, 3, 4 },
.k = NULL,
.l = false,
};
static const unsigned char yaml[] =
"a: Hello\n"
"b: World!\n"
"e: [ 4, 3, 2, 1 ]\n"
"f: Required!\n"
"i: 9876\n"
"j: [ 1, 2, 3, 4 ]\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_value sequence_entry = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, sizeof(long)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("a",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
struct target_struct, a, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING("b", CYAML_FLAG_OPTIONAL,
struct target_struct, b, 0),
CYAML_FIELD_INT("c", CYAML_FLAG_OPTIONAL,
struct target_struct, c),
CYAML_FIELD_SEQUENCE_FIXED("d", CYAML_FLAG_OPTIONAL,
struct target_struct, d, &sequence_entry, 4),
CYAML_FIELD_SEQUENCE("e",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
struct target_struct, e, &sequence_entry,
0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("f",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
struct target_struct, f, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("g",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
struct target_struct, g, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING("h", CYAML_FLAG_OPTIONAL,
struct target_struct, h, 0),
CYAML_FIELD_INT("i", CYAML_FLAG_OPTIONAL,
struct target_struct, i),
CYAML_FIELD_SEQUENCE_FIXED("j", CYAML_FLAG_OPTIONAL,
struct target_struct, j, &sequence_entry, 4),
CYAML_FIELD_SEQUENCE("k",
CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
struct target_struct, k, &sequence_entry,
0, CYAML_UNLIMITED),
CYAML_FIELD_BOOL("l",
CYAML_FLAG_OPTIONAL,
struct target_struct, l),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->a, data.a) != 0) {
return ttest_fail(&tc, "Incorrect value for entry a: "
"Expected: %s, got: %s",
data.a, data_tgt->a);
}
if (strcmp(data_tgt->b, data.b) != 0) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
for (unsigned i = 0; i < 4; i++) {
if (data_tgt->d[i] != data.d[i]) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
}
for (unsigned i = 0; i < 4; i++) {
if (data_tgt->e[i] != data.e[i]) {
return ttest_fail(&tc, "Incorrect value for entry e "
"Index: %u: Expected: %ld, got: %ld",
i, data.e[i], data_tgt->e[i]);
}
}
if (strcmp(data_tgt->f, data.f) != 0) {
return ttest_fail(&tc, "Incorrect value for entry f: "
"Expected: %s, got: %s",
data.f, data_tgt->f);
}
if (data_tgt->g != data.g) {
return ttest_fail(&tc, "Incorrect value for entry g: "
"Expected: %s, got: %s",
data.g, data_tgt->g);
}
if (strcmp(data_tgt->h, data.h) != 0) {
return ttest_fail(&tc, "Incorrect value for entry h");
}
if (data_tgt->i != data.i) {
return ttest_fail(&tc, "Incorrect value for entry i");
}
for (unsigned i = 0; i < 4; i++) {
if (data_tgt->j[i] != data.j[i]) {
return ttest_fail(&tc, "Incorrect value for entry j");
}
}
if (data_tgt->k != data.k) {
return ttest_fail(&tc, "Incorrect value for entry k");
}
if (data_tgt->l != data.l) {
return ttest_fail(&tc, "Incorrect value for entry l");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with only optional fields.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_only_optional_fields(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
int c;
int i;
};
static const unsigned char yaml[] =
"\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("c", CYAML_FLAG_OPTIONAL,
struct target_struct, c),
CYAML_FIELD_INT("i", CYAML_FLAG_OPTIONAL,
struct target_struct, i),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt != NULL) {
return ttest_fail(&tc, "Shouldn't have allocated anything");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with only optional fields.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_without_any_fields(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
int i;
};
static const unsigned char yaml[] =
"{}\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt == NULL) {
return ttest_fail(&tc, "Should have allocated empty structure");
}
if (data_tgt->i != 0) {
return ttest_fail(&tc, "Value should be initialised to 0");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with unknown keys ignored by config.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_ignored_unknown_keys(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
short b;
int c;
long d;
long long e;
} data = {
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"a: 9\n"
"b: 90\n"
"c: 900\n"
"d: 9000\n"
"e: 90000\n"
"f: 900000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("c", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("d", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("e", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
cfg.flags |= CYAML_CFG_IGNORE_UNKNOWN_KEYS;
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with unknown keys ignored by config.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_warn_ignored_keys(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
short b;
int c;
long d;
long long e;
} data = {
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"a: 9\n"
"b: 90\n"
"c: 900\n"
"d: 9000\n"
"e: 90000\n"
"f: 900000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("c", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("d", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("e", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
cfg.flags |= CYAML_CFG_IGNORE_UNKNOWN_KEYS |
CYAML_CFG_IGNORED_KEY_WARNING;
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence with max size 4, and only 2 entries in YAML.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_sequence_without_max_entries(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
const char *seq[4];
unsigned seq_count;
} data = {
.seq = { "1", "2", NULL, NULL },
.seq_count = 2,
};
static const unsigned char yaml[] =
"seq: [ 1, 2 ]\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_value sequence_entry = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char *,
0, CYAML_UNLIMITED)
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("seq", CYAML_FLAG_OPTIONAL,
struct target_struct, seq, &sequence_entry,
0, 4),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->seq_count != 2) {
return ttest_fail(&tc, "Incorrect sequence entry count");
}
for (unsigned i = 0; i < 4; i++) {
if ((data_tgt->seq[i] == NULL) != (data.seq[i] == NULL)) {
return ttest_fail(&tc, "Incorrect value for entry %u",
i);
}
if (data_tgt->seq[i] != NULL) {
if (strcmp(data_tgt->seq[i], data.seq[i]) != 0) {
return ttest_fail(&tc,
"Incorrect value for entry %u",
i);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading without a logging function.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_no_log(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
cyaml_config_t cfg = *config;
struct target_struct {
const char *seq[4];
unsigned seq_count;
} data = {
.seq = { "1", "2", NULL, NULL },
.seq_count = 2,
};
static const unsigned char yaml[] =
"seq: [ 1, 2 ]\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_value sequence_entry = {
CYAML_VALUE_STRING(CYAML_FLAG_POINTER, char *,
0, CYAML_UNLIMITED)
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE("seq", CYAML_FLAG_OPTIONAL,
struct target_struct, seq, &sequence_entry,
0, 4),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.log_fn = NULL;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->seq_count != 2) {
return ttest_fail(&tc, "Incorrect sequence entry count");
}
for (unsigned i = 0; i < 4; i++) {
if ((data_tgt->seq[i] == NULL) != (data.seq[i] == NULL)) {
return ttest_fail(&tc, "Incorrect value for entry %u",
i);
}
if (data_tgt->seq[i] != NULL) {
if (strcmp(data_tgt->seq[i], data.seq[i]) != 0) {
return ttest_fail(&tc,
"Incorrect value for entry %u",
i);
}
}
}
return ttest_pass(&tc);
}
/**
* Test loading with duplicate ignored mapping fields.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_duplicate_ignored(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
int value = 90;
static const unsigned char yaml[] =
"ignore: 90\n"
"ignore: 90\n"
"test_int: 90\n";
struct target_struct {
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_IGNORE("ignore", CYAML_FLAG_DEFAULT),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->test_value_int != value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading a sequence with arbitrary C struct member name for entry count.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_schema_sequence_entry_count_member(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
unsigned ref[] = { 99999, 99998, 99997, 99996, 99995, 99994 };
static const unsigned char yaml[] =
"sequence:\n"
" - 99999\n"
" - 99998\n"
" - 99997\n"
" - 99996\n"
" - 99995\n"
" - 99994\n";
struct target_struct {
unsigned *entries;
uint32_t n_entries;
} *data_tgt = NULL;
static const struct cyaml_schema_value entry_schema = {
CYAML_VALUE_UINT(CYAML_FLAG_DEFAULT, *(data_tgt->entries)),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_SEQUENCE_COUNT("sequence", CYAML_FLAG_POINTER,
struct target_struct, entries, n_entries,
&entry_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (CYAML_ARRAY_LEN(ref) != data_tgt->n_entries) {
return ttest_fail(&tc, "Incorrect sequence count");
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(ref); i++) {
if (data_tgt->entries[i] != ref[i]) {
return ttest_fail(&tc, "Incorrect value (i=%u): "
"got: %i, expected: %i", i,
data_tgt->entries[i], ref[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading an enum with case insensitive string matching configured.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_enum_insensitive(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_ENUM_FIRST,
TEST_ENUM_SECOND,
TEST_ENUM_THIRD,
TEST_ENUM__COUNT,
} ref = TEST_ENUM_SECOND;
static const cyaml_strval_t strings[TEST_ENUM__COUNT] = {
{ "first", TEST_ENUM_FIRST },
{ "second", TEST_ENUM_SECOND },
{ "third", TEST_ENUM_THIRD },
};
static const unsigned char yaml[] =
"SECOND\n";
enum test_enum *data_tgt = NULL;
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_ENUM(CYAML_FLAG_POINTER,
*data_tgt, strings, TEST_ENUM__COUNT),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt != ref) {
return ttest_fail(&tc, "Incorrect value for enum");
}
return ttest_pass(&tc);
}
/**
* Test loading a flags value with case insensitive string matching configured.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_flags_insensitive(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
enum test_enum {
TEST_FLAG_FIRST = (1 << 1),
TEST_FLAG_SECOND = (1 << 3),
TEST_FLAG_THIRD = (1 << 5),
} ref = TEST_FLAG_FIRST | TEST_FLAG_THIRD;
static const cyaml_strval_t strings[] = {
{ "first", TEST_FLAG_FIRST },
{ "second", TEST_FLAG_SECOND },
{ "third", TEST_FLAG_THIRD },
};
static const unsigned char yaml[] =
"- First\n"
"- Third\n";
enum test_enum *data_tgt = NULL;
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_FLAGS(CYAML_FLAG_POINTER,
*data_tgt, strings, CYAML_ARRAY_LEN(strings)),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (*data_tgt != ref) {
return ttest_fail(&tc, "Incorrect value for enum");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with case insensitive string matching configured.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_fields_cfg_insensitive_1(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"Lollipop: 9\n"
"Squiggle: 90\n"
"Unicorns: 900\n"
"Cheerful: 9000\n"
"LibCYAML: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("lollipop", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_INT("squiggle", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("unicorns", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("cheerful", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("libcyaml", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with case insensitive string matching configured.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_fields_cfg_insensitive_2(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"Plinth: 9\n"
"..Cusp?: 90\n"
"..Cusp!: 900\n"
"Bleat: 9000\n"
"Foo~-|Bar: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("plinth", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_INT("..cusp?", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("..cusp!", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("bleat", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("foO~-|baR", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with case insensitive string matching configured.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_fields_cfg_insensitive_3(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"Pling: 9\n"
"Plin: 90\n"
"Pli: 900\n"
"Pl: 9000\n"
"P: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("plin", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("pli", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("pl", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("p", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_INT("pling", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with case sensitive string matching for value.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_fields_value_sensitive_1(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"pling: 9\n"
"PLing: 90\n"
"PLINg: 900\n"
"pliNG: 9000\n"
"PLING: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("pling", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_INT("PLing", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("PLINg", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("pliNG", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("PLING", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(
CYAML_FLAG_POINTER | CYAML_FLAG_CASE_SENSITIVE,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading a mapping with case insensitive string matching for value.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_mapping_fields_value_insensitive_1(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
struct target_struct {
signed char a;
short b;
int c;
long d;
long long e;
} data = {
.a = 9,
.b = 90,
.c = 900,
.d = 9000,
.e = 90000,
};
static const unsigned char yaml[] =
"Pling: 9\n"
"Plin: 90\n"
"Pli: 900\n"
"Pl: 9000\n"
"P: 90000\n";
struct target_struct *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_INT("plin", CYAML_FLAG_DEFAULT,
struct target_struct, b),
CYAML_FIELD_INT("pli", CYAML_FLAG_DEFAULT,
struct target_struct, c),
CYAML_FIELD_INT("pl", CYAML_FLAG_DEFAULT,
struct target_struct, d),
CYAML_FIELD_INT("p", CYAML_FLAG_DEFAULT,
struct target_struct, e),
CYAML_FIELD_INT("pling", CYAML_FLAG_DEFAULT,
struct target_struct, a),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(
CYAML_FLAG_POINTER |
CYAML_FLAG_CASE_INSENSITIVE,
struct target_struct, mapping_schema),
};
cyaml_config_t cfg = *config;
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = &cfg,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
cfg.flags |= CYAML_CFG_CASE_INSENSITIVE;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), &cfg, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a != data.a) {
return ttest_fail(&tc, "Incorrect value for entry a");
}
if (data_tgt->b != data.b) {
return ttest_fail(&tc, "Incorrect value for entry b");
}
if (data_tgt->c != data.c) {
return ttest_fail(&tc, "Incorrect value for entry c");
}
if (data_tgt->d != data.d) {
return ttest_fail(&tc, "Incorrect value for entry d");
}
if (data_tgt->e != data.e) {
return ttest_fail(&tc, "Incorrect value for entry e");
}
return ttest_pass(&tc);
}
/**
* Test loading with an unused anchor.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_unused_anchor(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *string_value = "Hello World!";
const int int_value = 9;
static const unsigned char yaml[] =
"test_string: &foo Hello World!\n"
"test_int: 9\n";
struct target_struct {
char * test_value_string;
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, string_value) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
if (data_tgt->test_value_int != int_value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading with an aliased string value.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_scalar_int(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *string_value = "Hello World!";
const int int_value = 9;
static const unsigned char yaml[] =
"test_int_anchor: &foo 9\n"
"test_string: Hello World!\n"
"test_int: *foo\n";
struct target_struct {
char * test_value_string;
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("test_int_anchor", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, string_value) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
if (data_tgt->test_value_int != int_value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading with an aliased string value.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_scalar_string(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *string_value = "Hello World!";
const int int_value = 9;
static const unsigned char yaml[] =
"test_string_anchor: &foo Hello World!\n"
"test_string: *foo\n"
"test_int: 9\n";
struct target_struct {
char * test_value_string;
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("test_string_anchor", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_STRING_PTR("test_string", CYAML_FLAG_POINTER,
struct target_struct, test_value_string,
0, CYAML_UNLIMITED),
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string, string_value) != 0) {
return ttest_fail(&tc, "Incorrect value");
}
if (data_tgt->test_value_int != int_value) {
return ttest_fail(&tc, "Incorrect value");
}
return ttest_pass(&tc);
}
/**
* Test loading multiple anchored and alisased scalars.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_multiple_scalars(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *string_value1 = "Hello Me!";
const char *string_value2 = "Hello World!";
const int int_value = 99;
static const unsigned char yaml[] =
"anchors:\n"
" - &a1 Hello World!\n"
" - &a2 Hello Me!\n"
" - &a3 99\n"
"test_string1: *a2\n"
"test_int: *a3\n"
"test_string2: *a1\n";
struct target_struct {
char * test_value_string1;
char * test_value_string2;
int test_value_int;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_STRING_PTR("test_string1", CYAML_FLAG_POINTER,
struct target_struct, test_value_string1,
0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("test_string2", CYAML_FLAG_POINTER,
struct target_struct, test_value_string2,
0, CYAML_UNLIMITED),
CYAML_FIELD_INT("test_int", CYAML_FLAG_DEFAULT,
struct target_struct, test_value_int),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_value_string1, string_value1) != 0) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %s, got: %s",
string_value1, data_tgt->test_value_string1);
}
if (strcmp(data_tgt->test_value_string2, string_value2) != 0) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %s, got: %s",
string_value2, data_tgt->test_value_string2);
}
if (data_tgt->test_value_int != int_value) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %i, got: %i",
int_value, data_tgt->test_value_int);
}
return ttest_pass(&tc);
}
/**
* Test loading an aliased mapping.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_mapping(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *test_a = "Hello Me!";
const int test_b = 777;
static const unsigned char yaml[] =
"anchors:\n"
" - &a2 Hello Me!\n"
" - &a1 {\n"
" a: *a2,\n"
" b: 777,\n"
" }\n"
"test: *a1\n";
struct my_test {
int b;
char *a;
};
struct target_struct {
struct my_test test;
} *data_tgt = NULL;
static const struct cyaml_schema_field inner_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
struct my_test, a,
0, CYAML_UNLIMITED),
CYAML_FIELD_INT("b", CYAML_FLAG_DEFAULT,
struct my_test, b),
CYAML_FIELD_END
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_MAPPING("test", CYAML_FLAG_DEFAULT,
struct target_struct, test,
inner_mapping_schema),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test.a, test_a) != 0) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %s, got: %s",
test_a, data_tgt->test.a);
}
if (data_tgt->test.b != test_b) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %i, got: %i",
test_b, data_tgt->test.b);
}
return ttest_pass(&tc);
}
/**
* Test loading an aliased sequence.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_sequence(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const int test_a[] = { 1, 22, 333, 4444 };
static const unsigned char yaml[] =
"anchors:\n"
" - &a1 [\n"
" 1,\n"
" 22,\n"
" 333,\n"
" 4444,\n"
" ]\n"
"test: *a1\n";
struct target_struct {
int *a;
unsigned a_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value sequence_entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_SEQUENCE("test", CYAML_FLAG_POINTER,
struct target_struct, a,
&sequence_entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (data_tgt->a_count != CYAML_ARRAY_LEN(test_a)) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %u, got: %u",
data_tgt->a_count, CYAML_ARRAY_LEN(test_a));
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(test_a); i++) {
if (data_tgt->a[i] != test_a[i]) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %i, got: %i",
data_tgt->a[i], test_a[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading with anchors within anchors, etc.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_deep_mapping_sequence(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *test_a = "Hello Me!";
const int test_b[] = { 1, 22, 333, 4444 };
static const unsigned char yaml[] =
"anchors:\n"
" - &a1 Hello Me!\n"
" - &a2 {\n"
" a: *a1,\n"
" b: &a3 [ 1, 22, 333, 4444 ],\n"
" c: *a1,\n"
" d: *a3,\n"
" }\n"
"test_a: *a2\n"
"test_b: *a3\n";
struct my_test {
char *a;
int *b;
unsigned b_count;
char *c;
int *d;
unsigned d_count;
};
struct target_struct {
struct my_test test_a;
int *test_b;
unsigned test_b_count;
} *data_tgt = NULL;
static const struct cyaml_schema_value sequence_entry_schema = {
CYAML_VALUE_INT(CYAML_FLAG_DEFAULT, int),
};
static const struct cyaml_schema_field inner_mapping_schema[] = {
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
struct my_test, a, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE("b", CYAML_FLAG_POINTER, struct my_test, b,
&sequence_entry_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("c", CYAML_FLAG_POINTER,
struct my_test, c, 0, CYAML_UNLIMITED),
CYAML_FIELD_SEQUENCE("d", CYAML_FLAG_POINTER, struct my_test, d,
&sequence_entry_schema, 0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_IGNORE("anchors", CYAML_FLAG_OPTIONAL),
CYAML_FIELD_MAPPING("test_a", CYAML_FLAG_DEFAULT,
struct target_struct, test_a,
inner_mapping_schema),
CYAML_FIELD_SEQUENCE("test_b", CYAML_FLAG_POINTER,
struct target_struct, test_b,
&sequence_entry_schema,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->test_a.a, test_a) != 0) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %s, got: %s",
test_a, data_tgt->test_a.a);
}
if (strcmp(data_tgt->test_a.c, test_a) != 0) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %s, got: %s",
test_a, data_tgt->test_a.c);
}
if (data_tgt->test_b_count != CYAML_ARRAY_LEN(test_b)) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %u, got: %u",
data_tgt->test_b_count,
CYAML_ARRAY_LEN(test_b));
}
for (unsigned i = 0; i < CYAML_ARRAY_LEN(test_b); i++) {
if (data_tgt->test_b[i] != test_b[i]) {
return ttest_fail(&tc, "Incorrect value: "
"expected: %i, got: %i",
data_tgt->test_b[i], test_b[i]);
}
}
return ttest_pass(&tc);
}
/**
* Test loading when an anchor is updated.
*
* The newest definition should be used.
*
* \param[in] report The test report context.
* \param[in] config The CYAML config to use for the test.
* \return true if test passes, false otherwise.
*/
static bool test_load_anchor_updated_anchor(
ttest_report_ctx_t *report,
const cyaml_config_t *config)
{
const char *string_value1 = "Hello Me!";
const char *string_value2 = "Hello World!";
static const unsigned char yaml[] =
"a: &a1 Hello Me!\n"
"b: *a1\n"
"c: &a1 Hello World!\n"
"d: *a1\n";
struct target_struct {
char *a;
char *b;
char *c;
char *d;
} *data_tgt = NULL;
static const struct cyaml_schema_field mapping_schema[] = {
CYAML_FIELD_STRING_PTR("a", CYAML_FLAG_POINTER,
struct target_struct, a,
0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("b", CYAML_FLAG_POINTER,
struct target_struct, b,
0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("c", CYAML_FLAG_POINTER,
struct target_struct, c,
0, CYAML_UNLIMITED),
CYAML_FIELD_STRING_PTR("d", CYAML_FLAG_POINTER,
struct target_struct, d,
0, CYAML_UNLIMITED),
CYAML_FIELD_END
};
static const struct cyaml_schema_value top_schema = {
CYAML_VALUE_MAPPING(CYAML_FLAG_POINTER,
struct target_struct, mapping_schema),
};
test_data_t td = {
.data = (cyaml_data_t **) &data_tgt,
.config = config,
.schema = &top_schema,
};
cyaml_err_t err;
ttest_ctx_t tc;
if (!ttest_start(report, __func__, cyaml_cleanup, &td, &tc)) {
return true;
}
err = cyaml_load_data(yaml, YAML_LEN(yaml), config, &top_schema,
(cyaml_data_t **) &data_tgt, NULL);
if (err != CYAML_OK) {
return ttest_fail(&tc, cyaml_strerror(err));
}
if (strcmp(data_tgt->a, string_value1) != 0) {
return ttest_fail(&tc, "Incorrect value (a): "
"expected: %s, got: %s",
string_value1, data_tgt->a);
}
if (strcmp(data_tgt->b, string_value1) != 0) {
return ttest_fail(&tc, "Incorrect value (b): "
"expected: %s, got: %s",
string_value1, data_tgt->b);
}
if (strcmp(data_tgt->c, string_value2) != 0) {
return ttest_fail(&tc, "Incorrect value (c): "
"expected: %s, got: %s",
string_value2, data_tgt->c);
}
if (strcmp(data_tgt->d, string_value2) != 0) {
return ttest_fail(&tc, "Incorrect value (d): "
"expected: %s, got: %s",
string_value2, data_tgt->d);
}
return ttest_pass(&tc);
}
/**
* Run the YAML loading unit tests.
*
* \param[in] rc The ttest report context.
* \param[in] log_level CYAML log level.
* \param[in] log_fn CYAML logging function, or NULL.
* \return true iff all unit tests pass, otherwise false.
*/
bool load_tests(
ttest_report_ctx_t *rc,
cyaml_log_t log_level,
cyaml_log_fn_t log_fn)
{
bool pass = true;
cyaml_config_t config = {
.log_fn = log_fn,
.mem_fn = cyaml_mem,
.log_level = log_level,
.flags = CYAML_CFG_DEFAULT,
};
ttest_heading(rc, "Load single entry mapping tests: simple types");
pass &= test_load_mapping_entry_enum(rc, &config);
pass &= test_load_mapping_entry_uint(rc, &config);
pass &= test_load_mapping_entry_float(rc, &config);
pass &= test_load_mapping_entry_double(rc, &config);
pass &= test_load_mapping_entry_string(rc, &config);
pass &= test_load_mapping_entry_int_pos(rc, &config);
pass &= test_load_mapping_entry_int_neg(rc, &config);
pass &= test_load_mapping_entry_enum_ptr(rc, &config);
pass &= test_load_mapping_entry_uint_ptr(rc, &config);
pass &= test_load_mapping_entry_float_ptr(rc, &config);
pass &= test_load_mapping_entry_bool_true(rc, &config);
pass &= test_load_mapping_entry_bool_false(rc, &config);
pass &= test_load_mapping_entry_double_ptr(rc, &config);
pass &= test_load_mapping_entry_string_ptr(rc, &config);
pass &= test_load_mapping_entry_int_pos_ptr(rc, &config);
pass &= test_load_mapping_entry_int_neg_ptr(rc, &config);
pass &= test_load_mapping_entry_enum_sparse(rc, &config);
pass &= test_load_mapping_entry_ignore_deep(rc, &config);
pass &= test_load_mapping_entry_ignore_scalar(rc, &config);
pass &= test_load_mapping_entry_enum_fallback(rc, &config);
pass &= test_load_mapping_entry_bool_true_ptr(rc, &config);
pass &= test_load_mapping_entry_bool_false_ptr(rc, &config);
pass &= test_load_mapping_entry_float_underflow(rc, &config);
pass &= test_load_mapping_entry_double_underflow(rc, &config);
pass &= test_load_mapping_entry_string_ptr_empty(rc, &config);
pass &= test_load_mapping_entry_string_ptr_null_str(rc, &config);
pass &= test_load_mapping_entry_string_ptr_null_empty(rc, &config);
ttest_heading(rc, "Load single entry mapping tests: complex types");
pass &= test_load_mapping_entry_flags(rc, &config);
pass &= test_load_mapping_entry_mapping(rc, &config);
pass &= test_load_mapping_entry_bitfield(rc, &config);
pass &= test_load_mapping_entry_flags_ptr(rc, &config);
pass &= test_load_mapping_entry_mapping_ptr(rc, &config);
pass &= test_load_mapping_entry_flags_empty(rc, &config);
pass &= test_load_mapping_entry_bitfield_ptr(rc, &config);
pass &= test_load_mapping_entry_flags_sparse(rc, &config);
ttest_heading(rc, "Load single entry mapping tests: sequences");
pass &= test_load_mapping_entry_sequence_int(rc, &config);
pass &= test_load_mapping_entry_sequence_enum(rc, &config);
pass &= test_load_mapping_entry_sequence_uint(rc, &config);
pass &= test_load_mapping_entry_sequence_bool(rc, &config);
pass &= test_load_mapping_entry_sequence_flags(rc, &config);
pass &= test_load_mapping_entry_sequence_string(rc, &config);
pass &= test_load_mapping_entry_sequence_mapping(rc, &config);
pass &= test_load_mapping_entry_sequence_string_ptr(rc, &config);
pass &= test_load_mapping_entry_sequence_mapping_ptr(rc, &config);
pass &= test_load_mapping_entry_sequence_sequence_fixed_int(rc, &config);
pass &= test_load_mapping_entry_sequence_sequence_fixed_ptr_int(rc, &config);
pass &= test_load_mapping_entry_sequence_sequence_fixed_flat_int(rc, &config);
ttest_heading(rc, "Load single entry mapping tests: ptr sequences");
pass &= test_load_mapping_entry_sequence_ptr_int(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_enum(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_uint(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_bool(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_flags(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_string(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_mapping(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_string_ptr(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_mapping_ptr(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_sequence_fixed_int(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_sequence_fixed_ptr_int(rc, &config);
pass &= test_load_mapping_entry_sequence_ptr_sequence_fixed_flat_int(rc, &config);
ttest_heading(rc, "Test integer limits");
pass &= test_load_mapping_entry_int8_limit_neg(rc, &config);
pass &= test_load_mapping_entry_int8_limit_pos(rc, &config);
pass &= test_load_mapping_entry_int16_limit_neg(rc, &config);
pass &= test_load_mapping_entry_int16_limit_pos(rc, &config);
pass &= test_load_mapping_entry_int32_limit_neg(rc, &config);
pass &= test_load_mapping_entry_int32_limit_pos(rc, &config);
pass &= test_load_mapping_entry_int64_limit_neg(rc, &config);
pass &= test_load_mapping_entry_int64_limit_pos(rc, &config);
ttest_heading(rc, "Load tests: ptr sequence with null values");
pass &= test_load_sequence_null_values_int(rc, &config);
pass &= test_load_sequence_null_str_values_int(rc, &config);
pass &= test_load_sequence_null_str_values_uint(rc, &config);
pass &= test_load_sequence_null_str_values_mapping(rc, &config);
ttest_heading(rc, "Load tests: sequence count sizes");
pass &= test_load_mapping_entry_sequence_count_1(rc, &config);
pass &= test_load_mapping_entry_sequence_count_2(rc, &config);
pass &= test_load_mapping_entry_sequence_count_3(rc, &config);
pass &= test_load_mapping_entry_sequence_count_4(rc, &config);
pass &= test_load_mapping_entry_sequence_count_5(rc, &config);
pass &= test_load_mapping_entry_sequence_count_6(rc, &config);
pass &= test_load_mapping_entry_sequence_count_7(rc, &config);
pass &= test_load_mapping_entry_sequence_count_8(rc, &config);
ttest_heading(rc, "Load tests: various");
pass &= test_load_no_log(rc, &config);
pass &= test_load_duplicate_ignored(rc, &config);
pass &= test_load_schema_top_level_scalar(rc, &config);
pass &= test_load_schema_top_level_string(rc, &config);
pass &= test_load_schema_top_level_sequence(rc, &config);
pass &= test_load_mapping_warn_ignored_keys(rc, &config);
pass &= test_load_multiple_documents_ignored(rc, &config);
pass &= test_load_mapping_without_any_fields(rc, &config);
pass &= test_load_mapping_with_multiple_fields(rc, &config);
pass &= test_load_mapping_with_optional_fields(rc, &config);
pass &= test_load_mapping_only_optional_fields(rc, &config);
pass &= test_load_mapping_ignored_unknown_keys(rc, &config);
pass &= test_load_sequence_without_max_entries(rc, &config);
pass &= test_load_schema_top_level_sequence_fixed(rc, &config);
pass &= test_load_schema_sequence_entry_count_member(rc, &config);
ttest_heading(rc, "Load tests: case sensitivity");
pass &= test_load_enum_insensitive(rc, &config);
pass &= test_load_flags_insensitive(rc, &config);
pass &= test_load_mapping_fields_cfg_insensitive_1(rc, &config);
pass &= test_load_mapping_fields_cfg_insensitive_2(rc, &config);
pass &= test_load_mapping_fields_cfg_insensitive_3(rc, &config);
pass &= test_load_mapping_fields_value_sensitive_1(rc, &config);
pass &= test_load_mapping_fields_value_insensitive_1(rc, &config);
ttest_heading(rc, "Load tests: anchors and aliases (scalars)");
pass &= test_load_unused_anchor(rc, &config);
pass &= test_load_anchor_scalar_int(rc, &config);
pass &= test_load_anchor_scalar_string(rc, &config);
pass &= test_load_anchor_multiple_scalars(rc, &config);
ttest_heading(rc, "Load tests: anchors and aliases (non scalars)");
pass &= test_load_anchor_mapping(rc, &config);
pass &= test_load_anchor_sequence(rc, &config);
pass &= test_load_anchor_deep_mapping_sequence(rc, &config);
ttest_heading(rc, "Load tests: anchors and aliases (edge cases)");
pass &= test_load_anchor_updated_anchor(rc, &config);
return pass;
}