141 lines
3 KiB
C
141 lines
3 KiB
C
#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();
|
|
}
|