Remove 'seed' arg from 'with_project' to FinishedTests event

Also polish a bit the output of tests, move test result to stdout to allow filtering out warnings by redirecting stderr to /dev/null.
This commit is contained in:
KtorZ 2024-03-04 18:43:39 +01:00
parent c9dd281b45
commit df3baa082e
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
10 changed files with 76 additions and 92 deletions

View File

@ -347,7 +347,7 @@ where
.collect(); .collect();
self.event_listener self.event_listener
.handle_event(Event::FinishedTests { tests }); .handle_event(Event::FinishedTests { seed, tests });
if !errors.is_empty() { if !errors.is_empty() {
Err(errors) Err(errors)

View File

@ -37,6 +37,7 @@ pub enum Event {
}, },
RunningTests, RunningTests,
FinishedTests { FinishedTests {
seed: u32,
tests: Vec<TestResult<UntypedExpr>>, tests: Vec<TestResult<UntypedExpr>>,
}, },
WaitingForBuildDirLock, WaitingForBuildDirLock,
@ -170,7 +171,7 @@ impl EventListener for Terminal {
"...".if_supports_color(Stderr, |s| s.bold()) "...".if_supports_color(Stderr, |s| s.bold())
); );
} }
Event::FinishedTests { tests } => { Event::FinishedTests { seed, tests } => {
let (max_mem, max_cpu, max_iter) = find_max_execution_units(&tests); let (max_mem, max_cpu, max_iter) = find_max_execution_units(&tests);
for (module, results) in &group_by_module(&tests) { for (module, results) in &group_by_module(&tests) {
@ -185,10 +186,22 @@ impl EventListener for Terminal {
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("\n"); .join("\n");
let summary = fmt_test_summary(results, true); let seed_info = if results
.iter()
.any(|t| matches!(t, TestResult::PropertyTestResult { .. }))
{
format!(
"with {opt}={seed} → ",
opt = "--seed".if_supports_color(Stderr, |s| s.bold()),
seed = format!("{seed}").if_supports_color(Stderr, |s| s.bold())
)
} else {
String::new()
};
eprintln!( let summary = format!("{}{}", seed_info, fmt_test_summary(results, true));
"{}\n", println!(
"{}",
pretty::indent( pretty::indent(
&pretty::open_box(&title, &tests, &summary, |border| border &pretty::open_box(&title, &tests, &summary, |border| border
.if_supports_color(Stderr, |s| s.bright_black()) .if_supports_color(Stderr, |s| s.bright_black())
@ -319,19 +332,20 @@ fn fmt_test(
}) = result }) = result
{ {
test = format!( test = format!(
"{test}\n{}", "{test}\n{}\n{}\n",
pretty::open_box( "× counterexample"
&pretty::style_if(styled, "counterexample".to_string(), |s| s .if_supports_color(Stderr, |s| s.red())
.if_supports_color(Stderr, |s| s.red()) .if_supports_color(Stderr, |s| s.bold()),
.if_supports_color(Stderr, |s| s.bold()) &Formatter::new()
.to_string()), .expr(counterexample, false)
&Formatter::new() .to_pretty_string(60)
.expr(counterexample, false) .lines()
.to_pretty_string(70), .map(|line| {
"", format!("{} {}", "".if_supports_color(Stderr, |s| s.red()), line)
|s| s.red().to_string() })
) .collect::<Vec<String>>()
) .join("\n")
);
} }
// Traces // Traces

View File

@ -75,12 +75,7 @@ pub fn default_filter(evt: &Event) -> bool {
} }
} }
pub fn with_project<A>( pub fn with_project<A>(directory: Option<&Path>, deny: bool, mut action: A) -> miette::Result<()>
directory: Option<&Path>,
seed: u32,
deny: bool,
mut action: A,
) -> miette::Result<()>
where where
A: FnMut(&mut Project<Terminal>) -> Result<(), Vec<crate::error::Error>>, A: FnMut(&mut Project<Terminal>) -> Result<(), Vec<crate::error::Error>>,
{ {
@ -113,23 +108,16 @@ where
err.report() err.report()
} }
eprintln!( if !errs.iter().any(|e| matches!(e, Error::TestFailure { .. })) {
"{}",
Summary {
warning_count,
error_count: errs.len(),
}
);
if errs.iter().any(|e| matches!(e, Error::TestFailure { .. })) {
eprintln!( eprintln!(
" {}══╤══\n{} ╰─▶ use {} {} to replay", "{}",
if errs.len() > 1 { "" } else { "" }, Summary {
if errs.len() > 1 { " " } else { "" }, warning_count,
"--seed".if_supports_color(Stderr, |s| s.bold()), error_count: errs.len(),
format!("{seed}").if_supports_color(Stderr, |s| s.bold()) }
); );
} }
return Err(ExitFailure::into_report()); return Err(ExitFailure::into_report());
} }
@ -162,7 +150,6 @@ where
pub fn watch_project<F, A>( pub fn watch_project<F, A>(
directory: Option<&Path>, directory: Option<&Path>,
filter: F, filter: F,
seed: u32,
debounce: u32, debounce: u32,
mut action: A, mut action: A,
) -> miette::Result<()> ) -> miette::Result<()>
@ -228,13 +215,14 @@ where
// If we have an event that survived the filter, then we can construct the project and invoke the action // If we have an event that survived the filter, then we can construct the project and invoke the action
if latest.is_some() { if latest.is_some() {
print!("{esc}c", esc = 27 as char); print!("{esc}c", esc = 27 as char);
println!( eprint!("{esc}c", esc = 27 as char);
eprintln!(
"{} ...", "{} ...",
" Watching" " Watching"
.if_supports_color(Stderr, |s| s.bold()) .if_supports_color(Stderr, |s| s.bold())
.if_supports_color(Stderr, |s| s.purple()), .if_supports_color(Stderr, |s| s.purple()),
); );
with_project(directory, seed, false, &mut action).unwrap_or(()) with_project(directory, false, &mut action).unwrap_or(())
} }
} }
} }

View File

@ -39,7 +39,7 @@ pub fn exec(
mainnet, mainnet,
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
with_project(directory.as_deref(), u32::default(), false, |p| { with_project(directory.as_deref(), false, |p| {
if rebuild { if rebuild {
p.build(false, Tracing::silent())?; p.build(false, Tracing::silent())?;
} }

View File

@ -47,7 +47,7 @@ pub fn exec(
validator, validator,
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
with_project(None, u32::default(), false, |p| { with_project(None, false, |p| {
let title = module.as_ref().map(|m| { let title = module.as_ref().map(|m| {
format!( format!(
"{m}{}", "{m}{}",

View File

@ -29,7 +29,7 @@ pub fn exec(
rebuild, rebuild,
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
with_project(directory.as_deref(), u32::default(), false, |p| { with_project(directory.as_deref(), false, |p| {
if rebuild { if rebuild {
p.build(false, Tracing::silent())?; p.build(false, Tracing::silent())?;
} }

View File

@ -29,7 +29,7 @@ pub fn exec(
rebuild, rebuild,
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
with_project(directory.as_deref(), u32::default(), false, |p| { with_project(directory.as_deref(), false, |p| {
if rebuild { if rebuild {
p.build(false, Tracing::silent())?; p.build(false, Tracing::silent())?;
} }

View File

@ -51,23 +51,17 @@ pub fn exec(
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
let result = if watch { let result = if watch {
watch_project( watch_project(directory.as_deref(), watch::default_filter, 500, |p| {
directory.as_deref(), p.build(
watch::default_filter, uplc,
u32::default(), match filter_traces {
500, Some(filter_traces) => filter_traces(trace_level),
|p| { None => Tracing::All(trace_level),
p.build( },
uplc, )
match filter_traces { })
Some(filter_traces) => filter_traces(trace_level),
None => Tracing::All(trace_level),
},
)
},
)
} else { } else {
with_project(directory.as_deref(), u32::default(), deny, |p| { with_project(directory.as_deref(), deny, |p| {
p.build( p.build(
uplc, uplc,
match filter_traces { match filter_traces {
@ -82,8 +76,8 @@ pub fn exec(
} }
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub fn filter_traces_parser( pub fn filter_traces_parser()
) -> MapValueParser<PossibleValuesParser, fn(String) -> fn(TraceLevel) -> Tracing> { -> MapValueParser<PossibleValuesParser, fn(String) -> fn(TraceLevel) -> Tracing> {
PossibleValuesParser::new(["user-defined", "compiler-generated", "all"]).map( PossibleValuesParser::new(["user-defined", "compiler-generated", "all"]).map(
|s: String| match s.as_str() { |s: String| match s.as_str() {
"user-defined" => Tracing::UserDefined, "user-defined" => Tracing::UserDefined,

View File

@ -79,27 +79,21 @@ pub fn exec(
let seed = seed.unwrap_or_else(|| rng.gen()); let seed = seed.unwrap_or_else(|| rng.gen());
let result = if watch { let result = if watch {
watch_project( watch_project(directory.as_deref(), watch::default_filter, 500, |p| {
directory.as_deref(), p.check(
watch::default_filter, skip_tests,
seed, match_tests.clone(),
500, debug,
|p| { exact_match,
p.check( seed,
skip_tests, match filter_traces {
match_tests.clone(), Some(filter_traces) => filter_traces(trace_level),
debug, None => Tracing::All(trace_level),
exact_match, },
seed, )
match filter_traces { })
Some(filter_traces) => filter_traces(trace_level),
None => Tracing::All(trace_level),
},
)
},
)
} else { } else {
with_project(directory.as_deref(), seed, deny, |p| { with_project(directory.as_deref(), deny, |p| {
p.check( p.check(
skip_tests, skip_tests,
match_tests.clone(), match_tests.clone(),

View File

@ -29,17 +29,11 @@ pub fn exec(
}: Args, }: Args,
) -> miette::Result<()> { ) -> miette::Result<()> {
let result = if watch { let result = if watch {
watch_project( watch_project(directory.as_deref(), watch::default_filter, 500, |p| {
directory.as_deref(),
watch::default_filter,
u32::default(),
500,
|p| p.docs(destination.clone()),
)
} else {
with_project(directory.as_deref(), u32::default(), deny, |p| {
p.docs(destination.clone()) p.docs(destination.clone())
}) })
} else {
with_project(directory.as_deref(), deny, |p| p.docs(destination.clone()))
}; };
result.map_err(|_| process::exit(1)) result.map_err(|_| process::exit(1))