mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-11 14:18:42 +01:00
Better embedding API support (and tests!) for strings with null bytes.
- Test that a foreign method can return strings. - Test that a foreign method can return a string with null bytes. - Test wrenCall(). - Allow passing NULL for "v" to wrenCall(). - Allow "a" for passing an explicit length byte array to wrenCall().
This commit is contained in:
50
test/api/call.c
Normal file
50
test/api/call.c
Normal file
@ -0,0 +1,50 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "call.h"
|
||||
#include "vm.h"
|
||||
|
||||
static void runTests(WrenVM* vm)
|
||||
{
|
||||
WrenValue* noParams = wrenGetMethod(vm, "main", "Api", "noParams");
|
||||
WrenValue* zero = wrenGetMethod(vm, "main", "Api", "zero()");
|
||||
WrenValue* one = wrenGetMethod(vm, "main", "Api", "one(_)");
|
||||
WrenValue* two = wrenGetMethod(vm, "main", "Api", "two(_,_)");
|
||||
|
||||
// Different arity.
|
||||
wrenCall(vm, noParams, NULL, "");
|
||||
wrenCall(vm, zero, NULL, "");
|
||||
wrenCall(vm, one, NULL, "i", 1);
|
||||
wrenCall(vm, two, NULL, "ii", 1, 2);
|
||||
|
||||
WrenValue* getValue = wrenGetMethod(vm, "main", "Api", "getValue(_)");
|
||||
|
||||
// Returning a value.
|
||||
WrenValue* value = NULL;
|
||||
wrenCall(vm, getValue, &value, "v", NULL);
|
||||
|
||||
// Different argument types.
|
||||
wrenCall(vm, two, NULL, "bb", true, false);
|
||||
wrenCall(vm, two, NULL, "dd", 1.2, 3.4);
|
||||
wrenCall(vm, two, NULL, "ii", 3, 4);
|
||||
wrenCall(vm, two, NULL, "ss", "string", "another");
|
||||
wrenCall(vm, two, NULL, "vv", NULL, value);
|
||||
|
||||
// Truncate a string, or allow null bytes.
|
||||
wrenCall(vm, two, NULL, "aa", "string", 3, "b\0y\0t\0e", 7);
|
||||
|
||||
wrenReleaseValue(vm, noParams);
|
||||
wrenReleaseValue(vm, zero);
|
||||
wrenReleaseValue(vm, one);
|
||||
wrenReleaseValue(vm, two);
|
||||
wrenReleaseValue(vm, getValue);
|
||||
wrenReleaseValue(vm, value);
|
||||
}
|
||||
|
||||
|
||||
WrenForeignMethodFn callBindMethod(const char* signature)
|
||||
{
|
||||
if (strcmp(signature, "static Api.runTests()") == 0) return runTests;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
3
test/api/call.h
Normal file
3
test/api/call.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "wren.h"
|
||||
|
||||
WrenForeignMethodFn callBindMethod(const char* signature);
|
||||
45
test/api/call.wren
Normal file
45
test/api/call.wren
Normal file
@ -0,0 +1,45 @@
|
||||
class Api {
|
||||
static noParams {
|
||||
System.print("noParams")
|
||||
}
|
||||
|
||||
static zero() {
|
||||
System.print("zero")
|
||||
}
|
||||
|
||||
static one(one) {
|
||||
System.print("one " + one.toString)
|
||||
}
|
||||
|
||||
static two(one, two) {
|
||||
// Don't print null bytes.
|
||||
if (two is String && two.bytes.contains(0)) {
|
||||
two = two.bytes.toList
|
||||
}
|
||||
|
||||
System.print("two " + one.toString + " " + two.toString)
|
||||
}
|
||||
|
||||
static getValue(value) {
|
||||
// Return a new value if we aren't given one.
|
||||
if (value == null) return ["a", "b"]
|
||||
|
||||
// Otherwise print it.
|
||||
System.print(value)
|
||||
}
|
||||
|
||||
foreign static runTests()
|
||||
}
|
||||
|
||||
Api.runTests()
|
||||
// expect: noParams
|
||||
// expect: zero
|
||||
// expect: one 1
|
||||
// expect: two 1 2
|
||||
|
||||
// expect: two true false
|
||||
// expect: two 1.2 3.4
|
||||
// expect: two 3 4
|
||||
// expect: two string another
|
||||
// expect: two null [a, b]
|
||||
// expect: two str [98, 0, 121, 0, 116, 0, 101]
|
||||
@ -4,6 +4,7 @@
|
||||
#include "vm.h"
|
||||
#include "wren.h"
|
||||
|
||||
#include "call.h"
|
||||
#include "foreign_class.h"
|
||||
#include "returns.h"
|
||||
#include "value.h"
|
||||
@ -35,6 +36,7 @@ static WrenForeignMethodFn bindForeignMethod(
|
||||
strcat(fullName, ".");
|
||||
strcat(fullName, signature);
|
||||
|
||||
REGISTER_METHOD(call, call);
|
||||
REGISTER_METHOD(foreign_class, foreignClass);
|
||||
REGISTER_METHOD(returns, returns);
|
||||
REGISTER_METHOD(value, value);
|
||||
@ -56,7 +58,6 @@ static WrenForeignClassMethods bindForeignClass(
|
||||
return methods;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
@ -73,7 +74,7 @@ int main(int argc, const char* argv[])
|
||||
strcat(testPath, testName);
|
||||
strcat(testPath, ".wren");
|
||||
|
||||
setForeignCallbacks(bindForeignMethod, bindForeignClass);
|
||||
setTestCallbacks(bindForeignMethod, bindForeignClass);
|
||||
runFile(testPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -27,6 +27,16 @@ static void returnFalse(WrenVM* vm)
|
||||
wrenReturnBool(vm, false);
|
||||
}
|
||||
|
||||
static void returnString(WrenVM* vm)
|
||||
{
|
||||
wrenReturnString(vm, "a string", -1);
|
||||
}
|
||||
|
||||
static void returnBytes(WrenVM* vm)
|
||||
{
|
||||
wrenReturnString(vm, "a\0b\0c", 5);
|
||||
}
|
||||
|
||||
WrenForeignMethodFn returnsBindMethod(const char* signature)
|
||||
{
|
||||
if (strcmp(signature, "static Api.implicitNull") == 0) return implicitNull;
|
||||
@ -34,6 +44,8 @@ WrenForeignMethodFn returnsBindMethod(const char* signature)
|
||||
if (strcmp(signature, "static Api.returnFloat") == 0) return returnFloat;
|
||||
if (strcmp(signature, "static Api.returnTrue") == 0) return returnTrue;
|
||||
if (strcmp(signature, "static Api.returnFalse") == 0) return returnFalse;
|
||||
if (strcmp(signature, "static Api.returnString") == 0) return returnString;
|
||||
if (strcmp(signature, "static Api.returnBytes") == 0) return returnBytes;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ class Api {
|
||||
|
||||
foreign static returnTrue
|
||||
foreign static returnFalse
|
||||
|
||||
foreign static returnString
|
||||
foreign static returnBytes
|
||||
}
|
||||
|
||||
System.print(Api.implicitNull == null) // expect: true
|
||||
@ -15,3 +18,6 @@ System.print(Api.returnFloat) // expect: 123.456
|
||||
|
||||
System.print(Api.returnTrue) // expect: true
|
||||
System.print(Api.returnFalse) // expect: false
|
||||
|
||||
System.print(Api.returnString) // expect: a string
|
||||
System.print(Api.returnBytes.bytes.toList) // expect: [97, 0, 98, 0, 99]
|
||||
|
||||
Reference in New Issue
Block a user