Ensure keys are alphanumeric, underscores, and do not begin with digits.
parent
0fc476ceed
commit
df65c8bcac
|
@ -5,7 +5,6 @@ CLI utility for defining custom project initialization scripts.
|
||||||
TODO:
|
TODO:
|
||||||
- [ ] Add evaluator tests.
|
- [ ] Add evaluator tests.
|
||||||
- [ ] Color output to console.
|
- [ ] Color output to console.
|
||||||
- [ ] Ensure keys are alphanumeric, underscore
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
@ -120,7 +119,8 @@ a string (submitted with a newline).
|
||||||
|
|
||||||
If the user were to enter, say `fieldvalue`, in response to the prompt,
|
If the user were to enter, say `fieldvalue`, in response to the prompt,
|
||||||
the `runner` script would then have access to an environment variable
|
the `runner` script would then have access to an environment variable
|
||||||
`FIELDNAME` set to `fieldvalue` on launch.
|
`FIELDNAME` set to `fieldvalue` on launch. Field names should consist of
|
||||||
|
alphanumeric characters or underscores, and may not start with a digit.
|
||||||
|
|
||||||
#### Types
|
#### Types
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,9 @@ enum ErrorCode {
|
||||||
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
ERROR_VALIDATOR_TOP_LEVEL_NOT_OBJECT,
|
||||||
/// A field in `spec.json` is not an object.
|
/// A field in `spec.json` is not an object.
|
||||||
ERROR_VALIDATOR_FIELD_NOT_OBJECT,
|
ERROR_VALIDATOR_FIELD_NOT_OBJECT,
|
||||||
|
/// A field name in `spec.json` is not alphanumeric and beginning with a
|
||||||
|
/// non-digit.
|
||||||
|
ERROR_VALIDATOR_FIELD_NAME_INVALID,
|
||||||
/// The `type` of a `spec.json` field is not a string.
|
/// The `type` of a `spec.json` field is not a string.
|
||||||
ERROR_VALIDATOR_FIELD_TYPE_INVALID,
|
ERROR_VALIDATOR_FIELD_TYPE_INVALID,
|
||||||
/// The `type` of a `spec.json` field does not correspond to a known prompt
|
/// The `type` of a `spec.json` field does not correspond to a known prompt
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "validator.h"
|
#include "validator.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include "string_utils.h"
|
#include "string_utils.h"
|
||||||
|
|
||||||
static struct Error *read_field(const cJSON *const field, struct Field **out) {
|
static struct Error *read_field(const cJSON *const field, struct Field **out) {
|
||||||
|
@ -12,6 +14,22 @@ static struct Error *read_field(const cJSON *const field, struct Field **out) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isdigit(field->string[0])) {
|
||||||
|
return ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_NAME_INVALID,
|
||||||
|
"Field names may not begin with a digit."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
for (const char *c = field->string; *c; ++c) {
|
||||||
|
if (*c != '_' && !isalnum(*c)) {
|
||||||
|
return ERROR_NEW(
|
||||||
|
ERROR_VALIDATOR_FIELD_NAME_INVALID,
|
||||||
|
"Field names must consist of alphanumeric characters or underscores."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Error *error = 0;
|
struct Error *error = 0;
|
||||||
*out = malloc(sizeof(struct Field));
|
*out = malloc(sizeof(struct Field));
|
||||||
(*out)->key = field->string;
|
(*out)->key = field->string;
|
||||||
|
|
|
@ -36,6 +36,8 @@ int main(int argc, char *argv[]) {
|
||||||
sput_enter_suite("validator");
|
sput_enter_suite("validator");
|
||||||
sput_run_test(test_validator_toplevel_not_object);
|
sput_run_test(test_validator_toplevel_not_object);
|
||||||
sput_run_test(test_validator_field_not_object);
|
sput_run_test(test_validator_field_not_object);
|
||||||
|
sput_run_test(test_validator_field_name_leading_digit);
|
||||||
|
sput_run_test(test_validator_field_name_non_alnum);
|
||||||
sput_run_test(test_validator_field_type_invalid);
|
sput_run_test(test_validator_field_type_invalid);
|
||||||
sput_run_test(test_validator_field_type_unknown);
|
sput_run_test(test_validator_field_type_unknown);
|
||||||
sput_run_test(test_validator_valid_type_ci);
|
sput_run_test(test_validator_valid_type_ci);
|
||||||
|
|
|
@ -52,6 +52,43 @@ static void test_validator_field_not_object() {
|
||||||
test_validator_teardown(fixture);
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_validator_field_name_leading_digit() {
|
||||||
|
struct TestValidatorFixture *fixture = test_validator_setup(
|
||||||
|
"{"
|
||||||
|
" \"1abc\": {"
|
||||||
|
" \"type\": \"text\""
|
||||||
|
" }"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
|
sput_fail_unless(
|
||||||
|
error->code == ERROR_VALIDATOR_FIELD_NAME_INVALID,
|
||||||
|
"field name leading digit"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
|
test_validator_teardown(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_validator_field_name_non_alnum() {
|
||||||
|
struct TestValidatorFixture *fixture = test_validator_setup(
|
||||||
|
"{"
|
||||||
|
" \"a~bc\": {"
|
||||||
|
" \"type\": \"text\""
|
||||||
|
" }"
|
||||||
|
"}"
|
||||||
|
);
|
||||||
|
|
||||||
|
struct Error *error = validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
|
sput_fail_unless(
|
||||||
|
error->code == ERROR_VALIDATOR_FIELD_NAME_INVALID, "field name non alnum"
|
||||||
|
);
|
||||||
|
error_free(error);
|
||||||
|
|
||||||
|
test_validator_teardown(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_validator_field_type_invalid() {
|
static void test_validator_field_type_invalid() {
|
||||||
struct TestValidatorFixture *fixture = test_validator_setup(
|
struct TestValidatorFixture *fixture = test_validator_setup(
|
||||||
"{"
|
"{"
|
||||||
|
|
Loading…
Reference in New Issue