diff options
| author | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2023-01-26 22:39:41 +0300 | 
|---|---|---|
| committer | Yaroslav de la Peña Smirnov <yps@yaroslavps.com> | 2023-01-26 22:39:41 +0300 | 
| commit | 49c2589427e0f81bea68ccba1a95c6890e10538d (patch) | |
| tree | 0633bc052552831b3860d1d4816bbee7b85d6313 /src/tests | |
| parent | 4665a620775da64ec7280762979a9fc6fa37c0bc (diff) | |
| download | roscha-master.tar.gz roscha-master.zip  | |
auto-formatted the code with clang-format.
Diffstat (limited to 'src/tests')
| -rw-r--r-- | src/tests/parser.c | 335 | 
1 files changed, 223 insertions, 112 deletions
diff --git a/src/tests/parser.c b/src/tests/parser.c index eb5c2a1..c8bdcc0 100644 --- a/src/tests/parser.c +++ b/src/tests/parser.c @@ -18,20 +18,20 @@ struct value {  	union {  		struct slice ident;  		struct slice string; -		int64_t integer; -		bool boolean; +		int64_t      integer; +		bool         boolean;  	};  	enum value_type type;  };  static void  check_parser_errors(struct parser *parser, const char *file, int line, -		const char *func) +                    const char *func)  {  	if (parser->errors->len > 0) {  		printf("\n");  		size_t i; -		sds val; +		sds    val;  		vector_foreach (parser->errors, i, val) {  			printf("parser error %lu: %s\n", i, val);  		} @@ -48,7 +48,7 @@ check_parser_errors(struct parser *parser, const char *file, int line,  static void  test_integer_literal(struct expression *expr, int64_t val)  { -	char buf[128]; +	char         buf[128];  	struct slice sval;  	asserteq(expr->type, EXPRESSION_INT);  	asserteq(expr->integer.value, val); @@ -67,7 +67,7 @@ test_identifier(struct expression *expr, struct slice *ident)  static void  test_boolean_literal(struct expression *expr, bool val)  { -	char *str = val ? "true" : "false"; +	char        *str  = val ? "true" : "false";  	struct slice sval = slice_whole(str);  	asserteq(expr->type, EXPRESSION_BOOL);  	asserteq(expr->boolean.value, val); @@ -81,41 +81,52 @@ test_string_literal(struct expression *expr, const struct slice *val)  	asserteq(slice_cmp(&expr->string.value, val), 0);  } -  static inline void  test_expected(struct expression *expr, struct value v)  { -	switch(v.type) { -		case VALUE_IDENT: -			test_identifier(expr, &v.ident); -			break; -		case VALUE_INT: -			test_integer_literal(expr, v.integer); -			break; -		case VALUE_BOOL: -			test_boolean_literal(expr, v.boolean); -			break; -		case VALUE_STRING: -			test_string_literal(expr, &v.string); -			break; +	switch (v.type) { +	case VALUE_IDENT: +		test_identifier(expr, &v.ident); +		break; +	case VALUE_INT: +		test_integer_literal(expr, v.integer); +		break; +	case VALUE_BOOL: +		test_boolean_literal(expr, v.boolean); +		break; +	case VALUE_STRING: +		test_string_literal(expr, &v.string); +		break;  	}  } -#define VIDENT(v) \ -	(struct value){ .type = VALUE_IDENT, .ident = slice_whole(v) } +#define VIDENT(v)                                    \ +	(struct value)                                   \ +	{                                                \ +		.type = VALUE_IDENT, .ident = slice_whole(v) \ +	} -#define VINT(v) \ -	(struct value){ .type = VALUE_INT, .integer = v } +#define VINT(v)                         \ +	(struct value)                      \ +	{                                   \ +		.type = VALUE_INT, .integer = v \ +	} -#define VBOOL(v) \ -	(struct value){ .type = VALUE_BOOL, .boolean = v } +#define VBOOL(v)                         \ +	(struct value)                       \ +	{                                    \ +		.type = VALUE_BOOL, .boolean = v \ +	} -#define VSTR(v) \ -	(struct value){ .type = VALUE_STRING, .string = slice_whole(v) } +#define VSTR(v)                                        \ +	(struct value)                                     \ +	{                                                  \ +		.type = VALUE_STRING, .string = slice_whole(v) \ +	}  static inline void  test_infix(struct infix *expr, struct value lval, struct slice *op, -		struct value rval) +           struct value rval)  {  	test_expected(expr->left, lval);  	asserteq(slice_cmp(&expr->operator, op), 0); @@ -126,18 +137,30 @@ static inline void  test_literal_variables(void)  {  	struct { -		char *input; +		char        *input;  		struct value val;  	} tests[] = { -		{ "{{ foo }}", VIDENT("foo"), }, -		{ "{{ 20 }}", VINT(20), }, -		{ "{{ true }}", VBOOL(true), }, -		{ "{{ false }}", VBOOL(false), }, -		{ 0 }, +		{ +			"{{ foo }}", +			VIDENT("foo"), +		}, +		{ +			"{{ 20 }}", +			VINT(20), +		}, +		{ +			"{{ true }}", +			VBOOL(true), +		}, +		{ +			"{{ false }}", +			VBOOL(false), +		}, +		{0},  	};  	for (size_t i = 0; tests[i].input != NULL; i++) { -		struct parser *parser = parser_new(strdup("test"), tests[i].input); -		struct template *tmpl = parser_parse_template(parser); +		struct parser   *parser = parser_new(strdup("test"), tests[i].input); +		struct template *tmpl   = parser_parse_template(parser);  		check_parser_errors(parser);  		assertneq(tmpl, NULL);  		asserteq(tmpl->blocks->len, 1); @@ -153,21 +176,45 @@ static inline void  test_prefix_variables(void)  {  	struct { -		char *input; +		char        *input;  		struct slice operator;  		struct value val;  	} tests[] = { -		{ "{{ !foo }}", slice_whole("!"), VIDENT("foo"), }, -		{ "{{ -bar }}", slice_whole("-"), VIDENT("bar"), }, -		{ "{{ -20 }}", slice_whole("-"), VINT(20), }, -		{ "{{ !true }}", slice_whole("!"), VBOOL(true), }, -		{ "{{ !false }}", slice_whole("!"), VBOOL(false), }, -		{ "{{ not false }}", slice_whole("not"), VBOOL(false), }, -		{ 0 }, +		{ +			"{{ !foo }}", +			slice_whole("!"), +			VIDENT("foo"), +		}, +		{ +			"{{ -bar }}", +			slice_whole("-"), +			VIDENT("bar"), +		}, +		{ +			"{{ -20 }}", +			slice_whole("-"), +			VINT(20), +		}, +		{ +			"{{ !true }}", +			slice_whole("!"), +			VBOOL(true), +		}, +		{ +			"{{ !false }}", +			slice_whole("!"), +			VBOOL(false), +		}, +		{ +			"{{ not false }}", +			slice_whole("not"), +			VBOOL(false), +		}, +		{0},  	};  	for (size_t i = 0; tests[i].input != NULL; i++) { -		struct parser *parser = parser_new(strdup("test"), tests[i].input); -		struct template *tmpl = parser_parse_template(parser); +		struct parser   *parser = parser_new(strdup("test"), tests[i].input); +		struct template *tmpl   = parser_parse_template(parser);  		check_parser_errors(parser);  		assertneq(tmpl, NULL);  		asserteq(tmpl->blocks->len, 1); @@ -175,7 +222,7 @@ test_prefix_variables(void)  		asserteq(blk->type, BLOCK_VARIABLE);  		asserteq(blk->variable.expression->type, EXPRESSION_PREFIX);  		struct expression *pref = blk->variable.expression; -		asserteq(slice_cmp(&pref->prefix.operator, &tests[i].operator), 0); +		asserteq(slice_cmp(&pref->prefix.operator, & tests[i].operator), 0);  		test_expected(pref->prefix.right, tests[i].val);  		parser_destroy(parser);  		template_destroy(tmpl); @@ -186,28 +233,88 @@ static inline void  test_infix_variables(void)  {  	struct { -		char *input; +		char        *input;  		struct value left;  		struct slice operator;  		struct value right;  	} tests[] = { -		{ "{{ foo + bar }}", VIDENT("foo"), slice_whole("+"), VIDENT("bar"), }, -		{ "{{ 6 - 9 }}", VINT(6),slice_whole("-"), VINT(9), }, -		{ "{{ 4 * 20 }}", VINT(4), slice_whole("*"), VINT(20), }, -		{ "{{ foo / 20 }}", VIDENT("foo"), slice_whole("/"), VINT(20), }, -		{ "{{ \"str\" == \"str\" }}", VSTR("str"), slice_whole("=="), VSTR("str"), }, -		{ "{{ true != false }}", VBOOL(true), slice_whole("!="), VBOOL(false), }, -		{ "{{ 4 < 20 }}", VINT(4), slice_whole("<"), VINT(20), }, -		{ "{{ 4 <= 20 }}", VINT(4), slice_whole("<="), VINT(20), }, -		{ "{{ 100 > 20 }}", VINT(100), slice_whole(">"), VINT(20), }, -		{ "{{ 100 >= 20 }}", VINT(100), slice_whole(">="), VINT(20), }, -		{ "{{ true and true }}", VBOOL(true), slice_whole("and"), VBOOL(true), }, -		{ "{{ true or false }}", VBOOL(true), slice_whole("or"), VBOOL(false), }, -		{ 0 }, +		{ +			"{{ foo + bar }}", +			VIDENT("foo"), +			slice_whole("+"), +			VIDENT("bar"), +		}, +		{ +			"{{ 6 - 9 }}", +			VINT(6), +			slice_whole("-"), +			VINT(9), +		}, +		{ +			"{{ 4 * 20 }}", +			VINT(4), +			slice_whole("*"), +			VINT(20), +		}, +		{ +			"{{ foo / 20 }}", +			VIDENT("foo"), +			slice_whole("/"), +			VINT(20), +		}, +		{ +			"{{ \"str\" == \"str\" }}", +			VSTR("str"), +			slice_whole("=="), +			VSTR("str"), +		}, +		{ +			"{{ true != false }}", +			VBOOL(true), +			slice_whole("!="), +			VBOOL(false), +		}, +		{ +			"{{ 4 < 20 }}", +			VINT(4), +			slice_whole("<"), +			VINT(20), +		}, +		{ +			"{{ 4 <= 20 }}", +			VINT(4), +			slice_whole("<="), +			VINT(20), +		}, +		{ +			"{{ 100 > 20 }}", +			VINT(100), +			slice_whole(">"), +			VINT(20), +		}, +		{ +			"{{ 100 >= 20 }}", +			VINT(100), +			slice_whole(">="), +			VINT(20), +		}, +		{ +			"{{ true and true }}", +			VBOOL(true), +			slice_whole("and"), +			VBOOL(true), +		}, +		{ +			"{{ true or false }}", +			VBOOL(true), +			slice_whole("or"), +			VBOOL(false), +		}, +		{0},  	};  	for (size_t i = 0; tests[i].input != NULL; i++) { -		struct parser *parser = parser_new(strdup("test"), tests[i].input); -		struct template *tmpl = parser_parse_template(parser); +		struct parser   *parser = parser_new(strdup("test"), tests[i].input); +		struct template *tmpl   = parser_parse_template(parser);  		check_parser_errors(parser);  		assertneq(tmpl, NULL);  		asserteq(tmpl->blocks->len, 1); @@ -215,7 +322,7 @@ test_infix_variables(void)  		asserteq(blk->type, BLOCK_VARIABLE);  		asserteq(blk->variable.expression->type, EXPRESSION_INFIX);  		test_infix(&blk->variable.expression->infix, -				tests[i].left, &tests[i].operator, tests[i].right); +		           tests[i].left, &tests[i].operator, tests[i].right);  		parser_destroy(parser);  		template_destroy(tmpl);  	} @@ -224,11 +331,11 @@ test_infix_variables(void)  static inline void  test_map_variables(void)  { -	char *input = "{{ map.key }}"; -	struct value left = VIDENT("map"); -	struct value key = VIDENT("key"); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input  = "{{ map.key }}"; +	struct value     left   = VIDENT("map"); +	struct value     key    = VIDENT("key"); +	struct parser   *parser = parser_new(strdup("test"), input); +	struct template *tmpl   = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL);  	asserteq(tmpl->blocks->len, 1); @@ -245,13 +352,13 @@ test_map_variables(void)  static inline void  test_index_variables(void)  { -	char *input = "{{ arr[1 + 2] }}"; -	struct value left = VIDENT("arr"); -	struct value ileft = VINT(1); -	struct slice iop = slice_whole("+"); -	struct value iright = VINT(2); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input  = "{{ arr[1 + 2] }}"; +	struct value     left   = VIDENT("arr"); +	struct value     ileft  = VINT(1); +	struct slice     iop    = slice_whole("+"); +	struct value     iright = VINT(2); +	struct parser   *parser = parser_new(strdup("test"), input); +	struct template *tmpl   = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL); @@ -350,11 +457,11 @@ test_operator_precedence(void)  			"{{ foo.bar + bar[0].baz * foo.bar.baz }}",  			"{{ (foo.bar + (bar[0].baz * foo.bar.baz)) }}",  		}, -		{ 0 }, +		{0},  	};  	for (size_t i = 0; tests[i].input != NULL; i++) { -		struct parser *parser = parser_new(strdup("test"), tests[i].input); -		struct template *tmpl = parser_parse_template(parser); +		struct parser   *parser = parser_new(strdup("test"), tests[i].input); +		struct template *tmpl   = parser_parse_template(parser);  		check_parser_errors(parser);  		assertneq(tmpl, NULL);  		asserteq(tmpl->blocks->len, 1); @@ -371,17 +478,18 @@ test_operator_precedence(void)  static inline void  test_loop_tag(void)  { -	char *input = "{% for v in seq %}" -				  "{% break %}" -				  "{% endfor %}"; -	struct slice item = slice_whole("v"); -	struct slice seq = slice_whole("seq"); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input  = "{% for v in seq %}" +							  "{% break %}" +							  "{% endfor %}" +							  "{{ foo }}"; +	struct slice     item   = slice_whole("v"); +	struct slice     seq    = slice_whole("seq"); +	struct parser   *parser = parser_new(strdup("test"), input); +	struct template *tmpl   = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL); -	asserteq(tmpl->blocks->len, 1); +	asserteq(tmpl->blocks->len, 2);  	struct block *blk = tmpl->blocks->values[0];  	asserteq(blk->type, BLOCK_TAG);  	asserteq(blk->tag.type, TAG_FOR); @@ -398,6 +506,9 @@ test_loop_tag(void)  	asserteq(sub2->tag.type, TAG_CLOSE);  	asserteq(sub2->tag.token.type, TOKEN_ENDFOR); +	struct block *extra_blk = tmpl->blocks->values[1]; +	asserteq(extra_blk->type, BLOCK_VARIABLE); +  	parser_destroy(parser);  	template_destroy(tmpl);  } @@ -405,21 +516,21 @@ test_loop_tag(void)  static inline void  test_cond_tag(void)  { -	char *input = "{% if false %}" -				  "{{ foo }}" -				  "{% elif 1 > 2 %}" -				  "{{ bar }}" -				  "{% else %}" -				  "baz" -				  "{% endif %}"; -	struct value ifexp = VIDENT("foo"); -	struct value elifl = VINT(1); -	struct slice elifop = slice_whole(">"); -	struct value elifr = VINT(2); -	struct value elifexp = VIDENT("bar"); -	struct slice elsecont = slice_whole("baz"); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input    = "{% if false %}" +								"{{ foo }}" +								"{% elif 1 > 2 %}" +								"{{ bar }}" +								"{% else %}" +								"baz" +								"{% endif %}"; +	struct value     ifexp    = VIDENT("foo"); +	struct value     elifl    = VINT(1); +	struct slice     elifop   = slice_whole(">"); +	struct value     elifr    = VINT(2); +	struct value     elifexp  = VIDENT("bar"); +	struct slice     elsecont = slice_whole("baz"); +	struct parser   *parser   = parser_new(strdup("test"), input); +	struct template *tmpl     = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL); @@ -462,10 +573,10 @@ test_cond_tag(void)  static inline void  test_parent_tag(void)  { -	char *input = "{% extends \"base.html\" %}"; -	struct slice name = slice_whole("base.html"); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input  = "{% extends \"base.html\" %}"; +	struct slice     name   = slice_whole("base.html"); +	struct parser   *parser = parser_new(strdup("test"), input); +	struct template *tmpl   = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL); @@ -482,11 +593,11 @@ test_parent_tag(void)  static inline void  test_tblock_tag(void)  { -	char *input = "{% block cock %}" -				  "{% endblock %}"; -	struct slice name = slice_whole("cock"); -	struct parser *parser = parser_new(strdup("test"), input); -	struct template *tmpl = parser_parse_template(parser); +	char            *input  = "{% block cock %}" +							  "{% endblock %}"; +	struct slice     name   = slice_whole("cock"); +	struct parser   *parser = parser_new(strdup("test"), input); +	struct template *tmpl   = parser_parse_template(parser);  	check_parser_errors(parser);  	assertneq(tmpl, NULL);  | 
