From 3455f16079c2ca676e092d2123b8895e68e1a3ee Mon Sep 17 00:00:00 2001 From: David Sherret Date: Tue, 21 Jun 2022 15:25:07 -0400 Subject: [PATCH] chore(test_util): add new string assertion macros (#14928) --- cli/tests/integration/bundle_tests.rs | 77 ++++----- cli/tests/integration/install_tests.rs | 26 +-- cli/tests/integration/repl_tests.rs | 221 +++++++++++++------------ cli/tests/integration/watcher_tests.rs | 10 +- test_util/src/assertions.rs | 39 +++++ test_util/src/lib.rs | 3 +- 6 files changed, 211 insertions(+), 165 deletions(-) create mode 100644 test_util/src/assertions.rs diff --git a/cli/tests/integration/bundle_tests.rs b/cli/tests/integration/bundle_tests.rs index 4bd342acdf..dd83f0a95a 100644 --- a/cli/tests/integration/bundle_tests.rs +++ b/cli/tests/integration/bundle_tests.rs @@ -2,6 +2,8 @@ use crate::itest; use test_util as util; +use test_util::assert_contains; +use test_util::assert_ends_with; use test_util::TempDir; #[test] @@ -39,10 +41,10 @@ fn bundle_exports() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -81,10 +83,10 @@ fn bundle_exports_no_check() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -113,10 +115,10 @@ fn bundle_circular() { .output() .unwrap(); // check the output of the the bundle program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("f2\nf1")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "f2\nf1", + ); assert_eq!(output.stderr, b""); } @@ -145,10 +147,10 @@ fn bundle_single_module() { .output() .unwrap(); // check the output of the the bundle program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello world!")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello world!", + ); assert_eq!(output.stderr, b""); } @@ -187,10 +189,10 @@ fn bundle_tla() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -249,10 +251,10 @@ fn bundle_dynamic_import() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -294,10 +296,10 @@ fn bundle_import_map() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -338,10 +340,10 @@ fn bundle_import_map_no_check() { .output() .unwrap(); // check the output of the test.ts program. - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("Hello")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "Hello", + ); assert_eq!(output.stderr, b""); } @@ -372,9 +374,7 @@ fn bundle_json_module() { // check that nothing went to stderr assert_eq!(output.stderr, b""); // ensure the output looks right - assert!(String::from_utf8(output.stdout) - .unwrap() - .contains("with space")); + assert_contains!(String::from_utf8(output.stdout).unwrap(), "with space",); } #[test] @@ -404,9 +404,10 @@ fn bundle_json_module_escape_sub() { // check that nothing went to stderr assert_eq!(output.stderr, b""); // make sure the output looks right and the escapes were effective - assert!(String::from_utf8(output.stdout) - .unwrap() - .contains("${globalThis}`and string literal`")); + assert_contains!( + String::from_utf8(output.stdout).unwrap(), + "${globalThis}`and string literal`", + ); } itest!(lock_check_err_with_bundle { diff --git a/cli/tests/integration/install_tests.rs b/cli/tests/integration/install_tests.rs index 60bfaf50e8..2db32bd285 100644 --- a/cli/tests/integration/install_tests.rs +++ b/cli/tests/integration/install_tests.rs @@ -3,6 +3,8 @@ use std::fs; use std::process::Command; use test_util as util; +use test_util::assert_contains; +use test_util::assert_ends_with; use test_util::TempDir; #[test] @@ -42,11 +44,12 @@ fn install_basic() { assert_eq!(content.chars().last().unwrap(), '\n'); if cfg!(windows) { - assert!( - content.contains(r#""run" "--check" "http://localhost:4545/echo.ts""#) + assert_contains!( + content, + r#""run" "--check" "http://localhost:4545/echo.ts""# ); } else { - assert!(content.contains(r#"run --check 'http://localhost:4545/echo.ts'"#)); + assert_contains!(content, r#"run --check 'http://localhost:4545/echo.ts'"#); } } @@ -83,11 +86,12 @@ fn install_custom_dir_env_var() { let content = fs::read_to_string(file_path).unwrap(); if cfg!(windows) { - assert!( - content.contains(r#""run" "--check" "http://localhost:4545/echo.ts""#) + assert_contains!( + content, + r#""run" "--check" "http://localhost:4545/echo.ts""# ); } else { - assert!(content.contains(r#"run --check 'http://localhost:4545/echo.ts'"#)); + assert_contains!(content, r#"run --check 'http://localhost:4545/echo.ts'"#); } } @@ -124,7 +128,7 @@ fn installer_test_local_module_run() { .output() .unwrap(); let stdout_str = std::str::from_utf8(&output.stdout).unwrap().trim(); - assert!(stdout_str.ends_with("hello, foo")); + assert_ends_with!(stdout_str, "hello, foo"); } #[test] @@ -158,10 +162,10 @@ fn installer_test_remote_module_run() { .env("PATH", util::target_dir()) .output() .unwrap(); - assert!(std::str::from_utf8(&output.stdout) - .unwrap() - .trim() - .ends_with("hello, foo")); + assert_ends_with!( + std::str::from_utf8(&output.stdout).unwrap().trim(), + "hello, foo", + ); } #[test] diff --git a/cli/tests/integration/repl_tests.rs b/cli/tests/integration/repl_tests.rs index a6c0536758..bea5efff42 100644 --- a/cli/tests/integration/repl_tests.rs +++ b/cli/tests/integration/repl_tests.rs @@ -1,6 +1,9 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. use test_util as util; +use test_util::assert_contains; +use test_util::assert_ends_with; +use test_util::assert_not_contains; #[test] fn pty_multiline() { @@ -19,17 +22,17 @@ fn pty_multiline() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains('3')); - assert!(output.contains("{ foo: \"foo\" }")); - assert!(output.contains("\"\\nfoo\\n\"")); - assert!(output.contains("\"\\n`\\n\"")); - assert!(output.contains("\"{\"")); - assert!(output.contains("\"(\"")); - assert!(output.contains("\"[\"")); - assert!(output.contains("/{/")); - assert!(output.contains("/\\(/")); - assert!(output.contains("/\\[/")); - assert!(output.contains("[ \"{test1}\", \"test1\" ]")); + 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\" ]"); }); } @@ -40,7 +43,7 @@ fn pty_null() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("null")); + assert_contains!(output, "null"); }); } @@ -53,9 +56,9 @@ fn pty_unpaired_braces() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Unexpected token `)`")); - assert!(output.contains("Unexpected token `]`")); - assert!(output.contains("Unexpected token `}`")); + assert_contains!(output, "Unexpected token `)`"); + assert_contains!(output, "Unexpected token `]`"); + assert_contains!(output, "Unexpected token `}`"); }); } @@ -66,7 +69,7 @@ fn pty_bad_input() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Unterminated string literal")); + assert_contains!(output, "Unterminated string literal"); }); } @@ -79,10 +82,12 @@ fn pty_syntax_error_input() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output - .contains("Bad character escape sequence, expected 4 hex characters")); - assert!(output.contains("Unterminated string constant")); - assert!(output.contains("Expected a semicolon")); + assert_contains!( + output, + "Bad character escape sequence, expected 4 hex characters" + ); + assert_contains!(output, "Unterminated string constant"); + assert_contains!(output, "Expected a semicolon"); }); } @@ -93,7 +98,7 @@ fn pty_complete_symbol() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Symbol(Symbol.iterator)")); + assert_contains!(output, "Symbol(Symbol.iterator)"); }); } @@ -107,8 +112,8 @@ fn pty_complete_declarations() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("> MyClass")); - assert!(output.contains("> myVar")); + assert_contains!(output, "> MyClass"); + assert_contains!(output, "> myVar"); }); } @@ -126,11 +131,11 @@ fn pty_complete_primitives() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("> func.apply")); - assert!(output.contains("> str.length")); - assert!(output.contains("> 5n.valueOf")); - assert!(output.contains("> false.valueOf")); - assert!(output.contains("> num.toString")); + 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"); }); } @@ -142,12 +147,12 @@ fn pty_complete_expression() { console.write_line(""); console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Display all")); - assert!(output.contains("core")); - assert!(output.contains("args")); - assert!(output.contains("exit")); - assert!(output.contains("symlink")); - assert!(output.contains("permissions")); + assert_contains!(output, "Display all"); + assert_contains!(output, "core"); + assert_contains!(output, "args"); + assert_contains!(output, "exit"); + assert_contains!(output, "symlink"); + assert_contains!(output, "permissions"); }); } @@ -162,12 +167,13 @@ fn pty_complete_imports() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Hello World")); - if cfg!(windows) { - assert!(output.contains("testing output\u{1b}")); - } else { - assert!(output.contains("\ntesting output")); - } + assert_contains!(output, "Hello World"); + assert_contains!( + output, + // on windows, could contain either (it's flaky) + "\ntesting output", + "testing output\u{1b}", + ); }); // ensure when the directory changes that the suggestions come from the cwd @@ -177,7 +183,7 @@ fn pty_complete_imports() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("Hello World")); + assert_contains!(output, "Hello World"); }); } @@ -188,9 +194,10 @@ fn pty_ignore_symbols() { console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("undefined")); - assert!( - !output.contains("Uncaught TypeError: Array.Symbol is not a function") + assert_contains!(output, "undefined"); + assert_not_contains!( + output, + "Uncaught TypeError: Array.Symbol is not a function" ); }); } @@ -202,7 +209,7 @@ fn pty_assign_global_this() { console.write_line("close();"); let output = console.read_all_output(); - assert!(!output.contains("panicked")); + assert_not_contains!(output, "panicked"); }); } @@ -229,7 +236,7 @@ fn console_log() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("hello\nundefined\n\"world\"\n")); + assert_ends_with!(out, "hello\nundefined\n\"world\"\n"); assert!(err.is_empty()); } @@ -242,7 +249,7 @@ fn object_literal() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("{}\n{ foo: \"bar\" }\n")); + assert_ends_with!(out, "{}\n{ foo: \"bar\" }\n"); assert!(err.is_empty()); } @@ -255,7 +262,7 @@ fn block_expression() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\n\"\"\n")); + assert_ends_with!(out, "undefined\n\"\"\n"); assert!(err.is_empty()); } @@ -268,7 +275,7 @@ fn await_resolve() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("\"done\"\n")); + assert_ends_with!(out, "\"done\"\n"); assert!(err.is_empty()); } @@ -281,7 +288,7 @@ fn await_timeout() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("\"done\"\n")); + assert_ends_with!(out, "\"done\"\n"); assert!(err.is_empty()); } @@ -294,7 +301,7 @@ fn let_redeclaration() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\n0\nundefined\n1\n")); + assert_ends_with!(out, "undefined\n0\nundefined\n1\n"); assert!(err.is_empty()); } @@ -323,7 +330,7 @@ fn typescript() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\nundefined\n3\n")); + assert_ends_with!(out, "undefined\nundefined\n3\n"); assert!(err.is_empty()); } @@ -343,10 +350,7 @@ fn typescript_declarations() { false, ); let expected_end_text = "undefined\n0\n2\nundefined\nundefined\n"; - assert_eq!( - &out[out.len() - expected_end_text.len()..], - expected_end_text - ); + assert_ends_with!(out, expected_end_text); assert!(err.is_empty()); } @@ -363,7 +367,7 @@ fn typescript_decorators() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\n[Function: Test]\n2\n")); + assert_ends_with!(out, "undefined\n[Function: Test]\n2\n"); assert!(err.is_empty()); } @@ -376,7 +380,7 @@ fn eof() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("3\n")); + assert_ends_with!(out, "3\n"); assert!(err.is_empty()); } @@ -393,9 +397,10 @@ fn strict() { None, false, ); - assert!(out.contains( + assert_contains!( + out, "Uncaught TypeError: Cannot add property c, object is not extensible" - )); + ); assert!(err.is_empty()); } @@ -409,7 +414,7 @@ fn close_command() { false, ); - assert!(!out.contains("ignored")); + assert_not_contains!(out, "ignored"); assert!(err.is_empty()); } @@ -422,7 +427,7 @@ fn function() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("[Function: writeFileSync]\n")); + assert_ends_with!(out, "[Function: writeFileSync]\n"); assert!(err.is_empty()); } @@ -436,7 +441,7 @@ fn multiline() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("3\n")); + assert_ends_with!(out, "3\n"); assert!(err.is_empty()); } @@ -449,7 +454,7 @@ fn import() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.contains("hello!\n")); + assert_contains!(out, "hello!\n"); } #[test] @@ -461,7 +466,7 @@ fn import_declarations() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.contains("hello!\n")); + assert_contains!(out, "hello!\n"); } #[test] @@ -473,7 +478,7 @@ fn exports_stripped() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.contains("5\n")); + assert_contains!(out, "5\n"); assert!(err.is_empty()); } @@ -486,7 +491,7 @@ fn call_eval_unterminated() { None, false, ); - assert!(out.contains("Unexpected end of input")); + assert_contains!(out, "Unexpected end of input"); assert!(err.is_empty()); } @@ -500,7 +505,7 @@ fn unpaired_braces() { None, false, ); - assert!(out.contains("Unexpected token")); + assert_contains!(out, "Unexpected token"); assert!(err.is_empty()); } } @@ -514,7 +519,7 @@ fn reference_error() { None, false, ); - assert!(out.contains("not_a_variable is not defined")); + assert_contains!(out, "not_a_variable is not defined"); assert!(err.is_empty()); } @@ -530,7 +535,7 @@ fn syntax_error() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("parse error: Expected ';', '}' or at 1:8\n2\n")); + assert_ends_with!(out, "parse error: Expected ';', '}' or at 1:8\n2\n"); assert!(err.is_empty()); } @@ -544,7 +549,7 @@ fn syntax_error_jsx() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.contains("Unexpected token `>`")); + assert_contains!(out, "Unexpected token `>`"); assert!(err.is_empty()); } @@ -557,7 +562,7 @@ fn type_error() { None, false, ); - assert!(out.contains("console is not a function")); + assert_contains!(out, "console is not a function"); assert!(err.is_empty()); } @@ -570,7 +575,7 @@ fn variable() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\n123\n")); + assert_ends_with!(out, "undefined\n123\n"); assert!(err.is_empty()); } @@ -583,7 +588,7 @@ fn lexical_scoped_variable() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("undefined\n123\n")); + assert_ends_with!(out, "undefined\n123\n"); assert!(err.is_empty()); } @@ -604,7 +609,7 @@ fn missing_deno_dir() { ); assert!(read_dir(&test_deno_dir).is_ok()); remove_dir_all(&test_deno_dir).unwrap(); - assert!(out.ends_with("1\n")); + assert_ends_with!(out, "1\n"); assert!(err.is_empty()); } @@ -617,7 +622,7 @@ fn save_last_eval() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("1\n1\n")); + assert_ends_with!(out, "1\n1\n"); assert!(err.is_empty()); } @@ -630,7 +635,7 @@ fn save_last_thrown() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!(out.ends_with("Uncaught 1\n1\n")); + assert_ends_with!(out, "Uncaught 1\n1\n"); assert!(err.is_empty()); } @@ -643,8 +648,9 @@ fn assign_underscore() { Some(vec![("NO_COLOR".to_owned(), "1".to_owned())]), false, ); - assert!( - out.ends_with("Last evaluation result is no longer saved to _.\n1\n2\n1\n") + assert_ends_with!( + out, + "Last evaluation result is no longer saved to _.\n1\n2\n1\n" ); assert!(err.is_empty()); } @@ -659,9 +665,10 @@ fn assign_underscore_error() { false, ); println!("{}", out); - assert!(out.ends_with( + assert_ends_with!( + out, "Last thrown error is no longer saved to _error.\n1\nUncaught 2\n1\n" - )); + ); assert!(err.is_empty()); } @@ -682,7 +689,7 @@ fn custom_inspect() { false, ); - assert!(out.contains("Oops custom inspect error")); + assert_contains!(out, "Oops custom inspect error"); assert!(err.is_empty()); } @@ -695,7 +702,7 @@ fn eval_flag_valid_input() { None, false, ); - assert!(out.contains("5000")); + assert_contains!(out, "5000"); assert!(err.is_empty()); } @@ -708,9 +715,11 @@ fn eval_flag_parse_error() { None, false, ); - assert!(test_util::strip_ansi_codes(&out) - .contains("error in --eval flag. parse error: Unexpected token `%`.")); - assert!(out.contains("2500")); // should not prevent input + assert_contains!( + test_util::strip_ansi_codes(&out), + "error in --eval flag. parse error: Unexpected token `%`." + ); + assert_contains!(out, "2500"); // should not prevent input assert!(err.is_empty()); } @@ -723,8 +732,8 @@ fn eval_flag_runtime_error() { None, false, ); - assert!(out.contains("error in --eval flag. Uncaught Error: Testing")); - assert!(out.contains("2500")); // should not prevent input + assert_contains!(out, "error in --eval flag. Uncaught Error: Testing"); + assert_contains!(out, "2500"); // should not prevent input assert!(err.is_empty()); } @@ -737,7 +746,7 @@ fn eval_file_flag_valid_input() { None, false, ); - assert!(out.contains("Hello World")); + assert_contains!(out, "Hello World"); assert!(err.is_empty()); } @@ -750,7 +759,7 @@ fn eval_file_flag_call_defined_function() { None, false, ); - assert!(out.contains("hello")); + assert_contains!(out, "hello"); assert!(err.is_empty()); } @@ -763,7 +772,7 @@ fn eval_file_flag_http_input() { None, true, ); - assert!(out.contains("hello")); + assert_contains!(out, "hello"); assert!(err.contains("Download")); } @@ -776,8 +785,8 @@ fn eval_file_flag_multiple_files() { None, true, ); - assert!(out.contains("helloFOO")); - assert!(err.contains("Download")); + assert_contains!(out, "helloFOO"); + assert_contains!(err, "Download"); } #[test] @@ -794,14 +803,14 @@ fn pty_clear_function() { // 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!(output.contains("\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K")); + assert_contains!(output, "\r\n\u{1b}[K\r\n\u{1b}[K\r\n\u{1b}[K"); } else { - assert!(output.contains("hello")); - assert!(output.contains("[1;1H")); + assert_contains!(output, "hello"); + assert_contains!(output, "[1;1H"); } - assert!(output.contains("undefined")); - assert!(output.contains("const clear = 1234 + 2000;")); - assert!(output.contains("3234")); + assert_contains!(output, "undefined"); + assert_contains!(output, "const clear = 1234 + 2000;"); + assert_contains!(output, "3234"); }); } @@ -812,17 +821,17 @@ fn pty_tab_handler() { console.write_line("a\t\t"); console.write_line("close();"); let output = console.read_all_output(); - assert!(output.contains("addEventListener")); - assert!(output.contains("alert")); - assert!(output.contains("atob")); + assert_contains!(output, "addEventListener"); + assert_contains!(output, "alert"); + assert_contains!(output, "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("a; \t\t"); // last character is whitespace console.write_line("close();"); let output = console.read_all_output(); - assert!(!output.contains("addEventListener")); - assert!(!output.contains("alert")); - assert!(!output.contains("atob")); + assert_not_contains!(output, "addEventListener"); + assert_not_contains!(output, "alert"); + assert_not_contains!(output, "atob"); }); } diff --git a/cli/tests/integration/watcher_tests.rs b/cli/tests/integration/watcher_tests.rs index 046dcec071..1e79a219dd 100644 --- a/cli/tests/integration/watcher_tests.rs +++ b/cli/tests/integration/watcher_tests.rs @@ -4,19 +4,11 @@ use flaky_test::flaky_test; use std::fs::write; use std::io::BufRead; use test_util as util; +use test_util::assert_contains; use test_util::TempDir; const CLEAR_SCREEN: &str = r#"[2J"#; -macro_rules! assert_contains { - ($string:expr, $($test:expr),+) => { - let string = $string; // This might be a function call or something - if !($(string.contains($test))||+) { - panic!("{:?} does not contain any of {:?}", string, [$($test),+]); - } - } -} - // Helper function to skip watcher output that contains "Restarting" // phrase. fn skip_restarting_line( diff --git a/test_util/src/assertions.rs b/test_util/src/assertions.rs new file mode 100644 index 0000000000..ecee14b1f9 --- /dev/null +++ b/test_util/src/assertions.rs @@ -0,0 +1,39 @@ +#[macro_export] +macro_rules! assert_ends_with { + ($left:expr, $right:expr $(,)?) => { + match (&$left, &$right) { + (actual, expected) => { + let actual = if expected.len() > actual.len() { + actual + } else { + &actual[actual.len() - expected.len()..] + }; + pretty_assertions::assert_eq!( + actual, + *expected, + "should end with expected." + ); + } + } + }; +} + +#[macro_export] +macro_rules! assert_contains { + ($string:expr, $($test:expr),+ $(,)?) => { + let string = &$string; // This might be a function call or something + if !($(string.contains($test))||+) { + panic!("{:?} does not contain any of {:?}", string, [$($test),+]); + } + } +} + +#[macro_export] +macro_rules! assert_not_contains { + ($string:expr, $($test:expr),+ $(,)?) => { + let string = &$string; // This might be a function call or something + if !($(!string.contains($test))||+) { + panic!("{:?} contained {:?}", string, [$($test),+]); + } + } +} diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs index 1373f758d4..8df222115f 100644 --- a/test_util/src/lib.rs +++ b/test_util/src/lib.rs @@ -49,6 +49,7 @@ use tokio_rustls::rustls; use tokio_rustls::TlsAcceptor; use tokio_tungstenite::accept_async; +pub mod assertions; pub mod lsp; pub mod pty; mod temp_dir; @@ -1924,7 +1925,7 @@ pub fn test_pty2(args: &str, data: Vec) { println!("ECHO: {}", echo.escape_debug()); // Windows may also echo the previous line, so only check the end - assert!(normalize_text(&echo).ends_with(&normalize_text(s))); + assert_ends_with!(normalize_text(&echo), normalize_text(s)); } PtyData::Output(s) => { let mut line = String::new();