diff options
author | David Sherret <dsherret@users.noreply.github.com> | 2023-03-28 17:49:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-28 21:49:00 +0000 |
commit | 6fb6b0c1f302e8637c96131c9ffc4c4b9f3f5f0f (patch) | |
tree | dff55c1b345f317ebd3ec5a3b62c26ed27d5830c /cli/tests/integration/repl_tests.rs | |
parent | c65149c0a072fa710098b14776c6cd3cc8a204d6 (diff) |
chore: restore pty tests and make them run on the Linux CI (#18424)
1. Rewrites the tests to be more back and forth rather than getting the
output all at once (which I believe was causing the hangs on linux and
maybe mac)
2. Runs the pty tests on the linux ci.
3. Fixes a bunch of tests that were just wrong.
4. Adds timeouts on the pty tests.
Diffstat (limited to 'cli/tests/integration/repl_tests.rs')
-rw-r--r-- | cli/tests/integration/repl_tests.rs | 808 |
1 files changed, 311 insertions, 497 deletions
diff --git a/cli/tests/integration/repl_tests.rs b/cli/tests/integration/repl_tests.rs index f7bd627c3..82cae5024 100644 --- a/cli/tests/integration/repl_tests.rs +++ b/cli/tests/integration/repl_tests.rs @@ -6,35 +6,31 @@ use test_util::assert_ends_with; use test_util::assert_not_contains; use util::TempDir; -#[ignore] #[test] fn pty_multiline() { util::with_pty(&["repl"], |mut console| { console.write_line("(\n1 + 2\n)"); + console.expect("3"); console.write_line("{\nfoo: \"foo\"\n}"); + console.expect("{ foo: \"foo\" }"); console.write_line("`\nfoo\n`"); + console.expect("\"\\nfoo\\n\""); console.write_line("`\n\\`\n`"); + console.expect(r#""\n`\n""#); console.write_line("'{'"); + console.expect(r#""{""#); console.write_line("'('"); + console.expect(r#""(""#); console.write_line("'['"); + console.expect(r#""[""#); console.write_line("/{/"); + console.expect("/{/"); console.write_line("/\\(/"); + console.expect("/\\(/"); console.write_line("/\\[/"); + console.expect("/\\[/"); console.write_line("console.log(\"{test1} abc {test2} def {{test3}}\".match(/{([^{].+?)}/));"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, '3'); - assert_contains!(output, "{ foo: \"foo\" }"); - assert_contains!(output, "\"\\nfoo\\n\""); - assert_contains!(output, "\"\\n`\\n\""); - assert_contains!(output, "\"{\""); - assert_contains!(output, "\"(\""); - assert_contains!(output, "\"[\""); - assert_contains!(output, "/{/"); - assert_contains!(output, "/\\(/"); - assert_contains!(output, "/\\[/"); - assert_contains!(output, "[ \"{test1}\", \"test1\" ]"); + console.expect("[ \"{test1}\", \"test1\" ]"); }); } @@ -42,10 +38,7 @@ fn pty_multiline() { fn pty_null() { util::with_pty(&["repl"], |mut console| { console.write_line("null"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "null"); + console.expect("null"); }); } @@ -54,10 +47,7 @@ fn pty_unpaired_braces() { for right_brace in &[")", "]", "}"] { util::with_pty(&["repl"], |mut console| { console.write_line(right_brace); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "Expression expected"); + console.expect("parse error: Expression expected"); }); } } @@ -66,10 +56,7 @@ fn pty_unpaired_braces() { fn pty_bad_input() { util::with_pty(&["repl"], |mut console| { console.write_line("'\\u{1f3b5}'[0]"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "Unterminated string literal"); + console.expect("Unterminated string literal"); }); } @@ -77,28 +64,21 @@ fn pty_bad_input() { fn pty_syntax_error_input() { util::with_pty(&["repl"], |mut console| { console.write_line("('\\u')"); + console.expect("Bad character escape sequence, expected 4 hex characters"); + console.write_line("'"); - console.write_line("[{'a'}];"); - console.write_line("close();"); + console.expect("Unterminated string constant"); - let output = console.read_all_output(); - assert_contains!( - output, - "Bad character escape sequence, expected 4 hex characters" - ); - assert_contains!(output, "Unterminated string constant"); - assert_contains!(output, "Expected a semicolon"); + console.write_line("[{'a'}];"); + console.expect("Expected a semicolon"); }); } #[test] fn pty_complete_symbol() { util::with_pty(&["repl"], |mut console| { - console.write_line("Symbol.it\t"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "Symbol(Symbol.iterator)"); + console.write_line_raw("Symbol.it\t"); + console.expect("Symbol(Symbol.iterator)"); }); } @@ -106,14 +86,13 @@ fn pty_complete_symbol() { fn pty_complete_declarations() { util::with_pty(&["repl"], |mut console| { console.write_line("class MyClass {}"); - console.write_line("My\t"); - console.write_line("let myVar;"); - console.write_line("myV\t"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "> MyClass"); - assert_contains!(output, "> myVar"); + console.expect("undefined"); + console.write_line_raw("My\t"); + console.expect("[Class: MyClass]"); + console.write_line("let myVar = 2 + 3;"); + console.expect("undefined"); + console.write_line_raw("myV\t"); + console.expect("5"); }); } @@ -121,37 +100,31 @@ fn pty_complete_declarations() { fn pty_complete_primitives() { util::with_pty(&["repl"], |mut console| { console.write_line("let func = function test(){}"); - console.write_line("func.appl\t"); + console.expect("undefined"); + console.write_line_raw("func.appl\t"); + console.expect("func.apply"); console.write_line("let str = ''"); - console.write_line("str.leng\t"); - console.write_line("false.valueO\t"); - console.write_line("5n.valueO\t"); + console.expect("undefined"); + console.write_line_raw("str.leng\t"); + console.expect("str.length"); + console.write_line_raw("false.valueO\t"); + console.expect("false.valueOf"); + console.write_line_raw("5n.valueO\t"); + console.expect("5n.valueOf"); console.write_line("let num = 5"); - console.write_line("num.toStrin\t"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "> func.apply"); - assert_contains!(output, "> str.length"); - assert_contains!(output, "> 5n.valueOf"); - assert_contains!(output, "> false.valueOf"); - assert_contains!(output, "> num.toString"); + console.expect("undefined"); + console.write_line_raw("num.toStrin\t"); + console.expect("num.toString"); }); } #[test] fn pty_complete_expression() { util::with_pty(&["repl"], |mut console| { - console.write_text("Deno.\t\t"); - console.write_text("y"); - console.write_line(""); - console.write_line("close();"); - let output = console.read_all_output(); - assert_contains!(output, "Display all"); - assert_contains!(output, "args"); - assert_contains!(output, "exit"); - assert_contains!(output, "symlink"); - assert_contains!(output, "permissions"); + console.write_raw("Deno.\t\t"); + console.expect("Display all"); + console.write_raw("y"); + console.expect_all(&["symlink", "args", "permissions", "exit"]); }); } @@ -159,66 +132,51 @@ fn pty_complete_expression() { fn pty_complete_imports() { util::with_pty(&["repl", "-A"], |mut console| { // single quotes - console.write_line("import './run/001_hel\t'"); + console.write_line_raw("import './run/001_hel\t'"); + console.expect("Hello World"); // double quotes - console.write_line("import { output } from \"./run/045_out\t\""); - console.write_line("output('testing output');"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "Hello World"); - assert_contains!( - output, - // on windows, could any (it's flaky) - "\ntesting output", - "testing output\u{1b}", - "\r\n\u{1b}[?25htesting output", - ); + console.write_line_raw("import { output } from \"./run/045_out\t\""); + console.expect("\"./run/045_output.ts\""); + console.write_line_raw("output('testing output');"); + console.expect("testing output"); }); // ensure when the directory changes that the suggestions come from the cwd util::with_pty(&["repl", "-A"], |mut console| { console.write_line("Deno.chdir('./subdir');"); - console.write_line("import '../run/001_hel\t'"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "Hello World"); + console.expect("undefined"); + console.write_line_raw("import '../run/001_hel\t'"); + console.expect("Hello World"); }); } #[test] fn pty_complete_imports_no_panic_empty_specifier() { // does not panic when tabbing when empty - util::with_pty(&["repl"], |mut console| { - console.write_line("import '\t';"); - console.write_line("close();"); + util::with_pty(&["repl", "-A"], |mut console| { + if cfg!(windows) { + console.write_line_raw("import '\t'"); + console.expect_any(&["not prefixed with", "https://deno.land"]); + } else { + console.write_raw("import '\t"); + console.expect("import 'https://deno.land"); + } }); } #[test] fn pty_ignore_symbols() { util::with_pty(&["repl"], |mut console| { - console.write_line("Array.Symbol\t"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_contains!(output, "undefined"); - assert_not_contains!( - output, - "Uncaught TypeError: Array.Symbol is not a function" - ); + console.write_line_raw("Array.Symbol\t"); + console.expect("undefined"); }); } #[test] fn pty_assign_global_this() { util::with_pty(&["repl"], |mut console| { - console.write_line("globalThis = 42;"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_not_contains!(output, "panicked"); + console.write_line("globalThis = 40 + 2;"); + console.expect("42"); }); } @@ -228,13 +186,12 @@ fn pty_assign_deno_keys_and_deno() { console.write_line( "Object.keys(Deno).forEach((key)=>{try{Deno[key] = undefined} catch {}})", ); + console.expect("undefined"); console.write_line("delete globalThis.Deno"); - console.write_line("console.log('testing ' + 'this out')"); - console.write_line("close();"); - - let output = console.read_all_output(); - assert_not_contains!(output, "panicked"); - assert_contains!(output, "testing this out"); + console.expect("true"); + console.write_line("console.log('testing ' + 'this out');"); + console.expect("testing this out"); + console.expect("undefined"); }); } @@ -242,9 +199,14 @@ fn pty_assign_deno_keys_and_deno() { fn pty_internal_repl() { util::with_pty(&["repl"], |mut console| { console.write_line("globalThis"); - console.write_line("__\t\t"); - console.write_line("close();"); - let output = console.read_all_output(); + console.write_line_raw("1 + 256"); + let output = console.read_until("257"); + assert_contains!(output, "clear:"); + assert_not_contains!(output, "__DENO_"); + + console.write_line_raw("__\t\t"); + console.expect("> __"); + let output = console.read_until("> __"); assert_contains!(output, "__defineGetter__"); // should not contain the internal repl variable // in the `globalThis` or completions output @@ -257,190 +219,139 @@ fn pty_emoji() { // windows was having issues displaying this util::with_pty(&["repl"], |mut console| { console.write_line(r#"console.log('\u{1F995}');"#); - console.write_line("close();"); - - let output = console.read_all_output(); - // only one for the output (since input is escaped) - let emoji_count = output.chars().filter(|c| *c == '🦕').count(); - assert_eq!(emoji_count, 1); + console.expect("🦕"); }); } #[test] fn console_log() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["console.log('hello')", "'world'"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "hello\nundefined\n\"world\"\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log('hello');"); + console.expect("hello"); + console.write_line("'world'"); + console.expect("\"world\""); + }); } #[test] fn object_literal() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["{}", "{ foo: 'bar' }"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "{}\n{ foo: \"bar\" }\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("{}"); + console.expect("{}"); + console.write_line("{ foo: 'bar' }"); + console.expect("{ foo: \"bar\" }"); + }); } #[test] fn block_expression() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["{};", "{\"\"}"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\n\"\"\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("{};"); + console.expect("undefined"); + console.write_line("{\"\"}"); + console.expect("\"\""); + }); } #[test] fn await_resolve() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["await Promise.resolve('done')"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "\"done\"\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("await Promise.resolve('done')"); + console.expect("\"done\""); + }); } #[test] fn await_timeout() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["await new Promise((r) => setTimeout(r, 0, 'done'))"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "\"done\"\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("await new Promise((r) => setTimeout(r, 0, 'done'))"); + console.expect("\"done\""); + }); } #[test] fn let_redeclaration() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["let foo = 0;", "foo", "let foo = 1;", "foo"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\n0\nundefined\n1\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("let foo = 0;"); + console.expect("undefined"); + console.write_line("foo"); + console.expect("0"); + console.write_line("let foo = 1;"); + console.expect("undefined"); + console.write_line("foo"); + console.expect("1"); + }); } #[test] fn repl_cwd() { - let (_out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["Deno.cwd()"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert!(err.is_empty()); + util::with_pty(&["repl", "-A"], |mut console| { + console.write_line("Deno.cwd()"); + console.expect("testdata"); + }); } #[test] fn typescript() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - "function add(a: number, b: number) { return a + b }", - "const result: number = add(1, 2) as number;", - "result", - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\nundefined\n3\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("function add(a: number, b: number) { return a + b }"); + console.expect("undefined"); + console.write_line("const result: number = add(1, 2) as number;"); + console.expect("undefined"); + console.write_line("result"); + console.expect("3"); + }); } #[test] fn typescript_declarations() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - "namespace Test { export enum Values { A, B, C } }", - "Test.Values.A", - "Test.Values.C", - "interface MyInterface { prop: string; }", - "type MyTypeAlias = string;", - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - let expected_end_text = "undefined\n0\n2\nundefined\nundefined\n"; - assert_ends_with!(out, expected_end_text); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("namespace Test { export enum Values { A, B, C } }"); + console.expect("undefined"); + console.write_line("Test.Values.A"); + console.expect("0"); + console.write_line("Test.Values.C"); + console.expect("2"); + console.write_line("interface MyInterface { prop: string; }"); + console.expect("undefined"); + console.write_line("type MyTypeAlias = string;"); + console.expect("undefined"); + }); } #[test] fn typescript_decorators() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - "function dec(target) { target.prototype.test = () => 2; }", - "@dec class Test {}", - "new Test().test()", - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\n[Class: Test]\n2\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console + .write_line("function dec(target) { target.prototype.test = () => 2; }"); + console.expect("undefined"); + console.write_line("@dec class Test {}"); + console.expect("[Class: Test]"); + console.write_line("new Test().test()"); + console.expect("2"); + }); } #[test] fn eof() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["1 + 2"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "3\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("1 + 2"); + console.expect("3"); + }); } #[test] fn strict() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - "let a = {};", - "Object.preventExtensions(a);", - "a.c = 1;", - ]), - None, - false, - ); - assert_contains!( - out, - "Uncaught TypeError: Cannot add property c, object is not extensible" - ); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("let a = {};"); + console.expect("undefined"); + console.write_line("Object.preventExtensions(a)"); + console.expect("{}"); + console.write_line("a.c = 1;"); + console.expect( + "Uncaught TypeError: Cannot add property c, object is not extensible", + ); + }); } #[test] @@ -459,176 +370,118 @@ fn close_command() { #[test] fn function() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["Deno.writeFileSync"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "[Function: writeFileSync]\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("Deno.writeFileSync"); + console.expect("[Function: writeFileSync]"); + }); } #[test] -#[ignore] fn multiline() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["(\n1 + 2\n)"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "3\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("(\n1 + 2\n)"); + console.expect("3"); + }); } #[test] fn import() { - let (out, _) = util::run_and_collect_output_with_args( - true, - vec![], - Some(vec!["import('./subdir/auto_print_hello.ts')"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_contains!(out, "hello!\n"); + util::with_pty(&["repl", "-A"], |mut console| { + console.write_line("import('./subdir/auto_print_hello.ts')"); + console.expect("hello!"); + }); } #[test] fn import_declarations() { - let (out, _) = util::run_and_collect_output_with_args( - true, - vec!["repl", "--allow-read"], - Some(vec!["import './subdir/auto_print_hello.ts';"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_contains!(out, "hello!\n"); + util::with_pty(&["repl", "-A"], |mut console| { + console.write_line("import './subdir/auto_print_hello.ts'"); + console.expect("hello!"); + }); } #[test] fn exports_stripped() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["export default 5;", "export class Test {}"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_contains!(out, "5\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("const test = 5 + 1; export default test;"); + console.expect("6"); + console.write_line("export class Test {}"); + console.expect("undefined"); + }); } #[test] fn call_eval_unterminated() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["eval('{')"]), - None, - false, - ); - assert_contains!(out, "Unexpected end of input"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("eval('{')"); + console.expect("Unexpected end of input"); + }); } #[test] fn unpaired_braces() { - for right_brace in &[")", "]", "}"] { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![right_brace]), - None, - false, - ); - assert_contains!(out, "Expression expected"); - assert!(err.is_empty()); - } + util::with_pty(&["repl"], |mut console| { + for right_brace in &[")", "]", "}"] { + console.write_line(right_brace); + console.expect("Expression expected"); + } + }); } #[test] fn reference_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["not_a_variable"]), - None, - false, - ); - assert_contains!(out, "not_a_variable is not defined"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("not_a_variable"); + console.expect("not_a_variable is not defined"); + }); } #[test] fn syntax_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - "syntax error", - "2", // ensure it keeps accepting input after - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "parse error: Expected ';', '}' or <eof> at 1:8\n2\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("syntax error"); + console.expect("parse error: Expected ';', '}' or <eof>"); + // ensure it keeps accepting input after + console.write_line("7 * 6"); + console.expect("42"); + }); } #[test] fn syntax_error_jsx() { // JSX is not supported in the REPL - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["const element = <div />;"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_contains!(out, "Expression expected"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("const element = <div />;"); + console.expect("Expression expected"); + }); } #[test] fn type_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["console()"]), - None, - false, - ); - assert_contains!(out, "console is not a function"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("console()"); + console.expect("console is not a function"); + }); } #[test] fn variable() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["var a = 123;", "a"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\n123\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("var a = 123 + 456;"); + console.expect("undefined"); + console.write_line("a"); + console.expect("579"); + }); } #[test] fn lexical_scoped_variable() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["let a = 123;", "a"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "undefined\n123\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("let a = 123 + 456;"); + console.expect("undefined"); + console.write_line("a"); + console.expect("579"); + }); } #[test] @@ -702,95 +555,70 @@ fn disable_history_file() { #[test] fn save_last_eval() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["1", "_"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "1\n1\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("1 + 2"); + console.expect("3"); + console.write_line("_ + 3"); + console.expect("6"); + }); } #[test] fn save_last_thrown() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["throw 1", "_error"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!(out, "Uncaught 1\n1\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("throw 1 + 2"); + console.expect("Uncaught 3"); + console.write_line("_error + 3"); + console.expect("6"); + }); } #[test] fn assign_underscore() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["_ = 1", "2", "_"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - assert_ends_with!( - out, - "Last evaluation result is no longer saved to _.\n1\n2\n1\n" - ); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("_ = 1"); + console.expect("Last evaluation result is no longer saved to _."); + console.write_line("2 + 3"); + console.expect("5"); + console.write_line("_"); + console.expect("1"); + }); } #[test] fn assign_underscore_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["_error = 1", "throw 2", "_error"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - println!("{out}"); - assert_ends_with!( - out, - "Last thrown error is no longer saved to _error.\n1\nUncaught 2\n1\n" - ); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("_error = 1"); + console.expect("Last thrown error is no longer saved to _error."); + console.write_line("throw 2"); + console.expect("Uncaught 2"); + console.write_line("_error"); + console.expect("1"); + }); } #[test] fn custom_inspect() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ + util::with_pty(&["repl"], |mut console| { + console.write_line( r#"const o = { - [Symbol.for("Deno.customInspect")]() { - throw new Error('Oops custom inspect error'); - }, - };"#, - "o", - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - - assert_contains!(out, "Oops custom inspect error"); - assert!(err.is_empty()); + [Symbol.for("Deno.customInspect")]() { + throw new Error('Oops custom inspect error'); + }, + };"#, + ); + console.expect("undefined"); + console.write_line("o"); + console.expect("Oops custom inspect error"); + }); } #[test] fn eval_flag_valid_input() { - let (out, err) = util::run_and_collect_output_with_args( - true, - vec!["repl", "--eval", "const t = 10;"], - Some(vec!["t * 500;"]), - None, - false, - ); - assert_contains!(out, "5000"); - assert!(err.is_empty()); + util::with_pty(&["repl", "--eval", "const t = 10;"], |mut console| { + console.write_line("t * 500"); + console.expect("5000"); + }); } #[test] @@ -879,25 +707,23 @@ fn eval_file_flag_multiple_files() { #[test] fn pty_clear_function() { util::with_pty(&["repl"], |mut console| { - console.write_line("console.log('hello');"); - console.write_line("clear();"); - console.write_line("const clear = 1234 + 2000;"); - console.write_line("clear;"); - console.write_line("close();"); - - let output = console.read_all_output(); + console.write_line("console.log('h' + 'ello');"); + console.expect_all(&["hello", "undefined"]); + console.write_line_raw("clear();"); if cfg!(windows) { - // Windows will overwrite what's in the console buffer before - // we read from it. It contains this string repeated many times - // to clear the screen. - assert_contains!(output, "\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K"); + // expect a bunch of these in the output + console.expect_raw_in_current_output( + "\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K", + ); } else { - assert_contains!(output, "hello"); - assert_contains!(output, "[1;1H"); + console.expect_raw_in_current_output("[1;1H"); } - assert_contains!(output, "undefined"); - assert_contains!(output, "const clear = 1234 + 2000;"); - assert_contains!(output, "3234"); + console.expect("undefined"); // advance past the "clear()"'s undefined + console.expect("> "); + console.write_line("const clear = 1234 + 2000;"); + console.expect("undefined"); + console.write_line("clear;"); + console.expect("3234"); }); } @@ -905,53 +731,42 @@ fn pty_clear_function() { fn pty_tab_handler() { // If the last character is **not** whitespace, we show the completions util::with_pty(&["repl"], |mut console| { - console.write_line("a\t\t"); - console.write_line("close();"); - let output = console.read_all_output(); - assert_contains!(output, "addEventListener"); - assert_contains!(output, "alert"); - assert_contains!(output, "atob"); + console.write_raw("a\t\t"); + console.expect_all(&["addEventListener", "alert", "atob"]); }); // If the last character is whitespace, we just insert a tab util::with_pty(&["repl"], |mut console| { - console.write_line("a; \t\t"); // last character is whitespace - console.write_line("close();"); - let output = console.read_all_output(); - assert_not_contains!(output, "addEventListener"); - assert_not_contains!(output, "alert"); - assert_not_contains!(output, "atob"); + console.write_line("const a = 5;"); + console.expect("undefined"); + console.write_raw("a; \t\ta + 2;\n"); // last character is whitespace + console.expect_any(&[ + // windows + "a; a + 2;", + // unix + "a; \t\ta + 2;", + ]); }); } #[test] fn repl_report_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec![ - r#"console.log(1); reportError(new Error("foo")); console.log(2);"#, - ]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - - // TODO(nayeemrmn): The REPL should report event errors and rejections. - assert_contains!(out, "1\n2\nundefined\n"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("console.log(1);"); + console.expect_all(&["1", "undefined"]); + // TODO(nayeemrmn): The REPL should report event errors and rejections. + console.write_line(r#"reportError(new Error("foo"));"#); + console.expect("undefined"); + console.write_line("console.log(2);"); + console.expect("2"); + }); } #[test] fn pty_aggregate_error() { - let (out, err) = util::run_and_collect_output( - true, - "repl", - Some(vec!["await Promise.any([])"]), - Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), - false, - ); - - assert_contains!(out, "AggregateError"); - assert!(err.is_empty()); + util::with_pty(&["repl"], |mut console| { + console.write_line("await Promise.any([])"); + console.expect("AggregateError"); + }); } #[test] @@ -1062,11 +877,10 @@ fn npm_packages() { fn pty_tab_indexable_props() { util::with_pty(&["repl"], |mut console| { console.write_line("const arr = [1, 2, 3]"); - console.write_line("arr.\t\t"); - console.write_line("close();"); - - let output = console.read_all_output(); - println!("output"); + console.expect("undefined"); + console.write_raw("arr.\t\t"); + console.expect("> arr."); + let output = console.read_until("> arr."); assert_contains!(output, "constructor"); assert_contains!(output, "sort"); assert_contains!(output, "at"); |