ソースを参照

Initial implementation of multitester

Matt Ickstadt 8 年 前
コミット
02140cddc9
2 ファイル変更41 行追加54 行削除
  1. 9 6
      src/float/add.rs
  2. 32 48
      src/qc.rs

+ 9 - 6
src/float/add.rs

@@ -186,16 +186,13 @@ add!(__adddf3: f64);
 #[cfg(test)]
 mod tests {
     use core::{f32, f64};
+    use core::fmt;
 
     use float::Float;
     use qc::{U32, U64};
 
-    // NOTE The tests below have special handing for NaN values.
-    // Because NaN != NaN, the floating-point representations must be used
-    // 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.
-
+    // TODO: Move this to F32/F64 in qc.rs
+    #[derive(Copy, Clone)]
     struct FRepr<F>(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)
     check! {
         fn __addsf3(f: extern fn(f32, f32) -> f32,

+ 32 - 48
src/qc.rs

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