From 4e99f95b9452b7903d5dc2f8829206cce1631397 Mon Sep 17 00:00:00 2001
From: Brendan Bartels <bbartels@iastate.edu>
Date: Thu, 20 Apr 2017 10:53:02 -0500
Subject: [PATCH] quad: improve unit testing

---
 .../test/test_computation_graph.c             | 54 +++++++++----------
 quad/src/queue/test/test_queue.c              | 12 ++---
 quad/src/test/README.md                       | 20 +++++--
 quad/src/test/example/example.c               | 24 ---------
 quad/src/test/test/example.c                  | 32 +++++++++++
 5 files changed, 81 insertions(+), 61 deletions(-)
 delete mode 100644 quad/src/test/example/example.c
 create mode 100644 quad/src/test/test/example.c

diff --git a/quad/src/computation_graph/test/test_computation_graph.c b/quad/src/computation_graph/test/test_computation_graph.c
index e0882d4d1..f44d71381 100644
--- a/quad/src/computation_graph/test/test_computation_graph.c
+++ b/quad/src/computation_graph/test/test_computation_graph.c
@@ -13,7 +13,7 @@ static int nequal(double val1, double val2) {
     return -1;
 }
 
-int graph_test_one_add() {
+int test_adding_2_numbers() {
     struct computation_graph *graph = create_graph();
     int block = graph_add_defined_block(graph, BLOCK_ADD, "Add");
     int cblock3 = graph_add_defined_block(graph, BLOCK_CONSTANT, "3");
@@ -29,7 +29,7 @@ int graph_test_one_add() {
 }
 
 
-int graph_test_circular_runs() {
+int test_computing_cycles() {
     struct computation_graph *graph = create_graph();
     int gain1 = graph_add_defined_block(graph, BLOCK_GAIN, "gain1");
     int gain2 = graph_add_defined_block(graph, BLOCK_GAIN, "gain2");
@@ -41,7 +41,7 @@ int graph_test_circular_runs() {
     return 0;
 }
 
-int graph_test_circular_resets() {
+int test_resetting_cycles() {
     struct computation_graph *graph = create_graph();
     int acum1 = graph_add_defined_block(graph, BLOCK_ACCUMULATE, "accumulator1");
     int acum2 = graph_add_defined_block(graph, BLOCK_ACCUMULATE, "accumulator2");
@@ -51,7 +51,7 @@ int graph_test_circular_resets() {
 }
 
 // Tests the accumulator block, thereby testing reset and state changes
-int graph_test_accumulator() {
+int test_accumulator_state() {
     struct computation_graph *graph = create_graph();
     int cblock = graph_add_defined_block(graph, BLOCK_CONSTANT, "const");
     int acum_b = graph_add_defined_block(graph, BLOCK_ACCUMULATE, "accumulator");
@@ -87,7 +87,7 @@ int graph_test_accumulator() {
 
 // Tests that a block will only execute once per compute,
 // even if its output is connected to multiple inputs
-int graph_test_single_run() {
+int test_that_blocks_only_get_executed_once() {
     struct computation_graph *graph = create_graph();
     int acum_b = graph_add_defined_block(graph, BLOCK_ACCUMULATE, "accumulator");
     int add_block = graph_add_defined_block(graph, BLOCK_ADD, "Add");
@@ -106,7 +106,7 @@ int graph_test_single_run() {
 }
 
 // Tests that upon connection of a second child, a block will not reset
-int graph_test_reset_rules() {
+int tests_that_already_connected_blocks_dont_get_reset() {
     struct computation_graph *graph = create_graph();
     int cblock = graph_add_defined_block(graph, BLOCK_CONSTANT, "5");
     graph_set_param_val(graph, cblock, CONST_SET, 5);
@@ -132,7 +132,7 @@ int graph_test_reset_rules() {
     return nequal(result, 5);
 }
 
-int graph_test_self_loop() {
+int test_that_a_self_loop_computation_terminates() {
     struct computation_graph *graph = create_graph();
     int gain1 = graph_add_defined_block(graph, BLOCK_GAIN, "gain1");
     graph_set_source(graph, gain1, GAIN_INPUT, gain1, GAIN_RESULT);
@@ -141,7 +141,7 @@ int graph_test_self_loop() {
     return 0;
 }
 
-int graph_test_update_rules() {
+int test_that_nodes_only_update_when_their_inputs_change() {
     struct computation_graph *graph = create_graph();
     int cblock = graph_add_defined_block(graph, BLOCK_CONSTANT, "const");
     int acum_b = graph_add_defined_block(graph, BLOCK_ACCUMULATE, "accumulator");
@@ -161,7 +161,7 @@ C1 --->| accum_b1 --->|
                       | Add --->
 C2 --->| accum_b2 --->|
 */
-int graph_test_update_propagation() {
+int test_that_updates_propagate_only_to_their_children() {
     struct computation_graph *graph = create_graph();
     int cblock1 = graph_add_defined_block(graph, BLOCK_CONSTANT, "const1");
     int cblock2 = graph_add_defined_block(graph, BLOCK_CONSTANT, "const2");
@@ -192,7 +192,7 @@ This caused problems, because if a node had its output to two things, then it wo
 Since it didn't get marked as "updated" when it got connected to the computation path, and it had its original "updated" flag cleared,
 the node would never get set.
 */
-int graph_test_update_disconnected() {
+int test_that_nodes_get_executed_when_updated_even_if_disconnected() {
     printf("\n\n---------\n");
     struct computation_graph *graph = create_graph();
     int d_block = graph_add_defined_block(graph, BLOCK_CONSTANT, "const1");
@@ -213,7 +213,7 @@ int graph_test_update_disconnected() {
     return nequal(set_val, 2*1.2345);
 }
 
-int graph_test_get_source() {
+int test_that_the_get_source_call_works_normally() {
     struct computation_graph *graph = create_graph();
     int add_block = graph_add_defined_block(graph, BLOCK_ADD, "Add");
     int cblock3 = graph_add_defined_block(graph, BLOCK_CONSTANT, "3");
@@ -228,7 +228,7 @@ int graph_test_get_source() {
     }
 }
 
-int graph_test_get_source_null() {
+int test_that_the_get_source_call_returns_ID_neg_1_when_invalid_ID_is_passed() {
     struct computation_graph *graph = create_graph();
     int add_block = graph_add_defined_block(graph, BLOCK_ADD, "Add");
 
@@ -241,7 +241,7 @@ int graph_test_get_source_null() {
     }
 }
 
-int graph_test_add_by_id() {
+int test_that_new_nodes_can_be_created_by_ID() {
     struct computation_graph *graph = create_graph();
     int desired_id = 87;
     int add_block = graph_add_node_id(graph, desired_id, "Add", &node_add_type);
@@ -264,18 +264,18 @@ int graph_test_add_by_id() {
 }
 
 int main() {
-    test(graph_test_one_add, "Test adding 2 numbers");
-    test(graph_test_circular_runs, "Test computing cycles");
-    test(graph_test_circular_resets, "Test resetting cycles");
-    test(graph_test_accumulator, "Test accumulator (state)");
-    test(graph_test_single_run, "Test that blocks only get executed once");
-    test(graph_test_reset_rules, "Tests that already connected blocks don't get reset");
-    test(graph_test_self_loop, "Tests that a self-loop computation terminates");
-    test(graph_test_update_rules, "Tests that nodes only update when their inputs change");
-    test(graph_test_update_propagation, "Tests that updates propagate only to their children");
-    test(graph_test_update_disconnected, "Tests that nodes get executed when updated, even if disconnected");
-    test(graph_test_get_source, "Tests that the get_source call works normally");
-    test(graph_test_get_source_null, "Tests that the get_source call returns ID -1 when invalid ID is passed");
-    test(graph_test_add_by_id, "Tests that new nodes can be created by ID");
-    return test_summary();
+  TEST(test_adding_2_numbers);
+  TEST(test_computing_cycles);
+  TEST(test_resetting_cycles);
+  TEST(test_accumulator_state);
+  TEST(test_that_blocks_only_get_executed_once);
+  TEST(tests_that_already_connected_blocks_dont_get_reset);
+  TEST(test_that_a_self_loop_computation_terminates);
+  TEST(test_that_nodes_only_update_when_their_inputs_change);
+  TEST(test_that_updates_propagate_only_to_their_children);
+  TEST(test_that_nodes_get_executed_when_updated_even_if_disconnected);
+  TEST(test_that_the_get_source_call_works_normally);
+  TEST(test_that_the_get_source_call_returns_ID_neg_1_when_invalid_ID_is_passed);
+  TEST(test_that_new_nodes_can_be_created_by_ID);
+  return test_summary();
 }
diff --git a/quad/src/queue/test/test_queue.c b/quad/src/queue/test/test_queue.c
index 02328d1f9..aa23c9efa 100644
--- a/quad/src/queue/test/test_queue.c
+++ b/quad/src/queue/test/test_queue.c
@@ -160,11 +160,11 @@ int test_empty() {
 
 
 int main() {
-  test(test_free, "test_free");
-  test(test_add, "test_add");
-  test(test_remove, "test_remove");
-  test(test_size, "test_size");
-  test(test_full, "test_full");
-  test(test_empty, "test_empty");
+  TEST(test_free);
+  TEST(test_add);
+  TEST(test_remove);
+  TEST(test_size);
+  TEST(test_full);
+  TEST(test_empty);
   return test_summary();
 }
diff --git a/quad/src/test/README.md b/quad/src/test/README.md
index 8bec810e2..229cb6bdf 100644
--- a/quad/src/test/README.md
+++ b/quad/src/test/README.md
@@ -1,6 +1,9 @@
 Basic Testing Suite in C
 ----
-This test suite helps you run tests. It handles the result of every test
+THIS IS NOT A DIRECTORY OF TESTS. Rather, it is a library of test utility
+functions that you can use to write unit tests.
+
+The functions in this library help handles the result of every test
 whether it be a success, failure, or segfault, and keeps running until
 all tests have been executed. It then gives a summary of the test results.
 
@@ -12,11 +15,16 @@ function along with a name you want included in the test report.
 
 ```c
 int main() {
-    test(test_func, "this test will pass!");
-    test(another_func, "this one might fail...");
+    TEST(test_func);
+    TEST(another_func);
     ...
 ```
 
+When writing your `test_func`, you can use the `test_assert` method to perform
+basic assertions. If any assertion fails, then `test_func` will fail right
+away. If you have multiple assertions in a single `test_func`, the output will
+tell you specifically which assertion failed.
+
 Then at the end of your main function, call the `test_summary()` function, and
 return its return value from your main function.
 
@@ -27,4 +35,8 @@ int main() {
 }
 ```
 
-An `example.c` file is included for reference.
\ No newline at end of file
+An example of creating a `test/` directory is done in this folder. To run make
+the unit tests in your library, run
+```
+make test
+```
\ No newline at end of file
diff --git a/quad/src/test/example/example.c b/quad/src/test/example/example.c
deleted file mode 100644
index b757c6e5d..000000000
--- a/quad/src/test/example/example.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdio.h>
-#include "test.h"
-
-int test1() {
-  puts("hi world.");
-  return 0;
-}
-
-int test2() {
-  return 1;
-}
-
-int test3() {
-  int *bad = NULL;
-  int x = *bad;
-  return 0;
-}
-
-int main() {
-  test(test1, "print hello world");
-  test(test2, "just fail");
-  test(test3, "survive segfault");
-  return test_summary();
-}
diff --git a/quad/src/test/test/example.c b/quad/src/test/test/example.c
new file mode 100644
index 000000000..bca8528ca
--- /dev/null
+++ b/quad/src/test/test/example.c
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include "test.h"
+
+int test_always_passes() {
+  puts("hi world.");
+  return 0;
+}
+
+int test_always_fails() {
+  return 1;
+}
+
+int test_assertions() {
+  test_assert(1 == 1);
+  test_assert(2 == 3);
+  test_assert(3 == 3);
+  return 1;
+}
+
+int test_always_segfaults() {
+  int *bad = NULL;
+  int x = *bad;
+  return 0;
+}
+
+int main() {
+  TEST(test_always_passes);
+  TEST(test_always_fails);
+  TEST(test_assertions);
+  TEST(test_always_segfaults);
+  return test_summary();
+}
-- 
GitLab