summaryrefslogtreecommitdiff
path: root/cli/tests
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tests')
-rw-r--r--cli/tests/integration/repl_tests.rs808
-rw-r--r--cli/tests/integration/run_tests.rs580
-rw-r--r--cli/tests/integration/task_tests.rs9
-rw-r--r--cli/tests/integration/test_tests.rs5
-rw-r--r--cli/tests/testdata/run/stdio_streams_are_locked_in_permission_prompt/text.txt1
5 files changed, 688 insertions, 715 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");
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 4a0581b84..4504c970d 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -6,6 +6,7 @@ use std::io::Read;
use std::io::Write;
use std::process::Command;
use std::process::Stdio;
+use std::time::Duration;
use test_util as util;
use test_util::TempDir;
use tokio::task::LocalSet;
@@ -570,88 +571,183 @@ itest!(_089_run_allow_list {
#[test]
fn _090_run_permissions_request() {
- let args = "run --quiet run/090_run_permissions_request.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests run access to \"ls\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("y\n"),
- Output("⚠️ ️Deno requests run access to \"cat\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("granted\r\n"),
- Output("prompt\r\n"),
- Output("denied\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/090_run_permissions_request.ts"],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"ls\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("y");
+ console.expect("Granted run access to \"ls\".");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"cat\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect("Denied run access to \"cat\".");
+ console.expect("granted");
+ console.expect("denied");
+ },
+ );
}
#[test]
fn _090_run_permissions_request_sync() {
- let args = "run --quiet run/090_run_permissions_request_sync.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests run access to \"ls\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("y\n"),
- Output("⚠️ ️Deno requests run access to \"cat\". Run again with --allow-run to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("granted\r\n"),
- Output("prompt\r\n"),
- Output("denied\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/090_run_permissions_request_sync.ts"],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"ls\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("y");
+ console.expect("Granted run access to \"ls\".");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"cat\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect("Denied run access to \"cat\".");
+ console.expect("granted");
+ console.expect("denied");
+ },
+ );
}
#[test]
fn permissions_prompt_allow_all() {
- let args = "run --quiet run/permissions_prompt_allow_all.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- // "run" permissions
- Output("β”Œ ⚠️ Deno requests run access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-run to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all run access.\r\n"),
- // "read" permissions
- Output("β”Œ ⚠️ Deno requests read access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-read to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all read access.\r\n"),
- // "write" permissions
- Output("β”Œ ⚠️ Deno requests write access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-write to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all write access.\r\n"),
- // "net" permissions
- Output("β”Œ ⚠️ Deno requests net access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-net to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all net access.\r\n"),
- // "env" permissions
- Output("β”Œ ⚠️ Deno requests env access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-env to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all env access.\r\n"),
- // "sys" permissions
- Output("β”Œ ⚠️ Deno requests sys access to \"loadavg\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-sys to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all sys access.\r\n"),
- // "ffi" permissions
- Output("β”Œ ⚠️ Deno requests ffi access to \"FOO\".\r\nβ”œ Requested by `Deno.permissions.query()` API\r\n β”œ Run again with --allow-ffi to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions) >"),
- Input("a\n"),
- Output("βœ… Granted all ffi access.\r\n")
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/permissions_prompt_allow_all.ts"],
+ |mut console| {
+ // "run" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all run access.");
+ // "read" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all read access.");
+ // "write" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests write access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-write to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all write access.");
+ // "net" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests network access to \"foo\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-net to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all net permissions)",
+ ));
+ console.write_line_raw("A\n");
+ console.expect("βœ… Granted all net access.");
+ // "env" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests env access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-env to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
+ ));
+ console.write_line_raw("A\n");
+ console.expect("βœ… Granted all env access.");
+ // "sys" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-sys to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
+ ));
+ console.write_line_raw("A\n");
+ console.expect("βœ… Granted all sys access.");
+ // "ffi" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests ffi access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-ffi to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all ffi permissions)",
+ ));
+ console.write_line_raw("A\n");
+ console.expect("βœ… Granted all ffi access.")
+ },
+ );
}
#[test]
fn permissions_prompt_allow_all_2() {
- let args = "run --quiet run/permissions_prompt_allow_all_2.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- // "env" permissions
- Output("β”Œ ⚠️ Deno requests env access to \"FOO\".\r\nβ”œ Run again with --allow-env to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions) >"),
- Input("d\n"),
- Output("βœ… Granted all env access.\r\n"),
- // "sys" permissions
- Output("β”Œ ⚠️ Deno requests sys access to \"FOO\".\r\nβ”œ Run again with --allow-sys to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions) >"),
- Input("d\n"),
- Output("βœ… Granted all sys access.\r\n"),
- // "read" permissions
- Output("β”Œ ⚠️ Deno requests read access to \"FOO\".\r\nβ”œ Run again with --allow-read to bypass this prompt.\r\nβ”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions) >"),
- Input("d\n"),
- Output("βœ… Granted all read access.\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/permissions_prompt_allow_all_2.ts"],
+ |mut console| {
+ // "env" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests env access to \"FOO\".\r\n",
+ "β”œ Run again with --allow-env to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all env access.");
+
+ // "sys" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests sys access to \"loadavg\".\r\n",
+ "β”œ Requested by `Deno.loadavg()` API.\r\n",
+ "β”œ Run again with --allow-sys to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all sys permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all sys access.");
+
+ // "read" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to <CWD>.\r\n",
+ "β”œ Requested by `Deno.cwd()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("A");
+ console.expect("βœ… Granted all read access.");
+ },
+ );
+}
+
+#[test]
+fn permissions_prompt_allow_all_lowercase_a() {
+ util::with_pty(
+ &["run", "--quiet", "run/permissions_prompt_allow_all.ts"],
+ |mut console| {
+ // "run" permissions
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests run access to \"FOO\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-run to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all run permissions)",
+ ));
+ console.write_line_raw("a");
+ console.expect("Unrecognized option.");
+ },
+ );
}
itest!(_091_use_define_for_class_fields {
@@ -2407,58 +2503,102 @@ mod permissions {
#[test]
fn _061_permissions_request() {
- let args = "run --quiet run/061_permissions_request.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests read access to \"foo\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
- Input("y\n"),
- Output("⚠️ ️Deno requests read access to \"bar\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("granted\r\n"),
- Output("prompt\r\n"),
- Output("denied\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/061_permissions_request.ts"],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to \"foo\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("y");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to \"bar\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect("granted");
+ console.expect("prompt");
+ console.expect("denied");
+ },
+ );
}
#[test]
fn _061_permissions_request_sync() {
- let args = "run --quiet run/061_permissions_request_sync.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests read access to \"foo\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
- Input("y\n"),
- Output("⚠️ ️Deno requests read access to \"bar\". Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("granted\r\n"),
- Output("prompt\r\n"),
- Output("denied\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/061_permissions_request_sync.ts"],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to \"foo\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("y");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access to \"bar\".\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect("granted");
+ console.expect("prompt");
+ console.expect("denied");
+ },
+ );
}
#[test]
fn _062_permissions_request_global() {
- let args = "run --quiet run/062_permissions_request_global.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests read access. Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
- Input("y\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- ]);
+ util::with_pty(
+ &["run", "--quiet", "run/062_permissions_request_global.ts"],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access.\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("y\n");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ },
+ );
}
#[test]
fn _062_permissions_request_global_sync() {
- let args = "run --quiet run/062_permissions_request_global_sync.ts";
- use util::PtyData::*;
- util::test_pty2(args, vec![
- Output("⚠️ ️Deno requests read access. Run again with --allow-read to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)] "),
- Input("y\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- Output("PermissionStatus { state: \"granted\", onchange: null }\r\n"),
- ]);
+ util::with_pty(
+ &[
+ "run",
+ "--quiet",
+ "run/062_permissions_request_global_sync.ts",
+ ],
+ |mut console| {
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests read access.\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-read to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all read permissions)",
+ ));
+ console.write_line_raw("y");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ console
+ .expect("PermissionStatus { state: \"granted\", onchange: null }");
+ },
+ );
}
itest!(_063_permissions_revoke {
@@ -2483,44 +2623,42 @@ mod permissions {
#[test]
fn _066_prompt() {
- let args = "run --quiet --unstable run/066_prompt.ts";
- use util::PtyData::*;
- util::test_pty2(
- args,
- vec![
- Output("What is your name? [Jane Doe] "),
- Input("John Doe\n"),
- Output("Your name is John Doe.\r\n"),
- Output("What is your name? [Jane Doe] "),
- Input("\n"),
- Output("Your name is Jane Doe.\r\n"),
- Output("Prompt "),
- Input("foo\n"),
- Output("Your input is foo.\r\n"),
- Output("Question 0 [y/N] "),
- Input("Y\n"),
- Output("Your answer is true\r\n"),
- Output("Question 1 [y/N] "),
- Input("N\n"),
- Output("Your answer is false\r\n"),
- Output("Question 2 [y/N] "),
- Input("yes\n"),
- Output("Your answer is false\r\n"),
- Output("Confirm [y/N] "),
- Input("\n"),
- Output("Your answer is false\r\n"),
- Output("What is Windows EOL? "),
- Input("windows\n"),
- Output("Your answer is \"windows\"\r\n"),
- Output("Hi [Enter] "),
- Input("\n"),
- Output("Alert [Enter] "),
- Input("\n"),
- Output("The end of test\r\n"),
- Output("What is EOF? "),
- Input("\n"),
- Output("Your answer is null\r\n"),
- ],
+ util::with_pty(
+ &["run", "--quiet", "--unstable", "run/066_prompt.ts"],
+ |mut console| {
+ console.expect("What is your name? [Jane Doe] ");
+ console.write_line_raw("John Doe");
+ console.expect("Your name is John Doe.");
+ console.expect("What is your name? [Jane Doe] ");
+ console.write_line_raw("");
+ console.expect("Your name is Jane Doe.");
+ console.expect("Prompt ");
+ console.write_line_raw("foo");
+ console.expect("Your input is foo.");
+ console.expect("Question 0 [y/N] ");
+ console.write_line_raw("Y");
+ console.expect("Your answer is true");
+ console.expect("Question 1 [y/N] ");
+ console.write_line_raw("N");
+ console.expect("Your answer is false");
+ console.expect("Question 2 [y/N] ");
+ console.write_line_raw("yes");
+ console.expect("Your answer is false");
+ console.expect("Confirm [y/N] ");
+ console.write_line("");
+ console.expect("Your answer is false");
+ console.expect("What is Windows EOL? ");
+ console.write_line("windows");
+ console.expect("Your answer is \"windows\"");
+ console.expect("Hi [Enter] ");
+ console.write_line("");
+ console.expect("Alert [Enter] ");
+ console.write_line("");
+ console.expect("The end of test");
+ console.expect("What is EOF? ");
+ console.write_line("");
+ console.expect("Your answer is null");
+ },
);
}
@@ -2577,19 +2715,28 @@ itest!(byte_order_mark {
#[test]
fn issue9750() {
- use util::PtyData::*;
- util::test_pty2(
- "run --prompt run/issue9750.js",
- vec![
- Output("Enter 'yy':\r\n"),
- Input("yy\n"),
- Output("⚠️ ️Deno requests env access. Run again with --allow-env to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("⚠️ ️Deno requests env access to \"SECRET\". Run again with --allow-env to bypass this prompt.\r\n Allow? [y/n (y = yes allow, n = no deny)]"),
- Input("n\n"),
- Output("error: Uncaught (in promise) PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag\r\n"),
- ],
- );
+ util::with_pty(&["run", "--prompt", "run/issue9750.js"], |mut console| {
+ console.expect("Enter 'yy':");
+ console.write_line_raw("yy");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests env access.\r\n",
+ "β”œ Requested by `Deno.permissions.query()` API.\r\n",
+ "β”œ Run again with --allow-env to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect("Denied env access.");
+ console.expect(concat!(
+ "β”Œ ⚠️ Deno requests env access to \"SECRET\".\r\n",
+ "β”œ Run again with --allow-env to bypass this prompt.\r\n",
+ "β”” Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all env permissions)",
+ ));
+ console.write_line_raw("n");
+ console.expect_all(&[
+ "Denied env access to \"SECRET\".",
+ "PermissionDenied: Requires env access to \"SECRET\", run again with the --allow-env flag",
+ ]);
+ });
}
// Regression test for https://github.com/denoland/deno/issues/11451.
@@ -4100,87 +4247,94 @@ itest!(permission_args_quiet {
});
// Regression test for https://github.com/denoland/deno/issues/16772
-#[ignore]
#[test]
+// todo(dsherret): getting a dns error on windows for some reason
+#[cfg(unix)]
fn file_fetcher_preserves_permissions() {
let _guard = util::http_server();
- util::with_pty(&["repl"], |mut console| {
- console.write_text(
- "const a = import('http://127.0.0.1:4545/run/019_media_types.ts');",
+ util::with_pty(&["repl", "--quiet"], |mut console| {
+ console.write_line(
+ "const a = await import('http://localhost:4545/run/019_media_types.ts');",
);
- console.write_text("y");
- console.write_line("");
- console.write_line("close();");
- let output = console.read_all_output();
- assert_contains!(output, "success");
- assert_contains!(output, "true");
+ console.expect("Allow?");
+ console.write_line_raw("y");
+ console.expect_all(&["success", "true"]);
});
}
-#[ignore]
#[test]
fn stdio_streams_are_locked_in_permission_prompt() {
- let _guard = util::http_server();
- util::with_pty(&[
- "repl",
- "--allow-read=run/stdio_streams_are_locked_in_permission_prompt/worker.js,run/stdio_streams_are_locked_in_permission_prompt/text.txt"
- ], |mut console| {
- console.write_line(
- r#"new Worker(`${Deno.cwd()}/run/stdio_streams_are_locked_in_permissions_prompt/worker.js`, { type: "module" });
- await Deno.writeTextFile("./run/stdio_streams_are_locked_in_permissions_prompt/text.txt", "some code");"#,
- );
- console.write_line("y");
- console.write_line("close();");
- let output = console.read_all_output();
-
- let expected_output = r#"\x1b[1;1H\x1b[0JAre you sure you want to continue?"#;
- assert_eq!(output, expected_output);
- });
+ let context = TestContextBuilder::new()
+ .use_http_server()
+ .use_copy_temp_dir("run/stdio_streams_are_locked_in_permission_prompt")
+ .build();
+ context
+ .new_command()
+ .args("repl --allow-read")
+ .with_pty(|mut console| {
+ console.write_line(r#"const url = "file://" + Deno.cwd().replace("\\", "/") + "/run/stdio_streams_are_locked_in_permission_prompt/worker.js";"#);
+ console.expect("undefined");
+ // ensure this file exists
+ console.write_line(r#"const _file = Deno.readTextFileSync("./run/stdio_streams_are_locked_in_permission_prompt/worker.js");"#);
+ console.expect("undefined");
+ console.write_line(r#"new Worker(url, { type: "module" }); await Deno.writeTextFile("./text.txt", "some code");"#);
+ console.expect("Allow? [y/n/A] (y = yes, allow; n = no, deny; A = allow all write permissions)");
+ std::thread::sleep(Duration::from_millis(50)); // give the other thread some time to output
+ console.write_line_raw("invalid");
+ console.expect("Unrecognized option.");
+ console.write_line_raw("y");
+ console.expect("Granted write access to");
+
+ // this output should now be shown below and not above
+ let expected_output = r#"Are you sure you want to continue?"#;
+ console.expect(expected_output);
+ });
}
#[test]
-#[ignore]
fn permission_prompt_strips_ansi_codes_and_control_chars() {
let _guard = util::http_server();
util::with_pty(&["repl"], |mut console| {
console.write_line(
r#"Deno.permissions.request({ name: "env", variable: "\rDo you like ice cream? y/n" });"#
);
- console.write_line("close();");
- let output = console.read_all_output();
-
- assert!(output.contains(
- "β”Œ ⚠️ Deno requests env access to \"Do you like ice cream? y/n\"."
- ));
+ console.expect(
+ "β”Œ ⚠️ Deno requests env access to \"Do you like ice cream? y/n\".",
+ )
});
util::with_pty(&["repl"], |mut console| {
- console.write_line(
- r#"
-const boldANSI = "\u001b[1m" // bold
-const unboldANSI = "\u001b[22m" // unbold
-
-const prompt = `β”Œ ⚠️ ${boldANSI}Deno requests run access to "echo"${unboldANSI}
-β”œ Requested by \`Deno.Command().output()`
-
-const moveANSIUp = "\u001b[1A" // moves to the start of the line
-const clearANSI = "\u001b[2K" // clears the line
-const moveANSIStart = "\u001b[1000D" // moves to the start of the line
-
-Deno[Object.getOwnPropertySymbols(Deno)[0]].core.ops.op_spawn_child({
+ console.write_line_raw(r#"const boldANSI = "\u001b[1m";"#);
+ console.expect("undefined");
+ console.write_line_raw(r#"const unboldANSI = "\u001b[22m";"#);
+ console.expect("undefined");
+ console.write_line_raw(r#"const prompt = `β”Œ ⚠️ ${boldANSI}Deno requests run access to "echo"${unboldANSI}\n β”œ Requested by \`Deno.Command().output()`"#);
+ console.expect("undefined");
+ console.write_line_raw(r#"const moveANSIUp = "\u001b[1A";"#);
+ console.expect("undefined");
+ console.write_line_raw(r#"const clearANSI = "\u001b[2K";"#);
+ console.expect("undefined");
+ console.write_line_raw(r#"const moveANSIStart = "\u001b[1000D";"#);
+ console.expect("undefined");
+
+ console.write_line_raw(
+ r#"Deno[Deno.internal].core.ops.op_spawn_child({
cmd: "cat",
- args: ["/etc/passwd"],
+ args: ["file.txt"],
clearEnv: false,
+ cwd: undefined,
env: [],
+ uid: undefined,
+ gid: undefined,
stdin: "null",
stdout: "inherit",
- stderr: "piped"
+ stderr: "piped",
+ signal: undefined,
+ windowsRawArguments: false,
}, moveANSIUp + clearANSI + moveANSIStart + prompt)"#,
);
- console.write_line("close();");
- let output = console.read_all_output();
- assert!(output.contains(r#"β”Œ ⚠️ Deno requests run access to "cat""#));
+ console.expect(r#"β”Œ ⚠️ Deno requests run access to "cat""#);
});
}
diff --git a/cli/tests/integration/task_tests.rs b/cli/tests/integration/task_tests.rs
index 3dce90a0c..f090deff5 100644
--- a/cli/tests/integration/task_tests.rs
+++ b/cli/tests/integration/task_tests.rs
@@ -53,9 +53,12 @@ itest!(task_non_existent {
#[test]
fn task_emoji() {
// this bug only appears when using a pty/tty
- let args = "task --config task/deno_json/deno.json echo_emoji";
- use test_util::PtyData::*;
- test_util::test_pty2(args, vec![Output("Task echo_emoji echo πŸ”₯\r\nπŸ”₯")]);
+ test_util::with_pty(
+ &["task", "--config", "task/deno_json/deno.json", "echo_emoji"],
+ |mut console| {
+ console.expect("Task echo_emoji echo πŸ”₯\r\nπŸ”₯");
+ },
+ );
}
itest!(task_boolean_logic {
diff --git a/cli/tests/integration/test_tests.rs b/cli/tests/integration/test_tests.rs
index 107d137e7..3a7f37db8 100644
--- a/cli/tests/integration/test_tests.rs
+++ b/cli/tests/integration/test_tests.rs
@@ -446,6 +446,8 @@ itest!(parallel_output {
});
#[test]
+// todo(#18480): re-enable
+#[ignore]
fn sigint_with_hanging_test() {
util::with_pty(
&[
@@ -457,9 +459,10 @@ fn sigint_with_hanging_test() {
|mut console| {
std::thread::sleep(std::time::Duration::from_secs(1));
console.write_line("\x03");
+ let text = console.read_until("hanging_test.ts:10:15");
wildcard_match(
include_str!("../testdata/test/sigint_with_hanging_test.out"),
- &console.read_all_output(),
+ &text,
);
},
);
diff --git a/cli/tests/testdata/run/stdio_streams_are_locked_in_permission_prompt/text.txt b/cli/tests/testdata/run/stdio_streams_are_locked_in_permission_prompt/text.txt
deleted file mode 100644
index e6177e9cf..000000000
--- a/cli/tests/testdata/run/stdio_streams_are_locked_in_permission_prompt/text.txt
+++ /dev/null
@@ -1 +0,0 @@
-\x1B[2J\x1B[1;1H \ No newline at end of file