contrib/mul/mbl/mbl_test.h
Go to the documentation of this file.
00001 // This is mul/mbl/mbl_test.h
00002 #ifndef mbl_test_h_
00003 #define mbl_test_h_
00004 //:
00005 // \file
00006 // \brief A place for useful things associated with testing.
00007 // \author iscott
00008 // \date  Dec 2003
00009 
00010 #include <vcl_sstream.h>
00011 #include <vcl_string.h>
00012 #include <vcl_iostream.h>
00013 #include <vcl_vector.h>
00014 #include <vul/vul_reg_exp.h>
00015 
00016 //: Test if the summaries of two objects are the same.
00017 // Both objects \a a and \a b must be the same class, and have
00018 // vsl_print_summary defined for them.
00019 // \param exceptions is an optional, 0 terminated, list of c-strings.
00020 //
00021 // Any pair of lines from the two summaries that don't match
00022 // each other, but do match one of the exception regular expressions will
00023 // be ignored.
00024 // \code
00025 //  base_class_wibble *base_ptr, *base_ptr2;
00026 //  ...
00027 //  // Compare but ignore all lines containing the string "Model address:" :
00028 //  const char *exceptions[] = { "Model address:", 0}; // Don't forget terminating 0
00029 //
00030 //  TEST("saved and loaded extractors are identical",
00031 //       mbl_test_summaries_are_equal(base_ptr,base_ptr2, exceptions),
00032 //       true);
00033 // \endcode
00034 
00035 template <class S>
00036 bool mbl_test_summaries_are_equal(const S &a, const S &b, const char **exceptions=0 )
00037 {
00038   vcl_stringstream ssa, ssb;
00039   vcl_string sa, sb;
00040   vsl_print_summary(ssa, a);
00041   vsl_print_summary(ssb, b);
00042   vcl_vector<vul_reg_exp> exceptions_re;
00043   while (exceptions && *exceptions)
00044   {
00045     exceptions_re.push_back(vul_reg_exp(*exceptions));
00046     exceptions++;
00047   }
00048 
00049   while (!ssa.eof() || !ssb.eof())
00050   {
00051     vcl_getline(ssa, sa);
00052     vcl_getline(ssb, sb);
00053     if (sa != sb && exceptions_re.empty())
00054     {
00055       vcl_cerr << "Found differences:\n>"<<sa<<"\n<"<<sb<<vcl_endl;
00056       return false;
00057     }
00058     else if (sa != sb)
00059     {
00060       bool exception_found = false;
00061 //      for (const char **it = exceptions; *it!=0; ++it)
00062 //        if (sa.find(*it)!=vcl_string::npos && sb.find(*it)!=vcl_string::npos)
00063       for (vcl_vector<vul_reg_exp>::iterator it=exceptions_re.begin(), end=exceptions_re.end();
00064         it != end; ++it)
00065         if (it->find(sa) && it->find(sb))
00066         {
00067           exception_found = true;
00068           break;
00069         }
00070       if (!exception_found)
00071       {
00072         vcl_cerr << "Found differences:\n>"<<sa<<"\n<"<<sb<<vcl_endl;
00073         return false;
00074       }
00075     }
00076   }
00077   return true;
00078 }
00079 
00080 
00081 //: A historical measurement recording framework.
00082 // The function will append the measurement to the file specified
00083 // by $CMAKE_VAR{VXL_MBL_TEST_SAVE_MEASUREMENT_PATH}/measurement_path. The
00084 // value is also copied to stdout where it can be automatically
00085 // picked up by CTest and Dart.
00086 // We suggest formatting the measurement path as follows
00087 // "path/from/code/root/to/test_source_filename_minus_extension/MEASUREMENT_DESCRIPTION",
00088 // e.g. in the file "$CODE_SRC/algo/krr/tests/test_krr_optimise_model_parameters.cxx" 
00089 // \verbatim
00090 // mbl_test_save_measurement("algo/krr/tests/test_krr_optimise_model_parameters/Point_To_Point_RMS_Error",value);
00091 // \endverbatim
00092 void mbl_test_save_measurement( const vcl_string &measurement_path, double value);
00093 
00094 
00095 #endif // mbl_test_h_