From b9de6b5ce5898adb6f03b6eb6fd541163ccca51e Mon Sep 17 00:00:00 2001 From: Corwin Kuiper Date: Sat, 10 Apr 2021 22:22:56 +0100 Subject: [PATCH] add what's required for cargo test --- .cargo/config.toml | 6 ++-- Cargo.toml | 2 -- src/lib.rs | 83 ++++++++++++++++++++++++++++++++++++++++++++++ src/single.rs | 7 ++++ 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index e9d1ca90..1c878481 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,10 +1,10 @@ [unstable] -build-std = ["core", "compiler_builtins", "alloc"] +build-std = ["core"] build-std-features = ["compiler-builtins-mem"] [build] target = "thumbv4t-none-eabi" [target.thumbv4t-none-eabi] -runner = "mgba-qt -l 31 -d -C logToStdout=1" -rustflags = ["-Clink-arg=-Tgba.ld"] \ No newline at end of file +rustflags = ["-Clink-arg=-Tgba.ld"] +runner = "mgba-test-runner" \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 309464fd..909b43f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,8 +6,6 @@ edition = "2018" [profile.dev] opt-level = 2 -panic = "abort" -lto = true [profile.release] panic = "abort" diff --git a/src/lib.rs b/src/lib.rs index 85a6ba3a..1cfd51f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,10 @@ #![no_std] +#![no_main] #![feature(asm)] #![deny(clippy::all)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::test_runner)] +#![reexport_test_harness_main = "test_main"] use core::fmt::Write; pub mod display; @@ -13,6 +17,7 @@ mod single; pub mod syscall; +#[cfg(not(test))] #[panic_handler] #[allow(unused_must_use)] fn panic_implementation(info: &core::panic::PanicInfo) -> ! { @@ -24,8 +29,12 @@ fn panic_implementation(info: &core::panic::PanicInfo) -> ! { loop {} } +#[cfg(not(test))] static mut GBASINGLE: single::Singleton = single::Singleton::new(unsafe { Gba::single_new() }); +#[cfg(test)] +static mut GBASINGLE: single::Singleton = single::Singleton::empty(); + pub struct Gba { pub display: display::Display, } @@ -47,3 +56,77 @@ impl Default for Gba { Self::new() } } + +pub trait Testable { + fn run(&self, gba: &mut Gba) -> (); +} + +impl Testable for T +where + T: Fn(&mut Gba), +{ + fn run(&self, gba: &mut Gba) { + let mut mgba = mgba::Mgba::new().unwrap(); + mgba.print( + format_args!("{}...", core::any::type_name::()), + mgba::DebugLevel::Info, + ); + self(gba); + mgba.print(format_args!("[ok]"), mgba::DebugLevel::Info); + } +} + +#[panic_handler] +#[cfg(test)] +fn panic_implementation(info: &core::panic::PanicInfo) -> ! { + if let Some(mut mgba) = mgba::Mgba::new() { + mgba.print(format_args!("[failed]"), mgba::DebugLevel::Error); + mgba.print(format_args!("Error: {}", info), mgba::DebugLevel::Fatal); + } + + loop {} +} + +pub fn test_runner(tests: &[&dyn Testable]) { + let mut mgba = mgba::Mgba::new().unwrap(); + mgba.print( + format_args!("Running {} tests", tests.len()), + mgba::DebugLevel::Info, + ); + + let mut gba = unsafe { Gba::single_new() }; + + for test in tests { + test.run(&mut gba); + } + + mgba.print( + format_args!("Tests finished successfully"), + mgba::DebugLevel::Info, + ); +} + +#[no_mangle] +#[cfg(test)] +pub extern "C" fn main() -> ! { + test_main(); + loop {} +} + +#[test_case] +fn trivial_test(_gba: &mut Gba) { + assert_eq!(1, 1); +} + +#[test_case] +fn wait_30_frames(gba: &mut Gba) { + let vblank = gba.display.vblank.get(); + let mut counter = 0; + loop { + if counter > 30 { + break; + } + vblank.wait_for_VBlank(); + counter += 1 + } +} diff --git a/src/single.rs b/src/single.rs index 83eb3867..aca6619a 100644 --- a/src/single.rs +++ b/src/single.rs @@ -6,10 +6,17 @@ impl Singleton { pub const fn new(s: T) -> Self { Singleton { single: Some(s) } } + pub const fn empty() -> Self { + Singleton { single: None } + } pub fn take(&mut self) -> T { let g = core::mem::replace(&mut self.single, None); g.unwrap() } + + pub fn ret(&mut self, ret: T) { + self.single = Some(ret); + } } pub struct Single {