forked from Mirror/wren
Tests for IO.read().
This commit is contained in:
@ -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
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 = []
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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
13
test/io/read.wren
Normal 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
|
||||
1
test/io/read_arg_not_string.wren
Normal file
1
test/io/read_arg_not_string.wren
Normal file
@ -0,0 +1 @@
|
||||
IO.read(null) // expect runtime error: Prompt must be a string.
|
||||
Reference in New Issue
Block a user