mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Squashed: Added integration and standalone tests, read more
This wasn't an easy fix, as it was primarily the test pipelines that were failing. I resorted to using forced pushes to run the CI, to try and track down the problems. The primary cause seems to be the differences in how each supported platform handles file paths, specifically, slash vs. backslash. I've also added gdb scripts to set up automated breakpoints, and to run operations on them to check for issues - the 'gdb_init' files are mostly empty for the time being. commit a34b0ff5d407bbe7d70ff9504aa035ec6fbecb7c Author: Kayne Ruse <kayneruse@gmail.com> Date: Fri Oct 18 11:45:40 2024 +1100 Restored the workflows commit eb3d94f30d4dc4150139517f44cc874f2901124f Author: Kayne Ruse <kayneruse@gmail.com> Date: Fri Oct 18 11:35:39 2024 +1100 I think the library path on macos is fixed commit 964572b5e93c7cb464686f19ddbe3e9d315f391b Author: Kayne Ruse <kayneruse@gmail.com> Date: Fri Oct 18 11:22:56 2024 +1100 I think the file paths are fixed commit 1721f3da7252b4063f4347926e800ef4f7c9bf4c Author: Kayne Ruse <kayneruse@gmail.com> Date: Thu Oct 17 15:57:28 2024 +1100 Added standalone tests commit 90c783f4059d88f4a7bbaf18215a9b414f3ab66f Author: Kayne Ruse <kayneruse@gmail.com> Date: Thu Oct 17 15:01:18 2024 +1100 Trying to fix the integration test pipeline commit fccced1396568a55c1385e2f1b04fedf7c2585a5 Author: Kayne Ruse <kayneruse@gmail.com> Date: Wed Oct 16 00:31:39 2024 +1100 Workflow integration tests are not passing commit 6b1e0d1e0f89291e89768bf6102f4f7ed4581496 Author: Kayne Ruse <kayneruse@gmail.com> Date: Tue Oct 15 20:07:20 2024 +1100 Fixed file paths in workflow commit c0f1ec78fe79a5abb34c3e05308236cb18c23b97 Author: Kayne Ruse <kayneruse@gmail.com> Date: Tue Oct 15 19:46:14 2024 +1100 Moved example scripts into proper integration tests Also adjusted makefiles to allow easy invoking of the tests. Adjusted and updated CI to invoke tests correctly. Fixed #141
This commit is contained in:
2
tests/cases/gdb_init
Normal file
2
tests/cases/gdb_init
Normal file
@@ -0,0 +1,2 @@
|
||||
set breakpoint pending on
|
||||
|
||||
@@ -15,9 +15,9 @@ else
|
||||
endif
|
||||
|
||||
#directories
|
||||
TEST_ROOTDIR=..
|
||||
TEST_ROOTDIR=../..
|
||||
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||
TEST_CASESDIR=cases
|
||||
TEST_CASESDIR=.
|
||||
|
||||
TEST_OUTDIR=out
|
||||
TEST_OBJDIR=obj
|
||||
@@ -27,7 +27,7 @@ TEST_SOURCEFILES=$(wildcard $(TEST_SOURCEDIR)/*.c)
|
||||
TEST_CASESFILES=$(wildcard $(TEST_CASESDIR)/test_*.c)
|
||||
|
||||
#build the object files, compile the test cases, and run
|
||||
all: clean build-source build-cases build-link build-run
|
||||
all: build-source build-cases build-link build-run
|
||||
|
||||
#targets for each step
|
||||
.PHONY: build-source
|
||||
@@ -64,42 +64,11 @@ $(TEST_OUTDIR)/%.run: $(TEST_OUTDIR)/%.exe
|
||||
$<
|
||||
|
||||
#debugging targets
|
||||
all-gdb: clean build-source build-cases build-link build-run-gdb
|
||||
gdb: build-source build-cases build-link build-run-gdb
|
||||
|
||||
.PHONY: build-run-gdb
|
||||
build-run-gdb: $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.exe))) $(addprefix $(TEST_OUTDIR)/,$(notdir $(TEST_CASESFILES:%.c=%.run-gdb)))
|
||||
|
||||
.PRECIOUS: $(TEST_OUTDIR)/%.run-gdb
|
||||
$(TEST_OUTDIR)/%.run-gdb: $(TEST_OUTDIR)/%.exe
|
||||
gdb $< -ex "run" --batch
|
||||
|
||||
#util commands
|
||||
.PHONY: clean
|
||||
clean:
|
||||
ifeq ($(shell uname),Linux)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
$(RM) *.o *.a *.exe *.dll *.lib *.so *.dylib
|
||||
$(RM) out
|
||||
$(RM) obj
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
find . -type f -name '*.o' -delete
|
||||
find . -type f -name '*.a' -delete
|
||||
find . -type f -name '*.exe' -delete
|
||||
find . -type f -name '*.dll' -delete
|
||||
find . -type f -name '*.lib' -delete
|
||||
find . -type f -name '*.so' -delete
|
||||
find . -type f -name '*.dylib' -delete
|
||||
find . -type d -name 'out' -delete
|
||||
find . -type d -name 'obj' -delete
|
||||
else
|
||||
@echo "Deletion failed - what platform is this?"
|
||||
endif
|
||||
gdb $< -ix gdb_init -ex=run --batch --return-child-result --args "$<"
|
||||
12
tests/integrations/gdb_init
Normal file
12
tests/integrations/gdb_init
Normal file
@@ -0,0 +1,12 @@
|
||||
set breakpoint pending on
|
||||
|
||||
break main if argc > 1
|
||||
|
||||
command 1
|
||||
set $i=0
|
||||
while($i < argc)
|
||||
p argv[$i++]
|
||||
end
|
||||
continue
|
||||
end
|
||||
|
||||
58
tests/integrations/makefile
Normal file
58
tests/integrations/makefile
Normal file
@@ -0,0 +1,58 @@
|
||||
#compiler settings
|
||||
CC=gcc
|
||||
CFLAGS+=-std=c17 -g -Wall -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wformat=2
|
||||
LIBS+=-lm
|
||||
LDFLAGS+=
|
||||
|
||||
ifeq ($(shell uname),Linux)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
LDFLAGS=-Wl,-dead_strip
|
||||
else
|
||||
@echo "LDFLAGS set failed - what platform is this?"
|
||||
endif
|
||||
|
||||
#directories
|
||||
TEST_ROOTDIR=../..
|
||||
TEST_SOURCEDIR=$(TEST_ROOTDIR)/$(TOY_SOURCEDIR)
|
||||
TEST_REPLDIR=$(TEST_ROOTDIR)/$(TOY_REPLDIR)
|
||||
TEST_SCRIPTDIR=.
|
||||
|
||||
TEST_OUTDIR=out
|
||||
TEST_OBJDIR=obj
|
||||
|
||||
#file names
|
||||
TEST_SCRIPTFILES=$(wildcard $(TEST_SCRIPTDIR)/test_*.toy)
|
||||
TEST_REPLNAME=repl.exe
|
||||
|
||||
#build the source and repl, and run
|
||||
all: source repl run
|
||||
|
||||
run: $(TEST_SCRIPTFILES:.toy=.toy-run)
|
||||
|
||||
%.toy-run: %.toy
|
||||
$(TEST_OUTDIR)/$(TEST_REPLNAME) -f ../$<
|
||||
|
||||
#same as above, but with gdb
|
||||
gdb: source repl run-gdb
|
||||
|
||||
run-gdb: $(TEST_SCRIPTFILES:.toy=.toy-gdb)
|
||||
|
||||
%.toy-gdb: %.toy
|
||||
gdb $(TEST_OUTDIR)/$(TEST_REPLNAME) -ix gdb_init -ex=run --batch --return-child-result --args "$(TEST_OUTDIR)/$(TEST_REPLNAME)" "-f" "../$<"
|
||||
|
||||
#compile the source and repl first
|
||||
source: $(TEST_OBJDIR) $(TEST_OUTDIR)
|
||||
$(MAKE) SRC_OUTDIR=../$(TOY_INTEGRATIONSDIR)/$(TEST_OUTDIR) -C $(TEST_SOURCEDIR)
|
||||
|
||||
repl: $(TEST_OBJDIR) $(TEST_OUTDIR) source
|
||||
$(MAKE) REPL_TARGETNAME=$(TEST_REPLNAME) REPL_OUTDIR=../$(TOY_INTEGRATIONSDIR)/$(TEST_OUTDIR) -C $(TEST_REPLDIR)
|
||||
|
||||
#util targets
|
||||
$(TEST_OUTDIR):
|
||||
mkdir $(TEST_OUTDIR)
|
||||
|
||||
$(TEST_OBJDIR):
|
||||
mkdir $(TEST_OBJDIR)
|
||||
3
tests/integrations/test_expressions.toy
Normal file
3
tests/integrations/test_expressions.toy
Normal file
@@ -0,0 +1,3 @@
|
||||
//basic expressions with no side effects (other than debug stack dumps)
|
||||
(1 + 2) * (3 + 4);
|
||||
|
||||
15
tests/integrations/test_print.toy
Normal file
15
tests/integrations/test_print.toy
Normal file
@@ -0,0 +1,15 @@
|
||||
//basic print statement
|
||||
print 42;
|
||||
|
||||
//print complex expressions
|
||||
print 3 * 5;
|
||||
|
||||
//print a string
|
||||
print "Hello world!";
|
||||
|
||||
//print a concatenated string
|
||||
print "Hello" .. "world!";
|
||||
|
||||
//TODO: in the repl, -s to supress output, or -d to print debugging info
|
||||
|
||||
//TODO: the `assert` keyword will be useful for these
|
||||
6
tests/integrations/test_variables_and_scopes.toy
Normal file
6
tests/integrations/test_variables_and_scopes.toy
Normal file
@@ -0,0 +1,6 @@
|
||||
//declare a variable with an initial value
|
||||
var answer = 42;
|
||||
|
||||
//declare a variable without an initial value
|
||||
var empty;
|
||||
|
||||
0
tests/mustfails/.gitkeep
Normal file
0
tests/mustfails/.gitkeep
Normal file
1
tests/standalone/gdb_init
Normal file
1
tests/standalone/gdb_init
Normal file
@@ -0,0 +1 @@
|
||||
set breakpoint pending on
|
||||
60
tests/standalone/makefile
Normal file
60
tests/standalone/makefile
Normal file
@@ -0,0 +1,60 @@
|
||||
#compiler settings
|
||||
CC=gcc
|
||||
CFLAGS+=-std=c17 -g -Wall -Werror -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wformat=2
|
||||
LIBS+=-lm
|
||||
LDFLAGS+=
|
||||
|
||||
ifeq ($(shell uname),Linux)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(OS),Windows_NT)
|
||||
LDFLAGS=-Wl,--gc-sections
|
||||
else ifeq ($(shell uname),Darwin)
|
||||
LDFLAGS=-Wl,-dead_strip
|
||||
else
|
||||
@echo "LDFLAGS set failed - what platform is this?"
|
||||
endif
|
||||
|
||||
#directories
|
||||
TEST_SRCDIR=
|
||||
|
||||
TEST_OUTDIR=out/
|
||||
TEST_OBJDIR=obj/
|
||||
|
||||
#file names
|
||||
TEST_SRCFILES=$(wildcard $(TEST_SRCDIR)*.c)
|
||||
|
||||
#kick off
|
||||
all: $(TEST_OBJDIR) $(TEST_OUTDIR) build run
|
||||
|
||||
gdb: $(TEST_OBJDIR) $(TEST_OUTDIR) build gdb-run
|
||||
|
||||
#build
|
||||
build: $(TEST_OBJDIR)$(TEST_SRCFILES:.c=.o)
|
||||
|
||||
.PRECIOUS: $(TEST_OBJDIR)%.o
|
||||
$(TEST_OBJDIR)%.o: $(TEST_SRCDIR)%.c
|
||||
$(CC) -c -o $@ $< $(CFLAGS) -fdata-sections -ffunction-sections
|
||||
|
||||
|
||||
.PRECIOUS: $(TEST_OUTDIR)%.exe
|
||||
$(TEST_OUTDIR)%.exe: $(TEST_OBJDIR)%.o
|
||||
$(CC) -o $@ $< $(CFLAGS) $(LIBS) $(LDFLAGS)
|
||||
|
||||
#run
|
||||
run: $(addprefix $(TEST_OUTDIR),$(TEST_SRCFILES:.c=.exe-run))
|
||||
|
||||
$(TEST_OUTDIR)%.exe-run: $(TEST_OUTDIR)%.exe
|
||||
$<
|
||||
|
||||
#gdb-run
|
||||
gdb-run: $(addprefix $(TEST_OUTDIR),$(TEST_SRCFILES:.c=.exe-gdb-run))
|
||||
|
||||
$(TEST_OUTDIR)%.exe-gdb-run: $(TEST_OUTDIR)%.exe
|
||||
gdb $< -ix gdb_init -ex=run --batch --return-child-result
|
||||
|
||||
#util targets
|
||||
$(TEST_OUTDIR):
|
||||
mkdir $(TEST_OUTDIR)
|
||||
|
||||
$(TEST_OBJDIR):
|
||||
mkdir $(TEST_OBJDIR)
|
||||
147
tests/standalone/platform_behaviours.c
Normal file
147
tests/standalone/platform_behaviours.c
Normal file
@@ -0,0 +1,147 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
//utilities
|
||||
#define APPEND(dest, src) \
|
||||
strncpy((dest) + (strlen(dest)), (src), strlen((src)) + 1);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define FLIPSLASH(str) for (int i = 0; str[i]; i++) str[i] = str[i] == '/' ? '\\' : str[i];
|
||||
#else
|
||||
#define FLIPSLASH(str) for (int i = 0; str[i]; i++) str[i] = str[i] == '\\' ? '/' : str[i];
|
||||
#endif
|
||||
|
||||
unsigned char* readFile(char* path, int* size) {
|
||||
//BUGFIX: fix the path based on platform - it might be slower, but it's better than dealing with platform crap
|
||||
int pathLength = strlen(path);
|
||||
char realPath[pathLength + 1];
|
||||
strncpy(realPath, path, pathLength);
|
||||
realPath[pathLength] = '\0';
|
||||
FLIPSLASH(realPath);
|
||||
|
||||
//open the file
|
||||
FILE* file = fopen(path, "rb");
|
||||
if (file == NULL) {
|
||||
*size = -1; //missing file error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//determine the file's length
|
||||
fseek(file, 0L, SEEK_END);
|
||||
*size = ftell(file);
|
||||
rewind(file);
|
||||
|
||||
//make some space
|
||||
unsigned char* buffer = malloc(*size + 1);
|
||||
if (buffer == NULL) {
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//read the file
|
||||
if (fread(buffer, sizeof(unsigned char), *size, file) < *size) {
|
||||
fclose(file);
|
||||
*size = -2; //singal a read error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[(*size)++] = '\0';
|
||||
|
||||
//clean up and return
|
||||
fclose(file);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int getFilePath(char* dest, const char* src) {
|
||||
char* p = NULL;
|
||||
|
||||
//find the last slash, regardless of platform
|
||||
p = strrchr(src, '\\');
|
||||
if (p == NULL) {
|
||||
p = strrchr(src, '/');
|
||||
}
|
||||
if (p == NULL) {
|
||||
int len = strlen(src);
|
||||
strncpy(dest, src, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
//determine length of the path
|
||||
int len = p - src + 1;
|
||||
|
||||
//copy to the dest
|
||||
strncpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int getFileName(char* dest, const char* src) {
|
||||
char* p = NULL;
|
||||
|
||||
//find the last slash, regardless of platform
|
||||
p = strrchr(src, '\\');
|
||||
if (p == NULL) {
|
||||
p = strrchr(src, '/');
|
||||
}
|
||||
if (p == NULL) {
|
||||
int len = strlen(src);
|
||||
strncpy(dest, src, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
p++; //skip the slash
|
||||
|
||||
//determine length of the file name
|
||||
int len = strlen(p);
|
||||
|
||||
//copy to the dest
|
||||
strncpy(dest, p, len);
|
||||
dest[len] = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int main() {
|
||||
//check the platform
|
||||
printf("Platform: ");
|
||||
#if defined(__linux__)
|
||||
printf("Linux");
|
||||
#elif defined(_WIN64)
|
||||
printf("Win64");
|
||||
#elif defined(_WIN32)
|
||||
printf("Win32");
|
||||
#elif defined(__APPLE__)
|
||||
printf("macOS");
|
||||
#else
|
||||
printf("Unknown");
|
||||
#endif
|
||||
|
||||
printf("\n");
|
||||
|
||||
//run each test
|
||||
{
|
||||
char src[256] = "../folder/file.txt";
|
||||
char dest[256];
|
||||
getFilePath(dest, src);
|
||||
printf("Path: %s\n", dest);
|
||||
}
|
||||
|
||||
{
|
||||
char src[256] = "../folder/file.txt";
|
||||
char dest[256];
|
||||
getFileName(dest, src);
|
||||
printf("Name: %s\n", dest);
|
||||
}
|
||||
|
||||
{
|
||||
char src[256] = "../folder/file.txt";
|
||||
char dest[256];
|
||||
getFilePath(dest, src);
|
||||
APPEND(dest, "target.txt");
|
||||
printf("Target: %s\n", dest);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user