Пример #1
0
def test_make_a_link_on_matching_insert(tree_3v_goals):
    goals = tree_3v_goals
    goals.accept(ToggleAutoLink("me"))
    # Add a goal to the root
    goals.accept_all(Select(1), HoldSelect(), Select(3),
                     Insert("Link ME please"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(-12, EdgeType.PARENT), (4, EdgeType.PARENT)]
        },
        -12: {
            "name": "Autolink: 'me'",
            "edge": [(2, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": [(4, EdgeType.BLOCKER)]
        },
        4: {
            "name": "Link ME please",
            "edge": [(3, EdgeType.PARENT)]
        },
        3: {
            "name": "Another subgoal",
            "edge": []
        },
    }
Пример #2
0
def test_select_goal_by_full_id_with_non_empty_cache(goal_chain_11):
    e = Enumeration(goal_chain_11)
    assert e.q(keys="name,select") == {
        11: {"name": "a", "select": "select"},
        12: {"name": "b", "select": None},
        13: {"name": "c", "select": None},
        14: {"name": "d", "select": None},
        15: {"name": "e", "select": None},
        16: {"name": "f", "select": None},
        17: {"name": "g", "select": None},
        18: {"name": "h", "select": None},
        19: {"name": "i", "select": None},
        10: {"name": "j", "select": None},
        21: {"name": "k", "select": None},
    }
    e.accept_all(Select(2), Select(13))
    assert e.q(keys="name,select") == {
        11: {"name": "a", "select": "prev"},
        12: {"name": "b", "select": None},
        13: {"name": "c", "select": "select"},
        14: {"name": "d", "select": None},
        15: {"name": "e", "select": None},
        16: {"name": "f", "select": None},
        17: {"name": "g", "select": None},
        18: {"name": "h", "select": None},
        19: {"name": "i", "select": None},
        10: {"name": "j", "select": None},
        21: {"name": "k", "select": None},
    }
Пример #3
0
def test_non_switchable_goals_disappear_on_selection_change():
    e = SwitchableView(Goals("root"))
    e.accept_all(Add("1"), Add("2"), Select(2), ToggleSwitchableView(),
                 Select(2))
    assert e.q("name,switchable,select") == {
        1: {
            "name": "root",
            "switchable": False,
            "select": "prev"
        },
        2: {
            "name": "1",
            "switchable": True,
            "select": "select"
        },
        3: {
            "name": "2",
            "switchable": True,
            "select": None
        },
    }
    e.accept(HoldSelect())
    assert e.q("name,switchable,select") == {
        2: {
            "name": "1",
            "switchable": True,
            "select": "select"
        },
        3: {
            "name": "2",
            "switchable": True,
            "select": None
        },
    }
Пример #4
0
def test_change_progress_on_close(goaltree):
    goaltree.accept_all(ToggleProgress(), Select(4), ToggleClose())
    assert goaltree.q("name") == {
        1: {
            "name": "[1/4] Root"
        },
        2: {
            "name": "[0/1] With blocker"
        },
        3: {
            "name": "[1/2] With subgoal"
        },
        4: {
            "name": "[1/1] Top goal"
        },
    }
    goaltree.accept_all(Select(2), ToggleClose())
    assert goaltree.q("name") == {
        1: {
            "name": "[2/4] Root"
        },
        2: {
            "name": "[1/1] With blocker"
        },
        3: {
            "name": "[1/2] With subgoal"
        },
        4: {
            "name": "[1/1] Top goal"
        },
    }
Пример #5
0
def test_autolink_on_all_matching_goals(tree_3v_goals):
    goals = tree_3v_goals
    # make 2 autolinks
    goals.accept_all(ToggleAutoLink("me"), Select(3), ToggleAutoLink("plea"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(-12, EdgeType.PARENT), (-13, EdgeType.PARENT)]
        },
        -12: {
            "name": "Autolink: 'me'",
            "edge": [(2, EdgeType.PARENT)]
        },
        -13: {
            "name": "Autolink: 'plea'",
            "edge": [(3, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": []
        },
        3: {
            "name": "Another subgoal",
            "edge": []
        },
    }
    # add 2-mathing goal
    goals.accept_all(Select(1), Add("Link me to both please"))
    assert goals.q("name,edge") == {
        1: {
            "name":
            "Root",
            "edge": [
                (-12, EdgeType.PARENT),
                (-13, EdgeType.PARENT),
                (4, EdgeType.PARENT),
            ],
        },
        -12: {
            "name": "Autolink: 'me'",
            "edge": [(2, EdgeType.PARENT)]
        },
        -13: {
            "name": "Autolink: 'plea'",
            "edge": [(3, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": [(4, EdgeType.BLOCKER)]
        },
        3: {
            "name": "Another subgoal",
            "edge": [(4, EdgeType.BLOCKER)]
        },
        4: {
            "name": "Link me to both please",
            "edge": []
        },
    }
Пример #6
0
def test_selection_cache_should_avoid_overflow(goal_chain_11):
    e = Enumeration(goal_chain_11)
    assert e.q(keys="select")[11] == {"select": "select"}
    e.accept(Select(5))
    assert e.q(keys="select")[11] == {"select": "select"}
    e.accept(Select(1))
    assert e.q(keys="select")[11] == {"select": "select"}
    assert e.q(keys="select")[14] == {"select": None}
    e.accept(Select(4))
    assert e.q(keys="select")[11] == {"select": "prev"}
    assert e.q(keys="select")[14] == {"select": "select"}
Пример #7
0
 def test_close_goal_again(self):
     self.goals = self.build(
         open_(1, "Root", [2], select=selected),
         open_(2, "A", [3]),
         clos_(3, "Ab"),
     )
     self.goals.accept_all(Select(2), ToggleClose())
     assert self.goals.q(keys="open,switchable") == {
         1: {
             "open": True,
             "switchable": True
         },
         2: {
             "open": False,
             "switchable": True
         },
         3: {
             "open": False,
             "switchable": False
         },
     }
     self.goals.accept_all(Select(2), ToggleClose())
     assert self.goals.q(keys="open,switchable") == {
         1: {
             "open": True,
             "switchable": False
         },
         2: {
             "open": True,
             "switchable": True
         },
         3: {
             "open": False,
             "switchable": True
         },
     }
     self.goals.accept_all(Select(2), ToggleClose())
     assert self.goals.q(keys="open,switchable") == {
         1: {
             "open": True,
             "switchable": True
         },
         2: {
             "open": False,
             "switchable": True
         },
         3: {
             "open": False,
             "switchable": False
         },
     }
Пример #8
0
def test_closed_goals_are_shown_when_selected():
    v = OpenView(
        build_goaltree(
            open_(1, "Root", [2, 3], select=selected),
            clos_(2, "closed"),
            clos_(3, "closed too", [4]),
            clos_(4, "closed and not selected"),
        ))
    v.accept_all(ToggleOpenView(), Select(2), HoldSelect(), Select(3))
    assert v.q("name,select,open") == {
        1: {
            "name": "Root",
            "open": True,
            "select": None
        },
        2: {
            "name": "closed",
            "open": False,
            "select": "prev"
        },
        3: {
            "name": "closed too",
            "open": False,
            "select": "select"
        },
        4: {
            "name": "closed and not selected",
            "open": False,
            "select": None
        },
    }
    v.accept(ToggleOpenView())
    # Still show: open goals, selected goals
    assert v.q("name,select,open") == {
        1: {
            "name": "Root",
            "open": True,
            "select": None
        },
        2: {
            "name": "closed",
            "open": False,
            "select": "prev"
        },
        3: {
            "name": "closed too",
            "open": False,
            "select": "select"
        },
    }
Пример #9
0
def test_do_not_make_a_link_on_matching_subgoal_insert(tree_3i_goals):
    goals = tree_3i_goals
    goals.accept(ToggleAutoLink("me"))
    # Add a sub goal to the same subgoal
    goals.accept_all(HoldSelect(), Select(3), Insert("Do NOT link me please"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(-12, EdgeType.PARENT)]
        },
        -12: {
            "name": "Autolink: 'me'",
            "edge": [(2, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": [(4, EdgeType.PARENT)]
        },
        4: {
            "name": "Do NOT link me please",
            "edge": [(3, EdgeType.PARENT)]
        },
        3: {
            "name": "Another subgoal",
            "edge": []
        },
    }
Пример #10
0
def test_replace_same_autolink(tree_3v_goals):
    goals = tree_3v_goals
    goals.accept_all(ToggleAutoLink("same"), Select(3), ToggleAutoLink("same"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(2, EdgeType.PARENT), (-13, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": []
        },
        -13: {
            "name": "Autolink: 'same'",
            "edge": [(3, EdgeType.PARENT)]
        },
        3: {
            "name": "Another subgoal",
            "edge": []
        },
    }
    assert _autolink_events(goals) == [
        ("add_autolink", 2, "same"),
        ("remove_autolink", 2),
        ("add_autolink", 3, "same"),
    ]
Пример #11
0
def build_actions(command):
    simple_commands = {
        "c": ToggleClose(),
        "d": Delete(),
        "h": HoldSelect(),
        "k": ToggleLink(edge_type=EdgeType.PARENT),
        "l": ToggleLink(),
        "n": ToggleOpenView(),
        "p": ToggleProgress(),
        "t": ToggleSwitchableView(),
        "z": ToggleZoom(),
    }
    if command and all(c in "1234567890" for c in command):
        return [Select(int(c)) for c in command]
    if command.startswith("a "):
        return [Add(command[2:])]
    if command.startswith("i "):
        return [Insert(command[2:])]
    if command.startswith("r "):
        return [Rename(command[2:])]
    if command.startswith("f"):
        return [FilterBy(command[1:].lstrip())]
    if command.startswith("` "):
        return [ToggleAutoLink(command[2:])]
    if command in simple_commands:
        return [simple_commands[command]]
    return []
Пример #12
0
 def test_new_goal_is_added_to_the_selected_node(self):
     self.goals.accept_all(Add("A"), Select(2))
     assert self.goals.q(keys="name,select") == {
         1: {
             "name": "Root",
             "select": "prev"
         },
         2: {
             "name": "A",
             "select": "select"
         },
     }
     self.goals.accept(Add("B"))
     assert self.goals.q(keys="name,select,edge") == {
         1: {
             "name": "Root",
             "select": "prev",
             "edge": [(2, EdgeType.PARENT)]
         },
         2: {
             "name": "A",
             "select": "select",
             "edge": [(3, EdgeType.PARENT)]
         },
         3: {
             "name": "B",
             "select": None,
             "edge": []
         },
     }
Пример #13
0
 def test_insert_goal_in_the_middle(self):
     self.goals.accept_all(Add("B"), HoldSelect(), Select(2))
     assert self.goals.q(keys="name,edge,switchable") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT)],
             "switchable": False
         },
         2: {
             "name": "B",
             "edge": [],
             "switchable": True
         },
     }
     self.goals.accept(Insert("A"))
     assert self.goals.q(keys="name,edge,switchable") == {
         1: {
             "name": "Root",
             "edge": [(3, EdgeType.PARENT)],
             "switchable": False
         },
         2: {
             "name": "B",
             "edge": [],
             "switchable": True
         },
         3: {
             "name": "A",
             "edge": [(2, EdgeType.PARENT)],
             "switchable": False
         },
     }
Пример #14
0
def test_zoomed_parent_goal_must_not_be_filtered_out(zoomed_goaltree):
    zoomed_goaltree.accept_all(HoldSelect(), Select(2), ToggleZoom(),
                               FilterBy("mm"))
    assert zoomed_goaltree.q("name,edge,select") == {
        -1: {
            "name": "Alpha",
            "edge": [(-2, EdgeType.BLOCKER), (2, EdgeType.BLOCKER)],
            "select": "prev",
        },
        -2: {
            "name": "Filter by 'mm'",
            "edge": [(2, EdgeType.BLOCKER), (3, EdgeType.BLOCKER)],
            "select": None,
        },
        2: {
            "name": "Beta",
            "edge": [(3, EdgeType.PARENT)],
            "select": "select"
        },
        3: {
            "name": "Gamma",
            "edge": [],
            "select": None
        },
    }
Пример #15
0
def test_select_goal_by_id_parts(goal_chain_11):
    e = Enumeration(goal_chain_11)
    e.accept_all(Select(1), Select(6))
    assert e.q(keys="name,select") == {
        11: {"name": "a", "select": "prev"},
        12: {"name": "b", "select": None},
        13: {"name": "c", "select": None},
        14: {"name": "d", "select": None},
        15: {"name": "e", "select": None},
        16: {"name": "f", "select": "select"},
        17: {"name": "g", "select": None},
        18: {"name": "h", "select": None},
        19: {"name": "i", "select": None},
        10: {"name": "j", "select": None},
        21: {"name": "k", "select": None},
    }
Пример #16
0
 def test_closed_leaf_goal_could_not_be_reopened(self):
     self.goals = self.build(open_(1, "Root", [2], select=selected),
                             clos_(2, "A", [3]), clos_(3, "B"))
     assert self.goals.q(keys="open,switchable") == {
         1: {
             "open": True,
             "switchable": True
         },
         2: {
             "open": False,
             "switchable": True
         },
         3: {
             "open": False,
             "switchable": False
         },
     }
     self.goals.accept_all(Select(3), ToggleClose())
     # nothing should change
     assert self.goals.q(keys="open,switchable") == {
         1: {
             "open": True,
             "switchable": True
         },
         2: {
             "open": False,
             "switchable": True
         },
         3: {
             "open": False,
             "switchable": False
         },
     }
Пример #17
0
def test_make_a_link_on_matching_add(tree_2_goals):
    goals = tree_2_goals
    goals.accept(ToggleAutoLink("me"))
    # Add a goal to the root
    goals.accept_all(Select(1), Add("Link ME please"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(-12, EdgeType.PARENT), (3, EdgeType.PARENT)]
        },
        -12: {
            "name": "Autolink: 'me'",
            "edge": [(2, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": [(3, EdgeType.BLOCKER)]
        },
        3: {
            "name": "Link ME please",
            "edge": []
        },
    }
    assert _autolink_events(goals) == [
        ("add_autolink", 2, "me"),
    ]
Пример #18
0
def test_do_not_make_a_link_on_not_old_matching_add(tree_2_goals):
    goals = tree_2_goals
    goals.accept_all(ToggleAutoLink("old"), ToggleAutoLink("new"))
    # Add a goal to the root
    goals.accept_all(Select(1), Add("This is old subgoal"))
    assert goals.q("name,edge") == {
        1: {
            "name": "Root",
            "edge": [(-12, EdgeType.PARENT), (3, EdgeType.PARENT)]
        },
        -12: {
            "name": "Autolink: 'new'",
            "edge": [(2, EdgeType.PARENT)]
        },
        2: {
            "name": "Autolink on me",
            "edge": []
        },
        3: {
            "name": "This is old subgoal",
            "edge": []
        },
    }
    assert _autolink_events(goals) == [
        ("add_autolink", 2, "old"),
        ("remove_autolink", 2),
        ("add_autolink", 2, "new"),
    ]
Пример #19
0
class Enumeration(Graph):
    def __init__(self, goaltree: Graph) -> None:
        super().__init__(goaltree)
        self.selection_cache: List[int] = []

    def _id_mapping(
            self,
            keys: str = "name") -> Tuple[Dict[int, Any], BidirectionalIndex]:
        goals = self.goaltree.q(keys)
        return goals, BidirectionalIndex(goals)

    def q(self, keys: str = "name") -> Dict[int, Any]:
        result: Dict[int, Any] = dict()
        goals, index = self._id_mapping(keys)
        for old_id, val in goals.items():
            new_id = index.forward(old_id)
            result[new_id] = {k: v for k, v in val.items() if k != "edge"}
            if "edge" in val:
                result[new_id]["edge"] = [(index.forward(edge[0]), edge[1])
                                          for edge in val["edge"]]
        return result

    def accept_Select(self, command: Select):
        goals, index = self._id_mapping()
        if (goal_id := command.goal_id) >= 10:
            self.selection_cache = []
        if self.selection_cache:
            goal_id = 10 * self.selection_cache.pop() + goal_id
            if goal_id > max(index.forward(k) for k in goals.keys()):
                goal_id %= int(pow(10, int(math.log(goal_id, 10))))
        if (original_id :=
                index.backward(goal_id)) != BidirectionalIndex.NOT_FOUND:
            self.goaltree.accept(Select(original_id))
            self.selection_cache = []
Пример #20
0
 def insert(self, d):
     event("insert")
     candidates = sorted(
         list(goal_id
              for goal_id, attrs in self.goaltree.q("select").items()
              if attrs["select"] != "select"))
     random_goal = d.draw(sampled_from(candidates))
     self._accept_all(HoldSelect(), Select(random_goal), Insert("i"))
Пример #21
0
def test_selection_cache_should_be_reset_after_view_switch(goal_chain_11):
    e = Enumeration(SwitchableView(goal_chain_11))
    e.accept_all(Add("Also top"))
    e.accept(Select(1))
    # Select(1) is kept in a cache and not applied yet
    e.accept(ToggleSwitchableView())
    assert e.q("name,select") == {
        1: {"name": "a", "select": "select"},
        2: {"name": "k", "select": None},
        3: {"name": "Also top", "select": None},
    }
    # Select(2) is being applied without any effect from the previous selection
    # This happens because selection cache was reset
    e.accept(Select(2))
    assert e.q("name,select") == {
        1: {"name": "a", "select": "prev"},
        2: {"name": "k", "select": "select"},
        3: {"name": "Also top", "select": None},
    }
Пример #22
0
 def select_random_goal(self, d):
     event("select")
     max_key = max(self.goaltree.q().keys())
     assume(max_key >= 1)
     event("valid select 1")
     random_goal = d.draw(integers(min_value=1, max_value=max_key))
     assume(random_goal in self.goaltree.q())
     event("valid select 2")
     self._accept(Select(random_goal))
     # Any valid goal must be selectable
     assert self.goaltree.q("select")[random_goal]["select"] == "select"
Пример #23
0
def test_save_and_load():
    file_name = NamedTemporaryFile().name
    goals = Enumeration(all_layers(Goals("Root")))
    goals.accept_all(
        Add("Top"),
        Add("Middle"),
        Select(3),
        HoldSelect(),
        Select(2),
        ToggleLink(),
        Add("Closed"),
        Select(4),
        ToggleClose(),
        Select(2),
        ToggleZoom(),
    )
    save(goals, file_name)
    new_goals = load(file_name)
    goals.accept_all(ToggleOpenView())
    new_goals.accept_all(ToggleOpenView())
    assert goals.q(keys="open,name,edge,select,switchable") == new_goals.q(
        keys="open,name,edge,select,switchable")
Пример #24
0
 def accept_ToggleClose(self, command: ToggleClose) -> None:
     if self.selection in self.closed:
         if self._may_be_reopened():
             self.closed.remove(self.selection)
             self._events.append(("toggle_close", True, self.selection))
         else:
             self.error(
                 "This goal can't be reopened because other subgoals block it"
             )
     else:
         if self._may_be_closed():
             self.closed.add(self.selection)
             self._events.append(("toggle_close", False, self.selection))
             if self.previous_selection != self.selection:
                 self.accept_Select(Select(self.previous_selection))
             else:
                 self.accept_Select(
                     Select(self._first_open_and_switchable(command.root)))
                 self.accept(HoldSelect())
         else:
             self.error(
                 "This goal can't be closed because it have open subgoals")
Пример #25
0
def test_remove_autolink_on_parent_delete(tree_3i_goals):
    goals = tree_3i_goals
    goals.accept_all(Select(3), ToggleAutoLink("test"))
    assert goals.q("edge") == {
        1: {
            "edge": [(2, EdgeType.PARENT)]
        },
        2: {
            "edge": [(-13, EdgeType.PARENT)]
        },
        -13: {
            "edge": [(3, EdgeType.PARENT)]
        },
        3: {
            "edge": []
        },
    }
    goals.accept_all(Select(2), Delete())
    assert goals.q("edge") == {1: {"edge": []}}
    assert _autolink_events(goals) == [
        ("add_autolink", 3, "test"),
        ("remove_autolink", 3),
    ]
Пример #26
0
def test_use_mapping_in_selection(goal_chain_10):
    e = Enumeration(goal_chain_10)
    e.accept(Select(0))
    assert e.q(keys="name,select") == {
        1: {"name": "a", "select": "prev"},
        2: {"name": "b", "select": None},
        3: {"name": "c", "select": None},
        4: {"name": "d", "select": None},
        5: {"name": "e", "select": None},
        6: {"name": "f", "select": None},
        7: {"name": "g", "select": None},
        8: {"name": "h", "select": None},
        9: {"name": "i", "select": None},
        0: {"name": "j", "select": "select"},
    }
Пример #27
0
def test_restore_goals_from_db():
    file_name = NamedTemporaryFile().name
    with sqlite3.connect(file_name) as conn:
        run_migrations(conn)
        setup_sample_db(conn)
    actual_goals = load(file_name)
    actual_goals.accept(ToggleOpenView())
    expected_goals = Goals("Root")
    expected_goals.accept_all(
        Add("A"),
        Add("B"),
        Select(2),
        HoldSelect(),
        Select(3),
        ToggleLink(),
        Select(3),
        ToggleClose(),
        Select(1),
        HoldSelect(),
        Select(2),
    )
    keys = "name,edge,open,select"
    assert expected_goals.q(keys=keys) == actual_goals.q(keys=keys)
    assert not actual_goals.events()
Пример #28
0
def test_do_not_select_goal_by_partial_id(goal_chain_11):
    e = Enumeration(goal_chain_11)
    # Select(1) is kept in cache, and selection is not changed yet
    e.accept_all(Select(1))
    assert e.q(keys="name,select") == {
        11: {"name": "a", "select": "select"},
        12: {"name": "b", "select": None},
        13: {"name": "c", "select": None},
        14: {"name": "d", "select": None},
        15: {"name": "e", "select": None},
        16: {"name": "f", "select": None},
        17: {"name": "g", "select": None},
        18: {"name": "h", "select": None},
        19: {"name": "i", "select": None},
        10: {"name": "j", "select": None},
        21: {"name": "k", "select": None},
    }
Пример #29
0
 def test_remove_blocked_goal_without_children(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "A", [4]),
         open_(3, "B", blockers=[4]),
         open_(4, "C", select=selected),
     )
     assert self.goals.q(keys="name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)]
         },
         2: {
             "name": "A",
             "edge": [(4, EdgeType.PARENT)]
         },
         3: {
             "name": "B",
             "edge": [(4, EdgeType.BLOCKER)]
         },
         4: {
             "name": "C",
             "edge": []
         },
     }
     self.goals.accept_all(Select(3), Delete())
     assert self.goals.q(keys="name,edge,switchable") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT)],
             "switchable": False
         },
         2: {
             "name": "A",
             "edge": [(4, EdgeType.PARENT)],
             "switchable": False
         },
         4: {
             "name": "C",
             "edge": [],
             "switchable": True
         },
     }
Пример #30
0
def test_previously_selected_goal_must_not_be_filtered_out(goaltree):
    goaltree.accept_all(Select(3), FilterBy("matching no one"))
    assert goaltree.q("name,edge,select") == {
        1: {
            "name": "Alpha",
            "edge": [(-2, EdgeType.BLOCKER)],
            "select": "prev"
        },
        -2: {
            "name": "Filter by 'matching no one'",
            "edge": [(3, EdgeType.BLOCKER)],
            "select": None,
        },
        3: {
            "name": "Gamma",
            "edge": [],
            "select": "select"
        },
    }