tests: Further improvements to overall system stability and other minor adjustments have been made to enhance the user experience.

This commit is contained in:
John 2023-03-28 08:57:24 -05:00
parent f2f47e13d4
commit 83c178413d
4 changed files with 193 additions and 10 deletions

View File

@ -51,10 +51,15 @@ pub trait Write<T> {
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Region { pub enum Region {
/// Character ROM (but writable!)
Charset, Charset,
/// Program memory
Program, Program,
/// Screen buffer
Screen, Screen,
/// Stack space
Stack, Stack,
/// Total number of named regions
Count, Count,
} }
@ -191,6 +196,17 @@ impl Bus {
///# Ok(()) ///# Ok(())
///# } ///# }
/// ``` /// ```
/// If the region doesn't exist, that's okay.
/// ```rust
///# use chirp::prelude::*;
///# fn main() -> Result<()> {
/// let bus = Bus::new()
/// .add_region(Program, 0..1234)
/// .clear_region(Screen);
///# // TODO: test if region actually clear
///# Ok(())
///# }
/// ```
pub fn clear_region(&mut self, name: Region) -> &mut Self { pub fn clear_region(&mut self, name: Region) -> &mut Self {
if let Some(region) = self.get_region_mut(name) { if let Some(region) = self.get_region_mut(name) {
region.fill(0) region.fill(0)

View File

@ -314,6 +314,20 @@ impl CPU {
self self
} }
/// Gets a slice of breakpoints
/// # Examples
/// ```rust
///# use chirp::prelude::*;
///# fn main() -> Result<()> {
/// let mut cpu = CPU::default();
/// assert_eq!(cpu.breakpoints(), &[]);
///# Ok(())
///# }
/// ```
pub fn breakpoints(&self) -> &[Adr] {
&self.breakpoints.as_slice()
}
/// Unpauses the emulator for a single tick, /// Unpauses the emulator for a single tick,
/// even if cpu.flags.pause is set. /// even if cpu.flags.pause is set.
/// ///

View File

@ -171,7 +171,7 @@ impl Disassemble {
0x65 => self.dma_load(x), 0x65 => self.dma_load(x),
_ => self.unimplemented(opcode), _ => self.unimplemented(opcode),
}, },
_ => unimplemented!("Extracted nibble from byte, got >nibble?"), _ => unreachable!("Extracted nibble from byte, got >nibble?"),
} }
} }
} }

View File

@ -10,6 +10,159 @@ fn chip8() {
println!("{ch8:?}"); // Debug println!("{ch8:?}"); // Debug
} }
mod bus {
use super::*;
mod region {
use super::*;
// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[test]
fn copy() {
let r1 = Screen;
let r2 = r1;
assert_eq!(r1, r2);
}
#[test]
fn clone() {
let r1 = Screen;
let r2 = r1.clone();
assert_eq!(r1, r2);
}
#[test]
fn display() {
println!("{Charset}{Program}{Screen}{Stack}{Count}");
}
#[test]
fn debug() {
println!("{Charset:?}{Program:?}{Screen:?}{Stack:?}{Count:?}");
}
// lmao the things you do for test coverage
#[test]
fn eq() {
assert_eq!(Screen, Screen);
assert_ne!(Charset, Program);
}
#[test]
fn ord() {
assert_eq!(Stack, Charset.max(Program).max(Screen).max(Stack));
assert!(Charset < Program && Program < Screen && Screen < Stack);
}
#[test]
fn hash() {
let mut hasher = DefaultHasher::new();
Stack.hash(&mut hasher);
println!("{hasher:?}");
}
}
#[test]
#[should_panic]
fn bus_missing_region() {
// Print the screen of a bus with no screen
bus! {}.print_screen().unwrap()
}
}
mod cpu {
use super::*;
#[test]
fn set_break() {
let mut cpu = CPU::default();
let point = 0x234;
assert_eq!(cpu.breakpoints(), &[]);
// Attempt to set the same breakpoint 100 times
for _ in 0..100 {
cpu.set_break(point);
}
assert_eq!(cpu.breakpoints(), &[point]);
}
#[test]
fn unset_break() {
let mut cpu = CPU::default();
let point = 0x234;
// set TWO breakpoints
cpu.set_break(point + 1);
cpu.set_break(point);
assert_eq!(cpu.breakpoints(), &[point + 1, point]);
// Attempt to unset the same breakpoint 100 times
for _ in 0..100 {
cpu.unset_break(point);
}
// Only unset the matching point
assert_eq!(cpu.breakpoints(), &[point + 1]);
}
mod controlflags {
use super::*;
//#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[test]
fn clone() {
let cf1 = ControlFlags {
debug: false,
pause: false,
keypause: false,
vbi_wait: false,
lastkey: None,
quirks: Default::default(),
monotonic: None,
};
let cf2 = cf1.clone();
assert_eq!(cf1, cf2)
}
#[test]
fn debug() {
println!("{:?}", ControlFlags::default());
}
#[test]
fn default() {
assert_eq!(
ControlFlags::default(),
ControlFlags {
debug: false,
pause: false,
keypause: false,
vbi_wait: false,
lastkey: Default::default(),
quirks: Default::default(),
monotonic: Default::default()
}
)
}
#[test]
fn eq() {
let cf1 = ControlFlags::default();
let cf2 = ControlFlags {
debug: true,
pause: true,
keypause: true,
vbi_wait: true,
lastkey: Default::default(),
quirks: Default::default(),
monotonic: Default::default(),
};
assert_ne!(cf1, cf2);
}
#[test]
fn ord() {
let cf1 = ControlFlags::default();
let cf2 = ControlFlags {
debug: true,
pause: true,
keypause: true,
vbi_wait: true,
lastkey: Default::default(),
quirks: Default::default(),
monotonic: Default::default(),
};
assert!(cf1 < cf2);
assert_eq!(ControlFlags::default(), cf1.min(cf2));
}
#[test]
fn hash() {
let mut hasher = DefaultHasher::new();
ControlFlags::default().hash(&mut hasher);
println!("{:?}", hasher);
}
}
}
#[test] #[test]
fn error() { fn error() {
let error = chirp::error::Error::FunkyMath { let error = chirp::error::Error::FunkyMath {
@ -115,10 +268,9 @@ mod framebuffer_format {
} }
#[test] #[test]
fn hash() { fn hash() {
println!( let mut hasher = DefaultHasher::new();
"{:?}", FrameBufferFormat::default().hash(&mut hasher);
FrameBufferFormat::default().hash(&mut DefaultHasher::new()) println!("{hasher:?}");
);
} }
} }
@ -153,10 +305,9 @@ mod framebuffer {
#[test] #[test]
fn hash() { fn hash() {
println!( let mut hasher = DefaultHasher::new();
"{:?}", FrameBuffer::default().hash(&mut hasher);
FrameBuffer::default().hash(&mut DefaultHasher::new()) println!("{hasher:?}");
);
} }
} }
@ -225,6 +376,8 @@ mod quirks {
#[test] #[test]
fn hash() { fn hash() {
println!("{:?}", Quirks::from(true).hash(&mut DefaultHasher::new())); let mut hasher = DefaultHasher::new();
Quirks::from(true).hash(&mut hasher);
println!("{hasher:?}");
} }
} }