コード例 #1
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_change_link_type(self):
     self.goals = self.build(open_(1, "Root", [2], select=previous),
                             open_(2, "Top", [], select=selected))
     assert self.goals.q(keys="name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT)]
         },
         2: {
             "name": "Top",
             "edge": []
         },
     }
     self.goals.accept(ToggleLink())
     assert self.goals.q(keys="name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.BLOCKER)]
         },
         2: {
             "name": "Top",
             "edge": []
         },
     }
     self.goals.accept(ToggleLink(edge_type=EdgeType.PARENT))
     assert self.goals.q(keys="name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT)]
         },
         2: {
             "name": "Top",
             "edge": []
         },
     }
コード例 #2
0
ファイル: cli.py プロジェクト: ahitrin/SiebenApp
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 []
コード例 #3
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_add_link_between_goals(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "A", select=previous),
         open_(3, "B", select=selected),
     )
     assert self.goals.q(keys="switchable,edge") == {
         1: {
             "switchable": False,
             "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)],
         },
         2: {
             "switchable": True,
             "edge": []
         },
         3: {
             "switchable": True,
             "edge": []
         },
     }
     self.goals.accept(ToggleLink())
     assert self.goals.q(keys="switchable,edge") == {
         1: {
             "switchable": False,
             "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)],
         },
         2: {
             "switchable": False,
             "edge": [(3, EdgeType.BLOCKER)]
         },
         3: {
             "switchable": True,
             "edge": []
         },
     }
コード例 #4
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_message_on_link_to_self(self):
     self.goals = self.build(
         open_(1, "Root", [2]),
         open_(2, "Middle", [3]),
         open_(3, "Top", [], select=selected),
     )
     self.goals.accept(ToggleLink())
     assert len(self.messages) == 1
コード例 #5
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_no_message_on_allowed_link(self):
     self.goals = self.build(
         open_(1, "Root", [2], select=previous),
         open_(2, "Middle", [3]),
         open_(3, "Top", [], select=selected),
     )
     self.goals.accept(ToggleLink())
     assert self.messages == []
コード例 #6
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_message_when_remove_last_link(self):
     self.goals = self.build(
         open_(1, "Root", [2]),
         open_(2, "Middle", [3], select=previous),
         open_(3, "Top", [], select=selected),
     )
     self.goals.accept(ToggleLink(edge_type=EdgeType.PARENT))
     assert len(self.messages) == 1
コード例 #7
0
ファイル: goaltree.py プロジェクト: ahitrin/SiebenApp
 def accept_Add(self, command: Add) -> bool:
     add_to = command.add_to or self.selection
     if add_to in self.closed:
         self.error("A new subgoal cannot be added to the closed one")
         return False
     next_id = self._add_no_link(command.name)
     self.accept_ToggleLink(ToggleLink(add_to, next_id, command.edge_type))
     return True
コード例 #8
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_no_message_when_remove_not_last_link(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3], select=previous),
         open_(2, "Middle", blockers=[3]),
         open_(3, "Top", [], select=selected),
     )
     self.goals.accept(ToggleLink())
     assert self.messages == []
コード例 #9
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_message_when_closed_goal_is_blocked_by_open_one(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         clos_(2, "Middle", [], select=previous),
         open_(3, "Top", [], select=selected),
     )
     self.goals.accept(ToggleLink())
     assert len(self.messages) == 1
コード例 #10
0
 def _make_links(self, matching_goals: List[int], target_goal: int) -> None:
     if not matching_goals:
         return
     self_children: Dict[int, List[int]] = {
         goal_id: [e[0] for e in attrs["edge"]]
         for goal_id, attrs in self.goaltree.q("edge").items()
     }
     for add_to in matching_goals:
         if target_goal not in self_children[add_to]:
             self.goaltree.accept(
                 ToggleLink(add_to, target_goal, EdgeType.BLOCKER))
コード例 #11
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_change_link_type_events(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "Lower", blockers=[3], select=previous),
         open_(3, "Upper", [], select=selected),
     )
     self.goals.accept(ToggleLink(edge_type=EdgeType.PARENT))
     assert self.goals.events()[-4] == ("link", 2, 3, EdgeType.PARENT)
     assert self.goals.events()[-3] == ("unlink", 2, 3, EdgeType.BLOCKER)
     assert self.goals.events()[-2] == ("link", 1, 3, EdgeType.BLOCKER)
     assert self.goals.events()[-1] == ("unlink", 1, 3, EdgeType.PARENT)
コード例 #12
0
 def toggle_link(self, b, d):
     event("toggle link")
     goal_keys = sorted(list(k for k in self.goaltree.q().keys() if k > 0))
     assume(len(goal_keys) > 1)
     selection = d.draw(sampled_from(goal_keys))
     goal_keys.remove(selection)
     prev_selection = d.draw(sampled_from(goal_keys))
     event("valid toggle link")
     edge_type = EdgeType.PARENT if b else EdgeType.BLOCKER
     self._accept(
         ToggleLink(lower=prev_selection,
                    upper=selection,
                    edge_type=edge_type))
コード例 #13
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_remove_link_between_goals(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "A", blockers=[3], select=previous),
         open_(3, "B", select=selected),
     )
     self.goals.accept(ToggleLink(edge_type=EdgeType.BLOCKER))
     assert self.goals.q(keys="edge,switchable") == {
         1: {
             "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)],
             "switchable": False,
         },
         2: {
             "edge": [],
             "switchable": True
         },
         3: {
             "edge": [],
             "switchable": True
         },
     }
コード例 #14
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_new_parent_link_replaces_old_one_when_changed_from_blocker(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "A", select=selected),
         open_(3, "B", blockers=[2], select=previous),
     )
     self.goals.accept(ToggleLink(edge_type=EdgeType.PARENT))
     assert self.goals.q("name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.BLOCKER), (3, EdgeType.PARENT)]
         },
         2: {
             "name": "A",
             "edge": []
         },
         3: {
             "name": "B",
             "edge": [(2, EdgeType.PARENT)]
         },
     }
コード例 #15
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_new_parent_link_replaces_old_one(self):
     self.goals = self.build(
         open_(1, "Root", [2, 3]),
         open_(2, "Old parent", [4]),
         open_(3, "New parent", select=previous),
         open_(4, "Child", select=selected),
     )
     self.goals.accept(ToggleLink(edge_type=EdgeType.PARENT))
     assert self.goals.q(keys="edge") == {
         1: {
             "edge": [(2, EdgeType.PARENT), (3, EdgeType.PARENT)]
         },
         2: {
             "edge": [(4, EdgeType.BLOCKER)]
         },
         3: {
             "edge": [(4, EdgeType.PARENT)]
         },
         4: {
             "edge": []
         },
     }
コード例 #16
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_no_loops_allowed(self):
     self.goals = self.build(
         open_(1, "Root", [2], select=selected),
         open_(2, "step", [3]),
         open_(3, "next", [4]),
         open_(4, "more", select=previous),
     )
     self.goals.accept(ToggleLink())
     assert self.goals.q(keys="edge") == {
         1: {
             "edge": [(2, EdgeType.PARENT)]
         },
         2: {
             "edge": [(3, EdgeType.PARENT)]
         },
         3: {
             "edge": [(4, EdgeType.PARENT)]
         },
         4: {
             "edge": []
         },
     }
コード例 #17
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")
コード例 #18
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()
コード例 #19
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_link_events(self):
     self.goals.accept_all(Add("Next"), Add("More"), Select(2),
                           HoldSelect(), Select(3), ToggleLink())
     assert self.goals.events()[-1] == ("link", 2, 3, EdgeType.BLOCKER)
     self.goals.accept(ToggleLink())
     assert self.goals.events()[-1] == ("unlink", 2, 3, EdgeType.BLOCKER)
コード例 #20
0
ファイル: goaltree.py プロジェクト: ahitrin/SiebenApp
    def _switchable(self, key: int) -> bool:
        if key in self.closed:
            if back_edges := self._back_edges(key):
                return any(e.source not in self.closed for e in back_edges)
            return True
        return all(x.target in self.closed for x in self._forward_edges(key))

    def accept_Insert(self, command: Insert):
        if (lower := self.previous_selection) == (upper := self.selection):
            self.error(
                "A new goal can be inserted only between two different goals")
            return
        edge_type = self.edges_forward[lower].get(upper, EdgeType.BLOCKER)
        if self.accept_Add(Add(command.name, lower, edge_type)):
            key = len(self.goals)
            self.accept_ToggleLink(ToggleLink(key, upper, edge_type))
            if self._has_link(lower, upper):
                self.accept_ToggleLink(ToggleLink(lower, upper))

    def accept_Rename(self, command: Rename):
        goal_id = command.goal_id or self.selection
        self.goals[goal_id] = command.new_name
        self._events.append(("rename", command.new_name, goal_id))

    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(
コード例 #21
0
ファイル: test_goaltree.py プロジェクト: ahitrin/SiebenApp
 def test_no_link_to_self_is_allowed(self):
     self.goals.accept(ToggleLink())
     assert self.goals.q(keys="edge") == {1: {"edge": []}}
コード例 #22
0
 def keyPressEvent(self, event):
     key_handlers = {
         Qt.Key_1:
         self.select_number(1),
         Qt.Key_2:
         self.select_number(2),
         Qt.Key_3:
         self.select_number(3),
         Qt.Key_4:
         self.select_number(4),
         Qt.Key_5:
         self.select_number(5),
         Qt.Key_6:
         self.select_number(6),
         Qt.Key_7:
         self.select_number(7),
         Qt.Key_8:
         self.select_number(8),
         Qt.Key_9:
         self.select_number(9),
         Qt.Key_0:
         self.select_number(0),
         Qt.Key_A:
         self.start_edit("Add new goal", self.emit_add),
         Qt.Key_C:
         self.with_refresh(self.goals.accept, ToggleClose()),
         Qt.Key_D:
         self.with_refresh(self.goals.accept, Delete()),
         Qt.Key_F:
         self.start_edit(
             "Filter by substring (leave empty to reset filtration)",
             self.emit_filter,
         ),
         Qt.Key_I:
         self.start_edit("Insert new goal", self.emit_insert),
         Qt.Key_K:
         self.with_refresh(self.goals.accept,
                           ToggleLink(edge_type=EdgeType.PARENT)),
         Qt.Key_L:
         self.with_refresh(self.goals.accept, ToggleLink()),
         Qt.Key_N:
         self.with_refresh(self.toggle_open_view, True),
         Qt.Key_O:
         self.show_open_dialog,
         Qt.Key_P:
         self.with_refresh(self.toggle_progress_view, True),
         Qt.Key_Q:
         self.quit_app.emit,
         Qt.Key_R:
         self.start_edit("Rename goal", self.emit_rename,
                         self._current_goal_label),
         Qt.Key_T:
         self.with_refresh(self.toggle_switchable_view, True),
         Qt.Key_Z:
         self.toggle_zoom,
         Qt.Key_QuoteLeft:
         self.start_edit(
             "Auto link by keyword (leave empty to reset auto link)",
             self.emit_autolink,
         ),
         Qt.Key_Escape:
         self.cancel_edit,
         Qt.Key_Minus:
         self.with_refresh(self.change_columns, -1),
         Qt.Key_Plus:
         self.with_refresh(self.change_columns, 1),
         Qt.Key_Slash:
         self.show_keys_help,
         Qt.Key_Space:
         self.with_refresh(self.goals.accept, HoldSelect()),
     }
     if event.key() in key_handlers:
         key_handlers[event.key()]()
     else:
         super().keyPressEvent(event)