Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add roc test --ignore-error flag #6623

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub const FLAG_STDOUT: &str = "stdout";
pub const FLAG_WASM_STACK_SIZE_KB: &str = "wasm-stack-size-kb";
pub const FLAG_OUTPUT: &str = "output";
pub const FLAG_FUZZ: &str = "fuzz";
pub const FLAG_IGNORE_BUILD_ERRORS: &str = "ignore-build-errors";
pub const ROC_FILE: &str = "ROC_FILE";
pub const ROC_DIR: &str = "ROC_DIR";
pub const GLUE_DIR: &str = "GLUE_DIR";
Expand Down Expand Up @@ -149,6 +150,12 @@ pub fn build_app() -> Command {
.action(ArgAction::SetTrue)
.required(false);

let flag_ignore_build_errors = Arg::new(FLAG_IGNORE_BUILD_ERRORS)
.long(FLAG_IGNORE_BUILD_ERRORS)
.help("Run tests even if there were build errors")
.action(ArgAction::SetTrue)
.required(false);

let roc_file_to_run = Arg::new(ROC_FILE)
.help("The .roc file of an app to run")
.value_parser(value_parser!(PathBuf))
Expand Down Expand Up @@ -237,6 +244,7 @@ pub fn build_app() -> Command {
.arg(flag_linker.clone())
.arg(flag_prebuilt.clone())
.arg(flag_fuzz.clone())
.arg(flag_ignore_build_errors.clone())
.arg(
Arg::new(FLAG_VERBOSE)
.long(FLAG_VERBOSE)
Expand Down Expand Up @@ -496,6 +504,12 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
// TODO may need to determine this dynamically based on dev builds.
let function_kind = FunctionKind::LambdaSet;

let exec_mode = if matches.get_flag(FLAG_IGNORE_BUILD_ERRORS) {
ExecutionMode::TestIgnoreErrors
} else {
ExecutionMode::Test
};

// Step 1: compile the app and generate the .o file
let load_config = LoadConfig {
target,
Expand All @@ -504,7 +518,7 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {
render: roc_reporting::report::RenderTarget::ColorTerminal,
palette: roc_reporting::report::DEFAULT_PALETTE,
threading,
exec_mode: ExecutionMode::Test,
exec_mode,
};
let load_result = roc_load::load_and_monomorphize(
arena,
Expand Down Expand Up @@ -541,10 +555,12 @@ pub fn test(matches: &ArgMatches, target: Target) -> io::Result<i32> {

// Print warnings before running tests.
{
debug_assert_eq!(
problems.errors, 0,
"if there were errors, we would have already exited."
);
if matches!(exec_mode, ExecutionMode::Test) {
debug_assert_eq!(
problems.errors, 0,
"if there were errors, we would have already exited."
);
}
if problems.warnings > 0 {
problems.print_error_warning_count(start_time.elapsed());
println!(".\n\nRunning tests…\n\n\x1B[36m{}\x1B[39m", "─".repeat(80));
Expand Down
14 changes: 14 additions & 0 deletions crates/cli/tests/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,20 @@ mod cli_run {
);
}

#[test]
fn expect_ignore_build_errors() {
test_roc_expect(
"crates/cli/tests/expects",
"IgnoreBuildErrors.roc",
&["--ignore-build-errors"],
indoc!(
r#"
1 failed and 1 passed in <ignored for test> ms.
"#
),
)
}

#[test]
#[cfg_attr(windows, ignore)]
fn transitive_expects() {
Expand Down
12 changes: 12 additions & 0 deletions crates/cli/tests/expects/IgnoreBuildErrors.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
interface IgnoreBuildErrors
exposes []
imports []

x = 1

expect x == 1

foo = \x -> x + 1

expect foo 2 == 3

4 changes: 2 additions & 2 deletions crates/compiler/build/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,8 +692,8 @@ pub fn standard_load_config(
threading: Threading,
) -> LoadConfig {
let exec_mode = match order {
BuildOrdering::BuildIfChecks => ExecutionMode::ExecutableIfCheck,
BuildOrdering::AlwaysBuild => ExecutionMode::Executable,
BuildOrdering::BuildIfChecks => ExecutionMode::Executable,
BuildOrdering::AlwaysBuild => ExecutionMode::ExecutableIgnoreErrors,
};

// UNSTABLE(lambda-erasure)
Expand Down
27 changes: 15 additions & 12 deletions crates/compiler/load_internal/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,11 @@ pub struct LoadConfig {
#[derive(Debug, Clone, Copy)]
pub enum ExecutionMode {
Check,
ExecutableIgnoreErrors,
/// Like [`ExecutionMode::ExecutableIgnoreErrors`], but stops in the presence of type errors.
Executable,
/// Like [`ExecutionMode::Executable`], but stops in the presence of type errors.
ExecutableIfCheck,
/// Test is like [`ExecutionMode::ExecutableIfCheck`], but rather than producing a proper
/// executable, run tests.
TestIgnoreErrors,
/// Like [`ExecutionMode::TestIgnoreErrors`], but stops in the presence of type errors.
Test,
}

Expand All @@ -128,13 +128,17 @@ impl ExecutionMode {
use ExecutionMode::*;

match self {
Executable => Phase::MakeSpecializations,
Check | ExecutableIfCheck | Test => Phase::SolveTypes,
ExecutableIgnoreErrors | TestIgnoreErrors => Phase::MakeSpecializations,
Check | Executable | Test => Phase::SolveTypes,
}
}

fn build_if_checks(&self) -> bool {
matches!(self, Self::ExecutableIfCheck | Self::Test)
matches!(self, Self::Executable | Self::Test)
}

fn build_tests(&self) -> bool {
matches!(self, Self::Test | Self::TestIgnoreErrors)
}
}

Expand Down Expand Up @@ -397,8 +401,7 @@ fn start_phase<'a>(

let derived_module = SharedDerivedModule::clone(&state.derived_module);

let build_expects =
matches!(state.exec_mode, ExecutionMode::Test) && expectations.is_some();
let build_expects = state.exec_mode.build_tests() && expectations.is_some();

BuildTask::BuildPendingSpecializations {
layout_cache,
Expand Down Expand Up @@ -2638,7 +2641,7 @@ fn update<'a>(

let add_to_host_exposed = is_host_exposed &&
// During testing, we don't need to expose anything to the host.
!matches!(state.exec_mode, ExecutionMode::Test);
!state.exec_mode.build_tests();

if add_to_host_exposed {
state.exposed_to_host.top_level_values.extend(
Expand Down Expand Up @@ -3215,8 +3218,8 @@ fn finish_specialization<'a>(
let entry_point = {
let interns: &mut Interns = &mut interns;
match state.exec_mode {
ExecutionMode::Test => Ok(EntryPoint::Test),
ExecutionMode::Executable | ExecutionMode::ExecutableIfCheck => {
ExecutionMode::Test | ExecutionMode::TestIgnoreErrors => Ok(EntryPoint::Test),
ExecutionMode::ExecutableIgnoreErrors | ExecutionMode::Executable => {
use PlatformPath::*;

let platform_path = match &state.platform_path {
Expand Down
2 changes: 1 addition & 1 deletion crates/compiler/test_gen/src/helpers/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ fn create_llvm_module<'a>(
render: RenderTarget::ColorTerminal,
palette: DEFAULT_PALETTE,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
exec_mode: ExecutionMode::ExecutableIgnoreErrors,
};
let loaded = roc_load::load_and_monomorphize_from_str(
arena,
Expand Down
2 changes: 1 addition & 1 deletion crates/compiler/test_mono/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ fn compiles_to_ir(test_name: &str, src: &str, mode: &str, allow_type_errors: boo
use std::path::PathBuf;

let exec_mode = match mode {
"exec" => ExecutionMode::Executable,
"exec" => ExecutionMode::ExecutableIgnoreErrors,
"test" => ExecutionMode::Test,
_ => panic!("Invalid test_mono exec mode {mode}"),
};
Expand Down
2 changes: 1 addition & 1 deletion crates/compiler/uitest/src/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub(crate) fn write_compiled_ir<'a>(
use roc_packaging::cache::RocCacheDir;
use std::path::PathBuf;

let exec_mode = ExecutionMode::Executable;
let exec_mode = ExecutionMode::ExecutableIgnoreErrors;

let arena = &Bump::new();

Expand Down
2 changes: 1 addition & 1 deletion crates/linker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ pub fn generate_stub_lib(
render: RenderTarget::Generic,
palette: DEFAULT_PALETTE,
threading: Threading::AllAvailable,
exec_mode: ExecutionMode::Executable,
exec_mode: ExecutionMode::ExecutableIgnoreErrors,
},
)
.unwrap_or_else(|problem| todo!("{:?}", problem));
Expand Down
2 changes: 1 addition & 1 deletion crates/repl_eval/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ pub fn compile_to_mono<'a, 'i, I: Iterator<Item = &'i str>>(
render: roc_reporting::report::RenderTarget::ColorTerminal,
palette,
threading: Threading::Single,
exec_mode: ExecutionMode::Executable,
exec_mode: ExecutionMode::ExecutableIgnoreErrors,
},
);

Expand Down
Loading