From 628a77a8b01800a688f0b906617f1653b7c472df Mon Sep 17 00:00:00 2001 From: Michael Hines Date: Mon, 30 Oct 2023 08:39:02 -0400 Subject: [PATCH] 99% coverage of strfun.cpp --- src/ivoc/strfun.cpp | 12 ++--- .../hoc_python/test_StringFunctions.py | 54 +++++++++++++++++-- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/ivoc/strfun.cpp b/src/ivoc/strfun.cpp index 3cf636cad7..8bc53d4244 100644 --- a/src/ivoc/strfun.cpp +++ b/src/ivoc/strfun.cpp @@ -93,11 +93,12 @@ extern Object* hoc_newobj1(Symbol*, int); extern Symlist* hoc_top_level_symlist; extern Symbol* ivoc_alias_lookup(const char* name, Object* ob) { + Symbol* s{}; IvocAliases* a = (IvocAliases*) ob->aliases; if (a) { - return a->lookup(name); + s = a->lookup(name); } - return NULL; + return s; } extern void ivoc_free_alias(Object* ob) { @@ -150,8 +151,7 @@ static Object** l_alias_list(void*) { Symbol* sl = hoc_lookup("List"); Symbol* st = hoc_table_lookup("String", hoc_top_level_symlist); if (!st || st->type != TEMPLATE) { - printf("st=%p %s %d\n", st, st ? st->name : "NULL", st ? st->type : 0); - hoc_execerror("String is not a template", 0); + hoc_execerror("String is not a HOC template", 0); } Object** po = hoc_temp_objvar(sl, list); (*po)->refcount++; @@ -326,10 +326,8 @@ static void* l_cons(Object*) { return NULL; } -static void l_destruct(void*) {} - void StringFunctions_reg() { - class2oc("StringFunctions", l_cons, l_destruct, l_members, NULL, l_obj_members, NULL); + class2oc("StringFunctions", l_cons, NULL, l_members, NULL, l_obj_members, NULL); } diff --git a/test/unit_tests/hoc_python/test_StringFunctions.py b/test/unit_tests/hoc_python/test_StringFunctions.py index 905441e26a..57860655ce 100644 --- a/test/unit_tests/hoc_python/test_StringFunctions.py +++ b/test/unit_tests/hoc_python/test_StringFunctions.py @@ -1,4 +1,5 @@ from neuron import h +from neuron.expect_hocerr import expect_err sf = h.StringFunctions() @@ -89,11 +90,21 @@ def test_alias(): v = h.Vector() sf.alias(v, "xv", h.xvalue) assert v.xv == h.xvalue + h("""double x[2]""") + sf.alias(v, "xy", h._ref_x[0]) + v.xy = 3.14 + assert h.x[0] == 3.14 def test_alias_list(): - h.load_file("stdrun.hoc") v = h.Vector() + expect_err("sf.alias_list(v)") # no hoc String template + # after an expect error, must manually delete + del v + locals() + + v = h.Vector() + h.load_file("stdrun.hoc") assert len(sf.alias_list(v)) == 0 sf.alias(v, "xv1", h.xvalue) # Add alias assert len(sf.alias_list(v)) == 1 @@ -106,13 +117,46 @@ def test_alias_list(): def test_references(): - # This function print the number of references - pass + # This function prints the number of references + sf.references(None) + v = h.Vector() + + # different ways a hoc object can be referenced + h.hoc_obj_[0] = v + l = h.List() + l.append(v) + h( + """ +objref o +begintemplate Foo +public o, o2 +objref o, o2[2] +proc init() { + o = $o1 + o2[0] = o +} +endtemplate Foo + """ + ) + foo = h.Foo(v) + h.o = v + box = h.VBox() + box.ref(v) + + sf.references(foo.o) + box.ref(None) # without this, then assert error when box is destroyed def test_is_point_process(): - pass + sf = h.StringFunctions() # no destructor (removed a non-coverable line) + s = h.Section() + assert not sf.is_artificial(h.List()) + assert sf.is_point_process(h.IClamp(s(0.5))) + assert sf.is_point_process(h.NetStim()) def test_is_artificial(): - pass + s = h.Section() + assert not sf.is_artificial(h.List()) + assert not sf.is_artificial(h.IClamp(s(0.5))) + assert sf.is_artificial(h.NetStim())