X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fcom%2Fdogcows%2Fresources%2FC%2B%2BDriver;h=ca48428213dcb43325c87cd68c8d44fc8eef9b74;hb=c76b63d1b374ea6774d648c0a50021357fdd9b80;hp=9f25901fbdc34f972dc761abade4a17df0a0a704;hpb=8a2b2bbbe6e13cee2f5118e1ce814bf17f058299;p=chaz%2Fvimcoder diff --git a/src/com/dogcows/resources/C++Driver b/src/com/dogcows/resources/C++Driver index 9f25901..ca48428 100644 --- a/src/com/dogcows/resources/C++Driver +++ b/src/com/dogcows/resources/C++Driver @@ -1,21 +1,26 @@ #include "$CLASSNAME$.cc" +#include +#include +#include +#include #include #include +#include #include +#include -static bool __exit_on_fail = false; -static int __pass = 0; -static int __fail = 0; -static double __time = 0.0; + +const static double __EPSILON = 1e-9; +static double __time = 0.0; static void __timer_start() { struct timeval tv; if (gettimeofday(&tv, NULL) == 0) { - __time = (double)tv.tv_sec + (double)tv.tv_usec * 0.000001; + __time = double(tv.tv_sec) * 1000.0 + double(tv.tv_usec) * 0.001; } } @@ -26,77 +31,177 @@ static double __timer_stop() return __time - start; } -template -std::string __encode(const T& in) + +static void __eat_whitespace(std::istream& in) { - std::ostringstream s; - s << in; - return s.str(); + while (in.good() && std::isspace(in.peek())) in.get(); } -std::string __encode(const std::string& in) + +std::ostream& operator << (std::ostream& out, const std::string& str) { - std::ostringstream s; - s << '"' << in << '"'; - return s.str(); + out << '"' << str.c_str() << '"'; + return out; } template -std::string __join(const std::vector& in, const std::string& glue) +std::ostream& operator << (std::ostream& out, const std::vector& vec) { - if (in.size() == 0) return ""; - std::ostringstream s; - s << __encode(in[0]); - for (size_t i = 1; i < in.size(); ++i) s << glue << __encode(in[i]); - return s.str(); + out << '{'; + if (0 < vec.size()) + { + out << vec[0]; + for (size_t i = 1; i < vec.size(); ++i) out << ", " << vec[i]; + } + out << '}'; + return out; +} + +std::istream& operator >> (std::istream& in, std::string& str) +{ + __eat_whitespace(in); + + int c; + if (in.good() && (c = in.get()) == '"') + { + std::ostringstream s; + while (in.good() && (c = in.get()) != '"') + { + s.put(char(c)); + } + str = s.str(); + } + + return in; } template -std::string __encode(const std::vector& in) +std::istream& operator >> (std::istream& in, std::vector& vec) { - std::ostringstream s; - s << "{ " << __join(in, ", ") << " }"; - return s.str(); + __eat_whitespace(in); + + int c; + if (in.good() && (c = in.get()) == '{') + { + __eat_whitespace(in); + vec.clear(); + while (in.good() && (c = in.get()) != '}') + { + if (c != ',') in.putback(c); + + T t; + in >> t; + __eat_whitespace(in); + + vec.push_back(t); + } + } + + return in; } -void __do_test(const std::string& expected, $METHODPARAMS$) + +template +bool __equals(const T& actual, const T& expected) { - static int testNum = 0; - std::cout << "----------------------------------------" << std::endl - << "Test " << testNum++ << ": "; + return actual == expected; +} - __timer_start(); - - $CLASSNAME$ object; - $RETURNTYPE$ ret = object.$METHODNAME$($METHODPARAMNAMES$); - - double t = __timer_stop(); - - std::string actual = __encode(ret); - if (actual == expected) +bool __equals(double actual, double expected) +{ + if (std::abs(actual - expected) < __EPSILON) { - std::cout << "[PASS] in " << t << " seconds." << std::endl; - ++__pass; + return true; } else { - std::cout << "[FAIL] in " << t << " seconds." << std::endl - << " Actual: " << actual << std::endl - << " Expected: " << expected << std::endl; - ++__fail; - if (__exit_on_fail) exit(1); + double minimum = std::min(expected * (1.0 - __EPSILON), expected * (1.0 + __EPSILON)); + double maximum = std::max(expected * (1.0 - __EPSILON), expected * (1.0 + __EPSILON)); + return actual > minimum && actual < maximum; } } +bool __equals(const std::vector& actual, const std::vector& expected) +{ + if (actual.size() != expected.size()) + { + return false; + } + + for (size_t i = 0; i < actual.size(); ++i) + { + if (!__equals(actual[i], expected[i])) + { + return false; + } + } + + return true; +} + + int main(int argc, char* argv[]) { - if (1 < argc) __exit_on_fail = true; + bool __abort_on_fail = false; + int __pass = 0; + int __fail = 0; + + if (1 < argc) __abort_on_fail = true; + + std::cout << "TAP version 13" << std::endl; + std::cout.flush(); + + std::ifstream __in("testcases.txt"); + for(;;) + { + int __testnum = __pass + __fail + 1; + + $RETURNTYPE$ __expected; + $METHODPARAMDECLARES$ + __in >> __expected >> $METHODPARAMSTREAMIN$; + if (!__in.good()) break; -$TESTCASES$ - std::cout << "========================================" << std::endl - << " Total Pass: " << __pass << std::endl - << " Total Fail: " << __fail << std::endl; + std::cout << "# input for test " << __testnum << ": " << $METHODPARAMSTREAMOUT$ << std::endl; + std::cout.flush(); + + __timer_start(); + + $CLASSNAME$ __object; + $RETURNTYPE$ __actual = __object.$METHODNAME$($METHODPARAMNAMES$); + + double __t = __timer_stop(); + + std::cout << "# test completed in " << __t << "ms" << std::endl; + std::cout.flush(); + + if (__equals(__actual, __expected)) + { + std::cout << "ok"; + ++__pass; + } + else + { + std::cout << "not ok"; + ++__fail; + } + + std::cout << " " << __testnum << " - " << __actual << " must equal " << __expected << std::endl; + std::cout.flush(); + + if (__abort_on_fail && 0 < __fail) std::abort(); + } + + std::cout << "1.." << (__pass + __fail) << std::endl + << "# passed: " << __pass << std::endl + << "# failed: " << __fail << std::endl; + + if (__fail == 0) + { + std::cout << std::endl + << "# Nice! Don't forget to compile remotely before submitting." << std::endl; + } return __fail; } +// vim:ft=cpp:noet:ts=8