about summary refs log tree commit diff stats
path: root/002test.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-05 21:17:24 -0700
commitb96af395b9af2ff9df94b3e82213171f30827c8d (patch)
tree17c8c12648ccc25625e2534ec8d74fbe8f1542cc /002test.cc
parent2e3b597fe85b654e82b891c22d50754fa5a26156 (diff)
downloadmu-b96af395b9af2ff9df94b3e82213171f30827c8d.tar.gz
1276 - make C++ version the default
I've tried to update the Readme, but there are at least a couple of issues.
Diffstat (limited to '002test.cc')
-rw-r--r--002test.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/002test.cc b/002test.cc
new file mode 100644
index 00000000..776e78e9
--- /dev/null
+++ b/002test.cc
@@ -0,0 +1,93 @@
+//: A simple test harness. To create new tests define functions starting with
+//: 'test_'. To run all tests so defined, run:
+//:   $ wart test
+//:
+//: So far it seems tasteful for layers to never ever reach back to modify
+//: previously-defined tests. Every test is a contract once written, and should
+//: pass as-is if it is included, regardless of how much later layers change
+//: the program. Avoid writing 'temporary' tests that only work with some
+//: subsets of the program.
+
+:(before "End Types")
+typedef void (*test_fn)(void);
+
+:(before "End Globals")
+const test_fn Tests[] = {
+  #include "test_list"  // auto-generated; see makefile
+};
+
+bool Run_tests = false;
+bool Passed = true;  // set this to false inside any test to indicate failure
+long Num_failures = 0;
+
+#define CHECK(X) \
+  if (!(X)) { \
+    ++Num_failures; \
+    cerr << "\nF " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << '\n'; \
+    Passed = false; \
+    return;  /* Currently we stop at the very first failure. */ \
+  }
+
+#define CHECK_EQ(X, Y) \
+  if ((X) != (Y)) { \
+    ++Num_failures; \
+    cerr << "\nF " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): " << #X << " == " << #Y << '\n'; \
+    cerr << "  got " << (X) << '\n';  /* BEWARE: multiple eval */ \
+    Passed = false; \
+    return;  /* Currently we stop at the very first failure. */ \
+  }
+
+:(before "End Setup")
+Passed = true;
+
+:(before "End Commandline Parsing")
+if (argc > 1 && is_equal(argv[1], "test")) {
+  Run_tests = true;  --argc;  ++argv;  // shift 'test' out of commandline args
+}
+
+:(before "End Main")
+if (Run_tests) {
+  // Test Runs
+  // we run some tests and then exit; assume no state need be maintained afterward
+
+  // End Test Run Initialization
+  time_t t; time(&t);
+  cerr << "C tests: " << ctime(&t);
+  for (index_t i=0; i < sizeof(Tests)/sizeof(Tests[0]); ++i) {
+    run_test(i);
+  }
+  // End Tests
+  cerr << '\n';
+  if (Num_failures > 0)
+    cerr << Num_failures << " failure"
+         << (Num_failures > 1 ? "s" : "")
+         << '\n';
+  return 0;
+}
+
+:(code)
+void run_test(index_t i) {
+  if (i >= sizeof(Tests)/sizeof(Tests[0])) {
+    cerr << "no test " << i << '\n';
+    return;
+  }
+  setup();
+  // End Test Setup
+  (*Tests[i])();
+  teardown();
+  if (Passed) cerr << ".";
+}
+
+bool is_number(const string& s) {
+  return s.find_first_not_of("0123456789-.") == string::npos;
+}
+
+long long int to_int(string n) {
+  char* end = NULL;
+  long long int result = strtoll(n.c_str(), &end, /*any base*/0);
+  assert(*end == '\0');
+  return result;
+}
+
+:(before "End Includes")
+#include<cstdlib>