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
+26 -7
View File
@@ -4,7 +4,7 @@ from __future__ import print_function
from collections import defaultdict
from os import listdir
from os.path import abspath, dirname, isdir, isfile, join, realpath, relpath, splitext
from os.path import abspath, basename, dirname, isdir, isfile, join, realpath, relpath, splitext
import re
from subprocess import Popen, PIPE
import sys
@@ -12,6 +12,7 @@ import sys
# Runs the tests.
WREN_DIR = dirname(dirname(realpath(__file__)))
WREN_APP = join(WREN_DIR, 'bin', 'wrend')
TEST_APP = join(WREN_DIR, 'build', 'debug', 'test', 'wrend')
EXPECT_PATTERN = re.compile(r'// expect: (.*)')
EXPECT_ERROR_PATTERN = re.compile(r'// expect error')
@@ -72,7 +73,7 @@ def print_line(line=None):
sys.stdout.flush()
def run_test(path, example=False):
def run_script(app, path, type):
global passed
global failed
global skipped
@@ -155,7 +156,12 @@ def run_test(path, example=False):
input_bytes = "".join(input_lines).encode("utf-8")
# Invoke wren and run the test.
proc = Popen([WREN_APP, path], stdin=PIPE, stdout=PIPE, stderr=PIPE)
test_arg = path
if type == "api test":
# Just pass the suite name to API tests.
test_arg = basename(splitext(test_arg)[0])
proc = Popen([app, test_arg], stdin=PIPE, stdout=PIPE, stderr=PIPE)
(out, err) = proc.communicate(input_bytes)
fails = []
@@ -223,7 +229,9 @@ def run_test(path, example=False):
for line in out_lines:
if sys.version_info < (3, 0):
line = line.encode('utf-8')
if example:
if type == "example":
# Ignore output from examples.
pass
elif expect_index >= len(expect_output):
fails.append('Got output "{0}" when none was expected.'.format(line))
@@ -251,10 +259,21 @@ def run_test(path, example=False):
print(' ' + color.PINK + fail + color.DEFAULT)
print('')
def run_example(path):
return run_test(path, example=True)
walk(join(WREN_DIR, 'test'), run_test, ignored=['benchmark'])
def run_test(path, example=False):
run_script(WREN_APP, path, "test")
def run_api_test(path):
run_script(TEST_APP, path, "api test")
def run_example(path):
run_script(WREN_APP, path, "example")
walk(join(WREN_DIR, 'test'), run_test, ignored=['api', 'benchmark'])
walk(join(WREN_DIR, 'test', 'api'), run_api_test)
walk(join(WREN_DIR, 'example'), run_example)
print_line()
+28 -6
View File
@@ -23,6 +23,7 @@ CLI_HEADERS := $(wildcard src/cli/*.h)
VM_HEADERS := $(wildcard src/vm/*.h)
CLI_SOURCES := $(wildcard src/cli/*.c)
VM_SOURCES := $(wildcard src/vm/*.c)
TEST_SOURCES := $(shell find test/api -name '*.c')
BUILD_DIR := build
C_WARNINGS := -Wall -Wextra -Werror -Wno-unused-parameter
@@ -93,37 +94,58 @@ endif
CFLAGS := $(C_OPTIONS) $(C_WARNINGS)
CLI_OBJECTS := $(addprefix $(BUILD_DIR)/cli/, $(notdir $(CLI_SOURCES:.c=.o)))
VM_OBJECTS := $(addprefix $(BUILD_DIR)/vm/, $(notdir $(VM_SOURCES:.c=.o)))
CLI_OBJECTS := $(addprefix $(BUILD_DIR)/cli/, $(notdir $(CLI_SOURCES:.c=.o)))
VM_OBJECTS := $(addprefix $(BUILD_DIR)/vm/, $(notdir $(VM_SOURCES:.c=.o)))
TEST_OBJECTS := $(patsubst test/api/%.c, $(BUILD_DIR)/test/%.o, $(TEST_SOURCES))
# Targets ---------------------------------------------------------------------
all: prep bin/$(WREN) lib/lib$(WREN).a lib/lib$(WREN).$(SHARED_EXT)
# Builds the VM libraries and CLI interpreter.
all: bin/$(WREN) lib/lib$(WREN).a lib/lib$(WREN).$(SHARED_EXT)
prep:
@mkdir -p bin lib $(BUILD_DIR)/cli $(BUILD_DIR)/vm
# Builds the API test executable.
test: $(BUILD_DIR)/test/$(WREN)
# Command-line interpreter.
bin/$(WREN): $(CLI_OBJECTS) $(VM_OBJECTS)
@printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)"
@$(CC) $(CFLAGS) -Isrc/include -o $@ $^ -lm
@mkdir -p bin
@$(CC) $(CFLAGS) -o $@ $^ -lm
# Static library.
lib/lib$(WREN).a: $(VM_OBJECTS)
@printf "%10s %-30s %s\n" $(AR) $@ "rcu"
@mkdir -p lib
@$(AR) rcu $@ $^
# Shared library.
lib/lib$(WREN).$(SHARED_EXT): $(VM_OBJECTS)
@printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS) $(SHARED_LIB_FLAGS)"
@mkdir -p lib
@$(CC) $(CFLAGS) -shared $(SHARED_LIB_FLAGS) -o $@ $^
# Test executable.
$(BUILD_DIR)/test/$(WREN): $(TEST_OBJECTS) $(VM_OBJECTS) $(BUILD_DIR)/cli/io.o $(BUILD_DIR)/cli/vm.o
@printf "%10s %-30s %s\n" $(CC) $@ "$(C_OPTIONS)"
@mkdir -p $(BUILD_DIR)/test
@$(CC) $(CFLAGS) -o $@ $^ -lm
# CLI object files.
$(BUILD_DIR)/cli/%.o: src/cli/%.c $(CLI_HEADERS) $(VM_HEADERS)
@printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
@mkdir -p $(BUILD_DIR)/cli
@$(CC) -c $(CFLAGS) -Isrc/include -o $@ $(FILE_FLAG) $<
# VM object files.
$(BUILD_DIR)/vm/%.o: src/vm/%.c $(VM_HEADERS)
@printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
@mkdir -p $(BUILD_DIR)/vm
@$(CC) -c $(CFLAGS) -Isrc/include -o $@ $(FILE_FLAG) $<
# Test object files.
$(BUILD_DIR)/test/%.o: test/api/%.c $(VM_HEADERS)
@printf "%10s %-30s %s\n" $(CC) $< "$(C_OPTIONS)"
@mkdir -p $(dir $@)
@$(CC) -c $(CFLAGS) -Isrc/include -Isrc/cli -o $@ $(FILE_FLAG) $<
.PHONY: all test