42sh/tests/unit/parser/parser_tests.c

142 lines
3 KiB
C
Raw Normal View History

#include <criterion/criterion.h>
#include <criterion/new/assert.h>
#include <stdio.h>
#include "io_backend/io_backend.h"
#include "lexer/lexer.h"
#include "parser/parser.h"
#include "utils/ast/ast.h"
#include "utils/ast/ast_command.h"
TestSuite(parser);
static void init_lexer_ctx(struct lexer_context *ctx)
{
ctx->end_previous_token = NULL;
ctx->remaining_chars = 0;
ctx->only_digits = false;
ctx->previous_token = NULL;
ctx->current_token = NULL;
}
Test(parser, init_success)
{
int res = parser_init();
cr_assert(res == true, "parser_init should return true on success");
parser_close();
}
Test(parser, init_twice)
{
parser_init();
int res = parser_init();
cr_assert(res == false,
"parser_init should return false when called twice");
parser_close();
}
Test(parser, close_without_init)
{
parser_close();
}
Test(parser, close_already_closed)
{
parser_init();
parser_close();
parser_close();
}
Test(parser, get_ast_not_init)
{
struct lexer_context ctx;
init_lexer_ctx(&ctx);
struct ast *ast = get_ast(&ctx);
cr_assert_null(ast,
"get_ast should return NULL when parser is not initialized");
}
Test(parser, get_ast_closed)
{
parser_init();
parser_close();
struct lexer_context ctx;
init_lexer_ctx(&ctx);
struct ast *ast = get_ast(&ctx);
cr_assert_null(ast, "get_ast should return NULL when parser is closed");
}
Test(parser, get_ast_null_ctx)
{
parser_init();
struct ast *ast = get_ast(NULL);
cr_assert_null(ast, "get_ast should return NULL when ctx is NULL");
parser_close();
}
Test(parser, get_ast_simple_cmd)
{
char command[] = "echo hello";
struct iob_context iob_ctx = { IOB_MODE_CMD, command };
iob_init(&iob_ctx);
struct lexer_context ctx;
init_lexer_ctx(&ctx);
parser_init();
struct ast *ast = get_ast(&ctx);
cr_assert_not_null(ast,
"get_ast should return a valid AST for simple command");
cr_assert(ast_is_command(ast), "AST root should be a command");
ast_free(&ast);
parser_close();
iob_close();
}
Test(parser, get_ast_eof)
{
char command[] = "";
struct iob_context iob_ctx = { IOB_MODE_CMD, command };
iob_init(&iob_ctx);
struct lexer_context ctx;
init_lexer_ctx(&ctx);
parser_init();
struct ast *ast = get_ast(&ctx);
cr_assert_not_null(ast,
"get_ast should return AST_END node on empty input");
cr_assert_eq(ast->type, AST_END, "AST type should be AST_END");
ast_free(&ast);
parser_close();
iob_close();
}
Test(parser, get_ast_syntax_error)
{
char command[] = "if true; then"; // Missing fi
struct iob_context iob_ctx = { IOB_MODE_CMD, command };
iob_init(&iob_ctx);
struct lexer_context ctx;
init_lexer_ctx(&ctx);
parser_init();
struct ast *ast = get_ast(&ctx);
cr_assert_null(ast, "get_ast should return NULL on syntax error");
parser_close();
iob_close();
}