def test_graph_named_union(): g = Graph(a, b) g.union(nested=Graph(c)) assert _node_def_equals(g.a, g, a, ("a",), (), {}) assert _node_def_equals(g.b, g, b, ("b",), (), {}) assert _node_def_equals(g.nested.c, g, c, ("nested", "c"), (), {})
def test_graph_set_target_params(): nest_graph = Graph(a, b, sub=Graph(c, sub=Graph(d))) nest_graph.pipe(nest_graph.a, nest_graph.b) nest_graph.join([nest_graph.a, nest_graph.b], nest_graph.sub.c) nest_graph.pipe(nest_graph.sub.c, nest_graph.sub.sub.d) g = nest_graph(a=params(5, y=10), b=params(fudge=10), sub=group(c=params(fudge=20))) assert g.sub.sub.d.val == (133, "pong") assert g.sub.c.val == params(130, 1, 2, ping="pong") assert g.b.val == 60 assert g.a.val == 50 g.set(a=params(6, 10), b=params(fudge=20)) assert g.sub.sub.d.val == (163, "pong") assert g.sub.c.val == params(160, 1, 2, ping="pong") assert g.b.val == 80 assert g.a.val == 60 g.sub.set(fudge=30, sub=group(d=params(ping_override="ping"))) assert g.sub.sub.d.val == (173, "ping") assert g.sub.c.val == params(170, 1, 2, ping="pong") assert g.b.val == 80 assert g.a.val == 60
def test_doubly_nested_subgraph(): g1 = Graph(a) g2 = Graph(nested=g1) g = Graph(nested=g2) assert _node_def_equals(g.nested.nested.a, g, a, ("nested", "nested", "a"), (), {})
def test_graph_named_union(): g = Graph(a, b) g.union(nested=Graph(c)) assert _node_def_equals(g.a, g, a, ("a", ), (), {}) assert _node_def_equals(g.b, g, b, ("b", ), (), {}) assert _node_def_equals(g.nested.c, g, c, ("nested", "c"), (), {})
def test_eval_node(): g = Graph(node(lambda: 5, name="thunked_const"))() # Direct evaluation assert g.thunked_const() == 5 # Cached evaluation assert g.thunked_const.val == 5
def test_set_subgraph(): g = Graph() g.nested = Graph(a) g.nested.nested = Graph(b) assert _node_def_equals(g.nested.a, g, a, ("nested", "a"), (), {}) assert _node_def_equals(g.nested.nested.b, g, b, ("nested", "nested", "b"), (), {})
def test_override_node(): g = Graph(a) assert _node_def_equals(g.a, g, a, ("a",), (), {}) g.a = partial(b, 1, 2, named_arg="moof") assert _node_def_equals(g.a, g, b, ("a",), (1, 2), {"named_arg": "moof"})
def test_merged_graph(): g1 = Graph(a) g2 = Graph(b) g = Graph(g1, g2) assert _node_def_equals(g.a, g, a, ("a", ), (), {}) assert _node_def_equals(g.b, g, b, ("b", ), (), {})
def test_override_node(): g = Graph(a) assert _node_def_equals(g.a, g, a, ("a", ), (), {}) g.a = partial(b, 1, 2, named_arg="moof") assert _node_def_equals(g.a, g, b, ("a", ), (1, 2), {"named_arg": "moof"})
def test_graph_join(): g = Graph(a, b, c) g.join([g.a, g.b], g.c.target_param) assert g._downstream == {("a",): [EdgeDef(("c",), "target_param")], ("b",): [EdgeDef(("c",), "target_param")], ("c",): []} assert g._upstream == {("c",): [EdgeDef(("a",), "target_param"), EdgeDef(("b",), "target_param")], ("b",): [], ("a",): []}
def test_graph_fan(): g = Graph(a, b, c) g.fan(g.a, [g.b, g.c.target_param]) assert g._downstream == {("a",): [EdgeDef(("b",), None), EdgeDef(("c",), "target_param")], ("b",): [], ("c",): []} assert g._upstream == {("c",): [EdgeDef(("a",), "target_param")], ("b",): [EdgeDef(("a",), None)], ("a",): []}
def test_eval_node_override_params(): g = Graph(partial(a, 5, y=10))() # Assert that cached evaluation returns results with the default parameters assert g.a.val == 50 # Direct evaluation assert g.a(5) == 25 assert g.a(5, 6) == 30 assert g.a(5, y=7) == 35 # Assert that cached evaluation remains unchanged. assert g.a.val == 50
def test_set_node(): g = Graph() # Simple assignment g.a = a assert _node_def_equals(g.a, g, a, ("a", ), (), {}) # Specific name g.moof = a assert _node_def_equals(g.moof, g, a, ("moof", ), (), {}) # Parametrized assignment g.b = partial(b, 1, 2, named_arg="moof") assert _node_def_equals(g.b, g, b, ("b", ), (1, 2), {"named_arg": "moof"})
def test_set_node(): g = Graph() # Simple assignment g.a = a assert _node_def_equals(g.a, g, a, ("a",), (), {}) # Specific name g.moof = a assert _node_def_equals(g.moof, g, a, ("moof",), (), {}) # Parametrized assignment g.b = partial(b, 1, 2, named_arg="moof") assert _node_def_equals(g.b, g, b, ("b",), (1, 2), {"named_arg": "moof"})
def test_anon_callable_fail(): class _Cls(object): def __call__(self): pass with raises(ValueError): Graph(_Cls())
def test_graph_pipe(): g = Graph(a, b, c) g.nested = Graph(d) g.pipe(g.a, g.b, g.c.target_param, g.nested.d) assert g._downstream == {("a",): [EdgeDef(("b",), None)], ("b",): [EdgeDef(("c",), "target_param")], ("c",): [EdgeDef(("nested", "d"), None)], ("nested", "d"): []} assert g._upstream == {("nested", "d"): [EdgeDef(("c",), None)], ("c",): [EdgeDef(("b",), "target_param")], ("b",): [EdgeDef(("a",), None)], ("a",): []}
def test_graph_fan(): g = Graph(a, b, c) g.fan(g.a, [g.b, g.c.target_param]) assert g._downstream == { ("a", ): [EdgeDef(("b", ), None), EdgeDef(("c", ), "target_param")], ("b", ): [], ("c", ): [] } assert g._upstream == { ("c", ): [EdgeDef(("a", ), "target_param")], ("b", ): [EdgeDef(("a", ), None)], ("a", ): [] }
def test_graph_join(): g = Graph(a, b, c) g.join([g.a, g.b], g.c.target_param) assert g._downstream == { ("a", ): [EdgeDef(("c", ), "target_param")], ("b", ): [EdgeDef(("c", ), "target_param")], ("c", ): [] } assert g._upstream == { ("c", ): [EdgeDef(("a", ), "target_param"), EdgeDef(("b", ), "target_param")], ("b", ): [], ("a", ): [] }
def test_node_update_params(): g = Graph(partial(a, 5, y=10))() # Assert that cached evaluation returns results with the default parameters assert g.a.val == 50 # Update `y` g.a.update(y=7) assert g.a.val == 35
def test_node_method(): class _Cls(object): def moof(self): pass inst = _Cls() g = Graph(inst.moof) assert _node_def_equals(g.moof, g, inst.moof, ("moof", ), (), {})
def test_node_callable(): class _Cls(object): def __call__(self): pass inst = _Cls() g = Graph(node(inst, "moof")) assert _node_def_equals(g.moof, g, inst, ("moof", ), (), {})
def test_eval_node_memoized(): def gener(): counter = 0 while True: yield counter counter += 1 g_inst = gener() g = Graph(node(lambda: g_inst.next(), name="accumulator"))() # Assert that direct eval does not cache results assert g.accumulator() == 0 assert g.accumulator() == 1 # Assert that the function is only ever called once and then memoized assert g.accumulator.val == 2 assert g.accumulator.val == 2 assert g.accumulator.val == 2
def test_graph_union(): g1 = Graph(a) g1.nested = Graph(b) g1.pipe(g1.a, g1.nested.b) g = Graph(c) g.union(g1) assert _node_def_equals(g.a, g, a, ("a", ), (), {}) assert _node_def_equals(g.nested.b, g, b, ("nested", "b"), (), {}) assert _node_def_equals(g.c, g, c, ("c", ), (), {}) assert g._downstream == { ('a', ): [EdgeDef(('nested', 'b'), None)], ('nested', 'b'): [], ('c', ): [] } assert g._upstream == { ('a', ): [], ('nested', 'b'): [EdgeDef(('a', ), None)], ('c', ): [] }
def test_eval_class_method(): class _Cls(object): def __init__(self, y): self._y = y def plop(self, x): return x * self._y inst = _Cls(10) g = Graph(inst.plop)(plop=params(5)) assert g.plop.val == 50
def test_eval_class_callable(): class _Cls(object): def __init__(self, y): self._y = y def __call__(self, x): return x * self._y inst = _Cls(10) g = Graph(node(inst, "plop"))(plop=params(5)) assert g.plop.val == 50
def test_graph_union(): g1 = Graph(a) g1.nested = Graph(b) g1.pipe(g1.a, g1.nested.b) g = Graph(c) g.union(g1) assert _node_def_equals(g.a, g, a, ("a",), (), {}) assert _node_def_equals(g.nested.b, g, b, ("nested", "b"), (), {}) assert _node_def_equals(g.c, g, c, ("c",), (), {}) assert g._downstream == {('a',): [EdgeDef(('nested', 'b'), None)], ('nested', 'b'): [], ('c',): []} assert g._upstream == {('a',): [], ('nested', 'b'): [EdgeDef(('a',), None)], ('c',): []}
def test_graph_pipe(): g = Graph(a, b, c) g.nested = Graph(d) g.pipe(g.a, g.b, g.c.target_param, g.nested.d) assert g._downstream == { ("a", ): [EdgeDef(("b", ), None)], ("b", ): [EdgeDef(("c", ), "target_param")], ("c", ): [EdgeDef(("nested", "d"), None)], ("nested", "d"): [] } assert g._upstream == { ("nested", "d"): [EdgeDef(("c", ), None)], ("c", ): [EdgeDef(("b", ), "target_param")], ("b", ): [EdgeDef(("a", ), None)], ("a", ): [] }
def test_merged_graph_shared_root(): g_base = Graph(a) g1 = Graph(base=g_base, sub_b=Graph(b)) g1.pipe(g1.base.a, g1.sub_b.b) g2 = Graph(base=g_base, sub_c=Graph(c)) g2.pipe(g2.base.a, g2.sub_c.c) comb = Graph(g1, g2) assert _node_def_equals(comb.base.a, comb, a, ("base", "a"), (), {}) assert _node_def_equals(comb.sub_b.b, comb, b, ("sub_b", "b"), (), {}) assert _node_def_equals(comb.sub_c.c, comb, c, ("sub_c", "c"), (), {}) assert comb._downstream == {('base', 'a'): [EdgeDef(node=('sub_b', 'b'), param=None), EdgeDef(node=('sub_c', 'c'), param=None)], ('sub_b', 'b'): [], ('sub_c', 'c'): []} assert comb._upstream == {('base', 'a'): [], ('sub_b', 'b'): [EdgeDef(node=('base', 'a'), param=None)], ('sub_c', 'c'): [EdgeDef(node=('base', 'a'), param=None)]}
def test_fail_add_graph_into_itself(): g = Graph() with raises(ValueError): g.union(g)
def test_create_graph_node_params(): g = Graph(partial(a, 1, 2, named_arg="moof")) assert _node_def_equals(g.a, g, a, ("a", ), (1, 2), {"named_arg": "moof"})
def test_create_named_node(): g = Graph(node(a, "ping")) assert _node_def_equals(g.ping, g, a, ("ping", ), (), {})
def test_create_graph(): g = Graph(a) assert _node_def_equals(g.a, g, a, ("a", ), (), {})
def test_anon_lambda_fail(): with raises(ValueError): Graph(lambda: 5)
def test_node_set_params(): g = Graph(partial(a, 5, y=10))() assert g.a.val == 50 g.a.set(10, y=10) assert g.a.val == 100
def test_merged_graph_shared_root(): g_base = Graph(a) g1 = Graph(base=g_base, sub_b=Graph(b)) g1.pipe(g1.base.a, g1.sub_b.b) g2 = Graph(base=g_base, sub_c=Graph(c)) g2.pipe(g2.base.a, g2.sub_c.c) comb = Graph(g1, g2) assert _node_def_equals(comb.base.a, comb, a, ("base", "a"), (), {}) assert _node_def_equals(comb.sub_b.b, comb, b, ("sub_b", "b"), (), {}) assert _node_def_equals(comb.sub_c.c, comb, c, ("sub_c", "c"), (), {}) assert comb._downstream == { ('base', 'a'): [ EdgeDef(node=('sub_b', 'b'), param=None), EdgeDef(node=('sub_c', 'c'), param=None) ], ('sub_b', 'b'): [], ('sub_c', 'c'): [] } assert comb._upstream == { ('base', 'a'): [], ('sub_b', 'b'): [EdgeDef(node=('base', 'a'), param=None)], ('sub_c', 'c'): [EdgeDef(node=('base', 'a'), param=None)] }