Migrate to consolidated error handling.
parent
ea71a0d661
commit
400388b262
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- [ ] Make free-ing data consistent with null pointers.
|
- [ ] Make free-ing data consistent with null pointers.
|
||||||
- [ ] Make error handling consistent.
|
|
||||||
- [ ] Add documentation throughout (ownership, docstrings, etc.).
|
- [ ] Add documentation throughout (ownership, docstrings, etc.).
|
||||||
- [ ] Have main.c return status code of run.sh.
|
- [ ] Have main.c return status code of run.sh.
|
||||||
|
- [ ] Organize variables in each function to the top?
|
||||||
|
|
||||||
CLI utility for initializing projects in reproducible ways.
|
CLI utility for initializing projects in reproducible ways.
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ enum ErrorCode {
|
||||||
ERROR_CONFIG_TARGET_INVALID,
|
ERROR_CONFIG_TARGET_INVALID,
|
||||||
ERROR_CONFIG_TARGET_NOT_DIR,
|
ERROR_CONFIG_TARGET_NOT_DIR,
|
||||||
|
|
||||||
ERROR_PARSER_SPEC_JSON_CANNOT_OPEN,
|
ERROR_PARSER_SPEC_JSON_INVALID,
|
||||||
ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
||||||
|
|
||||||
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
||||||
|
|
|
@ -2,16 +2,10 @@
|
||||||
#define _BOOTSTRAP_EVALUATOR_H
|
#define _BOOTSTRAP_EVALUATOR_H
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "error.h"
|
||||||
#include "validator.h"
|
#include "validator.h"
|
||||||
|
|
||||||
enum SpecEvaluationError {
|
struct Error *evaluate_spec_json(
|
||||||
// Then `run.sh` file could not be found.
|
|
||||||
SEE_RUN_SH_NOT_FOUND = 1,
|
|
||||||
// The provided input does not match the expected prompt response type.
|
|
||||||
SEE_INVALID_PROMPT_RESPONSE,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SpecEvaluationError evaluate_spec_json(
|
|
||||||
const struct Config *const config, const struct DynArray *const prompts
|
const struct Config *const config, const struct DynArray *const prompts
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,23 +3,15 @@
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
enum SpecParseError {
|
/**
|
||||||
// The `spec.json` file exists but cannot be open.
|
|
||||||
SPE_CANNOT_OPEN = 1,
|
|
||||||
// The JSON of the corresponding file is not syntactically valid.
|
|
||||||
SPE_INVALID_SYNTAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Reads in the `spec.json` file relative to the paths of the provided @Config.
|
Reads in the `spec.json` file relative to the paths of the provided @Config.
|
||||||
|
|
||||||
A spec directory does not necessarily contain a `spec.json` file. If this file
|
A spec directory does not necessarily contain a `spec.json` file. If this file
|
||||||
cannot be found, the @parsed pointer is set to NULL with a success return code.
|
cannot be found, the @parsed pointer is set to NULL with a success return code.
|
||||||
|
|
||||||
@return: 0 on success and a @SpecParseError otherwise.
|
|
||||||
*/
|
*/
|
||||||
enum SpecParseError parse_spec_json(
|
struct Error *parse_spec_json(
|
||||||
const struct Config *const config, cJSON **parsed
|
const struct Config *const config, cJSON **parsed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "cJSON.h"
|
#include "cJSON.h"
|
||||||
#include "dyn_array.h"
|
#include "dyn_array.h"
|
||||||
|
#include "error.h"
|
||||||
|
|
||||||
enum FieldType {
|
enum FieldType {
|
||||||
FT_STRING = 1,
|
FT_STRING = 1,
|
||||||
|
@ -14,17 +15,7 @@ struct Field {
|
||||||
const char *prompt;
|
const char *prompt;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SpecValidationError {
|
struct Error *validate_spec_json(
|
||||||
// The top-level JSON value of a `spec.json` file must be a JSON object.
|
|
||||||
SVE_TOPLEVEL_NOT_OBJECT = 1,
|
|
||||||
// The field is not a JSON object.
|
|
||||||
SVE_FIELD_NOT_OBJECT,
|
|
||||||
SVE_FIELD_TYPE_INVALID,
|
|
||||||
SVE_FIELD_TYPE_UNKNOWN,
|
|
||||||
SVE_FIELD_PROMPT_INVALID,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SpecValidationError validate_spec_json(
|
|
||||||
const cJSON *const parsed, struct DynArray **fields
|
const cJSON *const parsed, struct DynArray **fields
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
40
main.c
40
main.c
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
static int run(const char *root_dir, const char *target) {
|
static int run(const char *root_dir, const char *target) {
|
||||||
int retval = EXIT_FAILURE;
|
int retval = EXIT_FAILURE;
|
||||||
|
|
||||||
char *cwd = getcwd(0, 0);
|
char *cwd = getcwd(0, 0);
|
||||||
if (!root_dir) {
|
if (!root_dir) {
|
||||||
root_dir = getenv("BOOTSTRAP_ROOT_DIR");
|
root_dir = getenv("BOOTSTRAP_ROOT_DIR");
|
||||||
|
@ -26,46 +27,19 @@ static int run(const char *root_dir, const char *target) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON *parsed = 0;
|
cJSON *parsed = 0;
|
||||||
switch (parse_spec_json(config, &parsed)) {
|
if ((error = parse_spec_json(config, &parsed))) {
|
||||||
case SPE_CANNOT_OPEN:
|
fprintf(stderr, "%s", error->message);
|
||||||
fprintf(stderr, "Cannot open `%s/spec.json`.\n", target);
|
|
||||||
goto cleanup_config;
|
|
||||||
case SPE_INVALID_SYNTAX:
|
|
||||||
fprintf(stderr, "`%s/spec.json` is not valid JSON.\n", target);
|
|
||||||
goto cleanup_config;
|
goto cleanup_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DynArray *prompts = 0;
|
struct DynArray *prompts = 0;
|
||||||
switch (validate_spec_json(parsed, &prompts)) {
|
if ((error = validate_spec_json(parsed, &prompts))) {
|
||||||
case SVE_TOPLEVEL_NOT_OBJECT:
|
fprintf(stderr, "%s", error->message);
|
||||||
fprintf(stderr, "`%s/spec.json` is not a JSON object.\n", target);
|
|
||||||
goto cleanup_parsed;
|
|
||||||
case SVE_FIELD_NOT_OBJECT:
|
|
||||||
fprintf(
|
|
||||||
stderr,
|
|
||||||
"Encountered child in `%s/spec.json` that is not a JSON object.\n",
|
|
||||||
target
|
|
||||||
);
|
|
||||||
goto cleanup_parsed;
|
|
||||||
case SVE_FIELD_TYPE_INVALID:
|
|
||||||
fprintf(stderr, "Types must be string values.\n");
|
|
||||||
goto cleanup_parsed;
|
|
||||||
case SVE_FIELD_TYPE_UNKNOWN:
|
|
||||||
fprintf(
|
|
||||||
stderr, "Encountered an unknown `type` in `%s/spec.json`.\n", target
|
|
||||||
);
|
|
||||||
goto cleanup_parsed;
|
|
||||||
case SVE_FIELD_PROMPT_INVALID:
|
|
||||||
fprintf(stderr, "Prompts must be string values.\n");
|
|
||||||
goto cleanup_parsed;
|
goto cleanup_parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (evaluate_spec_json(config, prompts)) {
|
if ((error = evaluate_spec_json(config, prompts))) {
|
||||||
case SEE_RUN_SH_NOT_FOUND:
|
fprintf(stderr, "%s", error->message);
|
||||||
fprintf(stderr, "Could not find `%s/run.sh`.\n", target);
|
|
||||||
goto cleanup_parsed;
|
|
||||||
case SEE_INVALID_PROMPT_RESPONSE:
|
|
||||||
fprintf(stderr, "Could not interpret response.\n");
|
|
||||||
goto cleanup_parsed;
|
goto cleanup_parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
#include "string_buf.h"
|
#include "string_buf.h"
|
||||||
|
|
||||||
static enum SpecEvaluationError find_run_sh(const struct Config *const config) {
|
static struct Error *find_run_sh(const struct Config *const config) {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
const char *segments[] = {config->root_dir, config->target, "run.sh"};
|
const char *segments[] = {config->root_dir, config->target, "run.sh"};
|
||||||
char *filepath =
|
char *filepath =
|
||||||
|
@ -16,18 +16,25 @@ static enum SpecEvaluationError find_run_sh(const struct Config *const config) {
|
||||||
free(filepath);
|
free(filepath);
|
||||||
|
|
||||||
if (stat_res == -1 && errno == ENOENT) {
|
if (stat_res == -1 && errno == ENOENT) {
|
||||||
return SEE_RUN_SH_NOT_FOUND;
|
return ERROR_NEW(
|
||||||
|
ERROR_EVALUATOR_RUN_SH_NOT_FOUND,
|
||||||
|
"Could not find ",
|
||||||
|
config->target,
|
||||||
|
"/run.sh"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Check run.sh is executable.
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecEvaluationError evaluate_spec_json(
|
struct Error *evaluate_spec_json(
|
||||||
const struct Config *const config, const struct DynArray *const prompts
|
const struct Config *const config, const struct DynArray *const prompts
|
||||||
) {
|
) {
|
||||||
enum SpecEvaluationError retval = find_run_sh(config);
|
struct Error *error = find_run_sh(config);
|
||||||
if (retval != 0) {
|
if (error) {
|
||||||
return retval;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prompts) {
|
if (prompts) {
|
||||||
|
@ -56,7 +63,6 @@ enum SpecEvaluationError evaluate_spec_json(
|
||||||
|
|
||||||
// TODO: Want to return this status out.
|
// TODO: Want to return this status out.
|
||||||
int status = system(command);
|
int status = system(command);
|
||||||
;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
25
src/parser.c
25
src/parser.c
|
@ -7,31 +7,35 @@
|
||||||
|
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
|
||||||
static int find_spec_json(const struct Config *const config, FILE **handle) {
|
static struct Error *find_spec_json(
|
||||||
|
const struct Config *const config, FILE **handle
|
||||||
|
) {
|
||||||
const char *segments[] = {config->root_dir, config->target, "spec.json"};
|
const char *segments[] = {config->root_dir, config->target, "spec.json"};
|
||||||
char *filepath =
|
char *filepath =
|
||||||
join_path_segments(sizeof(segments) / sizeof(char *), segments);
|
join_path_segments(sizeof(segments) / sizeof(char *), segments);
|
||||||
|
|
||||||
int retval = 0;
|
struct Error *error = 0;
|
||||||
// It is ok if the file does not exist. It is not ok if we couldn't open the
|
// It is ok if the file does not exist. It is not ok if we couldn't open the
|
||||||
// file for any other reason.
|
// file for any other reason.
|
||||||
*handle = fopen(filepath, "r");
|
*handle = fopen(filepath, "r");
|
||||||
if (!*handle && errno != ENOENT) {
|
if (!*handle && errno != ENOENT) {
|
||||||
retval = errno;
|
error = ERROR_NEW(
|
||||||
|
ERROR_PARSER_SPEC_JSON_INVALID, config->target, "/spec.json is invalid."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filepath);
|
free(filepath);
|
||||||
return retval;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecParseError parse_spec_json(
|
struct Error *parse_spec_json(
|
||||||
const struct Config *const config, cJSON **parsed
|
const struct Config *const config, cJSON **parsed
|
||||||
) {
|
) {
|
||||||
FILE *handle = 0;
|
FILE *handle = 0;
|
||||||
int retval = find_spec_json(config, &handle);
|
struct Error *error = find_spec_json(config, &handle);
|
||||||
|
|
||||||
if (retval != 0) {
|
if (error) {
|
||||||
return SPE_CANNOT_OPEN;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The `spec.json` file does not exist.
|
// The `spec.json` file does not exist.
|
||||||
|
@ -55,7 +59,10 @@ enum SpecParseError parse_spec_json(
|
||||||
|
|
||||||
// Can use `cJSON_GetErrorPtr()` to get the actual error message.
|
// Can use `cJSON_GetErrorPtr()` to get the actual error message.
|
||||||
if (!*parsed) {
|
if (!*parsed) {
|
||||||
return SPE_INVALID_SYNTAX;
|
return ERROR_NEW(
|
||||||
|
ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
||||||
|
"The spec.json file contains invalid JSON."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,27 +2,39 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static enum SpecValidationError read_field(
|
static struct Error *read_field(const cJSON *const field, struct Field **out) {
|
||||||
const cJSON *const field, struct Field **out
|
|
||||||
) {
|
|
||||||
if (!cJSON_IsObject(field)) {
|
if (!cJSON_IsObject(field)) {
|
||||||
return SVE_FIELD_NOT_OBJECT;
|
return ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_NOT_OBJECT,
|
||||||
|
"Field \"",
|
||||||
|
field->string,
|
||||||
|
"\" is not a JSON object."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecValidationError retval = 0;
|
struct Error *error = 0;
|
||||||
|
|
||||||
*out = malloc(sizeof(struct Field));
|
*out = malloc(sizeof(struct Field));
|
||||||
|
|
||||||
const cJSON *type = cJSON_GetObjectItemCaseSensitive(field, "type");
|
const cJSON *type = cJSON_GetObjectItemCaseSensitive(field, "type");
|
||||||
if (!cJSON_IsString(type)) {
|
if (!cJSON_IsString(type)) {
|
||||||
retval = SVE_FIELD_TYPE_INVALID;
|
error = ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_TYPE_INVALID,
|
||||||
|
"Field \"",
|
||||||
|
field->string,
|
||||||
|
"\" has non-string \"type\"."
|
||||||
|
);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(type->valuestring, "STRING") == 0) {
|
if (strcmp(type->valuestring, "STRING") == 0) {
|
||||||
(*out)->type = FT_STRING;
|
(*out)->type = FT_STRING;
|
||||||
} else {
|
} else {
|
||||||
retval = SVE_FIELD_TYPE_UNKNOWN;
|
error = ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_TYPE_UNKNOWN,
|
||||||
|
"Field \"",
|
||||||
|
field->string,
|
||||||
|
"\" has unknown \"type\"."
|
||||||
|
);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,18 +42,23 @@ static enum SpecValidationError read_field(
|
||||||
if (cJSON_IsString(prompt)) {
|
if (cJSON_IsString(prompt)) {
|
||||||
(*out)->prompt = prompt->valuestring;
|
(*out)->prompt = prompt->valuestring;
|
||||||
} else {
|
} else {
|
||||||
retval = SVE_FIELD_PROMPT_INVALID;
|
error = ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_PROMPT_INVALID,
|
||||||
|
"Field \"",
|
||||||
|
field->string,
|
||||||
|
"\" has non-string \"prompt\"."
|
||||||
|
);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
return retval;
|
return error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
free(*out);
|
free(*out);
|
||||||
return retval;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecValidationError validate_spec_json(
|
struct Error *validate_spec_json(
|
||||||
const cJSON *const parsed, struct DynArray **fields
|
const cJSON *const parsed, struct DynArray **fields
|
||||||
) {
|
) {
|
||||||
*fields = 0;
|
*fields = 0;
|
||||||
|
@ -52,10 +69,13 @@ enum SpecValidationError validate_spec_json(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cJSON_IsObject(parsed)) {
|
if (!cJSON_IsObject(parsed)) {
|
||||||
return SVE_TOPLEVEL_NOT_OBJECT;
|
return ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
||||||
|
"Top-level JSON value in spec.json is not an object."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecValidationError retval = 0;
|
struct Error *error = 0;
|
||||||
// `cJSON_GetArraySize` works because internally JSON objects are stored as
|
// `cJSON_GetArraySize` works because internally JSON objects are stored as
|
||||||
// arrays.
|
// arrays.
|
||||||
*fields = dyn_array_new(cJSON_GetArraySize(parsed));
|
*fields = dyn_array_new(cJSON_GetArraySize(parsed));
|
||||||
|
@ -63,8 +83,8 @@ enum SpecValidationError validate_spec_json(
|
||||||
cJSON *child = parsed->child;
|
cJSON *child = parsed->child;
|
||||||
while (child) {
|
while (child) {
|
||||||
struct Field *field = 0;
|
struct Field *field = 0;
|
||||||
retval = read_field(child, &field);
|
error = read_field(child, &field);
|
||||||
if (retval) {
|
if (error) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
dyn_array_push(*fields, field);
|
dyn_array_push(*fields, field);
|
||||||
|
@ -78,5 +98,5 @@ cleanup:
|
||||||
dyn_array_free(*fields);
|
dyn_array_free(*fields);
|
||||||
*fields = 0;
|
*fields = 0;
|
||||||
}
|
}
|
||||||
return retval;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,8 +49,8 @@ static void test_parser_missing() {
|
||||||
struct TestParserFixture *fixture = test_parser_setup("no_spec_json");
|
struct TestParserFixture *fixture = test_parser_setup("no_spec_json");
|
||||||
|
|
||||||
cJSON *parsed = 0;
|
cJSON *parsed = 0;
|
||||||
enum SpecParseError retval = parse_spec_json(&fixture->config, &parsed);
|
struct Error *error = parse_spec_json(&fixture->config, &parsed);
|
||||||
sput_fail_unless(retval == 0, "no spec.json, success");
|
sput_fail_unless(error == 0, "no spec.json, success");
|
||||||
sput_fail_unless(parsed == 0, "no spec.json, no parsed");
|
sput_fail_unless(parsed == 0, "no spec.json, no parsed");
|
||||||
|
|
||||||
test_parser_teardown(fixture);
|
test_parser_teardown(fixture);
|
||||||
|
@ -60,8 +60,8 @@ static void test_parser_minimal() {
|
||||||
struct TestParserFixture *fixture = test_parser_setup("minimal_spec_json");
|
struct TestParserFixture *fixture = test_parser_setup("minimal_spec_json");
|
||||||
|
|
||||||
cJSON *parsed = 0;
|
cJSON *parsed = 0;
|
||||||
enum SpecParseError retval = parse_spec_json(&fixture->config, &parsed);
|
struct Error *error = parse_spec_json(&fixture->config, &parsed);
|
||||||
sput_fail_unless(retval == 0, "minimal spec.json, success");
|
sput_fail_unless(error == 0, "minimal spec.json, success");
|
||||||
sput_fail_unless(parsed != 0, "minimal spec.json, parsed");
|
sput_fail_unless(parsed != 0, "minimal spec.json, parsed");
|
||||||
|
|
||||||
test_parser_teardown(fixture);
|
test_parser_teardown(fixture);
|
||||||
|
@ -71,10 +71,12 @@ static void test_parser_invalid() {
|
||||||
struct TestParserFixture *fixture = test_parser_setup("invalid_spec_json");
|
struct TestParserFixture *fixture = test_parser_setup("invalid_spec_json");
|
||||||
|
|
||||||
cJSON *parsed = 0;
|
cJSON *parsed = 0;
|
||||||
enum SpecParseError retval = parse_spec_json(&fixture->config, &parsed);
|
struct Error *error = parse_spec_json(&fixture->config, &parsed);
|
||||||
sput_fail_unless(
|
sput_fail_unless(
|
||||||
retval == SPE_INVALID_SYNTAX, "invalid spec.json, INVALID_SYNTAX"
|
error->code == ERROR_PARSER_SPEC_JSON_INVALID_SYNTAX,
|
||||||
|
"invalid spec.json, INVALID_SYNTAX"
|
||||||
);
|
);
|
||||||
|
error_free(error);
|
||||||
sput_fail_unless(parsed == 0, "invalid spec.json, not parsed");
|
sput_fail_unless(parsed == 0, "invalid spec.json, not parsed");
|
||||||
|
|
||||||
test_parser_teardown(fixture);
|
test_parser_teardown(fixture);
|
||||||
|
|
|
@ -30,9 +30,11 @@ static void test_validator_teardown(struct TestValidatorFixture *fixture) {
|
||||||
static void test_validator_toplevel_not_object() {
|
static void test_validator_toplevel_not_object() {
|
||||||
struct TestValidatorFixture *fixture = test_validator_setup("[]");
|
struct TestValidatorFixture *fixture = test_validator_setup("[]");
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(
|
||||||
sput_fail_unless(retval == SVE_TOPLEVEL_NOT_OBJECT, "top-level not object");
|
error->code == ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT, "top-level not object"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
@ -41,9 +43,11 @@ static void test_validator_field_not_object() {
|
||||||
struct TestValidatorFixture *fixture =
|
struct TestValidatorFixture *fixture =
|
||||||
test_validator_setup("{\"key\": \"$UNKNOWN\"}");
|
test_validator_setup("{\"key\": \"$UNKNOWN\"}");
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(
|
||||||
sput_fail_unless(retval == SVE_FIELD_NOT_OBJECT, "field not object");
|
error->code == ERROR_VALIDATOR_FIELD_NOT_OBJECT, "field not object"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
@ -57,9 +61,11 @@ static void test_validator_field_type_invalid() {
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(
|
||||||
sput_fail_unless(retval == SVE_FIELD_TYPE_INVALID, "field type invalid");
|
error->code == ERROR_VALIDATOR_FIELD_TYPE_INVALID, "field type invalid"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
@ -73,9 +79,11 @@ static void test_validator_field_type_unknown() {
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(
|
||||||
sput_fail_unless(retval == SVE_FIELD_TYPE_UNKNOWN, "field type unknown");
|
error->code == ERROR_VALIDATOR_FIELD_TYPE_UNKNOWN, "field type unknown"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
@ -90,9 +98,11 @@ static void test_validator_field_prompt_invalid() {
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(
|
||||||
sput_fail_unless(retval == SVE_FIELD_PROMPT_INVALID, "field prompt invalid");
|
error->code == ERROR_VALIDATOR_FIELD_PROMPT_INVALID, "field prompt invalid"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
@ -107,9 +117,8 @@ static void test_validator_valid() {
|
||||||
"}"
|
"}"
|
||||||
);
|
);
|
||||||
|
|
||||||
enum SpecValidationError retval =
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
validate_spec_json(fixture->parsed, &fixture->prompts);
|
sput_fail_unless(error == 0, "valid");
|
||||||
sput_fail_unless(retval == 0, "valid");
|
|
||||||
|
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue