Add tests for some parsing errors
This commit is contained in:
parent
0995739ca8
commit
8d1eaf5d78
3 changed files with 148 additions and 0 deletions
|
|
@ -131,6 +131,8 @@ enum apfl_error_type {
|
|||
APFL_ERR_EMPTY_ASSIGNMENT,
|
||||
};
|
||||
|
||||
const char *apfl_error_type_name(enum apfl_error_type);
|
||||
|
||||
struct apfl_error {
|
||||
enum apfl_error_type type;
|
||||
|
||||
|
|
|
|||
43
src/error.c
43
src/error.c
|
|
@ -6,6 +6,49 @@
|
|||
#define POSARGS error.position.line, error.position.col
|
||||
#define POS2ARGS error.position2.line, error.position2.col
|
||||
|
||||
const char *
|
||||
apfl_error_type_name(enum apfl_error_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case APFL_ERR_MALLOC_FAILED:
|
||||
return "APFL_ERR_MALLOC_FAILED";
|
||||
case APFL_ERR_INPUT_ERROR:
|
||||
return "APFL_ERR_INPUT_ERROR";
|
||||
case APFL_ERR_UNEXPECTED_EOF:
|
||||
return "APFL_ERR_UNEXPECTED_EOF";
|
||||
case APFL_ERR_EXPECTED_EQ_AFTER_COLON:
|
||||
return "APFL_ERR_EXPECTED_EQ_AFTER_COLON";
|
||||
case APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER:
|
||||
return "APFL_ERR_UNEXPECTED_BYTE_IN_NUMBER";
|
||||
case APFL_ERR_EXPECTED_DIGIT:
|
||||
return "APFL_ERR_EXPECTED_DIGIT";
|
||||
case APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE:
|
||||
return "APFL_ERR_EXPECTED_HEX_IN_HEX_ESCAPE";
|
||||
case APFL_ERR_INVALID_ESCAPE_SEQUENCE:
|
||||
return "APFL_ERR_INVALID_ESCAPE_SEQUENCE";
|
||||
case APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE:
|
||||
return "APFL_ERR_NO_LINEBREAK_AFTER_CONTINUE_LINE";
|
||||
case APFL_ERR_UNEXPECTED_TOKEN:
|
||||
return "APFL_ERR_UNEXPECTED_TOKEN";
|
||||
case APFL_ERR_MISMATCHING_CLOSING_BRACKET:
|
||||
return "APFL_ERR_MISMATCHING_CLOSING_BRACKET";
|
||||
case APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN:
|
||||
return "APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN";
|
||||
case APFL_ERR_STATEMENTS_BEFORE_PARAMETERS:
|
||||
return "APFL_ERR_STATEMENTS_BEFORE_PARAMETERS";
|
||||
case APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS:
|
||||
return "APFL_ERR_EMPTY_ASSIGNMENT_BEFORE_PARAMETERS";
|
||||
case APFL_ERR_UNEXPECTED_EXPRESSION:
|
||||
return "APFL_ERR_UNEXPECTED_EXPRESSION";
|
||||
case APFL_ERR_INVALID_ASSIGNMENT_LHS:
|
||||
return "APFL_ERR_INVALID_ASSIGNMENT_LHS";
|
||||
case APFL_ERR_EMPTY_ASSIGNMENT:
|
||||
return "APFL_ERR_EMPTY_ASSIGNMENT";
|
||||
}
|
||||
|
||||
return "<unknown error>";
|
||||
}
|
||||
|
||||
void
|
||||
apfl_error_print(struct apfl_error error, FILE *file)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,6 +87,27 @@ expect_expr(struct parser_test *pt, struct apfl_expr expected)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
expect_error_of_type(struct parser_test *pt, enum apfl_error_type want)
|
||||
{
|
||||
struct apfl_error have;
|
||||
switch (apfl_parser_next(pt->parser)) {
|
||||
case APFL_PARSE_OK:
|
||||
test_failf(pt->t, "Expected error but got an OK");
|
||||
break;
|
||||
case APFL_PARSE_EOF:
|
||||
test_fatalf(pt->t, "Expected error but got an EOF");
|
||||
break;
|
||||
case APFL_PARSE_ERROR:
|
||||
have = apfl_parser_get_error(pt->parser);
|
||||
if (have.type != want) {
|
||||
test_failf(pt->t, "Expected error of type %s, got this error instead:", apfl_error_type_name(want));
|
||||
apfl_error_print(have, stderr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct apfl_string
|
||||
new_string(struct parser_test *pt, const char *in)
|
||||
{
|
||||
|
|
@ -1120,6 +1141,77 @@ TEST(complex_function, t) {
|
|||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_empty_assignment, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "= foo bar");
|
||||
expect_error_of_type(pt, APFL_ERR_EMPTY_ASSIGNMENT);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_mismatching_parens, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "{[(}");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_TOKEN);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_unclosed_func, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "{ foo -> bar; baz a; b ->");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_EOF);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_unclosed_paren, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "(a b.c@d");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_EOF_AFTER_TOKEN);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_assignment_missing_rhs, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "foo = bar = ;");
|
||||
expect_error_of_type(pt, APFL_ERR_EMPTY_ASSIGNMENT);
|
||||
// TODO: Actually kinda weird that we return the same error as in err_empty_assignment.
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_assignment_invalid_lhs, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "{foo} = bar");
|
||||
expect_error_of_type(pt, APFL_ERR_INVALID_ASSIGNMENT_LHS);
|
||||
destroy_parser_test(pt);
|
||||
|
||||
pt = new_parser_test(t, "(a b) = bar");
|
||||
expect_error_of_type(pt, APFL_ERR_INVALID_ASSIGNMENT_LHS);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_fragments_after_mapsto_in_empty_dict, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "[-> foo]");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_TOKEN);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_fragments_after_mapsto_in_dict, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "[a -> b, (c d) -> e foo->]");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_TOKEN);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_mapsto_in_list, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "[a b c -> d]");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_TOKEN);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_expr_in_param, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "{ foo (bar baz) -> }");
|
||||
expect_error_of_type(pt, APFL_ERR_UNEXPECTED_EXPRESSION);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TEST(err_statements_before_params, t) {
|
||||
struct parser_test *pt = new_parser_test(t, "{ a = b = foo bar; 1 \n baz -> }");
|
||||
expect_error_of_type(pt, APFL_ERR_STATEMENTS_BEFORE_PARAMETERS);
|
||||
destroy_parser_test(pt);
|
||||
}
|
||||
|
||||
TESTS_BEGIN
|
||||
ADDTEST(empty),
|
||||
ADDTEST(hello_world),
|
||||
|
|
@ -1139,4 +1231,15 @@ TESTS_BEGIN
|
|||
ADDTEST(assignment),
|
||||
ADDTEST(simple_function),
|
||||
ADDTEST(complex_function),
|
||||
ADDTEST(err_empty_assignment),
|
||||
ADDTEST(err_mismatching_parens),
|
||||
ADDTEST(err_unclosed_func),
|
||||
ADDTEST(err_unclosed_paren),
|
||||
ADDTEST(err_assignment_missing_rhs),
|
||||
ADDTEST(err_assignment_invalid_lhs),
|
||||
ADDTEST(err_fragments_after_mapsto_in_empty_dict),
|
||||
ADDTEST(err_fragments_after_mapsto_in_dict),
|
||||
ADDTEST(err_mapsto_in_list),
|
||||
ADDTEST(err_expr_in_param),
|
||||
ADDTEST(err_statements_before_params),
|
||||
TESTS_END
|
||||
|
|
|
|||
Loading…
Reference in a new issue