Auto merge of #86 - mattico:multitester, r=japaric

Initial implementation of multitester

Implements part of #72.

I wanted to work on this first because it should help me find the problem in the add implementation.

Test failures now look like this:
```
__addsf3 - Args: 1 1264853201
  rustc-builtins: Some(0)
  compiler_rt:    Some(14950609)
  gcc_s:          None
__addsf3 - Args: 1 632426600
  rustc-builtins: Some(0)
  compiler_rt:    Some(0.00000000000000030889195)
  gcc_s:          None
__addsf3 - Args: 1 316213300
  rustc-builtins: Some(0)
  compiler_rt:    Some(0.0000000000000000000000000013696648)
  gcc_s:          None

[snip]

thread 'float::add::tests::_test::__addsf3' panicked at '[quickcheck] TEST FAILED. Arguments: (1, 1)', /home/matt/.cargo/registry/src/github.com-1ecc6299db9ec823/quickcheck-0.3.1/src/tester.rs:118
```

It currently prints all of the errors, if that's undesirable we'd need to remove the shrinkers or modify quickcheck.
This commit is contained in:
homunkulus 2016-10-03 06:58:30 +00:00
commit 954e3b7095
2 changed files with 41 additions and 54 deletions

View File

@ -186,16 +186,13 @@ add!(__adddf3: f64);
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use core::{f32, f64}; use core::{f32, f64};
use core::fmt;
use float::Float; use float::Float;
use qc::{U32, U64}; use qc::{U32, U64};
// NOTE The tests below have special handing for NaN values. // TODO: Move this to F32/F64 in qc.rs
// Because NaN != NaN, the floating-point representations must be used #[derive(Copy, Clone)]
// Because there are many diffferent values of NaN, and the implementation
// doesn't care about calculating the 'correct' one, if both values are NaN
// the values are considered equivalent.
struct FRepr<F>(F); struct FRepr<F>(F);
impl<F: Float> PartialEq for FRepr<F> { impl<F: Float> PartialEq for FRepr<F> {
@ -212,6 +209,12 @@ mod tests {
} }
} }
impl<F: fmt::Debug> fmt::Debug for FRepr<F> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
// TODO: Add F32/F64 to qc so that they print the right values (at the very least) // TODO: Add F32/F64 to qc so that they print the right values (at the very least)
check! { check! {
fn __addsf3(f: extern fn(f32, f32) -> f32, fn __addsf3(f: extern fn(f32, f32) -> f32,

View File

@ -195,7 +195,7 @@ macro_rules! check {
} }
)* )*
mod _compiler_rt { mod _test {
use qc::*; use qc::*;
use std::mem; use std::mem;
use quickcheck::TestResult; use quickcheck::TestResult;
@ -207,54 +207,38 @@ macro_rules! check {
let my_answer = super::$name(super::super::$name, let my_answer = super::$name(super::super::$name,
$($arg),*); $($arg),*);
let compiler_rt_fn = ::compiler_rt::get(stringify!($name)); let compiler_rt_fn = ::compiler_rt::get(stringify!($name));
unsafe { let compiler_rt_answer = unsafe {
let compiler_rt_answer =
super::$name(mem::transmute(compiler_rt_fn), super::$name(mem::transmute(compiler_rt_fn),
$($arg),*); $($arg),*)
match (my_answer, compiler_rt_answer) { };
(None, _) | (_, None) => TestResult::discard(),
(Some(a), Some(b)) => {
TestResult::from_bool(a == b)
}
}
}
}
::quickcheck::quickcheck(my_check as fn($($t),*) -> TestResult)
}
)*
}
mod _gcc_s {
use qc::*;
use std::mem;
use quickcheck::TestResult;
$(
#[test]
fn $name() {
fn my_check($($arg:$t),*) -> TestResult {
let my_answer = super::$name(super::super::$name,
$($arg),*);
let gcc_s_fn = ::gcc_s::get(stringify!($name)).unwrap();
unsafe {
let gcc_s_answer = let gcc_s_answer =
super::$name(mem::transmute(gcc_s_fn), match ::gcc_s::get(stringify!($name)) {
$($arg),*); Some(f) => unsafe {
match (my_answer, gcc_s_answer) { Some(super::$name(mem::transmute(f),
(None, _) | (_, None) => TestResult::discard(), $($arg),*))
(Some(a), Some(b)) => { },
TestResult::from_bool(a == b) None => None,
} };
}
}
}
// If it's not in libgcc, or we couldn't find libgcc, then let print_values = || {
// just ignore this. We should have tests through print!("{} - Args: ", stringify!($name));
// compiler-rt in any case $(print!("{:?} ", $arg);)*
if ::gcc_s::get(stringify!($name)).is_none() { print!("\n");
return println!(" rustc-builtins: {:?}", my_answer);
println!(" compiler_rt: {:?}", compiler_rt_answer);
println!(" gcc_s: {:?}", gcc_s_answer);
};
if my_answer != compiler_rt_answer {
print_values();
TestResult::from_bool(false)
} else if gcc_s_answer.is_some() &&
my_answer != gcc_s_answer.unwrap() {
print_values();
TestResult::from_bool(false)
} else {
TestResult::from_bool(true)
}
} }
::quickcheck::quickcheck(my_check as fn($($t),*) -> TestResult) ::quickcheck::quickcheck(my_check as fn($($t),*) -> TestResult)