feat: add C API test infrastructure with foreign method binding support

Add a new test framework for exercising the Wren C embedding API directly from C code, including a Makefile target, test runner modifications, and the first API test case for boolean return values. The build system now compiles test sources from `test/api/` into a separate test executable, and the CLI's `createVM` and `runFile` functions accept an optional `WrenBindForeignMethodFn` callback to enable foreign method binding in tests. The test runner (`script/test.py`) is refactored to support both script and API test types, passing the test name instead of the full path for API tests. The initial `return_bool` test verifies that `wrenReturnBool` correctly returns `true` and `false` from foreign methods.
This commit is contained in:
Bob Nystrom
2015-05-24 16:23:30 +00:00
parent 6d2bafc211
commit 3901ab57e7
10 changed files with 152 additions and 21 deletions
+58
View File
@@ -0,0 +1,58 @@
#include <stdio.h>
#include <string.h>
#include "io.h"
#include "vm.h"
#include "wren.h"
#include "return_bool/return_bool.h"
// The name of the currently executing API test.
const char* testName;
static WrenForeignMethodFn bindForeign(
WrenVM* vm, const char* module, const char* className,
bool isStatic, const char* signature)
{
if (strcmp(module, "main") != 0) return NULL;
// For convenience, concatenate all of the method qualifiers into a single
// signature string.
char fullName[256];
fullName[0] = '\0';
if (isStatic) strcat(fullName, "static ");
strcat(fullName, className);
strcat(fullName, ".");
strcat(fullName, signature);
if (strcmp(testName, "return_bool") == 0)
{
return returnBoolBindForeign(fullName);
}
fprintf(stderr,
"Unknown foreign method '%s' for test '%s'\n", fullName, testName);
return NULL;
}
int main(int argc, const char* argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: wren <test>\n");
return 64; // EX_USAGE.
}
testName = argv[1];
// The test script is at "test/api/<test>/<test>.wren".
char testPath[256];
strcpy(testPath, "test/api/");
strcat(testPath, testName);
strcat(testPath, "/");
strcat(testPath, testName);
strcat(testPath, ".wren");
runFile(bindForeign, testPath);
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
#include <string.h>
#include "wren.h"
static void returnTrue(WrenVM* vm)
{
wrenReturnBool(vm, true);
}
static void returnFalse(WrenVM* vm)
{
wrenReturnBool(vm, false);
}
WrenForeignMethodFn returnBoolBindForeign(const char* signature)
{
if (strcmp(signature, "static Api.returnTrue") == 0) return returnTrue;
if (strcmp(signature, "static Api.returnFalse") == 0) return returnFalse;
return NULL;
}
+3
View File
@@ -0,0 +1,3 @@
#include "wren.h"
WrenForeignMethodFn returnBoolBindForeign(const char* signature);
+7
View File
@@ -0,0 +1,7 @@
class Api {
foreign static returnTrue
foreign static returnFalse
}
IO.print(Api.returnTrue) // expect: true
IO.print(Api.returnFalse) // expect: false