Browse Source

add examples with expected outputs

master
Martin Dørum 3 years ago
parent
commit
591e913bee

+ 1
- 0
test/examples/.gitignore View File

@@ -0,0 +1 @@
*.actual

+ 6
- 0
test/examples/arrays.l2 View File

@@ -0,0 +1,6 @@
arr := [10 20 30]
print arr
print arr.2

arr.1 = "nope"
print arr

+ 3
- 0
test/examples/arrays.l2.expected View File

@@ -0,0 +1,3 @@
[10 20 30]
30
[10 nope 30]

+ 10
- 0
test/examples/namespaces.l2 View File

@@ -0,0 +1,10 @@
obj := {
foo: "hello world"
}
print obj.foo

obj.foo = 100
print obj.foo

obj.bar = {baz: "how's your day going?"}
print obj.bar.baz

+ 3
- 0
test/examples/namespaces.l2.expected View File

@@ -0,0 +1,3 @@
hello world
100
how's your day going?

+ 137
- 0
test/src/examples.t.c View File

@@ -0,0 +1,137 @@
#ifdef __unix__

#include "vm/vm.h"
#include "parse/parse.h"

#include <sys/types.h>
#include <libgen.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <snow/snow.h>

static char example_path[512];
static char example_expected_path[512];
static char example_actual_path[512];
static char *error_message = NULL;

static void check_diff(const char *expected, const char *actual) {
FILE *e = fopen(expected, "r");
if (e == NULL) {
snow_fail("%s: %s\n Actual result stored in %s", expected, strerror(errno), actual);
}

FILE *a = fopen(actual, "r");
if (a == NULL) {
fclose(e);
snow_fail("%s: %s", actual, strerror(errno));
}

int line = 1;
int ch = 1;
while (1) {
int ech = fgetc(e);
int ach = fgetc(a);
if (ech != ach) {
fclose(e);
fclose(a);
snow_fail("%s differs at location %i:%i:\n Expected %c(%i), got %c(%i)",
actual, line, ch, ech, ech, ach, ach);
}

if (ech == EOF) {
break;
}

if (ech == '\n') {
line += 1;
ch = 1;
} else {
ch += 1;
}
}

fclose(e);
fclose(a);
}

static void check_impl(const char *name) {
char fname[] = __FILE__;
char *dname = dirname(fname);
snprintf(example_path, sizeof(example_path), "%s/../examples/%s", dname, name);
snprintf(example_expected_path, sizeof(example_path), "%s/../examples/%s.expected", dname, name);
snprintf(example_actual_path, sizeof(example_path), "%s/../examples/%s.actual", dname, name);

FILE *inf = fopen(example_path, "r");
if (inf == NULL) {
snow_fail("%s: %s", example_path, strerror(errno));
}

struct l2_io_file_reader input ={
.r.read = l2_io_file_read,
.f = inf,
};

struct l2_io_mem_writer bytecode = {
.w.write = l2_io_mem_write,
.len = 0,
.mem = NULL,
};

struct l2_lexer lexer;
l2_lexer_init(&lexer, &input.r);

struct l2_generator gen;
l2_gen_init(&gen, &bytecode.w);

struct l2_parse_error err;
if (l2_parse_program(&lexer, &gen, &err) < 0) {
free(bytecode.mem);
fclose(input.f);
error_message = err.message;
snow_fail("%s: %s", example_path, err.message);
}

fclose(inf);

FILE *outf = fopen(example_actual_path, "w");
if (outf == NULL) {
snow_fail("%s: %s", example_actual_path, strerror(errno));
}

struct l2_io_file_writer output = {
.w.write = l2_io_file_write,
.f = outf,
};

struct l2_vm vm;
l2_vm_init(&vm, (l2_word *)bytecode.mem, bytecode.len / sizeof(l2_word));
vm.std_output = &output.w;

l2_vm_run(&vm);

l2_vm_free(&vm);
free(bytecode.mem);
fclose(output.f);

check_diff(example_expected_path, example_actual_path);
}

#define check(name) do { \
snow_fail_update(); \
check_impl(name); \
} while (0)

describe(exaples) {
test("examples") {
check("namespaces.l2");
check("arrays.l2");
}

if (error_message != NULL) {
free(error_message);
}
}

#endif

Loading…
Cancel
Save