diff --git a/run-tests/Dockerfile b/run-tests/Dockerfile index 655195b..aa95b1d 100644 --- a/run-tests/Dockerfile +++ b/run-tests/Dockerfile @@ -8,11 +8,7 @@ ARG CITRA_CHANNEL=nightly ARG CITRA_RELEASE=1995 RUN download_citra ${CITRA_CHANNEL} ${CITRA_RELEASE} -<<<<<<< Updated upstream:run-tests/Dockerfile FROM devkitpro/devkitarm:latest as devkitarm -======= -FROM devkitpro/devkitarm as devkitarm ->>>>>>> Stashed changes:Dockerfile # For some reason, citra isn't always happy when you try to run it for the first time, # so we build a simple dummy program to force it to create its directory structure diff --git a/test-runner/src/console.rs b/test-runner/src/console.rs index c3e53ed..d062ae8 100644 --- a/test-runner/src/console.rs +++ b/test-runner/src/console.rs @@ -1,8 +1,9 @@ +use std::process::Termination; + use ctru::prelude::*; use ctru::services::gfx::{Flush, Swap}; use super::TestRunner; -use crate::TestResult; pub struct ConsoleRunner { gfx: Gfx, @@ -29,11 +30,10 @@ impl TestRunner for ConsoleRunner { Console::new(self.gfx.top_screen.borrow_mut()) } - fn cleanup(mut self, result: T) -> T { - // We don't actually care about the test result, either way we'll stop - // and show the results to the user + fn cleanup(mut self, result: T) -> T { + // We don't actually care about the output of the test result, either + // way we'll stop and show the results to the user. - // Wait to make sure the user can actually see the results before we exit println!("Press START to exit."); while self.apt.main_loop() { diff --git a/test-runner/src/gdb.rs b/test-runner/src/gdb.rs index e62aa7b..c77ad86 100644 --- a/test-runner/src/gdb.rs +++ b/test-runner/src/gdb.rs @@ -1,7 +1,8 @@ +use std::process::Termination; + use ctru::error::ResultCode; use super::TestRunner; -use crate::TestResult; #[derive(Default)] pub struct GdbRunner; @@ -28,10 +29,10 @@ impl TestRunner for GdbRunner { .expect("failed to redirect I/O streams to GDB"); } - fn cleanup(self, test_result: T) -> T { + fn cleanup(self, test_result: T) -> T { // GDB actually has the opportunity to inspect the exit code, // unlike other runners, so let's follow the default behavior of the // stdlib test runner. - std::process::exit(if test_result.succeeded() { 0 } else { 101 }) + test_result.report().exit_process() } } diff --git a/test-runner/src/lib.rs b/test-runner/src/lib.rs index a9ba89c..a60079d 100644 --- a/test-runner/src/lib.rs +++ b/test-runner/src/lib.rs @@ -15,9 +15,7 @@ mod console; mod gdb; mod socket; -use std::any::Any; -use std::error::Error; -use std::fmt::Display; +use std::process::{ExitCode, Termination}; pub use console::ConsoleRunner; pub use gdb::GdbRunner; @@ -126,17 +124,6 @@ macro_rules! doctest { }; } -#[derive(Debug)] -struct TestsFailed; - -impl Display for TestsFailed { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "some tests failed!") - } -} - -impl Error for TestsFailed {} - fn run(tests: &[&TestDescAndFn]) { std::env::set_var("RUST_BACKTRACE", "1"); @@ -162,7 +149,13 @@ fn run(tests: &[&TestDescAndFn]) { drop(ctx); - let _ = runner.cleanup(result); + let reportable_result = match result { + Ok(true) => Ok(()), + // Try to match stdlib console test runner behavior as best we can + _ => Err(ExitCode::from(101)), + }; + + let _ = runner.cleanup(reportable_result); } /// Adapted from [`test::make_owned_test`]. @@ -189,9 +182,6 @@ mod private { impl Sealed for super::ConsoleRunner {} impl Sealed for super::GdbRunner {} impl Sealed for super::SocketRunner {} - - impl Sealed for () {} - impl Sealed for Result {} } /// A helper trait to make the behavior of test runners consistent. @@ -209,38 +199,13 @@ pub trait TestRunner: private::Sealed + Sized + Default { /// Handle the results of the test and perform any necessary cleanup. /// The [`Context`](Self::Context) will be dropped just before this is called. - fn cleanup(self, test_result: T) -> T { + /// + /// This returns `T` so that the result can be used in doctests. + fn cleanup(self, test_result: T) -> T { test_result } } -// A helper trait to determine whether tests succeeded. This trait is implemented -// for -pub trait TestResult: private::Sealed { - fn succeeded(&self) -> bool; -} - -impl TestResult for () { - fn succeeded(&self) -> bool { - true - } -} - -impl TestResult for Result { - fn succeeded(&self) -> bool { - // This is sort of a hack workaround for lack of specialized trait impls. - // Basically, check if T is a boolean and use it if so. Otherwise default - // to mapping Ok to success and Err to failure. - match self - .as_ref() - .map(|val| (val as &dyn Any).downcast_ref::()) - { - Ok(Some(&result)) => result, - other => other.is_ok(), - } - } -} - /// This module has stubs needed to link the test library, but they do nothing /// because we don't actually need them for the runner to work. mod link_fix {