161 lines
4.7 KiB
C
161 lines
4.7 KiB
C
// https://github.com/sheredom/utest.h/blob/master/utest.h
|
|
#include "utest.h"
|
|
#include "expr.h"
|
|
#include <stdio.h>
|
|
|
|
/* Clunky: Declare the parse function generated from parser.bison */
|
|
extern int yyparse();
|
|
|
|
/* Clunky: Declare the result of the parser from parser.bison */
|
|
extern struct stmt *parser_result;
|
|
|
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
|
extern int yyrestart();
|
|
extern YY_BUFFER_STATE yy_scan_buffer(char *str, int i);
|
|
extern YY_BUFFER_STATE yy_scan_string(char *str);
|
|
extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
|
|
extern FILE *yyin;
|
|
extern int yylineno;
|
|
|
|
UTEST_MAIN();
|
|
|
|
char* read_file_dynamic(const char* filename) {
|
|
FILE* file = fopen(filename, "r");
|
|
if (file == NULL) {
|
|
perror("fopen");
|
|
return NULL;
|
|
}
|
|
|
|
// Seek to the end of the file to determine its size
|
|
fseek(file, 0, SEEK_END);
|
|
long file_size = ftell(file);
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
// Allocate a buffer to hold the file contents
|
|
char* buffer = (char*)malloc(file_size + 1);
|
|
if (buffer == NULL) {
|
|
perror("malloc");
|
|
fclose(file);
|
|
return NULL;
|
|
}
|
|
|
|
// Read the entire file into the buffer
|
|
size_t read_size = fread(buffer, 1, file_size, file);
|
|
if (read_size != file_size) {
|
|
perror("fread");
|
|
free(buffer);
|
|
fclose(file);
|
|
return NULL;
|
|
}
|
|
|
|
// Null-terminate the buffer
|
|
buffer[file_size] = '\0';
|
|
|
|
fclose(file);
|
|
return buffer;
|
|
}
|
|
|
|
void redirect_stdout(const char *filename, int evalutate) {
|
|
fflush(stdout);
|
|
|
|
// Redirect stdout to a temporary file
|
|
FILE *temp_file = fopen(filename, "w");
|
|
if (temp_file == NULL) {
|
|
perror("tmpfile");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
int temp_fd = fileno(temp_file);
|
|
int stdout_fd = dup(STDOUT_FILENO);
|
|
dup2(temp_fd, STDOUT_FILENO);
|
|
|
|
// Perform operations that generate output
|
|
if (evalutate != 0) {
|
|
stmt_evaluate(parser_result);
|
|
} else {
|
|
stmt_print(parser_result);
|
|
}
|
|
|
|
// Flush and close stdout
|
|
fflush(stdout);
|
|
dup2(stdout_fd, STDOUT_FILENO);
|
|
close(stdout_fd);
|
|
}
|
|
|
|
struct InterpreterTestFile {
|
|
const char *evaluated_file;
|
|
const char *print_file;
|
|
const char *test_file;
|
|
};
|
|
|
|
UTEST_F_SETUP(InterpreterTestFile) {
|
|
}
|
|
|
|
UTEST_F_TEARDOWN(InterpreterTestFile) {
|
|
// and also assert and expect in teardown!
|
|
yyin = fopen(utest_fixture->test_file, "r");
|
|
yyrestart(yyin);
|
|
ASSERT_TRUE(yyin);
|
|
|
|
yylineno = 1;
|
|
int result = yyparse();
|
|
|
|
if (result == 0) {
|
|
// Catch the standard output and compare with expected test result
|
|
redirect_stdout("test_print.txt", 0);
|
|
redirect_stdout("test_evaluate.txt", 1);
|
|
}
|
|
|
|
// Assert the result to test correctness
|
|
ASSERT_EQ(result, 0);
|
|
|
|
char *actual_print = read_file_dynamic("test_print.txt");
|
|
char *expected_print = read_file_dynamic(utest_fixture->print_file);
|
|
ASSERT_STREQ(actual_print, expected_print);
|
|
|
|
char *actual_evaluate = read_file_dynamic("test_evaluate.txt");
|
|
char *expected_evaluate = read_file_dynamic(utest_fixture->evaluated_file);
|
|
ASSERT_STREQ(actual_evaluate, expected_evaluate);
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, helloworld) {
|
|
utest_fixture->test_file = "samples/hello-world.cbl";
|
|
utest_fixture->print_file = "samples/outputs/hello-world_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/hello-world_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, quadratic) {
|
|
utest_fixture->test_file = "samples/quadratic-snippet.cbl";
|
|
utest_fixture->print_file = "samples/outputs/quadratic_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/quadratic_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, sorting) {
|
|
utest_fixture->test_file = "samples/sorting-snippet.cbl";
|
|
utest_fixture->print_file = "samples/outputs/sorting_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/sorting_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, assignment) {
|
|
utest_fixture->test_file = "samples/assignment.cbl";
|
|
utest_fixture->print_file = "samples/outputs/assignment_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/assignment_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, addition) {
|
|
utest_fixture->test_file = "samples/addition.cbl";
|
|
utest_fixture->print_file = "samples/outputs/addition_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/addition_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, branching) {
|
|
utest_fixture->test_file = "samples/branching.cbl";
|
|
utest_fixture->print_file = "samples/outputs/branching_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/branching_evaluate.txt";
|
|
}
|
|
|
|
UTEST_F(InterpreterTestFile, looping) {
|
|
utest_fixture->test_file = "samples/looping.cbl";
|
|
utest_fixture->print_file = "samples/outputs/looping_print.txt";
|
|
utest_fixture->evaluated_file = "samples/outputs/looping_evaluate.txt";
|
|
}
|