evalexpr: tests: add Criterion testsuite

main
Bruno BELANYI 2 years ago
parent b5b2744a1e
commit f9719e9c9b
  1. 16
      Makefile
  2. 181
      tests/climbing.c
  3. 181
      tests/recursive.c
  4. 13
      tests/testsuite.c

@ -1,7 +1,7 @@
CC = gcc
CPPFLAGS = -Isrc/ -D_POSIX_C_SOURCE=200809L -D_USE_CLIMBING=$(USE_CLIMBING)
CFLAGS = -Wall -Wextra -pedantic -Werror -std=c99
VPATH = src/
VPATH = src/ tests/
USE_CLIMBING = 1
SRC = \
@ -19,6 +19,20 @@ all: $(BIN)
# Write this one rule instead of using the implicit rules to buid at the root
$(BIN): $(OBJ) src/evalexpr.o
check: testsuite
./testsuite --verbose
TEST_SRC = \
tests/climbing.c \
tests/recursive.c \
tests/testsuite.c \
TEST_OBJ = $(TEST_SRC:.c=.o)
testsuite: LDFLAGS+=-lcriterion -fsanitize=address
testsuite: CFLAGS+=-fsanitize=address
testsuite: $(OBJ) $(TEST_OBJ)
.PHONY: clean
clean:
$(RM) $(OBJ) # remove object files

@ -0,0 +1,181 @@
#include <criterion/criterion.h>
#include "ast/ast.h"
#include "eval/eval.h"
#include "parse/parse.h"
static void do_success(const char *input, int expected)
{
struct ast_node *ast = climbing_parse(input);
cr_assert_not_null(ast);
cr_expect_eq(eval_ast(ast), expected);
destroy_ast(ast);
}
static void do_failure(const char *input)
{
struct ast_node *ast = climbing_parse(input);
cr_expect_null(ast);
destroy_ast(ast); // Do not leak if it exists
}
TestSuite(climbing);
Test(climbing, empty)
{
do_failure("");
}
Test(climbing, trailing_operator)
{
do_failure("1 +");
}
Test(climbing, trailing_expression)
{
do_failure("1 1");
}
Test(climbing, double_operator)
{
do_failure("1 * * 1");
}
Test(climbing, one)
{
do_success("1", 1);
}
Test(climbing, the_answer)
{
do_success("42", 42);
}
Test(climbing, int_max)
{
do_success("2147483647", 2147483647);
}
Test(climbing, whitespace)
{
do_success(" 1 ", 1);
}
Test(climbing, more_whitespace)
{
do_success(" 1 + 2 ", 3);
}
Test(climbing, one_plus_one)
{
do_success("1+1", 2);
}
Test(climbing, one_minus_one)
{
do_success("1-1", 0);
}
Test(climbing, additions)
{
do_success("1+1+1+1+1", 5);
}
Test(climbing, substractions)
{
do_success("1-1-1-1-1", -3);
}
Test(climbing, multiplication)
{
do_success("2 * 3", 6);
}
Test(climbing, multiplications)
{
do_success("1 * 2 * 3 * 4", 24);
}
Test(climbing, division)
{
do_success("12 / 3", 4);
}
Test(climbing, divisions)
{
do_success("24 / 4 / 3 / 2", 1);
}
Test(climbing, simple_priority)
{
do_success("1 + 2 * 3", 7);
}
Test(climbing, more_priority)
{
do_success("1 + 6 / 3 + 4 * 6 + 14 / 7", 29);
}
Test(climbing, fail_parenthesis)
{
do_failure("(1 + 2))");
}
Test(climbing, simple_parenthesis)
{
do_success("(1 + 2) * 3", 9);
}
Test(climbing, more_parentheses)
{
do_success("(1 + 2) * (3 - 4)", -3);
}
Test(climbing, unary_minus)
{
do_success("-1", -1);
}
Test(climbing, unary_plus)
{
do_success("+1", 1);
}
Test(climbing, unary_torture)
{
do_success("--+++--+-+-+-1", -1);
}
Test(climbing, factorial)
{
do_success("3!", 6);
}
Test(climbing, fail_factorial)
{
do_failure("3!!");
}
Test(climbing, power)
{
do_success("4^3", 64);
}
Test(climbing, powers)
{
do_success("4^3^2", 262144);
}
Test(climbing, fact_and_power)
{
do_success("2^3!", 64);
}
Test(climbing, altogether)
{
do_success(" - 3 ^ 2 + - 4 * 8 / 2 + + 3! -- 2 + ((-1) + 1) * 2 ", -17);
}

@ -0,0 +1,181 @@
#include <criterion/criterion.h>
#include "ast/ast.h"
#include "eval/eval.h"
#include "parse/parse.h"
static void do_success(const char *input, int expected)
{
struct ast_node *ast = recursive_parse(input);
cr_assert_not_null(ast);
cr_expect_eq(eval_ast(ast), expected);
destroy_ast(ast);
}
static void do_failure(const char *input)
{
struct ast_node *ast = recursive_parse(input);
cr_expect_null(ast);
destroy_ast(ast); // Do not leak if it exists
}
TestSuite(recursive);
Test(recursive, empty)
{
do_failure("");
}
Test(recursive, trailing_operator)
{
do_failure("1 +");
}
Test(recursive, trailing_expression)
{
do_failure("1 1");
}
Test(recursive, double_operator)
{
do_failure("1 * * 1");
}
Test(recursive, one)
{
do_success("1", 1);
}
Test(recursive, the_answer)
{
do_success("42", 42);
}
Test(recursive, int_max)
{
do_success("2147483647", 2147483647);
}
Test(recursive, whitespace)
{
do_success(" 1 ", 1);
}
Test(recursive, more_whitespace)
{
do_success(" 1 + 2 ", 3);
}
Test(recursive, one_plus_one)
{
do_success("1+1", 2);
}
Test(recursive, one_minus_one)
{
do_success("1-1", 0);
}
Test(recursive, additions)
{
do_success("1+1+1+1+1", 5);
}
Test(recursive, substractions)
{
do_success("1-1-1-1-1", -3);
}
Test(recursive, multiplication)
{
do_success("2 * 3", 6);
}
Test(recursive, multiplications)
{
do_success("1 * 2 * 3 * 4", 24);
}
Test(recursive, division)
{
do_success("12 / 3", 4);
}
Test(recursive, divisions)
{
do_success("24 / 4 / 3 / 2", 1);
}
Test(recursive, simple_priority)
{
do_success("1 + 2 * 3", 7);
}
Test(recursive, more_priority)
{
do_success("1 + 6 / 3 + 4 * 6 + 14 / 7", 29);
}
Test(recursive, fail_parenthesis)
{
do_failure("(1 + 2))");
}
Test(recursive, simple_parenthesis)
{
do_success("(1 + 2) * 3", 9);
}
Test(recursive, more_parentheses)
{
do_success("(1 + 2) * (3 - 4)", -3);
}
Test(recursive, unary_minus)
{
do_success("-1", -1);
}
Test(recursive, unary_plus)
{
do_success("+1", 1);
}
Test(recursive, unary_torture)
{
do_success("--+++--+-+-+-1", -1);
}
Test(recursive, factorial)
{
do_success("3!", 6);
}
Test(recursive, fail_factorial)
{
do_failure("3!!");
}
Test(recursive, power)
{
do_success("4^3", 64);
}
Test(recursive, powers)
{
do_success("4^3^2", 262144);
}
Test(recursive, fact_and_power)
{
do_success("2^3!", 64);
}
Test(recursive, altogether)
{
do_success(" - 3 ^ 2 + - 4 * 8 / 2 + + 3! -- 2 + ((-1) + 1) * 2 ", -17);
}

@ -0,0 +1,13 @@
#include <criterion/criterion.h>
int main(int argc, char *argv[])
{
struct criterion_test_set *tests = criterion_initialize();
int result = 0;
if (criterion_handle_args(argc, argv, true))
result = !criterion_run_all_tests(tests);
criterion_finalize(tests);
return result;
}
Loading…
Cancel
Save