Browse Source

Fix build and tweak some options

pull/41/head
Ian Chamberlain 3 years ago
parent
commit
75727fd3e9
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 45
      ctru-rs/src/services/ps.rs
  2. 131
      ctru-rs/src/test_runner.rs

45
ctru-rs/src/services/ps.rs

@ -27,3 +27,48 @@ impl Drop for Ps {
} }
} }
} }
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use super::*;
#[test]
fn construct_hash_map() {
let _ps = Ps::init().unwrap();
let mut m: HashMap<i32, String> = HashMap::from_iter([
(1_i32, String::from("123")),
(2, String::from("2")),
(6, String::from("six")),
]);
println!("{:?}", m);
m.remove(&2);
m.insert(5, "ok".into());
println!("{:#?}", m);
}
#[test]
#[should_panic]
fn construct_hash_map_no_rand() {
// Without initializing PS, we can't use `libc::getrandom` and constructing
// a HashMap panics at runtime.
let mut m: HashMap<i32, String> = HashMap::from_iter([
(1_i32, String::from("123")),
(2, String::from("2")),
(6, String::from("six")),
]);
println!("{:?}", m);
m.remove(&2);
m.insert(5, "ok".into());
println!("{:#?}", m);
}
}

131
ctru-rs/src/test_runner.rs

@ -2,7 +2,9 @@
extern crate test; extern crate test;
use test::TestFn; use std::io;
use test::{ColorConfig, Options, OutputFormat, RunIgnored, TestDescAndFn, TestFn, TestOpts};
use crate::console::Console; use crate::console::Console;
use crate::gfx::Gfx; use crate::gfx::Gfx;
@ -11,31 +13,57 @@ use crate::services::hid::{Hid, KeyPad};
/// A custom runner to be used with `#[test_runner]`. This simple implementation /// A custom runner to be used with `#[test_runner]`. This simple implementation
/// runs all tests in series, "failing" on the first one to panic (really, the /// runs all tests in series, "failing" on the first one to panic (really, the
/// panic is just treated the same as any normal application panic). /// panic is just treated the same as any normal application panic).
pub(crate) fn test_runner(test_cases: &[&test::TestDescAndFn]) { pub(crate) fn test_runner(tests: &[&TestDescAndFn]) {
crate::init(); crate::init();
let gfx = Gfx::default(); let gfx = Gfx::default();
let hid = Hid::init().expect("Couldn't obtain HID controller"); let hid = Hid::init().unwrap();
let _console = Console::init(gfx.top_screen.borrow_mut());
let mut top_screen = gfx.top_screen.borrow_mut();
// TODO: may want to use some more features of standard testing framework, top_screen.set_wide_mode(true);
// like output capture, filtering, panic handling, etc. let _console = Console::init(top_screen);
// For now this is works without too much setup.
for test_info in test_cases { // Start printing from the top left
if let TestFn::StaticTestFn(testfn) = test_info.testfn { print!("\x1b[1;1H");
println!("Running test {}", test_info.desc.name);
testfn(); // TODO: it would be nice to have a way of specifying argv to make these
} else { // configurable at runtime, but I can't figure out how to do it easily,
println!( // so for now, just hardcode everything.
"unsupported test type for {}: {:?}", let opts = TestOpts {
test_info.desc.name, test_info.testfn list: false,
); filters: Vec::new(),
} filter_exact: false,
} // Forking is not supported
force_run_in_process: true,
exclude_should_panic: false,
run_ignored: RunIgnored::No,
run_tests: true,
// Benchmarks are not supported
bench_benchmarks: false,
logfile: None,
nocapture: false,
// TODO: color doesn't work because of TERM/TERMINFO.
// With RomFS we might be able to fake this out nicely...
color: ColorConfig::AlwaysColor,
format: OutputFormat::Pretty,
shuffle: false,
shuffle_seed: None,
// tweak values? This seems to work out of the box
test_threads: Some(3),
skip: Vec::new(),
time_options: None,
options: Options::new(),
};
println!("All tests passed! Press START to exit."); // Use the default test implementation with our hardcoded options
let _success = run_static_tests(&opts, tests).unwrap();
// Make sure the user can actually see the results before we exit
println!("Press START to exit.");
gfx.flush_buffers();
gfx.swap_buffers();
// TODO: do we need apt.main_loop() here?
loop { loop {
hid.scan_input(); hid.scan_input();
@ -44,3 +72,64 @@ pub(crate) fn test_runner(test_cases: &[&test::TestDescAndFn]) {
} }
} }
} }
/// Adapted from [`test::test_main_static`], along with [`make_owned_test`].
fn run_static_tests(opts: &TestOpts, tests: &[&TestDescAndFn]) -> io::Result<bool> {
let tests = tests.iter().map(make_owned_test).collect();
test::run_tests_console(opts, tests)
}
/// Clones static values for putting into a dynamic vector, which test_main()
/// needs to hand out ownership of tests to parallel test runners.
///
/// This will panic when fed any dynamic tests, because they cannot be cloned.
fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn {
match test.testfn {
TestFn::StaticTestFn(f) => TestDescAndFn {
testfn: TestFn::StaticTestFn(f),
desc: test.desc.clone(),
},
TestFn::StaticBenchFn(f) => TestDescAndFn {
testfn: TestFn::StaticBenchFn(f),
desc: test.desc.clone(),
},
_ => panic!("non-static tests passed to test::test_main_static"),
}
}
/// The following functions are stubs needed to link the test library,
/// but do nothing because we don't actually need them for it to work (hopefully).
// TODO: move to linker-fix-3ds ?
mod link_fix {
#[no_mangle]
extern "C" fn execvp(
_argc: *const libc::c_char,
_argv: *mut *const libc::c_char,
) -> libc::c_int {
-1
}
#[no_mangle]
extern "C" fn pipe(_fildes: *mut libc::c_int) -> libc::c_int {
-1
}
#[no_mangle]
extern "C" fn pthread_sigmask(
_how: ::libc::c_int,
_set: *const libc::sigset_t,
_oldset: *mut libc::sigset_t,
) -> ::libc::c_int {
-1
}
#[no_mangle]
extern "C" fn sigemptyset(_arg1: *mut libc::sigset_t) -> ::libc::c_int {
-1
}
#[no_mangle]
extern "C" fn sysconf(_name: libc::c_int) -> libc::c_long {
-1
}
}

Loading…
Cancel
Save