Browse Source

Added tests for State

Andrei Bondarenko 2 years ago
parent
commit
b961e91d9b

+ 0 - 0
state/test/__init__.py


+ 2 - 0
state/test/conftest.py

@@ -0,0 +1,2 @@
+import pytest
+from .fixtures.state import state

+ 0 - 0
state/test/fixtures/__init__.py


+ 19 - 0
state/test/fixtures/state.py

@@ -0,0 +1,19 @@
+import pytest
+from state.pystate import PyState
+# from state.rdfstate import RDFState
+# from state.neo4jstate import Neo4jState
+
+
+@pytest.fixture(params=[
+    (PyState,),
+    # (RDFState, "http://example.org/#"),
+    # (Neo4jState,)
+])
+def state(request):
+    if len(request.param) > 1:
+        state = request.param[0](*request.param[1:])
+    else:
+        state = request.param[0]()
+    yield state
+    # if isinstance(state, Neo4jState):
+    #     state.close(clear=True)

+ 41 - 0
state/test/test_create_dict.py

@@ -0,0 +1,41 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_create_dict_simple(state):
+    id1 = state.create_node()
+    id2 = state.create_node()
+    assert id1 is not None
+    assert id2 is not None
+
+    n = state.create_dict(id1, "abc", id2)
+    assert n is None
+
+    v = state.read_dict(id1, "abc")
+    assert v == id2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_dict_no_source(state):
+    id1 = 100000
+    id2 = state.create_node()
+    assert id2 is not None
+
+    n = state.create_dict(id1, "abc", id2)
+    assert n is None
+
+    v = state.read_dict(id1, "abc")
+    assert v is None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_dict_no_target(state):
+    id2 = 100000
+    id1 = state.create_node()
+    assert id1 is not None
+
+    n = state.create_dict(id1, "abc", id2)
+    assert n is None
+
+    v = state.read_dict(id1, "abc")
+    assert v is None

+ 144 - 0
state/test/test_create_edge.py

@@ -0,0 +1,144 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_invalid_source(state):
+    a = -1
+    b = state.create_node()
+    assert b is not None
+
+    e = state.create_edge(a, b)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_invalid_target(state):
+    b = -1
+    a = state.create_node()
+    assert a is not None
+
+    e = state.create_edge(a, b)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_invalid_both(state):
+    a = -1
+    b = -1
+    e = state.create_edge(a, b)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_node_to_node(state):
+    a = state.create_node()
+    assert a is not None
+    b = state.create_node()
+    assert b is not None
+
+    edge = state.create_edge(a, b)
+    assert edge is not None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_multiple(state):
+    a = state.create_node()
+    assert a is not None
+    b = state.create_node()
+    assert b is not None
+
+    edge1 = state.create_edge(a, b)
+    assert edge1 is not None
+
+    edge2 = state.create_edge(a, b)
+    assert edge2 is not None
+
+    assert edge1 != edge2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_many(state):
+    v = set()
+    for i in range(1000):
+        a = state.create_node()
+        assert a is not None
+        b = state.create_node()
+        assert b is not None
+
+        edge = state.create_edge(a, b)
+        assert edge is not None
+
+        v.add(edge)
+    assert len(v) == 1000
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_edge_to_node(state):
+    a = state.create_node()
+    assert a is not None
+    b = state.create_node()
+    assert b is not None
+
+    edge1 = state.create_edge(a, b)
+    assert edge1 is not None
+
+    edge2 = state.create_edge(edge1, b)
+    assert edge2 is not None
+
+    assert edge1 != edge2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_node_to_edge(state):
+    a = state.create_node()
+    assert a is not None
+    b = state.create_node()
+    assert b is not None
+
+    edge1 = state.create_edge(a, b)
+    assert edge1 is not None
+
+    edge2 = state.create_edge(a, edge1)
+    assert edge2 is not None
+
+    assert edge1 != edge2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_edge_to_edge(state):
+    a = state.create_node()
+    assert a is not None
+    b = state.create_node()
+    assert b is not None
+
+    edge1 = state.create_edge(a, b)
+    assert edge1 is not None
+
+    edge2 = state.create_edge(a, b)
+    assert edge2 is not None
+
+    assert edge1 != edge2
+
+    edge3 = state.create_edge(edge1, edge2)
+    assert edge3 is not None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_loop_node(state):
+    a = state.create_node()
+    assert a is not None
+
+    edge = state.create_edge(a, a)
+    assert edge is not None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_edge_loop_edge(state):
+    a = state.create_node()
+    assert a is not None
+
+    edge1 = state.create_edge(a, a)
+    assert edge1 is not None
+
+    edge2 = state.create_edge(edge1, edge1)
+    assert edge2 is not None

+ 22 - 0
state/test/test_create_node.py

@@ -0,0 +1,22 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_create_node_different_id_simple(state):
+    id1 = state.create_node()
+    assert id1 is not None
+    id2 = state.create_node()
+    assert id2 is not None
+
+    assert id1 != id2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_node_different_id_long(state):
+    results = set()
+    for i in range(1000):
+        v = state.create_node()
+        assert v is not None
+        results.add(v)
+
+    assert len(results) == 1000

+ 167 - 0
state/test/test_create_nodevalue.py

@@ -0,0 +1,167 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_different_id_simple(state):
+    id1 = state.create_nodevalue(1)
+    id2 = state.create_nodevalue(1)
+
+    assert id1 is not None
+    assert id2 is not None
+    assert id1 != id2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_read(state):
+    id1 = state.create_nodevalue(1)
+    assert id1 is not None
+    val = state.read_value(id1)
+    assert val == 1
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_integer_ib_zero(state):
+    # Nicely within range
+    v = set()
+    size = 0
+    for i in range(-10, 10):
+        id1 = state.create_nodevalue(i)
+        assert id1 is not None
+        size += 1
+        v.add(id1)
+    assert len(v) == size
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_boolean(state):
+    id1 = state.create_nodevalue(True)
+    id2 = state.create_nodevalue(False)
+
+    assert id1 is not None
+    assert id2 is not None
+    assert id1 != id2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_boolean_same(state):
+    id1 = state.create_nodevalue(True)
+    id2 = state.create_nodevalue(True)
+
+    assert id1 is not None
+    assert id2 is not None
+    assert id1 != id2
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_float_keeps_type(state):
+    id1 = state.create_nodevalue(0.0)
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == float
+    assert v == 0.0
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_string_empty(state):
+    id1 = state.create_nodevalue("")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == ""
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_string_normal(state):
+    id1 = state.create_nodevalue("ABC")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == "ABC"
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_string_not_parsed(state):
+    id1 = state.create_nodevalue("1")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == "1"
+
+    id1 = state.create_nodevalue("1.0")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == "1.0"
+
+    id1 = state.create_nodevalue("-1.0")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == "-1.0"
+
+    id1 = state.create_nodevalue("True")
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert type(v) == str
+    assert v == "True"
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_junk(state):
+    class Unknown(object):
+        pass
+
+    n = state.create_nodevalue(Unknown())
+    assert n is None
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_type_type(state):
+    id1 = state.create_nodevalue({"type": "Type"})
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert v == {"type": "Type"}
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_integer_type(state):
+    id1 = state.create_nodevalue({"type": "Integer"})
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert v == {"type": "Integer"}
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_float_type(state):
+    id1 = state.create_nodevalue({"type": "Float"})
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert v == {"type": "Float"}
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_boolean_type(state):
+    id1 = state.create_nodevalue({"type": "Boolean"})
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert v == {"type": "Boolean"}
+
+
+@pytest.mark.usefixtures("state")
+def test_create_nodevalue_string_type(state):
+    id1 = state.create_nodevalue({"type": "String"})
+    assert id1 is not None
+
+    v = state.read_value(id1)
+    assert v == {"type": "String"}

+ 396 - 0
state/test/test_delete_edge.py

@@ -0,0 +1,396 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_no_exists(state):
+    e = state.delete_edge(1)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_node(state):
+    a = state.create_node()
+    assert a is not None
+
+    e = state.delete_edge(a)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_nodevalue(state):
+    a = state.create_nodevalue(1)
+    assert a is not None
+
+    e = state.delete_edge(a)
+    assert e is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_normal(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_edge(c)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_remove_recursive(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+
+    n = state.delete_edge(c)
+    assert n is None
+
+    l = state.read_value(a)
+    assert l == 1
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(c)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(d)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_remove_edge_recursive_deep(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_node()
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    f = state.create_node()
+    g = state.create_edge(f, e)
+    h = state.create_edge(b, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+    assert f is not None
+    assert g is not None
+    assert h is not None
+
+    n = state.delete_edge(d)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([h])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([h])
+
+    s, t = state.read_edge(d)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(e)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(g)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(h)
+    assert s == b
+    assert t == c
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_edge_remove_edge_recursive_steps(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_node()
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    f = state.create_node()
+    g = state.create_edge(f, e)
+    h = state.create_edge(b, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+    assert f is not None
+    assert g is not None
+    assert h is not None
+
+    n = state.delete_edge(g)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([d])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([h])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([d])
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([h, e])
+
+    s, t = state.read_edge(d)
+    assert s == a
+    assert t == b
+
+    l = state.read_outgoing(d)
+    assert l is not None
+    assert set(l) == set([e])
+
+    l = state.read_incoming(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(e)
+    assert s == d
+    assert t == c
+
+    l = state.read_outgoing(e)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(e)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(g)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(g)
+    assert l is None
+
+    l = state.read_incoming(g)
+    assert l is None
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(h)
+    assert s == b
+    assert t == c
+
+    n = state.delete_edge(e)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([d])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([h])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([d])
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([h])
+
+    s, t = state.read_edge(d)
+    assert s == a
+    assert t == b
+
+    l = state.read_outgoing(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(e)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(e)
+    assert l is None
+
+    l = state.read_incoming(e)
+    assert l is None
+
+    s, t = state.read_edge(g)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(g)
+    assert l is None
+
+    l = state.read_incoming(g)
+    assert l is None
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(h)
+    assert s == b
+    assert t == c
+
+    n = state.delete_edge(d)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([h])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([h])
+
+    s, t = state.read_edge(d)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(d)
+    assert l is None
+
+    l = state.read_incoming(d)
+    assert l is None
+
+    s, t = state.read_edge(e)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(e)
+    assert l is None
+
+    l = state.read_incoming(e)
+    assert l is None
+
+    s, t = state.read_edge(g)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(g)
+    assert l == None
+
+    l = state.read_incoming(g)
+    assert l == None
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(h)
+    assert s == b
+    assert t == c

+ 227 - 0
state/test/test_delete_node.py

@@ -0,0 +1,227 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_no_exists(state):
+    n = state.delete_node(-1)
+    assert n is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_no_value(state):
+    a = state.create_node()
+    assert a is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_value(state):
+    a = state.create_nodevalue(1)
+    assert a is not None
+
+    d = state.read_value(a)
+    assert d == 1
+
+    n = state.delete_node(a)
+    assert n is None
+
+    d = state.read_value(a)
+    assert d is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_node(c)
+    assert n is None
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_remove_edge_outgoing(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+    d = state.read_value(a)
+    assert d is None
+
+    s, t = state.read_edge(c)
+    assert s is None
+    assert t is None
+
+    d = state.read_outgoing(b)
+    assert d is not None
+    assert set(d) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_remove_edge_incoming(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(b, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+    d = state.read_value(a)
+    assert d is None
+
+    s, t = state.read_edge(c)
+    assert s is None
+    assert t is None
+
+    d = state.read_outgoing(b)
+    assert d is not None
+    assert set(d) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_remove_edge_both(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    e = state.create_node()
+    f = state.create_edge(e, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert e is not None
+    assert f is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+    d = state.read_value(a)
+    assert d is None
+
+    s, t = state.read_edge(c)
+    assert s is None
+    assert t is None
+
+    d = state.read_incoming(b)
+    assert d is not None
+    assert set(d) == set([])
+
+    s, t = state.read_edge(f)
+    assert s is None
+    assert t is None
+
+    d = state.read_outgoing(e)
+    assert d is not None
+    assert set(d) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_remove_edge_recursive(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+    d = state.read_value(a)
+    assert d is None
+
+    s, t = state.read_edge(c)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(d)
+    assert s is None
+    assert t is None
+
+    d = state.read_outgoing(b)
+    assert d is not None
+    assert set(d) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_delete_node_remove_edge_recursive_deep(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_node()
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    f = state.create_node()
+    g = state.create_edge(f, e)
+    h = state.create_edge(b, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+    assert f is not None
+    assert g is not None
+    assert h is not None
+
+    n = state.delete_node(a)
+    assert n is None
+
+    l = state.read_outgoing(a)
+    assert l is None
+
+    l = state.read_incoming(a)
+    assert l is None
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([h])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([h])
+
+    s, t = state.read_edge(d)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(e)
+    assert s is None
+    assert t is None
+
+    s, t = state.read_edge(g)
+    assert s is None
+    assert t is None
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+    s, t = state.read_edge(h)
+    assert s == b
+    assert t == c

+ 94 - 0
state/test/test_read_dict.py

@@ -0,0 +1,94 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_no_exists(state):
+    assert state.read_dict(-1, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_not_found_node(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict(a, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_not_found_nodevalue(state):
+    a = state.create_nodevalue(1)
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict(a, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_not_found_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict(c, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_no_primitive(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict(a, a) is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_simple(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_dict(a, "f")
+    assert l == b
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_nodevalue("k")
+    i = state.create_edge(a, g)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_dict(a, "f")
+    assert l == b
+
+    l = state.read_dict(a, "k")
+    assert l == g
+
+    assert state.read_dict(a, "l") is None

+ 94 - 0
state/test/test_read_dict_edge.py

@@ -0,0 +1,94 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_no_exists(state):
+    assert state.read_dict_edge(-1, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_not_found_node(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_edge(a, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_not_found_nodevalue(state):
+    a = state.create_nodevalue(1)
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_edge(a, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_not_found_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_edge(c, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_no_primitive(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_edge(a, a) is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_node_simple(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_dict_edge(a, "f")
+    assert l == d
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_edge_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_nodevalue("k")
+    i = state.create_edge(a, g)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_dict_edge(a, "f")
+    assert l == d
+
+    l = state.read_dict_edge(a, "k")
+    assert l == i
+
+    assert state.read_dict_edge(a, "l") is None

+ 51 - 0
state/test/test_read_dict_keys.py

@@ -0,0 +1,51 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_keys_no_exists(state):
+    assert state.read_dict_keys(100000) is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_keys_simple(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_dict_keys(a)
+    assert l is not None
+    assert set(l) == set([c])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_keys_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_nodevalue("k")
+    i = state.create_edge(a, g)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_dict_keys(a)
+    assert l is not None
+    assert set(l) == set([c, h])

+ 74 - 0
state/test/test_read_dict_node.py

@@ -0,0 +1,74 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_no_exists(state):
+    assert state.read_dict_node(-1, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_not_found_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_node(c, "abc") is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_no_primitive(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    assert state.read_dict_node(a, a) is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_node_simple(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_node()
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_dict_node(a, c)
+    assert l == b
+
+
+@pytest.mark.usefixtures("state")
+def test_read_dict_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_node()
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_node()
+    i = state.create_edge(a, g)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_dict_node(a, c)
+    assert l == b
+
+    l = state.read_dict_node(a, h)
+    assert l == g

+ 136 - 0
state/test/test_read_edge.py

@@ -0,0 +1,136 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_node(state):
+    b = state.create_node()
+    assert b is not None
+
+    s, t = state.read_edge(b)
+    assert s is None
+    assert t is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_no_exists(state):
+    s, t = state.read_edge(-1)
+    assert s is None
+    assert t is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_nodevalue(state):
+    b = state.create_nodevalue(1)
+    assert b is not None
+
+    s, t = state.read_edge(b)
+    assert s is None
+    assert t is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_normal(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_edge_to_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(c, d)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b
+
+    s, t = state.read_edge(d)
+    assert s == a
+    assert t == b
+
+    s, t = state.read_edge(e)
+    assert s == c
+    assert t == d
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_edge_to_node(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b
+
+    s, t = state.read_edge(d)
+    assert s == c
+    assert t == b
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_node_to_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(b, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b
+
+    s, t = state.read_edge(d)
+    assert s == b
+    assert t == c
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_node_to_nodevalue(state):
+    a = state.create_node()
+    b = state.create_nodevalue(1)
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b
+
+
+@pytest.mark.usefixtures("state")
+def test_read_edge_nodevalue_to_nodevalue(state):
+    a = state.create_nodevalue(1)
+    b = state.create_nodevalue(1)
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    s, t = state.read_edge(c)
+    assert s == a
+    assert t == b

+ 275 - 0
state/test/test_read_incoming.py

@@ -0,0 +1,275 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_node_none(state):
+    b = state.create_node()
+    assert b is not None
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_node_one(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([c])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_node_multi_others_unaffected(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    f = state.create_node()
+    assert f is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_edge_none(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_edge_one(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, a)
+    e = state.create_edge(a, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([e])
+
+    l = state.read_incoming(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(e)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_edge_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, c)
+    e = state.create_edge(b, c)
+    f = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+    assert f is not None
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([c])
+
+    l = state.read_incoming(c)
+    assert l is not None
+    assert set(l) == set([d, e, f])
+
+    l = state.read_incoming(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(e)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_nodevalue_none(state):
+    b = state.create_nodevalue(1)
+    assert b is not None
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_nodevalue_one(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(b, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([c])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_nodevalue_multi(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(b, a)
+    d = state.create_edge(b, a)
+    e = state.create_edge(b, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_nodevalue_multi_others_unaffected(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(b, a)
+    d = state.create_edge(b, a)
+    e = state.create_edge(b, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    f = state.create_nodevalue(1)
+    assert f is not None
+
+    l = state.read_incoming(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_incoming(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_incoming(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_node_deleted(state):
+    b = state.create_node()
+    assert b is not None
+
+    n = state.delete_node(b)
+    assert n is None
+
+    l = state.read_incoming(b)
+    assert l is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_nodevalue_deleted(state):
+    b = state.create_nodevalue(1)
+    assert b is not None
+
+    n = state.delete_node(b)
+    assert n is None
+
+    l = state.read_incoming(b)
+    assert l is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_incoming_edge_deleted(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_edge(c)
+    assert n is None
+
+    l = state.read_incoming(c)
+    assert l is None

+ 265 - 0
state/test/test_read_outgoing.py

@@ -0,0 +1,265 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_node_none(state):
+    b = state.create_node()
+    assert b is not None
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_node_one(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_node_multi_others_unaffected(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    f = state.create_node()
+    assert f is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_edge_none(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_edge_one(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, a)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([d])
+
+    l = state.read_outgoing(d)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_edge_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(c, a)
+    e = state.create_edge(c, b)
+    f = state.create_edge(c, d)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+    assert f is not None
+
+    l = state.read_outgoing(c)
+    assert l is not None
+    assert set(l) == set([d, e, f])
+
+    l = state.read_outgoing(d)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(e)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_nodevalue_none(state):
+    b = state.create_nodevalue(1)
+    assert b is not None
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_nodevalue_one(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_nodevalue_multi(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_nodevalue_multi_others_unaffected(state):
+    a = state.create_nodevalue(1)
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    d = state.create_edge(a, b)
+    e = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    f = state.create_nodevalue(1)
+    assert f is not None
+
+    l = state.read_outgoing(a)
+    assert l is not None
+    assert set(l) == set([c, d, e])
+
+    l = state.read_outgoing(b)
+    assert l is not None
+    assert set(l) == set([])
+
+    l = state.read_outgoing(f)
+    assert l is not None
+    assert set(l) == set([])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_node_deleted(state):
+    b = state.create_node()
+    assert b is not None
+
+    n = state.delete_node(b)
+    assert n is None
+
+    l = state.read_outgoing(b)
+    assert l is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_nodevalue_deleted(state):
+    b = state.create_nodevalue(1)
+    assert b is not None
+
+    n = state.delete_node(b)
+    assert n is None
+
+    l = state.read_outgoing(b)
+    assert l is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_outgoing_edge_deleted(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    n = state.delete_edge(c)
+    assert n is None
+
+    l = state.read_outgoing(c)
+    assert l is None

+ 165 - 0
state/test/test_read_reverse_dict.py

@@ -0,0 +1,165 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_no_exists(state):
+    l = state.read_reverse_dict(-1, "abc")
+    assert l is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_not_found_node(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    l = state.read_reverse_dict(a, "abc")
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_not_found_nodevalue(state):
+    a = state.create_nodevalue(1)
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    l = state.read_reverse_dict(a, "abc")
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_not_found_edge(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_edge(a, b)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    l = state.read_reverse_dict(c, "abc")
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_no_primitive(state):
+    a = state.create_node()
+    assert a is not None
+
+    # Passing data is not enforced, as the data will be interpreted if necessary
+    l = state.read_reverse_dict(a, a)
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_node_simple(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_reverse_dict(b, "f")
+    assert set(l) == set([a])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_no_match(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("g")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    l = state.read_reverse_dict(b, "f")
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_node_multi(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_nodevalue("k")
+    i = state.create_edge(a, g)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_reverse_dict(b, "f")
+    assert set(l) == set([a])
+
+    l = state.read_reverse_dict(g, "k")
+    assert set(l) == set([a])
+
+    l = state.read_reverse_dict(a, "l")
+    assert l == []
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_node_multi_ambiguous(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(b, a)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    g = state.create_node()
+    h = state.create_nodevalue("f")
+    i = state.create_edge(g, a)
+    j = state.create_edge(i, h)
+    assert g is not None
+    assert h is not None
+    assert i is not None
+    assert j is not None
+
+    l = state.read_reverse_dict(a, "f")
+    assert set(l) == set([b, g])
+
+
+@pytest.mark.usefixtures("state")
+def test_read_reverse_dict_node_uncertain(state):
+    a = state.create_node()
+    b = state.create_node()
+    c = state.create_nodevalue("f")
+    d = state.create_edge(a, b)
+    e = state.create_edge(d, c)
+    assert a is not None
+    assert b is not None
+    assert c is not None
+    assert d is not None
+    assert e is not None
+
+    h = state.create_nodevalue("g")
+    i = state.create_edge(d, h)
+    assert h is not None
+    assert i is not None
+
+    l = state.read_reverse_dict(b, "f")
+    assert set(l) == set([a])

+ 88 - 0
state/test/test_read_value.py

@@ -0,0 +1,88 @@
+import pytest
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_different_id_simple(state):
+    id1 = state.create_nodevalue(1)
+    id2 = state.create_nodevalue(2)
+    assert id1 is not None
+    assert id2 is not None
+
+    v1 = state.read_value(id1)
+    v2 = state.read_value(id2)
+    assert v1 == 1
+    assert v2 == 2
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_integer_ib_negative(state):
+    # Just within range
+    for i in range(-2 ** 63, -2 ** 63 + 10):
+        id1 = state.create_nodevalue(i)
+        assert id1 is not None
+
+        v = state.read_value(id1)
+        assert v == i
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_integer_ib_zero(state):
+    # Nicely within range
+    for i in range(-10, 10):
+        id1 = state.create_nodevalue(i)
+        assert id1 is not None
+
+        v = state.read_value(id1)
+        assert v == i
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_integer_ib_positive(state):
+    # Just within range
+    for i in range(2 ** 63 - 10, 2 ** 63):
+        id1 = state.create_nodevalue(i)
+        assert id1 is not None
+
+        v = state.read_value(id1)
+        assert v == i
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_boolean(state):
+    id1 = state.create_nodevalue(True)
+    id2 = state.create_nodevalue(False)
+    assert id1 is not None
+    assert id2 is not None
+
+    v1 = state.read_value(id1)
+    v2 = state.read_value(id2)
+    assert v1 == True
+    assert v2 == False
+
+
+@pytest.mark.usefixtures("state")
+def test_read_nodevalue_boolean_same(state):
+    id1 = state.create_nodevalue(True)
+    id2 = state.create_nodevalue(True)
+    assert id1 is not None
+    assert id2 is not None
+
+    v1 = state.read_value(id1)
+    v2 = state.read_value(id2)
+    assert v1 == True
+    assert v2 == True
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_no_exist(state):
+    v1 = state.read_value(100000)
+    assert v1 is None
+
+
+@pytest.mark.usefixtures("state")
+def test_read_value_no_value(state):
+    id1 = state.create_node()
+    assert id1 is not None
+
+    v1 = state.read_value(id1)
+    assert v1 is None