1
0
forked from Mirror/wren

Tests for IO.read().

This commit is contained in:
Bob Nystrom
2015-01-11 21:47:29 -08:00
parent 7a7c7a8fad
commit 1d9445d9bc
8 changed files with 44 additions and 5 deletions

View File

@ -80,6 +80,7 @@ class IO {
}
static read(prompt) {
if (!(prompt is String)) Fiber.abort("Prompt must be a string.")
IO.write(prompt)
return IO.read
}

View File

@ -85,6 +85,10 @@ WrenVM* wrenNewVM(WrenConfiguration* configuration);
void wrenFreeVM(WrenVM* vm);
// Runs [source], a string of Wren source code in a new fiber in [vm].
//
// [sourcePath] is a string describing where [source] was located, for use in
// debugging stack traces. It must not be `null`. If an empty string, it will
// not be shown in a stack trace.
WrenInterpretResult wrenInterpret(WrenVM* vm, const char* sourcePath,
const char* source);

View File

@ -20,6 +20,7 @@ EXPECT_ERROR_LINE_PATTERN = re.compile(r'// expect error line (\d+)')
EXPECT_RUNTIME_ERROR_PATTERN = re.compile(r'// expect runtime error: (.+)')
ERROR_PATTERN = re.compile(r'\[.* line (\d+)\] Error')
STACK_TRACE_PATTERN = re.compile(r'\[.* line (\d+)\] in')
STDIN_PATTERN = re.compile(r'// stdin: (.*)')
SKIP_PATTERN = re.compile(r'// skip: (.*)')
NONTEST_PATTERN = re.compile(r'// nontest')
@ -90,6 +91,8 @@ def run_test(path):
expect_runtime_error = None
expect_return = 0
input_lines = []
print_line('Passed: ' + color.GREEN + str(passed) + color.DEFAULT +
' Failed: ' + color.RED + str(failed) + color.DEFAULT +
' Skipped: ' + color.YELLOW + str(num_skipped) + color.DEFAULT)
@ -120,6 +123,10 @@ def run_test(path):
# If we expect a runtime error, it should exit with EX_SOFTWARE.
expect_return = 70
match = STDIN_PATTERN.search(line)
if match:
input_lines.append(match.group(1) + '\n')
match = SKIP_PATTERN.search(line)
if match:
num_skipped += 1
@ -133,10 +140,16 @@ def run_test(path):
line_num += 1
# If any input is fed to the test in stdin, concatetate it into one string.
input_string = None
if input_lines > 0:
input_string = "".join(input_lines)
# Invoke wren and run the test.
proc = Popen([WREN_APP, path], stdout=PIPE, stderr=PIPE)
(out, err) = proc.communicate()
(out, err) = out.decode("utf-8").replace('\r\n', '\n'), err.decode("utf-8").replace('\r\n', '\n')
proc = Popen([WREN_APP, path], stdin=PIPE, stdout=PIPE, stderr=PIPE)
(out, err) = proc.communicate(input_string)
out = out.decode("utf-8").replace('\r\n', '\n')
err = err.decode("utf-8").replace('\r\n', '\n')
fails = []

View File

@ -1202,7 +1202,7 @@ void wrenInitializeCore(WrenVM* vm)
vm->numClass->name->obj.classObj = vm->stringClass;
vm->stringClass->name->obj.classObj = vm->stringClass;
wrenInterpret(vm, "Wren core library", libSource);
wrenInterpret(vm, "", libSource);
vm->listClass = AS_CLASS(findGlobal(vm, "List"));
NATIVE(vm->listClass->obj.classObj, " instantiate", list_instantiate);

View File

@ -19,6 +19,12 @@ void wrenDebugPrintStackTrace(WrenVM* vm, ObjFiber* fiber)
fn = ((ObjClosure*)frame->fn)->fn;
}
// Built-in libraries have no source path and are explicitly omitted from
// stack traces since we don't want to highlight to a user the
// implementation detail of what part of a core library is implemented in
// C and what is in Wren.
if (fn->debug->sourcePath->length == 0) continue;
// - 1 because IP has advanced past the instruction that it just executed.
int line = fn->debug->sourceLines[frame->ip - fn->bytecode - 1];
fprintf(stderr, "[%s line %d] in %s\n",

View File

@ -93,6 +93,7 @@ static const char* libSource =
" }\n"
"\n"
" static read(prompt) {\n"
" if (!(prompt is String)) Fiber.abort(\"Prompt must be a string.\")\n"
" IO.write(prompt)\n"
" return IO.read\n"
" }\n"
@ -133,7 +134,7 @@ static void ioClock(WrenVM* vm)
void wrenLoadIOLibrary(WrenVM* vm)
{
wrenInterpret(vm, "Wren IO library", libSource);
wrenInterpret(vm, "", libSource);
wrenDefineStaticMethod(vm, "IO", "writeString_", 1, ioWriteString);
wrenDefineStaticMethod(vm, "IO", "clock", 0, ioClock);
wrenDefineStaticMethod(vm, "IO", "read", 0, ioRead);

13
test/io/read.wren Normal file
View File

@ -0,0 +1,13 @@
var a = IO.read("a:") // stdin: first
var b = IO.read("b:") // stdin: second
IO.print
// Using write() here because the read lines include the trailing newline.
IO.write(a)
IO.write(b)
// Since stdin isn't echoed back to stdout, we don't see the input lines here,
// and there is no newline between the two prompts since that normally comes
// from the input itself.
// expect: a:b:
// expect: first
// expect: second

View File

@ -0,0 +1 @@
IO.read(null) // expect runtime error: Prompt must be a string.