#include #include #include #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(); }