Ejemplo n.º 1
0
def test_set_positions_with_gap_in_sequence(cur, nd1, nd2, nd3):
    set_position(cur, nd1, 0, auto_position=False)
    set_position(cur, nd2, 1, auto_position=False)
    set_position(cur, nd3, 3, auto_position=False)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 1
    assert get_node(cur, nd3.id).position == 3
Ejemplo n.º 2
0
def test_set_position_autoposition(cur, root, nd1, nd2, nd3):
    set_position(cur, nd1, 0, auto_position=True)
    set_position(cur, nd2, 2, auto_position=True)
    set_position(cur, nd3.id, -1, auto_position=True)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 2
    assert get_node(cur, nd3.id).position == nd3.position + 1
Ejemplo n.º 3
0
def test_set_position_autoposition(cur, root, nd1, nd2, nd3):
    set_position(cur, nd1, 0, auto_position=True)
    set_position(cur, nd2, 2, auto_position=True)
    set_position(cur, nd3.id, -1, auto_position=True)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 2
    assert get_node(cur, nd3.id).position == nd3.position + 1
Ejemplo n.º 4
0
def test_set_positions_with_gap_in_sequence(cur, nd1, nd2, nd3):
    set_position(cur, nd1, 0, auto_position=False)
    set_position(cur, nd2, 1, auto_position=False)
    set_position(cur, nd3, 3, auto_position=False)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 1
    assert get_node(cur, nd3.id).position == 3
Ejemplo n.º 5
0
def get_inherited_properties(cur, node):
    """
    Get the entire inherited property dictionary.

    To calculate this, the trees path from root node till ``node`` will
    be traversed. For each level, the property dictionary will be merged
    into the previous one. This is a simple merge, only the first level
    of keys will be combined.

    :param node:
    :type node: Node or uuid4
    :rtype: dict
    """
    ret = {}
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    ancestors = list(get_ancestors(cur, id))

    for ancestor in ancestors[::-1]:  # Go top down
        ret.update(ancestor.properties)

    ret.update(node.properties)

    return ret
Ejemplo n.º 6
0
def get_inherited_properties(cur, node):
    """
    Get the entire inherited property dictionary.

    To calculate this, the trees path from root node till ``node`` will
    be traversed. For each level, the property dictionary will be merged
    into the previous one. This is a simple merge, only the first level
    of keys will be combined.

    :param node:
    :type node: Node or uuid4
    :rtype: dict
    """
    ret = {}
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    ancestors = list(get_ancestors(cur, id))

    for ancestor in ancestors[::-1]:  # Go top down
        ret.update(ancestor.properties)

    ret.update(node.properties)

    return ret
Ejemplo n.º 7
0
def set_properties(cur, node, new_properties):
    """
    Set the property dictionary to ``new_properties``.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param new_properties: dict
    """
    if not isinstance(new_properties, dict):
        raise TypeError('Only dictionaries are supported.')

    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    sql = """
        UPDATE
          nodes
        SET
          properties=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (json.dumps(new_properties), str(node)))

    kwargs = node.to_dict()
    kwargs['properties'] = new_properties
    return NodeData(**kwargs)
Ejemplo n.º 8
0
def get_recursive_properties(cur, node):
    """
    Get the entire inherited and recursively merged property dictionary.

    To calculate this, the trees path from root node till ``node`` will
    be traversed. For each level, the property dictionary will be merged
    into the previous one. This is a recursive merge, so all dictionary
    levels will be combined.

    :param node:
    :type node: Node or uuid4
    :rtype: dict
    """
    ret = {}
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    ancestors = list(get_ancestors(cur, id))

    for ancestor in ancestors[::-1]:  # Go top down
        recursive_dict_merge(ret, ancestor.properties, create_copy=False)

    recursive_dict_merge(ret, node.properties, create_copy=False)

    return ret
Ejemplo n.º 9
0
def get_recursive_properties(cur, node):
    """
    Get the entire inherited and recursively merged property dictionary.

    To calculate this, the trees path from root node till ``node`` will
    be traversed. For each level, the property dictionary will be merged
    into the previous one. This is a recursive merge, so all dictionary
    levels will be combined.

    :param node:
    :type node: Node or uuid4
    :rtype: dict
    """
    ret = {}
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    ancestors = list(get_ancestors(cur, id))

    for ancestor in ancestors[::-1]:  # Go top down
        recursive_dict_merge(ret, ancestor.properties, create_copy=False)

    recursive_dict_merge(ret, node.properties, create_copy=False)

    return ret
Ejemplo n.º 10
0
def set_properties(cur, node, new_properties):
    """
    Set the property dictionary to ``new_properties``.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param new_properties: dict
    """
    if not isinstance(new_properties, dict):
        raise TypeError('Only dictionaries are supported.')

    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    sql = """
        UPDATE
          nodes
        SET
          properties=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (json.dumps(new_properties), str(node)))

    kwargs = node.to_dict()
    kwargs['properties'] = new_properties
    return NodeData(**kwargs)
Ejemplo n.º 11
0
def get_or_create_nd(cur, parent, properties, *args, **kwargs):
    xtype = properties.get('type')
    node_id = node_ids.get(xtype, None)
    if node_id is None:
        node = insert_node(cur, parent, properties=properties, *args, **kwargs)
        node_ids[xtype] = node.id
        return node
    return get_node(cur, node_id)
Ejemplo n.º 12
0
def get_or_create_nd(cur, parent, properties, *args, **kwargs):
    xtype = properties.get('type')
    node_id = node_ids.get(xtype, None)
    if node_id is None:
        node = insert_node(cur, parent, properties=properties, *args, **kwargs)
        node_ids[xtype] = node.id
        return node
    return get_node(cur, node_id)
Ejemplo n.º 13
0
def test_delete_node(cur, nd1, nd2_1, nd2_1_1, nd2_leaf):
    """
        Tree layout before delete:
        /
          - nd1
            - nd2-1
              - nd2-1-1
                - nd2-leaf
          - nd2
          - nd3

        Expected tree layout after move:
        /
          - nd1
            - nd2-1
          - nd2
          - nd3
    """
    delete_node(cur, nd2_1_1, auto_position=False)

    # Deleted node doesn't exist anymore
    with pytest.raises(exceptions.NodeNotFound):
        get_node(cur, nd2_1_1.id)

    # nd2-1 has no children and no descendants
    assert set(get_child_ids(cur, nd2_1)) == set()
    assert set(get_child_ids(cur, nd2_1_1)) == set()
    assert set(get_descendant_ids(cur, nd2_1)) == set()

    # nd1 just contains nd2-1
    assert set(get_child_ids(cur, nd1)) == {nd2_1.id}
    assert set(get_descendant_ids(cur, nd1)) == {nd2_1.id}

    # Ancestor and descendant sets of nd2-1-1 and nd2-leaf are empty
    # (or raise error in the future because they don't exist anymore)
    assert set(get_ancestor_ids(cur, nd2_1_1)) == set()
    assert set(get_ancestor_ids(cur, nd2_leaf)) == set()
    assert set(get_descendant_ids(cur, nd2_1_1)) == set()
    assert set(get_descendant_ids(cur, nd2_leaf)) == set()
Ejemplo n.º 14
0
def test_delete_node(cur, nd1, nd2_1, nd2_1_1, nd2_leaf):
    """
        Tree layout before delete:
        /
          - nd1
            - nd2-1
              - nd2-1-1
                - nd2-leaf
          - nd2
          - nd3

        Expected tree layout after move:
        /
          - nd1
            - nd2-1
          - nd2
          - nd3
    """
    delete_node(cur, nd2_1_1, auto_position=False)

    # Deleted node doesn't exist anymore
    with pytest.raises(ValueError):
        get_node(cur, nd2_1_1.id)

    # nd2-1 has no children and no descendants
    assert set(get_child_ids(cur, nd2_1)) == set()
    assert set(get_child_ids(cur, nd2_1_1)) == set()
    assert set(get_descendant_ids(cur, nd2_1)) == set()

    # nd1 just contains nd2-1
    assert set(get_child_ids(cur, nd1)) == {nd2_1.id}
    assert set(get_descendant_ids(cur, nd1)) == {nd2_1.id}

    # Ancestor and descendant sets of nd2-1-1 and nd2-leaf are empty
    # (or raise error in the future because they don't exist anymore)
    assert set(get_ancestor_ids(cur, nd2_1_1)) == set()
    assert set(get_ancestor_ids(cur, nd2_leaf)) == set()
    assert set(get_descendant_ids(cur, nd2_1_1)) == set()
    assert set(get_descendant_ids(cur, nd2_leaf)) == set()
Ejemplo n.º 15
0
def change_parent(cur, node, new_parent, position=None, auto_position=True):
    """
    Move node and its subtree from its current to another parent node.
    Return updated ``Node`` object with new parent set. Raise
    ``ValueError`` if ``new_parent`` is inside ``node`` s subtree.

    :param node:
    :type node: Node or int
    :param new_parent: Reference to the new parent node
    :type new_parent: Node or int
    :param int position: Position in between siblings. If 0, the node
                         will be inserted at the beginning of the
                         parents children. If -1, the node will be
                         inserted the the end of the parents children.
                         If `auto_position` is disabled, this is just a
                         value.
    :param bool auto_position: See :ref:`coreapi-positioning`.
    """
    new_parent_id = int(new_parent)
    if new_parent_id in get_descendant_ids(cur, node):
        raise ValueError('Cannot move node into its own subtree.')

    # Can't run set_position() here because the node hasn't been moved yet,
    # must do it manually
    if auto_position:
        if type(position) == int and position >= 0:
            ensure_free_position(cur, new_parent_id, position)
        else:
            position = find_highest_position(cur, new_parent_id) + 1

    sql = """
        UPDATE
          nodes
        SET
          parent=%s,
          position=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (new_parent_id, position, int(node)))

    if type(node) == int:
        node = get_node(cur, node)

    kwargs = node.to_dict()
    kwargs['parent'] = new_parent_id
    kwargs['position'] = position
    return NodeData(**kwargs)
Ejemplo n.º 16
0
def change_parent(cur, node, new_parent, position=None, auto_position=True):
    """
    Move node and its subtree from its current to another parent node.
    Return updated ``Node`` object with new parent set. Raise
    ``ValueError`` if ``new_parent`` is inside ``node`` s subtree.

    :param node:
    :type node: Node or int
    :param new_parent: Reference to the new parent node
    :type new_parent: Node or int
    :param int position: Position in between siblings. If 0, the node
                         will be inserted at the beginning of the
                         parents children. If -1, the node will be
                         inserted the the end of the parents children.
                         If `auto_position` is disabled, this is just a
                         value.
    :param bool auto_position: See :ref:`core-positioning`.
    """
    new_parent_id = int(new_parent)
    if new_parent_id in get_descendant_ids(cur, node):
        raise ValueError('Cannot move node into its own subtree.')

    # Can't run set_position() here because the node hasn't been moved yet,
    # must do it manually
    if auto_position:
        if type(position) == int and position >= 0:
            ensure_free_position(cur, new_parent_id, position)
        else:
            position = find_highest_position(cur, new_parent_id) + 1

    sql = """
        UPDATE
          nodes
        SET
          parent=%s,
          position=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (new_parent_id, position, int(node)))

    if type(node) == int:
        node = get_node(cur, node)

    kwargs = node.to_dict()
    kwargs['parent'] = new_parent_id
    kwargs['position'] = position
    return NodeData(**kwargs)
Ejemplo n.º 17
0
def update_properties(cur, node, new_properties):
    """
    Update existing property dictionary with another dictionary.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param new_properties: dict
    """
    if not isinstance(new_properties, dict):
        raise TypeError('Only dictionaries are supported.')

    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    properties = node.properties.copy()
    properties.update(new_properties)
    return set_properties(cur, node, properties)
Ejemplo n.º 18
0
def update_properties(cur, node, new_properties):
    """
    Update existing property dictionary with another dictionary.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param new_properties: dict
    """
    if not isinstance(new_properties, dict):
        raise TypeError('Only dictionaries are supported.')

    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    properties = node.properties.copy()
    properties.update(new_properties)
    return set_properties(cur, node, properties)
Ejemplo n.º 19
0
def update_properties(cur, node, new_properties):
    """
    Update existing property dictionary with another dictionary.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or int
    :param new_properties: dict
    """
    if type(new_properties) != dict:
        raise TypeError('Only dictionaries are supported.')

    id = int(node)
    if type(node) == int:
        node = get_node(cur, id)

    properties = node.properties.copy()
    properties.update(new_properties)
    return set_properties(cur, node, properties)
Ejemplo n.º 20
0
def set_property_value(cur, node, key, value):
    """
    Set the value for a single property key.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param key: str
    :param value: object
    """
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    properties = node.properties.copy()
    properties[key] = value
    set_properties(cur, node, properties)

    kwargs = node.to_dict()
    kwargs['properties'] = properties
    return NodeData(**kwargs)
Ejemplo n.º 21
0
def set_property_value(cur, node, key, value):
    """
    Set the value for a single property key.
    Return ``NodeData`` object with updated properties.

    :param node:
    :type node: Node or uuid4
    :param key: str
    :param value: object
    """
    id = str(node)
    if isinstance(node, str):
        node = get_node(cur, id)

    properties = node.properties.copy()
    properties[key] = value
    set_properties(cur, node, properties)

    kwargs = node.to_dict()
    kwargs['properties'] = properties
    return NodeData(**kwargs)
Ejemplo n.º 22
0
def delete_node(cur, node, auto_position=True):
    """
    Delete node and its subtree.

    :param node:
    :type node: Node or int
    :param bool auto_position: See :ref:`coreapi-positioning`
    """
    id = int(node)

    # Get Node object if integer (ID) was passed
    if auto_position and type(node) != NodeData:
        node = get_node(cur, id)

    sql = """
        DELETE FROM
          nodes
        WHERE
          id=%s;
    """
    cur.execute(sql, (id, ))

    if auto_position:
        shift_positions(cur, node.parent, node.position, -1)
Ejemplo n.º 23
0
def set_position(cur, node, position, auto_position=True):
    """
    Set ``position`` for ``node``.

    :param node:
    :type node: Node or int
    :param int position: Position in between siblings. If 0, the node
                         will be inserted at the beginning of the
                         parents children. If -1, the node will be
                         inserted the the end of the parents children.
                         If `auto_position` is disabled, this is just a
                         value.
    :param bool auto_position: See :ref:`core-positioning`
    """
    if auto_position:
        id = int(node)
        if type(node) == int:
            node = get_node(cur, id)

        if type(position) == int and position >= 0:
            ensure_free_position(cur, node.parent, position)
        else:
            position = find_highest_position(cur, node.parent) + 1
    else:
        id = int(node)

    sql = """
        UPDATE
          nodes
        SET
          position=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (position, int(node)))
    return position
Ejemplo n.º 24
0
def set_position(cur, node, position, auto_position=True):
    """
    Set ``position`` for ``node``.

    :param node:
    :type node: Node or int
    :param int position: Position in between siblings. If 0, the node
                         will be inserted at the beginning of the
                         parents children. If -1, the node will be
                         inserted the the end of the parents children.
                         If `auto_position` is disabled, this is just a
                         value.
    :param bool auto_position: See :ref:`coreapi-positioning`
    """
    if auto_position:
        id = int(node)
        if type(node) == int:
            node = get_node(cur, id)

        if type(position) == int and position >= 0:
            ensure_free_position(cur, node.parent, position)
        else:
            position = find_highest_position(cur, node.parent) + 1
    else:
        id = int(node)

    sql = """
        UPDATE
          nodes
        SET
          position=%s
        WHERE
          id=%s;
    """
    cur.execute(sql, (position, int(node)))
    return position
Ejemplo n.º 25
0
def delete_node(cur, node, auto_position=True):
    """
    Delete node and its subtree.

    :param node:
    :type node: Node or int
    :param bool auto_position: See :ref:`core-positioning`
    """
    id = int(node)

    # Get Node object if integer (ID) was passed
    if auto_position and type(node) != NodeData:
        node = get_node(cur, id)

    sql = """
        DELETE FROM
          nodes
        WHERE
          id=%s;
    """
    cur.execute(sql, (id, ))

    if auto_position:
        shift_positions(cur, node.parent, node.position, -1)
Ejemplo n.º 26
0
def test_get_node_non_existing(cur):
    with pytest.raises(exceptions.NodeNotFound):
        get_node(cur, str(uuid.uuid4()))
Ejemplo n.º 27
0
def test_get_node(cur, nd1):
    node = get_node(cur, nd1.id)
    assert node.id == nd1.id
    assert node.parent == nd1.parent
Ejemplo n.º 28
0
def test_swap_node_positions(cur, nd1, nd2):
    swap_node_positions(cur, nd1, nd2)
    assert get_node(cur, nd1.id).position == nd2.position
    assert get_node(cur, nd2.id).position == nd1.position
Ejemplo n.º 29
0
def test_shift_positions_to_the_left(cur, root, nd1, nd2, nd3):
    shift_positions(cur, root, nd2.position, -1)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 1
    assert get_node(cur, nd3.id).position == 3
Ejemplo n.º 30
0
def test_shift_positions_to_the_right(cur, root, nd1, nd2, nd3):
    shift_positions(cur, root, nd2.position, +1)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 2
    assert get_node(cur, nd3.id).position == 4
Ejemplo n.º 31
0
def test_change_parent_starts_couting_at_zero(cur, root, nd2, nd2_1):
    change_parent(cur, nd2_1, nd2, position=None, auto_position=True)
    nd2_1 = get_node(cur, nd2_1.id)
    assert nd2_1.position == 0
Ejemplo n.º 32
0
def test_change_parent(cur, root, nd1, nd2, nd2_1, nd2_1_1,
                       nd2_leaf):
    """
    Tree layout before move:
    /
      - nd1
      - nd2
        - nd2-1
          - nd2-1-1
            - nd2-leaf
      - nd3

    Expected tree layout after move:

    /
      - nd1
        - nd2-1
          - nd2-1-1
            - nd2-leaf
      - nd2
      - nd3
    """
    # We expect nd2-1 to be child of nd2 and nd2-1-1 to be child
    # of nd2-1.

    # Move nd2-1 from nd2 to nd1
    _temp_node = change_parent(cur, nd2_1.id, nd1, auto_position=False)

    # Return value should have new parent set
    assert _temp_node.parent == nd1.id

    # nd2-1 should have nd1 as parent
    node = get_node(cur, nd2_1.id)
    assert node.parent == nd1.id

    # nd2-1-1 should still have the same parent (nd2-1)
    child_node = get_node(cur, nd2_1_1.id)
    assert child_node.parent == nd2_1.id

    # nd2-leaf should still have the same parent (nd2-1-1)
    child_node = get_node(cur, nd2_leaf.id)
    assert child_node.parent == nd2_1_1.id

    # The ancestor set of nd2-1 should now contain nd1 and root
    assert set(get_ancestor_ids(cur, nd2_1)) == {root.id, nd1.id}

    # The ancestor set of nd2-1-1 should now contain nd2-1, nd1 and root
    expected = {root.id, nd1.id, nd2_1.id}
    assert set(get_ancestor_ids(cur, nd2_1_1)) == expected

    # The ancestor set of nd2-leaf should now contain node-2-1-1, nd2-1,
    # nd1 and root
    expected = {root.id, nd1.id, nd2_1.id, nd2_1_1.id}
    assert set(get_ancestor_ids(cur, nd2_leaf)) == expected

    # The ancestor set of nd2 should now only contain root
    assert set(get_ancestor_ids(cur, nd2)) == {root.id}

    # Check if nd2-1, nd2-1-1 and nd2-leaf are part of nd1's descendant
    # set now
    expected = {nd2_1.id, nd2_1_1.id, nd2_leaf.id}
    assert set(get_descendant_ids(cur, nd1)) == expected

    # nd2's descendant set should be empty now
    assert set(get_descendant_ids(cur, nd2)) == set()

    # Last but not least, the children function proof what we checked above too
    assert len(set(get_children(cur, nd1))) == 1
    assert len(set(get_children(cur, nd2))) == 0
Ejemplo n.º 33
0
def test_change_parent_starts_couting_at_zero(cur, root, nd2, nd2_1):
    change_parent(cur, nd2_1, nd2, position=None, auto_position=True)
    nd2_1 = get_node(cur, nd2_1.id)
    assert nd2_1.position == 0
Ejemplo n.º 34
0
def test_change_parent_to_highest_position(cur, root, nd2, nd2_1):
    highest_position = find_highest_position(cur, root)
    change_parent(cur, nd2_1, root, position=None, auto_position=True)
    nd2_1 = get_node(cur, nd2_1.id)
    assert nd2_1.position == highest_position + 1
Ejemplo n.º 35
0
def test_get_node_non_existing(cur):
    with pytest.raises(ValueError):
        get_node(cur, 1)
Ejemplo n.º 36
0
def test_change_parent(cur, root, nd1, nd2, nd2_1, nd2_1_1,
                       nd2_leaf):
    """
    Tree layout before move:
    /
      - nd1
      - nd2
        - nd2-1
          - nd2-1-1
            - nd2-leaf
      - nd3

    Expected tree layout after move:

    /
      - nd1
        - nd2-1
          - nd2-1-1
            - nd2-leaf
      - nd2
      - nd3
    """
    # We expect nd2-1 to be child of nd2 and nd2-1-1 to be child
    # of nd2-1.

    # Move nd2-1 from nd2 to nd1
    _temp_node = change_parent(cur, nd2_1.id, nd1, auto_position=False)

    # Return value should have new parent set
    assert _temp_node.parent == nd1.id

    # nd2-1 should have nd1 as parent
    node = get_node(cur, nd2_1.id)
    assert node.parent == nd1.id

    # nd2-1-1 should still have the same parent (nd2-1)
    child_node = get_node(cur, nd2_1_1.id)
    assert child_node.parent == nd2_1.id

    # nd2-leaf should still have the same parent (nd2-1-1)
    child_node = get_node(cur, nd2_leaf.id)
    assert child_node.parent == nd2_1_1.id

    # The ancestor set of nd2-1 should now contain nd1 and root
    assert set(get_ancestor_ids(cur, nd2_1)) == {root.id, nd1.id}

    # The ancestor set of nd2-1-1 should now contain nd2-1, nd1 and root
    expected = {root.id, nd1.id, nd2_1.id}
    assert set(get_ancestor_ids(cur, nd2_1_1)) == expected

    # The ancestor set of nd2-leaf should now contain node-2-1-1, nd2-1,
    # nd1 and root
    expected = {root.id, nd1.id, nd2_1.id, nd2_1_1.id}
    assert set(get_ancestor_ids(cur, nd2_leaf)) == expected

    # The ancestor set of nd2 should now only contain root
    assert set(get_ancestor_ids(cur, nd2)) == {root.id}

    # Check if nd2-1, nd2-1-1 and nd2-leaf are part of nd1's descendant
    # set now
    expected = {nd2_1.id, nd2_1_1.id, nd2_leaf.id}
    assert set(get_descendant_ids(cur, nd1)) == expected

    # nd2's descendant set should be empty now
    assert set(get_descendant_ids(cur, nd2)) == set()

    # Last but not least, the children function proof what we checked above too
    assert len(set(get_children(cur, nd1))) == 1
    assert len(set(get_children(cur, nd2))) == 0
Ejemplo n.º 37
0
def test_change_parent_to_highest_position(cur, root, nd2, nd2_1):
    highest_position = find_highest_position(cur, root)
    change_parent(cur, nd2_1, root, position=None, auto_position=True)
    nd2_1 = get_node(cur, nd2_1.id)
    assert nd2_1.position == highest_position + 1
Ejemplo n.º 38
0
def test_swap_node_positions(cur, nd1, nd2):
    swap_node_positions(cur, nd1, nd2)
    assert get_node(cur, nd1.id).position == nd2.position
    assert get_node(cur, nd2.id).position == nd1.position
Ejemplo n.º 39
0
def test_get_node(cur, nd1):
    node = get_node(cur, nd1.id)
    assert node.id == nd1.id
    assert node.parent == nd1.parent
Ejemplo n.º 40
0
def test_get_node_needs_number(cur, root):
    with pytest.raises(TypeError):
        get_node(cur, root)
Ejemplo n.º 41
0
def test_get_node_non_existing(cur):
    with pytest.raises(exceptions.NodeNotFound):
        get_node(cur, str(uuid.uuid4()))
Ejemplo n.º 42
0
def test_set_position(cur, root):
    set_position(cur, root, 0, auto_position=False)
    assert get_node(cur, root.id).position == 0
Ejemplo n.º 43
0
def test_shift_positions_to_the_right(cur, root, nd1, nd2, nd3):
    shift_positions(cur, root, nd2.position, +1)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 2
    assert get_node(cur, nd3.id).position == 4
Ejemplo n.º 44
0
def test_set_position(cur, root):
    set_position(cur, root, 0, auto_position=False)
    assert get_node(cur, root.id).position == 0
Ejemplo n.º 45
0
def test_shift_positions_to_the_left(cur, root, nd1, nd2, nd3):
    shift_positions(cur, root, nd2.position, -1)
    assert get_node(cur, nd1.id).position == 0
    assert get_node(cur, nd2.id).position == 1
    assert get_node(cur, nd3.id).position == 3
Ejemplo n.º 46
0
def test_get_node_non_existing(cur):
    with pytest.raises(ValueError):
        get_node(cur, 1)
Ejemplo n.º 47
0
def test_get_node_needs_number(cur, root):
    with pytest.raises(TypeError):
        get_node(cur, root)