Add first prompt type.
parent
795307f2a1
commit
9eeb858a9a
8
main.c
8
main.c
|
@ -58,14 +58,20 @@ static int run(const char *root_dir, const char *target) {
|
||||||
goto cleanup_parsed;
|
goto cleanup_parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Extract the prompts out of the `spec.json` file.
|
|
||||||
// TODO: Load in the curses interface.
|
// TODO: Load in the curses interface.
|
||||||
// TODO: Run `run.sh`.
|
// TODO: Run `run.sh`.
|
||||||
|
|
||||||
retval = EXIT_SUCCESS;
|
retval = EXIT_SUCCESS;
|
||||||
|
|
||||||
|
cleanup_prompts:
|
||||||
|
if (prompts) {
|
||||||
|
dyn_array_free(prompts);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup_parsed:
|
cleanup_parsed:
|
||||||
|
if (parsed) {
|
||||||
cJSON_Delete(parsed);
|
cJSON_Delete(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup_config:
|
cleanup_config:
|
||||||
config_free(config);
|
config_free(config);
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
[]
|
{
|
||||||
|
"test": "$STRING"
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ void dyn_array_free(struct DynArray *a) {
|
||||||
if (!a) {
|
if (!a) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < a->size; ++i) {
|
||||||
|
free(a->buf[i]);
|
||||||
|
}
|
||||||
free(a->buf);
|
free(a->buf);
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,22 @@
|
||||||
#include <assert.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "validator.h"
|
#include "validator.h"
|
||||||
|
|
||||||
|
static struct Prompt *create_prompt(const cJSON *const kv) {
|
||||||
|
if (!kv->string) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cJSON_IsString(kv) && strcmp(kv->valuestring, "$STRING") == 0) {
|
||||||
|
struct Prompt *prompt = malloc(sizeof(struct Prompt));
|
||||||
|
prompt->key = kv->string;
|
||||||
|
prompt->type = PT_STRING;
|
||||||
|
return prompt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
enum SpecValidationError
|
enum SpecValidationError
|
||||||
validate_spec_json(const cJSON *const parsed, struct DynArray **prompts) {
|
validate_spec_json(const cJSON *const parsed, struct DynArray **prompts) {
|
||||||
*prompts = 0;
|
*prompts = 0;
|
||||||
|
@ -16,13 +31,27 @@ validate_spec_json(const cJSON *const parsed, struct DynArray **prompts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SpecValidationError retval = 0;
|
enum SpecValidationError retval = 0;
|
||||||
// `cJSON_GetArraySize` works because internally objects are stored as arrays.
|
// `cJSON_GetArraySize` works because internally JSON objects are stored as
|
||||||
|
// arrays.
|
||||||
*prompts = dyn_array_new(cJSON_GetArraySize(parsed));
|
*prompts = dyn_array_new(cJSON_GetArraySize(parsed));
|
||||||
|
|
||||||
assert(0);
|
cJSON *child = parsed->child;
|
||||||
|
while (child) {
|
||||||
|
struct Prompt *prompt = create_prompt(child);
|
||||||
|
if (!prompt) {
|
||||||
|
retval = SVE_INVALID_VALUE;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
dyn_array_push(*prompts, prompt);
|
||||||
|
child = child->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
if (*prompts) {
|
||||||
dyn_array_free(*prompts);
|
dyn_array_free(*prompts);
|
||||||
*prompts = 0;
|
*prompts = 0;
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
sput_enter_suite("validator");
|
sput_enter_suite("validator");
|
||||||
sput_run_test(test_validate_spec_json_not_toplevel_object);
|
sput_run_test(test_validate_spec_json_not_toplevel_object);
|
||||||
|
sput_run_test(test_validate_spec_json_invalid_value_type);
|
||||||
|
|
||||||
sput_finish_testing();
|
sput_finish_testing();
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,13 @@ static void test_dyn_array_zero_capacity() {
|
||||||
sput_fail_unless(a->size == 0, "a->size == 0");
|
sput_fail_unless(a->size == 0, "a->size == 0");
|
||||||
sput_fail_unless(a->_capacity == 1, "a->_capacity == 1");
|
sput_fail_unless(a->_capacity == 1, "a->_capacity == 1");
|
||||||
|
|
||||||
int x;
|
int *x = malloc(sizeof(int));
|
||||||
dyn_array_push(a, &x);
|
dyn_array_push(a, x);
|
||||||
sput_fail_unless(a->size == 1, "a->size == 1");
|
sput_fail_unless(a->size == 1, "a->size == 1");
|
||||||
sput_fail_unless(a->_capacity == 1, "a->_capacity == 1");
|
sput_fail_unless(a->_capacity == 1, "a->_capacity == 1");
|
||||||
|
|
||||||
int y;
|
int *y = malloc(sizeof(int));
|
||||||
dyn_array_push(a, &y);
|
dyn_array_push(a, y);
|
||||||
sput_fail_unless(a->size == 2, "a->size == 2");
|
sput_fail_unless(a->size == 2, "a->size == 2");
|
||||||
sput_fail_unless(a->_capacity == 2, "a->_capacity == 2");
|
sput_fail_unless(a->_capacity == 2, "a->_capacity == 2");
|
||||||
|
|
||||||
|
@ -26,24 +26,25 @@ static void test_dyn_array_zero_capacity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A @DynArray with nonzero capacity can be instantiated and have entries pushed onto.
|
A @DynArray with nonzero capacity can be instantiated and have entries pushed
|
||||||
|
onto.
|
||||||
*/
|
*/
|
||||||
static void test_dyn_array_nonzero_capacity() {
|
static void test_dyn_array_nonzero_capacity() {
|
||||||
struct DynArray *a = dyn_array_new(3);
|
struct DynArray *a = dyn_array_new(3);
|
||||||
sput_fail_unless(a->size == 0, "a->size == 0");
|
sput_fail_unless(a->size == 0, "a->size == 0");
|
||||||
sput_fail_unless(a->_capacity == 3, "a->_capacity == 3");
|
sput_fail_unless(a->_capacity == 3, "a->_capacity == 3");
|
||||||
|
|
||||||
int x;
|
int *x = malloc(sizeof(int));
|
||||||
int y;
|
int *y = malloc(sizeof(int));
|
||||||
int z;
|
int *z = malloc(sizeof(int));
|
||||||
dyn_array_push(a, &x);
|
dyn_array_push(a, x);
|
||||||
dyn_array_push(a, &y);
|
dyn_array_push(a, y);
|
||||||
dyn_array_push(a, &z);
|
dyn_array_push(a, z);
|
||||||
sput_fail_unless(a->size == 3, "a->size == 3");
|
sput_fail_unless(a->size == 3, "a->size == 3");
|
||||||
sput_fail_unless(a->_capacity == 3, "a->_capacity == 3");
|
sput_fail_unless(a->_capacity == 3, "a->_capacity == 3");
|
||||||
|
|
||||||
int w;
|
int *w = malloc(sizeof(int));
|
||||||
dyn_array_push(a, &w);
|
dyn_array_push(a, w);
|
||||||
sput_fail_unless(a->size == 4, "a->size == 4");
|
sput_fail_unless(a->size == 4, "a->size == 4");
|
||||||
sput_fail_unless(a->_capacity == 6, "a->_capacity == 6");
|
sput_fail_unless(a->_capacity == 6, "a->_capacity == 6");
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,58 @@
|
||||||
#include "sput.h"
|
#include "sput.h"
|
||||||
#include "validator.h"
|
#include "validator.h"
|
||||||
|
|
||||||
|
struct TestValidatorFixture {
|
||||||
|
const char *json;
|
||||||
|
struct DynArray *prompts;
|
||||||
|
cJSON *parsed;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct TestValidatorFixture *test_validator_setup(const char *json) {
|
||||||
|
struct TestValidatorFixture *fixture =
|
||||||
|
malloc(sizeof(struct TestValidatorFixture));
|
||||||
|
fixture->json = json;
|
||||||
|
fixture->prompts = 0;
|
||||||
|
fixture->parsed = cJSON_Parse(json);
|
||||||
|
return fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_validator_teardown(struct TestValidatorFixture *fixture) {
|
||||||
|
if (fixture->parsed) {
|
||||||
|
cJSON_Delete(fixture->parsed);
|
||||||
|
}
|
||||||
|
free(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
static void test_validate_spec_json_not_toplevel_object() {
|
static void test_validate_spec_json_not_toplevel_object() {
|
||||||
struct DynArray *prompts = 0;
|
struct TestValidatorFixture *fixture = test_validator_setup("[]");
|
||||||
cJSON *parsed = cJSON_Parse("[]");
|
|
||||||
enum SpecValidationError retval = validate_spec_json(parsed, &prompts);
|
enum SpecValidationError retval =
|
||||||
|
validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
sput_fail_unless(retval == SVE_NOT_TOPLEVEL_OBJECT, "not top-level object");
|
sput_fail_unless(retval == SVE_NOT_TOPLEVEL_OBJECT, "not top-level object");
|
||||||
|
|
||||||
cJSON_Delete(parsed);
|
test_validator_teardown(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_validate_spec_json_invalid_value_type() {
|
||||||
|
struct TestValidatorFixture *fixture =
|
||||||
|
test_validator_setup("{\"key\": \"$UNKNOWN\"}");
|
||||||
|
|
||||||
|
enum SpecValidationError retval =
|
||||||
|
validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
|
sput_fail_unless(retval == SVE_INVALID_VALUE, "invalid value");
|
||||||
|
|
||||||
|
test_validator_teardown(fixture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_validate_spec_json_valid() {
|
||||||
|
struct TestValidatorFixture *fixture =
|
||||||
|
test_validator_setup("{\"key\": \"$STRING\"}");
|
||||||
|
|
||||||
|
enum SpecValidationError retval =
|
||||||
|
validate_spec_json(fixture->parsed, &fixture->prompts);
|
||||||
|
sput_fail_unless(retval == 0, "valid");
|
||||||
|
|
||||||
|
test_validator_teardown(fixture);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _BOOTSTRAP_TEST_VALIDATOR */
|
#endif /* _BOOTSTRAP_TEST_VALIDATOR */
|
||||||
|
|
Loading…
Reference in New Issue