void potion_test_sig(CuTest *T) { // test the simple parser entry point yy_sig, not the compiler transformation potion_sig_compile PN sig = potion_sig(P, "num1=N,num2=N"); CuAssert(T, "signature isn't a tuple", PN_IS_TUPLE(sig)); CuAssertIntEquals(T, "len=2", 2, PN_INT(PN_TUPLE_LEN(sig))); CuAssertIntEquals(T, "arity=2", 2, potion_sig_arity(P, sig)); CuAssertStrEquals(T, "num1=N,num2=N", //roundtrip PN_STR_PTR(potion_sig_string(P,0,sig))); CuAssertStrEquals(T, "(num1, 78, num2, 78)", PN_STR_PTR(potion_send(sig, PN_string))); CuAssertStrEquals(T, "num1", PN_STR_PTR(potion_send(PN_TUPLE_AT(sig,0), PN_string))); CuAssertIntEquals(T, "num1=N", 'N', PN_INT(PN_TUPLE_AT(sig,1))); CuAssertStrEquals(T, "num2", PN_STR_PTR(potion_send(PN_TUPLE_AT(sig,2), PN_string))); CuAssertIntEquals(T, "num2=N", 'N', PN_INT(PN_TUPLE_AT(sig,3))); sig = potion_sig(P, "x=N|y=N"); CuAssertStrEquals(T, "(x, 78, 124, y, 78)", PN_STR_PTR(potion_send(sig, PN_string))); CuAssertIntEquals(T, "arity=2", 2, potion_sig_arity(P, sig)); sig = potion_sig(P, "x=N,y=N|r=N"); CuAssert(T, "signature isn't a tuple", PN_IS_TUPLE(sig)); CuAssertStrEquals(T, "(x, 78, y, 78, 124, r, 78)", PN_STR_PTR(potion_send(sig, PN_string))); CuAssertStrEquals(T, "x=N,y=N|r=N", PN_STR_PTR(potion_sig_string(P,0,sig))); CuAssertIntEquals(T, "arity=3", 3, potion_sig_arity(P, sig)); { // roundtrips char *sigs[] = { "", "x,y", "x", "x=N", "x,y", "x=N,y=o", "x|y", "x|y,z", "x=o|y,z", "x|y=o", "x=N,y=N|r=N", /*optional */ "x:=1", "|x:=1", "x|y:=0", /* defaults */ "x,y.z", /* the dot */ }; int size = sizeof(sigs)/sizeof(char *); int i; for (i=0; i< size; i++) { CuAssertStrEquals(T, sigs[i], PN_STR_PTR(potion_sig_string(P,0,potion_sig(P, sigs[i])))); } } CuAssertIntEquals(T, "arity nil", 0, potion_sig_arity(P, PN_NIL)); // sig "" returns PN_FALSE, which throws an error //CuAssertIntEquals(T, "arity ''", 0, potion_sig_arity(P, potion_sig(P, ""))); CuAssertIntEquals(T, "arity x:=1", 1, potion_sig_arity(P, potion_sig(P, "x:=1"))); CuAssertIntEquals(T, "arity |x:=1", 1, potion_sig_arity(P, potion_sig(P, "|x:=1"))); CuAssertIntEquals(T, "arity x|y:=1", 2, potion_sig_arity(P, potion_sig(P, "x|y:=1"))); }
void potion_test_empty(CuTest *T) { PN empty = PN_TUP0(); CuAssert(T, "empty isn't a tuple", PN_IS_TUPLE(empty)); CuAssert(T, "empty isn't a ref", PN_IS_PTR(empty)); CuAssertIntEquals(T, "tuple length is off", 0, PN_INT(potion_send(empty, potion_str(P, "length")))); }
///\return string of the sig tuple. "arg1=o,arg2=o" PN potion_sig_string(Potion *P, PN cl, PN sig) { PN out = potion_byte_str(P, ""); if (PN_IS_TUPLE(sig)) { int nextdef = 0; struct PNTuple * volatile t = ((struct PNTuple *)potion_fwd(sig)); if (t->len != 0) { PN_SIZE i, comma=0; for (i = 0; i < t->len; i++) { PN v = (PN)t->set[i]; if (PN_IS_NUM(v)) { // currently types are still encoded as NUM, TODO: support VTABLE also int c = PN_INT(v); comma=0; if (c == '.') // is end pn_printf(P, out, "."); else if (c == '|') // is optional pn_printf(P, out, "|"); else if (c == ':') { nextdef = 1; pn_printf(P, out, ":"); // is default } else { if (comma++) pn_printf(P, out, ","); if (nextdef) { nextdef = 0; pn_printf(P, out, "="); potion_bytes_obj_string(P, out, v); } else pn_printf(P, out, "=%c", c); } } else { if (comma++) pn_printf(P, out, ","); if (nextdef) { nextdef = 0; pn_printf(P, out, "="); } potion_bytes_obj_string(P, out, v); }}}} return PN_STR_B(out); }
void potion_test_tuple(CuTest *T) { PN tup = potion_tuple_with_size(P, 3); PN_TUPLE_AT(tup, 0) = PN_NIL; PN_TUPLE_AT(tup, 1) = PN_string; PN_TUPLE_AT(tup, 2) = tup; CuAssert(T, "tuple isn't a tuple", PN_IS_TUPLE(tup)); CuAssert(T, "tuple isn't a ref", PN_IS_PTR(tup)); CuAssertIntEquals(T, "tuple length is off", 3, PN_INT(potion_send(tup, potion_str(P, "length")))); }