mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
use std::io::Write for making expect messages
This commit is contained in:
parent
7014fbb5ec
commit
1017bbc5ec
2 changed files with 116 additions and 81 deletions
|
@ -13,6 +13,7 @@ use roc_module::symbol::{Interns, ModuleId};
|
||||||
use roc_mono::ir::OptLevel;
|
use roc_mono::ir::OptLevel;
|
||||||
use roc_region::all::Region;
|
use roc_region::all::Region;
|
||||||
use roc_repl_cli::{expect_mono_module_to_dylib, ToplevelExpect};
|
use roc_repl_cli::{expect_mono_module_to_dylib, ToplevelExpect};
|
||||||
|
use roc_reporting::error::expect::Renderer;
|
||||||
use roc_target::TargetInfo;
|
use roc_target::TargetInfo;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::{CString, OsStr};
|
use std::ffi::{CString, OsStr};
|
||||||
|
@ -421,63 +422,42 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||||
let arena = &bumpalo::Bump::new();
|
let arena = &bumpalo::Bump::new();
|
||||||
let interns = arena.alloc(interns);
|
let interns = arena.alloc(interns);
|
||||||
|
|
||||||
use roc_gen_llvm::try_run_jit_function;
|
let mut writer = std::io::stdout();
|
||||||
|
|
||||||
let mut failed = 0;
|
let shared_ptr = unsafe {
|
||||||
let mut passed = 0;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let shared_fd = libc::shm_open(cstring.as_ptr().cast(), libc::O_RDWR, 0o666);
|
let shared_fd = libc::shm_open(cstring.as_ptr().cast(), libc::O_RDWR, 0o666);
|
||||||
|
|
||||||
libc::ftruncate(shared_fd, SHM_SIZE);
|
libc::ftruncate(shared_fd, SHM_SIZE);
|
||||||
|
|
||||||
let shared_ptr = libc::mmap(
|
libc::mmap(
|
||||||
std::ptr::null_mut(),
|
std::ptr::null_mut(),
|
||||||
SHM_SIZE as usize,
|
SHM_SIZE as usize,
|
||||||
libc::PROT_READ | libc::PROT_WRITE,
|
libc::PROT_READ | libc::PROT_WRITE,
|
||||||
libc::MAP_SHARED,
|
libc::MAP_SHARED,
|
||||||
shared_fd,
|
shared_fd,
|
||||||
0,
|
0,
|
||||||
);
|
)
|
||||||
|
.cast()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut failed = 0;
|
||||||
|
let mut passed = 0;
|
||||||
|
|
||||||
for expect in expects {
|
for expect in expects {
|
||||||
let sequence = ExpectSequence::new(shared_ptr.cast());
|
let result = run_expect(
|
||||||
|
&mut writer,
|
||||||
let result: Result<(), String> = try_run_jit_function!(lib, expect.name, (), |v: ()| v);
|
|
||||||
|
|
||||||
let shared_memory_ptr: *const u8 = shared_ptr.cast();
|
|
||||||
|
|
||||||
if let Err(roc_panic_message) = result {
|
|
||||||
failed += 1;
|
|
||||||
|
|
||||||
render_expect_panic(
|
|
||||||
arena,
|
arena,
|
||||||
|
interns,
|
||||||
|
&lib,
|
||||||
|
&mut expectations,
|
||||||
|
shared_ptr,
|
||||||
expect,
|
expect,
|
||||||
&roc_panic_message,
|
)
|
||||||
&mut expectations,
|
.unwrap();
|
||||||
interns,
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
} else if sequence.count_failures() > 0 {
|
|
||||||
failed += 1;
|
|
||||||
|
|
||||||
let mut offset = ExpectSequence::START_OFFSET;
|
match result {
|
||||||
|
true => passed += 1,
|
||||||
for _ in 0..sequence.count_failures() {
|
false => failed += 1,
|
||||||
offset += render_expect_failure(
|
|
||||||
arena,
|
|
||||||
Some(expect),
|
|
||||||
&mut expectations,
|
|
||||||
interns,
|
|
||||||
shared_memory_ptr,
|
|
||||||
offset,
|
|
||||||
);
|
|
||||||
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
passed += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,6 +489,60 @@ pub fn test(matches: &ArgMatches, triple: Triple) -> io::Result<i32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_expect<W: std::io::Write>(
|
||||||
|
writer: &mut W,
|
||||||
|
arena: &Bump,
|
||||||
|
interns: &Interns,
|
||||||
|
lib: &libloading::Library,
|
||||||
|
expectations: &mut VecMap<ModuleId, Expectations>,
|
||||||
|
shared_ptr: *mut u8,
|
||||||
|
expect: ToplevelExpect<'_>,
|
||||||
|
) -> std::io::Result<bool> {
|
||||||
|
use roc_gen_llvm::try_run_jit_function;
|
||||||
|
|
||||||
|
let sequence = ExpectSequence::new(shared_ptr.cast());
|
||||||
|
|
||||||
|
let result: Result<(), String> = try_run_jit_function!(lib, expect.name, (), |v: ()| v);
|
||||||
|
|
||||||
|
let shared_memory_ptr: *const u8 = shared_ptr.cast();
|
||||||
|
|
||||||
|
if result.is_err() || sequence.count_failures() > 0 {
|
||||||
|
let module_id = expect.symbol.module_id();
|
||||||
|
let data = expectations.get_mut(&module_id).unwrap();
|
||||||
|
|
||||||
|
let path = &data.path;
|
||||||
|
let filename = data.path.to_owned();
|
||||||
|
let source = std::fs::read_to_string(path).unwrap();
|
||||||
|
|
||||||
|
let renderer = Renderer::new(arena, interns, module_id, filename, &source);
|
||||||
|
|
||||||
|
if let Err(roc_panic_message) = result {
|
||||||
|
renderer.render_panic(writer, &roc_panic_message, expect.region)?;
|
||||||
|
} else {
|
||||||
|
let mut offset = ExpectSequence::START_OFFSET;
|
||||||
|
|
||||||
|
for _ in 0..sequence.count_failures() {
|
||||||
|
offset += render_expect_failure(
|
||||||
|
writer,
|
||||||
|
&renderer,
|
||||||
|
arena,
|
||||||
|
Some(expect),
|
||||||
|
expectations,
|
||||||
|
interns,
|
||||||
|
shared_memory_ptr,
|
||||||
|
offset,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeln!(writer)?;
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
} else {
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ExpectSequence {
|
struct ExpectSequence {
|
||||||
ptr: *const u8,
|
ptr: *const u8,
|
||||||
}
|
}
|
||||||
|
@ -1073,14 +1107,27 @@ unsafe fn roc_run_native_debug(
|
||||||
|
|
||||||
let shared_memory_ptr: *const u8 = shared_ptr.cast();
|
let shared_memory_ptr: *const u8 = shared_ptr.cast();
|
||||||
|
|
||||||
|
let frame =
|
||||||
|
ExpectFrame::at_offset(shared_memory_ptr, ExpectSequence::START_OFFSET);
|
||||||
|
let module_id = frame.module_id;
|
||||||
|
|
||||||
|
let data = expectations.get_mut(&module_id).unwrap();
|
||||||
|
let filename = data.path.to_owned();
|
||||||
|
let source = std::fs::read_to_string(&data.path).unwrap();
|
||||||
|
|
||||||
|
let renderer = Renderer::new(arena, interns, module_id, filename, &source);
|
||||||
|
|
||||||
render_expect_failure(
|
render_expect_failure(
|
||||||
|
&mut std::io::stdout(),
|
||||||
|
&renderer,
|
||||||
arena,
|
arena,
|
||||||
None,
|
None,
|
||||||
&mut expectations,
|
&mut expectations,
|
||||||
interns,
|
interns,
|
||||||
shared_memory_ptr,
|
shared_memory_ptr,
|
||||||
ExpectSequence::START_OFFSET,
|
ExpectSequence::START_OFFSET,
|
||||||
);
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
_ => println!("received signal {}", sig),
|
_ => println!("received signal {}", sig),
|
||||||
}
|
}
|
||||||
|
@ -1090,27 +1137,6 @@ unsafe fn roc_run_native_debug(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_expect_panic<'a>(
|
|
||||||
arena: &'a Bump,
|
|
||||||
expect: ToplevelExpect,
|
|
||||||
message: &str,
|
|
||||||
expectations: &mut VecMap<ModuleId, Expectations>,
|
|
||||||
interns: &'a Interns,
|
|
||||||
) {
|
|
||||||
let module_id = expect.symbol.module_id();
|
|
||||||
let data = expectations.get_mut(&module_id).unwrap();
|
|
||||||
|
|
||||||
let path = &data.path;
|
|
||||||
let filename = data.path.to_owned();
|
|
||||||
let source = std::fs::read_to_string(path).unwrap();
|
|
||||||
|
|
||||||
use roc_reporting::error::expect::Renderer;
|
|
||||||
|
|
||||||
let renderer = Renderer::new(arena, interns, module_id, filename, &source);
|
|
||||||
let buf = renderer.render_panic(message, expect.region);
|
|
||||||
println!("{}", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ExpectFrame {
|
struct ExpectFrame {
|
||||||
region: Region,
|
region: Region,
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
|
@ -1137,13 +1163,15 @@ impl ExpectFrame {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_expect_failure<'a>(
|
fn render_expect_failure<'a>(
|
||||||
|
writer: &mut impl std::io::Write,
|
||||||
|
renderer: &Renderer,
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
expect: Option<ToplevelExpect>,
|
expect: Option<ToplevelExpect>,
|
||||||
expectations: &mut VecMap<ModuleId, Expectations>,
|
expectations: &mut VecMap<ModuleId, Expectations>,
|
||||||
interns: &'a Interns,
|
interns: &'a Interns,
|
||||||
start: *const u8,
|
start: *const u8,
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) -> usize {
|
) -> std::io::Result<usize> {
|
||||||
// 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();
|
||||||
|
|
||||||
|
@ -1154,8 +1182,6 @@ fn render_expect_failure<'a>(
|
||||||
let expect_region = expect.map(|e| e.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();
|
||||||
let filename = data.path.to_owned();
|
|
||||||
let source = std::fs::read_to_string(&data.path).unwrap();
|
|
||||||
|
|
||||||
let current = match data.expectations.get(&failure_region) {
|
let current = match data.expectations.get(&failure_region) {
|
||||||
None => panic!("region not in list of expects"),
|
None => panic!("region not in list of expects"),
|
||||||
|
@ -1176,21 +1202,17 @@ fn render_expect_failure<'a>(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
use roc_reporting::error::expect::Renderer;
|
renderer.render_failure(
|
||||||
|
writer,
|
||||||
let renderer = Renderer::new(arena, interns, module_id, filename, &source);
|
|
||||||
let buf = renderer.render_failure(
|
|
||||||
subs,
|
subs,
|
||||||
&symbols,
|
&symbols,
|
||||||
&variables,
|
&variables,
|
||||||
&expressions,
|
&expressions,
|
||||||
expect_region,
|
expect_region,
|
||||||
failure_region,
|
failure_region,
|
||||||
);
|
)?;
|
||||||
|
|
||||||
println!("{}", buf);
|
Ok(offset)
|
||||||
|
|
||||||
offset
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
|
|
@ -121,15 +121,20 @@ impl<'a> Renderer<'a> {
|
||||||
self.line_info.convert_region(display_region)
|
self.line_info.convert_region(display_region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_failure(
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn render_failure<W>(
|
||||||
&self,
|
&self,
|
||||||
|
writer: &mut W,
|
||||||
subs: &mut Subs,
|
subs: &mut Subs,
|
||||||
symbols: &[Symbol],
|
symbols: &[Symbol],
|
||||||
variables: &[Variable],
|
variables: &[Variable],
|
||||||
expressions: &[Expr<'_>],
|
expressions: &[Expr<'_>],
|
||||||
expect_region: Option<Region>,
|
expect_region: Option<Region>,
|
||||||
failure_region: Region,
|
failure_region: Region,
|
||||||
) -> String {
|
) -> std::io::Result<()>
|
||||||
|
where
|
||||||
|
W: std::io::Write,
|
||||||
|
{
|
||||||
use crate::report::Report;
|
use crate::report::Report;
|
||||||
|
|
||||||
let line_col_region = self.to_line_col_region(expect_region, failure_region);
|
let line_col_region = self.to_line_col_region(expect_region, failure_region);
|
||||||
|
@ -151,10 +156,18 @@ impl<'a> Renderer<'a> {
|
||||||
&crate::report::DEFAULT_PALETTE,
|
&crate::report::DEFAULT_PALETTE,
|
||||||
);
|
);
|
||||||
|
|
||||||
buf
|
write!(writer, "{}", buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_panic(&self, message: &str, expect_region: Region) -> String {
|
pub fn render_panic<W>(
|
||||||
|
&self,
|
||||||
|
writer: &mut W,
|
||||||
|
message: &str,
|
||||||
|
expect_region: Region,
|
||||||
|
) -> std::io::Result<()>
|
||||||
|
where
|
||||||
|
W: std::io::Write,
|
||||||
|
{
|
||||||
use crate::report::Report;
|
use crate::report::Report;
|
||||||
use ven_pretty::DocAllocator;
|
use ven_pretty::DocAllocator;
|
||||||
|
|
||||||
|
@ -183,6 +196,6 @@ impl<'a> Renderer<'a> {
|
||||||
&crate::report::DEFAULT_PALETTE,
|
&crate::report::DEFAULT_PALETTE,
|
||||||
);
|
);
|
||||||
|
|
||||||
buf
|
write!(writer, "{}", buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue