use code from reporting to report expect failures

This commit is contained in:
Folkert 2022-07-25 23:50:07 +02:00
parent da4c4c5628
commit a5320c2cf9
No known key found for this signature in database
GPG Key ID: 1F17F6FFD112B97C

View File

@ -1174,60 +1174,28 @@ fn render_expect_failure<'a>(
start: *const u8, start: *const u8,
offset: usize, offset: usize,
) -> usize { ) -> usize {
use roc_reporting::report::Report;
use roc_reporting::report::RocDocAllocator;
use ven_pretty::DocAllocator;
// we always run programs as the host // we always run programs as the host
let target_info = (&target_lexicon::Triple::host()).into(); let target_info = (&target_lexicon::Triple::host()).into();
let frame = ExpectFrame::at_offset(start, offset); let frame = ExpectFrame::at_offset(start, offset);
let region = frame.region;
let module_id = frame.module_id; let module_id = frame.module_id;
let failure_region = frame.region;
let expect_region = expect.map(|e| e.region);
let data = expectations.get_mut(&module_id).unwrap(); let data = expectations.get_mut(&module_id).unwrap();
// TODO cache these line offsets?
let path = &data.path;
let filename = data.path.to_owned(); let filename = data.path.to_owned();
let file_string = std::fs::read_to_string(path).unwrap(); let source = std::fs::read_to_string(&data.path).unwrap();
let src_lines: Vec<_> = file_string.lines().collect();
let line_info = roc_region::all::LineInfo::new(&file_string); let current = match data.expectations.get(&failure_region) {
let display_region = match expect { None => panic!("region not in list of expects"),
Some(expect) => {
if !expect.region.contains(&region) {
// this is an expect outside of a toplevel expect,
// likely in some function we called
region
} else {
Region::across_all([&expect.region, &region])
}
}
None => region,
};
let line_col_region = line_info.convert_region(display_region);
let alloc = RocDocAllocator::new(&src_lines, module_id, interns);
let current = match data.expectations.get(&region) {
None => {
invalid_regions(alloc, filename, line_info, region);
return 0;
}
Some(current) => current, Some(current) => current,
}; };
let subs = arena.alloc(&mut data.subs); let subs = arena.alloc(&mut data.subs);
let (symbols, variables): (Vec<_>, Vec<_>) = current.iter().map(|(a, b)| (*a, *b)).unzip(); let (symbols, variables): (Vec<_>, Vec<_>) = current.iter().map(|(a, b)| (*a, *b)).unzip();
let error_types: Vec<_> = variables let mut subs2 = subs.clone();
.iter()
.map(|variable| {
let (error_type, _) = subs.var_to_error_type(*variable);
error_type
})
.collect();
let (offset, expressions) = roc_repl_expect::get_values( let (offset, expressions) = roc_repl_expect::get_values(
target_info, target_info,
@ -1240,58 +1208,16 @@ fn render_expect_failure<'a>(
) )
.unwrap(); .unwrap();
use roc_fmt::annotation::Formattable; use roc_reporting::error::expect::Renderer;
use roc_reporting::error::r#type::error_type_to_doc;
let it = let renderer = Renderer::new(arena, interns, module_id, filename, &source);
symbols let buf = renderer.render(
.iter() &mut subs2,
.zip(expressions) &symbols,
.zip(error_types) &variables,
.map(|((symbol, expr), error_type)| { &expressions,
let mut buf = roc_fmt::Buf::new_in(arena); expect_region,
expr.format(&mut buf, 0); failure_region,
alloc.vcat([
alloc
.symbol_unqualified(*symbol)
.append(" : ")
.append(error_type_to_doc(&alloc, error_type)),
alloc
.symbol_unqualified(*symbol)
.append(" = ")
.append(buf.into_bump_str()),
])
});
let doc = if it.len() > 0 {
alloc.stack([
alloc.text("This expectation failed:"),
alloc.region(line_col_region),
alloc.text("When it failed, these variables had these values:"),
alloc.stack(it),
])
} else {
alloc.stack([
alloc.text("This expectation failed:"),
alloc.region(line_col_region),
])
};
let report = Report {
title: "EXPECT FAILED".into(),
doc,
filename,
severity: roc_reporting::report::Severity::RuntimeError,
};
let mut buf = String::new();
report.render(
roc_reporting::report::RenderTarget::ColorTerminal,
&mut buf,
&alloc,
&roc_reporting::report::DEFAULT_PALETTE,
); );
println!("{}", buf); println!("{}", buf);
@ -1299,42 +1225,6 @@ fn render_expect_failure<'a>(
offset offset
} }
fn invalid_regions(
alloc: roc_reporting::report::RocDocAllocator,
filename: PathBuf,
line_info: roc_region::all::LineInfo,
region: Region,
) {
use ven_pretty::DocAllocator;
let line_col_region = line_info.convert_region(region);
let doc = alloc.stack([
alloc.text("Internal expect failure"),
alloc.region(line_col_region),
]);
let report = roc_reporting::report::Report {
title: "EXPECT FAILED".into(),
doc,
filename,
severity: roc_reporting::report::Severity::RuntimeError,
};
let mut buf = String::new();
report.render(
roc_reporting::report::RenderTarget::ColorTerminal,
&mut buf,
&alloc,
&roc_reporting::report::DEFAULT_PALETTE,
);
println!("{}", buf);
panic!();
}
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
fn roc_run_executable_file_path(binary_bytes: &mut [u8]) -> std::io::Result<ExecutableFile> { fn roc_run_executable_file_path(binary_bytes: &mut [u8]) -> std::io::Result<ExecutableFile> {
// on linux, we use the `memfd_create` function to create an in-memory anonymous file. // on linux, we use the `memfd_create` function to create an in-memory anonymous file.