mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-25 01:01:34 +11:00
move tests to conditionally compiled modules
also only enable custom test framework feature in test mode
This commit is contained in:
parent
039bc0acb1
commit
222efe9122
|
@ -61,6 +61,10 @@ fn get_data_end() -> usize {
|
||||||
(unsafe { &__ewram_data_end }) as *const _ as usize
|
(unsafe { &__ewram_data_end }) as *const _ as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn should_return_data_end_somewhere_in_ewram(_gba: &mut crate::Gba) {
|
fn should_return_data_end_somewhere_in_ewram(_gba: &mut crate::Gba) {
|
||||||
let data_end = get_data_end();
|
let data_end = get_data_end();
|
||||||
|
@ -75,3 +79,4 @@ fn should_return_data_end_somewhere_in_ewram(_gba: &mut crate::Gba) {
|
||||||
"data end should be smaller than 0x0203_0000"
|
"data end should be smaller than 0x0203_0000"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,9 @@ impl<const N: usize> Bitarray<N> {
|
||||||
self.a[index / 32] = self.a[index / 32] & !mask | value_mask
|
self.a[index / 32] = self.a[index / 32] & !mask | value_mask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn write_and_read(_gba: &mut crate::Gba) {
|
fn write_and_read(_gba: &mut crate::Gba) {
|
||||||
let mut a: Bitarray<2> = Bitarray::new();
|
let mut a: Bitarray<2> = Bitarray::new();
|
||||||
|
@ -52,3 +54,4 @@ fn test_everything(_gba: &mut crate::Gba) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ pub fn display_logo(gfx: &mut BackgroundDistributor) {
|
||||||
back.show();
|
back.show();
|
||||||
back.commit();
|
back.commit();
|
||||||
}
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn logo_display(gba: &mut crate::Gba) {
|
fn logo_display(gba: &mut crate::Gba) {
|
||||||
|
@ -28,3 +31,4 @@ fn logo_display(gba: &mut crate::Gba) {
|
||||||
|
|
||||||
crate::assert_image_output("gfx/test_logo.png");
|
crate::assert_image_output("gfx/test_logo.png");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -270,37 +270,6 @@ macro_rules! add_interrupt_handler {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_vblank_interrupt_handler(_gba: &mut crate::Gba) {
|
|
||||||
{
|
|
||||||
let counter = Mutex::new(0);
|
|
||||||
let counter_2 = Mutex::new(0);
|
|
||||||
add_interrupt_handler!(Interrupt::VBlank, |key| *counter.lock_with_key(&key) += 1);
|
|
||||||
add_interrupt_handler!(Interrupt::VBlank, |_| *counter_2.lock() += 1);
|
|
||||||
|
|
||||||
let vblank = VBlank::get();
|
|
||||||
|
|
||||||
while *counter.lock() < 100 || *counter_2.lock() < 100 {
|
|
||||||
vblank.wait_for_vblank();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
interrupt_to_root(Interrupt::VBlank).next.get(),
|
|
||||||
core::ptr::null(),
|
|
||||||
"expected the interrupt table for vblank to be empty"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_interrupt_table_length(_gba: &mut crate::Gba) {
|
|
||||||
assert_eq!(
|
|
||||||
unsafe { INTERRUPT_TABLE.len() },
|
|
||||||
Interrupt::Gamepak as usize + 1,
|
|
||||||
"interrupt table should be able to store gamepak interrupt"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
enum MutexState {
|
enum MutexState {
|
||||||
Unlocked,
|
Unlocked,
|
||||||
|
@ -409,3 +378,39 @@ impl Drop for VBlank {
|
||||||
interrupt_to_root(Interrupt::VBlank).reduce();
|
interrupt_to_root(Interrupt::VBlank).reduce();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_vblank_interrupt_handler(_gba: &mut crate::Gba) {
|
||||||
|
{
|
||||||
|
let counter = Mutex::new(0);
|
||||||
|
let counter_2 = Mutex::new(0);
|
||||||
|
add_interrupt_handler!(Interrupt::VBlank, |key| *counter.lock_with_key(&key) += 1);
|
||||||
|
add_interrupt_handler!(Interrupt::VBlank, |_| *counter_2.lock() += 1);
|
||||||
|
|
||||||
|
let vblank = VBlank::get();
|
||||||
|
|
||||||
|
while *counter.lock() < 100 || *counter_2.lock() < 100 {
|
||||||
|
vblank.wait_for_vblank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
interrupt_to_root(Interrupt::VBlank).next.get(),
|
||||||
|
core::ptr::null(),
|
||||||
|
"expected the interrupt table for vblank to be empty"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_interrupt_table_length(_gba: &mut crate::Gba) {
|
||||||
|
assert_eq!(
|
||||||
|
unsafe { INTERRUPT_TABLE.len() },
|
||||||
|
Interrupt::Gamepak as usize + 1,
|
||||||
|
"interrupt table should be able to store gamepak interrupt"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
// This appears to be needed for testing to work
|
// This appears to be needed for testing to work
|
||||||
#![cfg_attr(test, no_main)]
|
#![cfg_attr(test, no_main)]
|
||||||
|
#![cfg_attr(test, feature(custom_test_frameworks))]
|
||||||
|
#![cfg_attr(test, test_runner(crate::test_runner))]
|
||||||
|
#![cfg_attr(test, reexport_test_harness_main = "test_main")]
|
||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
#![feature(custom_test_frameworks)]
|
|
||||||
#![feature(alloc_error_handler)]
|
#![feature(alloc_error_handler)]
|
||||||
#![test_runner(crate::test_runner)]
|
|
||||||
#![reexport_test_harness_main = "test_main"]
|
|
||||||
//! # agb
|
//! # agb
|
||||||
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
//! `agb` is a library for making games on the Game Boy Advance using the Rust
|
||||||
//! programming language. It attempts to be a high level abstraction over the
|
//! programming language. It attempts to be a high level abstraction over the
|
||||||
|
|
|
@ -334,55 +334,6 @@ impl<const N: usize> Num<i32, N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn sqrt(_gba: &mut crate::Gba) {
|
|
||||||
for x in 1..1024 {
|
|
||||||
let n: Num<i32, 8> = Num::new(x * x);
|
|
||||||
assert_eq!(n.sqrt(), x.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_macro_conversion(_gba: &mut super::Gba) {
|
|
||||||
fn test_positive<A: FixedWidthUnsignedInteger, const B: usize>() {
|
|
||||||
let a: Num<A, B> = num!(1.5);
|
|
||||||
let one = A::one() << B;
|
|
||||||
let b = Num::from_raw(one + (one >> 1));
|
|
||||||
|
|
||||||
assert_eq!(a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_negative<A: FixedWidthSignedInteger, const B: usize>() {
|
|
||||||
let a: Num<A, B> = num!(-1.5);
|
|
||||||
let one = A::one() << B;
|
|
||||||
let b = Num::from_raw(one + (one >> 1));
|
|
||||||
|
|
||||||
assert_eq!(a, -b);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_base<const B: usize>() {
|
|
||||||
test_positive::<i32, B>();
|
|
||||||
test_positive::<u32, B>();
|
|
||||||
test_negative::<i32, B>();
|
|
||||||
|
|
||||||
if B < 16 {
|
|
||||||
test_positive::<u16, B>();
|
|
||||||
test_positive::<i16, B>();
|
|
||||||
test_negative::<i16, B>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// some nice powers of two
|
|
||||||
test_base::<8>();
|
|
||||||
test_base::<4>();
|
|
||||||
test_base::<16>();
|
|
||||||
// not a power of two
|
|
||||||
test_base::<10>();
|
|
||||||
// an odd number
|
|
||||||
test_base::<9>();
|
|
||||||
// and a prime
|
|
||||||
test_base::<11>();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: FixedWidthSignedInteger, const N: usize> Num<I, N> {
|
impl<I: FixedWidthSignedInteger, const N: usize> Num<I, N> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn abs(self) -> Self {
|
pub fn abs(self) -> Self {
|
||||||
|
@ -415,129 +366,6 @@ impl<I: FixedWidthSignedInteger, const N: usize> Num<I, N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_numbers(_gba: &mut super::Gba) {
|
|
||||||
// test addition
|
|
||||||
let n: Num<i32, 8> = 1.into();
|
|
||||||
assert_eq!(n + 2, 3.into(), "testing that 1 + 2 == 3");
|
|
||||||
|
|
||||||
// test multiplication
|
|
||||||
let n: Num<i32, 8> = 5.into();
|
|
||||||
assert_eq!(n * 3, 15.into(), "testing that 5 * 3 == 15");
|
|
||||||
|
|
||||||
// test division
|
|
||||||
let n: Num<i32, 8> = 30.into();
|
|
||||||
let p: Num<i32, 8> = 3.into();
|
|
||||||
assert_eq!(n / 20, p / 2, "testing that 30 / 20 == 3 / 2");
|
|
||||||
|
|
||||||
assert_ne!(n, p, "testing that 30 != 3");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_division_by_one(_gba: &mut super::Gba) {
|
|
||||||
let one: Num<i32, 8> = 1.into();
|
|
||||||
|
|
||||||
for i in -40..40 {
|
|
||||||
let n: Num<i32, 8> = i.into();
|
|
||||||
assert_eq!(n / one, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_division_and_multiplication_by_16(_gba: &mut super::Gba) {
|
|
||||||
let sixteen: Num<i32, 8> = 16.into();
|
|
||||||
|
|
||||||
for i in -40..40 {
|
|
||||||
let n: Num<i32, 8> = i.into();
|
|
||||||
let m = n / sixteen;
|
|
||||||
|
|
||||||
assert_eq!(m * sixteen, n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_division_by_2_and_15(_gba: &mut super::Gba) {
|
|
||||||
let two: Num<i32, 8> = 2.into();
|
|
||||||
let fifteen: Num<i32, 8> = 15.into();
|
|
||||||
let thirty: Num<i32, 8> = 30.into();
|
|
||||||
|
|
||||||
for i in -128..128 {
|
|
||||||
let n: Num<i32, 8> = i.into();
|
|
||||||
|
|
||||||
assert_eq!(n / two / fifteen, n / thirty);
|
|
||||||
assert_eq!(n / fifteen / two, n / thirty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_change_base(_gba: &mut super::Gba) {
|
|
||||||
let two: Num<i32, 9> = 2.into();
|
|
||||||
let three: Num<i32, 4> = 3.into();
|
|
||||||
|
|
||||||
assert_eq!(two + three.change_base(), 5.into());
|
|
||||||
assert_eq!(three + two.change_base(), 5.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_rem_returns_sensible_values_for_integers(_gba: &mut super::Gba) {
|
|
||||||
for i in -50..50 {
|
|
||||||
for j in -50..50 {
|
|
||||||
if j == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let i_rem_j_normally = i % j;
|
|
||||||
let i_fixnum: Num<i32, 8> = i.into();
|
|
||||||
|
|
||||||
assert_eq!(i_fixnum % j, i_rem_j_normally.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_rem_returns_sensible_values_for_non_integers(_gba: &mut super::Gba) {
|
|
||||||
let one: Num<i32, 8> = 1.into();
|
|
||||||
let third = one / 3;
|
|
||||||
|
|
||||||
for i in -50..50 {
|
|
||||||
for j in -50..50 {
|
|
||||||
if j == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// full calculation in the normal way
|
|
||||||
let x: Num<i32, 8> = third + i;
|
|
||||||
let y: Num<i32, 8> = j.into();
|
|
||||||
|
|
||||||
let truncated_division: Num<i32, 8> = (x / y).trunc().into();
|
|
||||||
|
|
||||||
let remainder = x - truncated_division * y;
|
|
||||||
|
|
||||||
assert_eq!(x % y, remainder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_rem_euclid_is_always_positive_and_sensible(_gba: &mut super::Gba) {
|
|
||||||
let one: Num<i32, 8> = 1.into();
|
|
||||||
let third = one / 3;
|
|
||||||
|
|
||||||
for i in -50..50 {
|
|
||||||
for j in -50..50 {
|
|
||||||
if j == 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let x: Num<i32, 8> = third + i;
|
|
||||||
let y: Num<i32, 8> = j.into();
|
|
||||||
|
|
||||||
let rem_euclid = x.rem_euclid(y);
|
|
||||||
assert!(rem_euclid > 0.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<I: FixedWidthUnsignedInteger, const N: usize> Display for Num<I, N> {
|
impl<I: FixedWidthUnsignedInteger, const N: usize> Display for Num<I, N> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
let mut integral = self.0 >> N;
|
let mut integral = self.0 >> N;
|
||||||
|
@ -643,15 +471,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn test_vector_multiplication_and_division(_gba: &mut super::Gba) {
|
|
||||||
let a: Vector2D<i32> = (1, 2).into();
|
|
||||||
let b = a * 5;
|
|
||||||
let c = b / 5;
|
|
||||||
assert_eq!(b, (5, 10).into());
|
|
||||||
assert_eq!(a, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod formatting_tests {
|
mod formatting_tests {
|
||||||
|
@ -759,15 +578,6 @@ impl<const N: usize> Vector2D<Num<i32, N>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test_case]
|
|
||||||
fn magnitude_accuracy(_gba: &mut crate::Gba) {
|
|
||||||
let n: Vector2D<Num<i32, 16>> = (3, 4).into();
|
|
||||||
assert!((n.magnitude() - 5).abs() < num!(0.1));
|
|
||||||
|
|
||||||
let n: Vector2D<Num<i32, 8>> = (3, 4).into();
|
|
||||||
assert!((n.magnitude() - 5).abs() < num!(0.1));
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Number, P: Number + Into<T>> From<(P, P)> for Vector2D<T> {
|
impl<T: Number, P: Number + Into<T>> From<(P, P)> for Vector2D<T> {
|
||||||
fn from(f: (P, P)) -> Self {
|
fn from(f: (P, P)) -> Self {
|
||||||
Vector2D::new(f.0.into(), f.1.into())
|
Vector2D::new(f.0.into(), f.1.into())
|
||||||
|
@ -934,8 +744,202 @@ impl<T: Number> Vector2D<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn test_vector_changing(_gba: &mut super::Gba) {
|
fn sqrt(_gba: &mut crate::Gba) {
|
||||||
|
for x in 1..1024 {
|
||||||
|
let n: Num<i32, 8> = Num::new(x * x);
|
||||||
|
assert_eq!(n.sqrt(), x.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_macro_conversion(_gba: &mut crate::Gba) {
|
||||||
|
fn test_positive<A: FixedWidthUnsignedInteger, const B: usize>() {
|
||||||
|
let a: Num<A, B> = num!(1.5);
|
||||||
|
let one = A::one() << B;
|
||||||
|
let b = Num::from_raw(one + (one >> 1));
|
||||||
|
|
||||||
|
assert_eq!(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_negative<A: FixedWidthSignedInteger, const B: usize>() {
|
||||||
|
let a: Num<A, B> = num!(-1.5);
|
||||||
|
let one = A::one() << B;
|
||||||
|
let b = Num::from_raw(one + (one >> 1));
|
||||||
|
|
||||||
|
assert_eq!(a, -b);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_base<const B: usize>() {
|
||||||
|
test_positive::<i32, B>();
|
||||||
|
test_positive::<u32, B>();
|
||||||
|
test_negative::<i32, B>();
|
||||||
|
|
||||||
|
if B < 16 {
|
||||||
|
test_positive::<u16, B>();
|
||||||
|
test_positive::<i16, B>();
|
||||||
|
test_negative::<i16, B>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// some nice powers of two
|
||||||
|
test_base::<8>();
|
||||||
|
test_base::<4>();
|
||||||
|
test_base::<16>();
|
||||||
|
// not a power of two
|
||||||
|
test_base::<10>();
|
||||||
|
// an odd number
|
||||||
|
test_base::<9>();
|
||||||
|
// and a prime
|
||||||
|
test_base::<11>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_numbers(_gba: &mut crate::Gba) {
|
||||||
|
// test addition
|
||||||
|
let n: Num<i32, 8> = 1.into();
|
||||||
|
assert_eq!(n + 2, 3.into(), "testing that 1 + 2 == 3");
|
||||||
|
|
||||||
|
// test multiplication
|
||||||
|
let n: Num<i32, 8> = 5.into();
|
||||||
|
assert_eq!(n * 3, 15.into(), "testing that 5 * 3 == 15");
|
||||||
|
|
||||||
|
// test division
|
||||||
|
let n: Num<i32, 8> = 30.into();
|
||||||
|
let p: Num<i32, 8> = 3.into();
|
||||||
|
assert_eq!(n / 20, p / 2, "testing that 30 / 20 == 3 / 2");
|
||||||
|
|
||||||
|
assert_ne!(n, p, "testing that 30 != 3");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_division_by_one(_gba: &mut crate::Gba) {
|
||||||
|
let one: Num<i32, 8> = 1.into();
|
||||||
|
|
||||||
|
for i in -40..40 {
|
||||||
|
let n: Num<i32, 8> = i.into();
|
||||||
|
assert_eq!(n / one, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_division_and_multiplication_by_16(_gba: &mut crate::Gba) {
|
||||||
|
let sixteen: Num<i32, 8> = 16.into();
|
||||||
|
|
||||||
|
for i in -40..40 {
|
||||||
|
let n: Num<i32, 8> = i.into();
|
||||||
|
let m = n / sixteen;
|
||||||
|
|
||||||
|
assert_eq!(m * sixteen, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_division_by_2_and_15(_gba: &mut crate::Gba) {
|
||||||
|
let two: Num<i32, 8> = 2.into();
|
||||||
|
let fifteen: Num<i32, 8> = 15.into();
|
||||||
|
let thirty: Num<i32, 8> = 30.into();
|
||||||
|
|
||||||
|
for i in -128..128 {
|
||||||
|
let n: Num<i32, 8> = i.into();
|
||||||
|
|
||||||
|
assert_eq!(n / two / fifteen, n / thirty);
|
||||||
|
assert_eq!(n / fifteen / two, n / thirty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_change_base(_gba: &mut crate::Gba) {
|
||||||
|
let two: Num<i32, 9> = 2.into();
|
||||||
|
let three: Num<i32, 4> = 3.into();
|
||||||
|
|
||||||
|
assert_eq!(two + three.change_base(), 5.into());
|
||||||
|
assert_eq!(three + two.change_base(), 5.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_rem_returns_sensible_values_for_integers(_gba: &mut crate::Gba) {
|
||||||
|
for i in -50..50 {
|
||||||
|
for j in -50..50 {
|
||||||
|
if j == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let i_rem_j_normally = i % j;
|
||||||
|
let i_fixnum: Num<i32, 8> = i.into();
|
||||||
|
|
||||||
|
assert_eq!(i_fixnum % j, i_rem_j_normally.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_rem_returns_sensible_values_for_non_integers(_gba: &mut crate::Gba) {
|
||||||
|
let one: Num<i32, 8> = 1.into();
|
||||||
|
let third = one / 3;
|
||||||
|
|
||||||
|
for i in -50..50 {
|
||||||
|
for j in -50..50 {
|
||||||
|
if j == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// full calculation in the normal way
|
||||||
|
let x: Num<i32, 8> = third + i;
|
||||||
|
let y: Num<i32, 8> = j.into();
|
||||||
|
|
||||||
|
let truncated_division: Num<i32, 8> = (x / y).trunc().into();
|
||||||
|
|
||||||
|
let remainder = x - truncated_division * y;
|
||||||
|
|
||||||
|
assert_eq!(x % y, remainder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_rem_euclid_is_always_positive_and_sensible(_gba: &mut crate::Gba) {
|
||||||
|
let one: Num<i32, 8> = 1.into();
|
||||||
|
let third = one / 3;
|
||||||
|
|
||||||
|
for i in -50..50 {
|
||||||
|
for j in -50..50 {
|
||||||
|
if j == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let x: Num<i32, 8> = third + i;
|
||||||
|
let y: Num<i32, 8> = j.into();
|
||||||
|
|
||||||
|
let rem_euclid = x.rem_euclid(y);
|
||||||
|
assert!(rem_euclid > 0.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_vector_multiplication_and_division(_gba: &mut crate::Gba) {
|
||||||
|
let a: Vector2D<i32> = (1, 2).into();
|
||||||
|
let b = a * 5;
|
||||||
|
let c = b / 5;
|
||||||
|
assert_eq!(b, (5, 10).into());
|
||||||
|
assert_eq!(a, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn magnitude_accuracy(_gba: &mut crate::Gba) {
|
||||||
|
let n: Vector2D<Num<i32, 16>> = (3, 4).into();
|
||||||
|
assert!((n.magnitude() - 5).abs() < num!(0.1));
|
||||||
|
|
||||||
|
let n: Vector2D<Num<i32, 8>> = (3, 4).into();
|
||||||
|
assert!((n.magnitude() - 5).abs() < num!(0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn test_vector_changing(_gba: &mut crate::Gba) {
|
||||||
let v1: Vector2D<FixedNum<8>> = Vector2D::new(1.into(), 2.into());
|
let v1: Vector2D<FixedNum<8>> = Vector2D::new(1.into(), 2.into());
|
||||||
|
|
||||||
let v2 = v1.trunc();
|
let v2 = v1.trunc();
|
||||||
|
@ -943,3 +947,4 @@ fn test_vector_changing(_gba: &mut super::Gba) {
|
||||||
|
|
||||||
assert_eq!(v1 + v1, (v2 + v2).into());
|
assert_eq!(v1 + v1, (v2 + v2).into());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -151,6 +151,10 @@ pub fn affine_matrix(
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn affine(_gba: &mut crate::Gba) {
|
fn affine(_gba: &mut crate::Gba) {
|
||||||
// expect identity matrix
|
// expect identity matrix
|
||||||
|
@ -160,3 +164,4 @@ fn affine(_gba: &mut crate::Gba) {
|
||||||
assert_eq!(aff.p_a, one.to_raw());
|
assert_eq!(aff.p_a, one.to_raw());
|
||||||
assert_eq!(aff.p_d, one.to_raw());
|
assert_eq!(aff.p_d, one.to_raw());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue