remove check_compile_error, fix cli tests

This commit is contained in:
Luke Boswell 2024-08-18 15:40:41 +10:00
parent e7a90f1ab5
commit cd955fdb7a
No known key found for this signature in database
GPG key ID: F6DB3C9DB47377B0
2 changed files with 116 additions and 132 deletions

View file

@ -1,4 +1,3 @@
#[macro_use]
extern crate pretty_assertions; extern crate pretty_assertions;
extern crate bumpalo; extern crate bumpalo;
@ -9,18 +8,15 @@ extern crate roc_module;
#[cfg(test)] #[cfg(test)]
mod cli_run { mod cli_run {
use cli_utils::helpers::{dir_from_root, file_from_root, known_bad_file, Run}; use cli_utils::helpers::{dir_from_root, file_from_root, Run};
use const_format::concatcp; use const_format::concatcp;
use indoc::indoc; use indoc::indoc;
use roc_cli::{CMD_BUILD, CMD_CHECK, CMD_FORMAT, CMD_RUN, CMD_TEST}; use roc_cli::{CMD_BUILD, CMD_CHECK, CMD_FORMAT, CMD_RUN, CMD_TEST};
use roc_reporting::report::strip_colors;
use roc_test_utils::assert_multiline_str_eq;
// TODO -- we may need to keep this to prevent race conditions... // TODO -- we may need to keep this to prevent race conditions...
// but we shouldn't be building a host more than once now, so it should be all good // but we shouldn't be building a host more than once now, so it should be all good
// //
// use serial_test::serial; // use serial_test::serial;
use std::path::Path;
#[cfg(all(unix, not(target_os = "macos")))] #[cfg(all(unix, not(target_os = "macos")))]
const ALLOW_VALGRIND: bool = true; const ALLOW_VALGRIND: bool = true;
@ -48,50 +44,13 @@ mod cli_run {
#[allow(dead_code)] #[allow(dead_code)]
const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET); const TARGET_FLAG: &str = concatcp!("--", roc_cli::FLAG_TARGET);
// TODO confirm we we need this #[cfg(all(target_os = "linux", target_arch = "x86_64"))]
// were we testing using Legacy linker anywhere? probably will get const TEST_LEGACY_LINKER: bool = true;
// to this when I start fixing things on linux
//
// #[cfg(all(target_os = "linux", target_arch = "x86_64"))]
// const TEST_LEGACY_LINKER: bool = true;
// // Surgical linker currently only supports linux x86_64, // Surgical linker currently only supports linux x86_64,
// // so we're always testing the legacy linker on other targets. // so we're always testing the legacy linker on other targets.
// #[cfg(not(all(target_os = "linux", target_arch = "x86_64")))] #[cfg(not(all(target_os = "linux", target_arch = "x86_64")))]
// const TEST_LEGACY_LINKER: bool = false; const TEST_LEGACY_LINKER: bool = false;
/// Run `roc check` on a file and check that the output matches the expected string.
fn check_compile_error(file: &Path, flags: &[&str], expected: &str) {
let runner = Run::new_roc().arg(CMD_CHECK).arg(file).add_args(flags);
let out = runner.run();
let err = out.stdout.trim();
let err = strip_colors(err);
// e.g. "1 error and 0 warnings found in 123 ms."
let (before_first_digit, _) = err.split_at(err.rfind("found in ").unwrap());
let err = format!("{before_first_digit}found in <ignored for test> ms.");
// make paths consistent
let err = err.replace('\\', "/");
// consistency with typewriters, very important
let err = err.replace('\r', "");
assert_multiline_str_eq!(err.as_str(), expected);
}
fn check_format_check_as_expected(file: &Path, expects_success_exit_code: bool) {
let runner = Run::new_roc()
.arg(CMD_FORMAT)
.arg(CHECK_FLAG)
.arg(file.to_str().unwrap());
let out = runner.run();
assert_eq!(out.status.success(), expects_success_exit_code);
}
// TODO -- confirm we are using Valgrind correctly // TODO -- confirm we are using Valgrind correctly
// leaving this here for now as a reminder // leaving this here for now as a reminder
@ -1468,124 +1427,160 @@ mod cli_run {
#[test] #[test]
fn known_type_error_with_long_path() { fn known_type_error_with_long_path() {
check_compile_error( let expected_ending = indoc!(
&known_bad_file("UnusedImportButWithALongFileNameForTesting.roc"), r#"
&[],
indoc!(
r#"
UNUSED IMPORT in ...nown_bad/UnusedImportButWithALongFileNameForTesting.roc
Symbol is imported but not used. UNUSED IMPORT in ...nown_bad/UnusedImportButWithALongFileNameForTesting.roc
3 import Symbol exposing [Ident] Symbol is imported but not used.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it. 3 import Symbol exposing [Ident]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it.
0 errors and 1 warning found in <ignored for test> ms."#
),
0 error and 1 warning found in <ignored for test> ms
"#
); );
Run::new_roc()
.arg(CMD_CHECK)
.arg(file_from_root(
"crates/cli/tests/known_bad",
"UnusedImportButWithALongFileNameForTesting.roc",
))
.run()
.assert_stdout_and_stderr_ends_with(expected_ending);
} }
#[test] #[test]
fn exposed_not_defined() { fn exposed_not_defined() {
check_compile_error( let expected_ending = indoc!(
&known_bad_file("ExposedNotDefined.roc"), r#"
&[],
indoc!(
r#"
MISSING DEFINITION in tests/known_bad/ExposedNotDefined.roc
bar is listed as exposed, but it isn't defined in this module. MISSING DEFINITION in tests/known_bad/ExposedNotDefined.roc
You can fix this by adding a definition for bar, or by removing it bar is listed as exposed, but it isn't defined in this module.
from exposes.
You can fix this by adding a definition for bar, or by removing it
from exposes.
1 error and 0 warnings found in <ignored for test> ms."#
),
1 error and 0 warning found in <ignored for test> ms
"#
); );
Run::new_roc()
.arg(CMD_CHECK)
.arg(file_from_root(
"crates/cli/tests/known_bad",
"ExposedNotDefined.roc",
))
.run()
.assert_stdout_and_stderr_ends_with(expected_ending);
} }
#[test] #[test]
fn unused_import() { fn unused_import() {
check_compile_error( let expected_ending = indoc!(
&known_bad_file("UnusedImport.roc"), r#"
&[],
indoc!(
r#"
UNUSED IMPORT in tests/known_bad/UnusedImport.roc
Symbol is imported but not used. UNUSED IMPORT in tests/known_bad/UnusedImport.roc
3 import Symbol exposing [Ident] Symbol is imported but not used.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it. 3 import Symbol exposing [Ident]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Since Symbol isn't used, you don't need to import it.
0 errors and 1 warning found in <ignored for test> ms."#
),
0 error and 1 warning found in <ignored for test> ms
"#
); );
Run::new_roc()
.arg(CMD_CHECK)
.arg(file_from_root(
"crates/cli/tests/known_bad",
"UnusedImport.roc",
))
.run()
.assert_stdout_and_stderr_ends_with(expected_ending);
} }
#[test] #[test]
fn unknown_generates_with() { fn unknown_generates_with() {
check_compile_error( let expected_ending = indoc!(
&known_bad_file("UnknownGeneratesWith.roc"), r#"
&[],
indoc!(
r#"
UNKNOWN GENERATES FUNCTION in tests/known_bad/UnknownGeneratesWith.roc
I don't know how to generate the foobar function. UNKNOWN GENERATES FUNCTION in tests/known_bad/UnknownGeneratesWith.roc
4 generates Effect with [after, map, always, foobar] I don't know how to generate the foobar function.
^^^^^^
Only specific functions like `after` and `map` can be generated.Learn 4 generates Effect with [after, map, always, foobar]
more about hosted modules at TODO. ^^^^^^
Only specific functions like `after` and `map` can be generated.Learn
more about hosted modules at TODO.
1 error and 0 warnings found in <ignored for test> ms."#
),
1 error and 0 warning found in <ignored for test> ms
"#
); );
Run::new_roc()
.arg(CMD_CHECK)
.arg(file_from_root(
"crates/cli/tests/known_bad",
"UnknownGeneratesWith.roc",
))
.run()
.assert_stdout_and_stderr_ends_with(expected_ending);
} }
#[test] #[test]
fn format_check_good() { fn format_check_good() {
check_format_check_as_expected( Run::new_roc()
file_from_root("crates/cli/tests/fixtures/format", "Formatted.roc").as_path(), .arg(CMD_FORMAT)
true, .arg(CHECK_FLAG)
); .arg(file_from_root("crates/cli/tests/fixtures/format", "Formatted.roc").as_path())
.run()
.assert_clean_success();
} }
#[test] #[test]
fn format_check_reformatting_needed() { fn format_check_reformatting_needed() {
check_format_check_as_expected( Run::new_roc()
file_from_root("crates/cli/tests/fixtures/format", "NotFormatted.roc").as_path(), .arg(CMD_FORMAT)
false, .arg(CHECK_FLAG)
); .arg(file_from_root("crates/cli/tests/fixtures/format", "NotFormatted.roc").as_path())
.run()
.assert_nonzero_exit();
} }
#[test] #[test]
fn format_check_folders() { fn format_check_folders() {
// This fails, because "NotFormatted.roc" is present in this folder // This fails, because "NotFormatted.roc" is present in this folder
check_format_check_as_expected( Run::new_roc()
dir_from_root("crates/cli/tests/fixtures/format").as_path(), .arg(CMD_FORMAT)
false, .arg(CHECK_FLAG)
); .arg(dir_from_root("crates/cli/tests/fixtures/format").as_path())
.run()
.assert_nonzero_exit();
// This doesn't fail, since only "Formatted.roc" and non-roc files are present in this folder // This doesn't fail, since only "Formatted.roc" and non-roc files are present in this folder
check_format_check_as_expected( Run::new_roc()
dir_from_root("crates/cli/tests/fixtures/format/formatted_directory").as_path(), .arg(CMD_FORMAT)
true, .arg(CHECK_FLAG)
); .arg(dir_from_root("crates/cli/tests/fixtures/format/formatted_directory").as_path())
.run()
.assert_clean_success();
} }
} }

View file

@ -62,6 +62,10 @@ impl Out {
self.assert_success_with_no_unexpected_errors(COMMON_STDERR.as_slice()); self.assert_success_with_no_unexpected_errors(COMMON_STDERR.as_slice());
} }
pub fn assert_nonzero_exit(&self) {
assert_eq!(self.status.success(), false);
}
/// Assert that the command succeeded and that there are no unexpected errors in the stderr. /// Assert that the command succeeded and that there are no unexpected errors in the stderr.
/// This DOES NOT normalise the output, use assert_stdout_ends_with for that. /// This DOES NOT normalise the output, use assert_stdout_ends_with for that.
pub fn assert_success_with_no_unexpected_errors(&self, expected_errors: &[ExpectedString]) { pub fn assert_success_with_no_unexpected_errors(&self, expected_errors: &[ExpectedString]) {
@ -79,8 +83,7 @@ impl Out {
let without_clrf = input.replace("\r\n", "\n"); let without_clrf = input.replace("\r\n", "\n");
// remove ANSI color codes // remove ANSI color codes
let ansi_regex = Regex::new(r"\x1b\[[0-9;]*[mGKH]").expect("Invalid ANSI regex pattern"); let without_ansi = roc_reporting::report::strip_colors(without_clrf.as_str());
let without_ansi = ansi_regex.replace_all(without_clrf.as_str(), "");
// replace timings with a placeholder // replace timings with a placeholder
let regex = Regex::new(r" in (\d+) ms\.").expect("Invalid regex pattern"); let regex = Regex::new(r" in (\d+) ms\.").expect("Invalid regex pattern");
@ -522,17 +525,3 @@ pub fn file_from_root(dir_name: &str, file_name: &str) -> PathBuf {
path path
} }
#[allow(dead_code)]
pub fn known_bad_file(file_name: &str) -> PathBuf {
let mut path = root_dir();
// Descend into cli/tests/known_bad/{file_name}
path.push("crates");
path.push("cli");
path.push("tests");
path.push("known_bad");
path.push(file_name);
path
}