add test for weakref
authorOlivier Matz <zer0@droids-corp.org>
Mon, 12 Mar 2018 20:32:07 +0000 (21:32 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Mon, 12 Mar 2018 20:33:51 +0000 (21:33 +0100)
lib/ecoli_node_weakref.c
lib/ecoli_node_weakref.h

index 8c7d030..4d75cfb 100644 (file)
@@ -19,6 +19,9 @@
 #include <ecoli_node_str.h>
 #include <ecoli_node_option.h>
 #include <ecoli_node_weakref.h>
+#include <ecoli_node_int.h>
+#include <ecoli_node_seq.h>
+#include <ecoli_node_or.h>
 
 EC_LOG_TYPE_REGISTER(node_weakref);
 
@@ -75,7 +78,7 @@ int ec_node_weakref_set(struct ec_node *gen_node, struct ec_node *child)
        return 0;
 
 fail:
-       ec_node_free(child);
+       /* do not free child */
        return -1;
 }
 
@@ -98,8 +101,49 @@ struct ec_node *ec_node_weakref(const char *id, struct ec_node *child)
 /* LCOV_EXCL_START */
 static int ec_node_weakref_testcase(void)
 {
-       //XXX weakref testcase
-       return 0;
+       struct ec_node *weak = NULL, *expr = NULL, *val = NULL;
+       struct ec_node *seq = NULL, *op = NULL;
+       int testres = 0;
+
+       expr = ec_node("or", EC_NO_ID);
+       val = ec_node_int(EC_NO_ID, 0, 10, 10);
+       op = ec_node_str(EC_NO_ID, "!");
+       weak = ec_node_weakref(EC_NO_ID, expr);
+       if (weak == NULL || expr == NULL || val == NULL || op == NULL)
+               goto fail;
+       seq = EC_NODE_SEQ(EC_NO_ID, op, weak);
+       op = NULL;
+       weak = NULL;
+
+       if (ec_node_or_add(expr, seq) < 0)
+               goto fail;
+       seq = NULL;
+       if (ec_node_or_add(expr, val) < 0)
+               goto fail;
+       val = NULL;
+
+       testres |= EC_TEST_CHECK_PARSE(expr, 1, "1");
+       testres |= EC_TEST_CHECK_PARSE(expr, 2, "!", "1");
+       testres |= EC_TEST_CHECK_PARSE(expr, 3, "!", "!", "1");
+
+       testres |= EC_TEST_CHECK_COMPLETE(expr,
+               "", EC_NODE_ENDLIST,
+               "!", EC_NODE_ENDLIST);
+       testres |= EC_TEST_CHECK_COMPLETE(expr,
+               "!", "", EC_NODE_ENDLIST,
+               "!", EC_NODE_ENDLIST);
+
+       ec_node_free(expr);
+
+       return testres;
+
+fail:
+       ec_node_free(weak);
+       ec_node_free(expr);
+       ec_node_free(val);
+       ec_node_free(seq);
+       ec_node_free(op);
+       return -1;
 }
 /* LCOV_EXCL_STOP */
 
index 6002f93..cb2aed1 100644 (file)
  *   freeable, due to reference counters
  *
  * Example:
+ *  expr = or()
  *  val = int(0, 10)
  *  op = str("!")
- *  expr = or()
- *  seq = seq(clone(op), clone(expr))
- *  expr.add(clone(seq))
- *  expr.add(clone(val))
- *  free(val)
- *  free(op)
- *  free(seq)
+ *  seq = seq(op, clone(expr))
+ *  expr.add(seq)
+ *  expr.add(val)
+ *  free(expr) // just decrease ref
  *
  * FAIL: expr cannot be freed due to cyclic refs
  * The references are like this:
  *                   val
  *                    ^
  *                    |
- *        $user ---> expr ---> seq ---> op
+ *     $user ~ ~ ~ > expr ---> seq ---> op
  *                        <---
  *
  * It is solved with:
+ *  expr = or()
  *  val = int(0, 10)
  *  op = str("!")
- *  expr = or()
  *  weak = weak(expr)
- *  seq = seq(clone(op), clone(weak))
- *  expr.add(clone(seq))
- *  expr.add(clone(val))
- *  free(val)
- *  free(op)
- *  free(weak)
- *  free(seq)
+ *  seq = seq(op, weak)
+ *  expr.add(op)
+ *  expr.add(val)
  *
  *
  *                   val
  *                    ^
  *                    |
- *        $user ---> expr ---------------> seq ---> op
+ *     $user ~ ~ ~ > expr ---------------> seq ---> op
  *                        <- - - weak <---
  *
  * The node expr can be freed.