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
        },
    }
Beispiel #2
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": []
         },
     }
Beispiel #3
0
 def test_two_new_goals_move_to_top(self):
     self.goals.accept_all(Add("A"), Add("B"))
     assert self.goals.q(keys="name,switchable") == {
         1: {
             "name": "Root",
             "switchable": False
         },
         2: {
             "name": "A",
             "switchable": True
         },
         3: {
             "name": "B",
             "switchable": True
         },
     }
Beispiel #4
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"),
    ]
Beispiel #5
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"),
    ]
Beispiel #6
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 []
def test_how_should_we_deal_with_zooming():
    g = build_goaltree(
        open_(1, "Root", [2]),
        open_(2, "Zoomed", blockers=[3], select=selected),
        open_(3, "Ex-top"),
    )
    v = SwitchableView(persistent_layers(g))
    v.accept_all(ToggleZoom(), ToggleSwitchableView())
    assert v.q("name,select") == {
        2: {
            "name": "Zoomed",
            "select": "select"
        },
        3: {
            "name": "Ex-top",
            "select": None
        },
    }
    v.accept(Add("Unexpectedly hidden"))
    assert v.q("name,select") == {
        2: {
            "name": "Zoomed",
            "select": "select"
        },
        3: {
            "name": "Ex-top",
            "select": None
        },
        4: {
            "name": "Unexpectedly hidden",
            "select": None
        },
    }
Beispiel #8
0
 def test_two_goals_in_a_chain(self):
     self.goals.accept_all(Add("A"), Add("AA", 2))
     assert self.goals.q(keys="name,switchable") == {
         1: {
             "name": "Root",
             "switchable": False
         },
         2: {
             "name": "A",
             "switchable": False
         },
         3: {
             "name": "AA",
             "switchable": True
         },
     }
Beispiel #9
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
         },
     }
Beispiel #10
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": []
        },
    }
Beispiel #11
0
def test_multiple_saves_works_fine():
    file_name = NamedTemporaryFile().name
    goals = all_layers(Goals("Root"))
    save(goals, file_name)
    goals.accept(Add("Next"))
    save(goals, file_name)
    new_goals = load(file_name)
    assert goals.q() == new_goals.q()
Beispiel #12
0
 def test_new_goal_moves_to_top(self):
     self.goals.accept(Add("A"))
     assert self.goals.q(keys="name,switchable") == {
         1: {
             "name": "Root",
             "switchable": False
         },
         2: {
             "name": "A",
             "switchable": True
         },
     }
Beispiel #13
0
 def test_added_goal_has_strong_link_with_parent(self):
     self.goals.accept(Add("New"))
     assert self.goals.q(keys="name,edge") == {
         1: {
             "name": "Root",
             "edge": [(2, EdgeType.PARENT)]
         },
         2: {
             "name": "New",
             "edge": []
         },
     }
Beispiel #14
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")
Beispiel #15
0
 def test_root_goal_is_selected_by_default(self):
     assert self.goals.q(keys="select") == {1: {"select": "select"}}
     self.goals.accept(Add("A"))
     assert self.goals.q(keys="select") == {
         1: {
             "select": "select"
         },
         2: {
             "select": None
         },
     }
     self.goals.accept(Add("B"))
     assert self.goals.q(keys="select") == {
         1: {
             "select": "select"
         },
         2: {
             "select": None
         },
         3: {
             "select": None
         },
     }
Beispiel #16
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()
Beispiel #17
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},
    }
Beispiel #18
0
def test_do_not_make_a_link_on_matching_subgoal_add(tree_2_goals):
    goals = tree_2_goals
    goals.accept(ToggleAutoLink("me"))
    # Add a sub goal to the same subgoal
    goals.accept_all(Add("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": [(3, EdgeType.PARENT)]
        },
        3: {
            "name": "Do NOT link me please",
            "edge": []
        },
    }
Beispiel #19
0
 def test_no_message_on_good_add(self):
     self.goals = self.build(open_(1, "Root", select=selected))
     self.goals.accept(Add("Success"))
     assert self.messages == []
Beispiel #20
0
 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)
Beispiel #21
0
 def test_delete_events(self):
     self.goals.accept_all(Add("Sheep"), Select(2), Delete())
     assert self.goals.events()[-3] == ("delete", 2)
     assert self.goals.events()[-2] == ("select", 1)
     assert self.goals.events()[-1] == ("hold_select", 1)
Beispiel #22
0
 def test_select_events(self):
     self.goals.accept_all(Add("Next"), Select(2))
     assert self.goals.events()[-1] == ("select", 2)
     self.goals.accept_all(HoldSelect(), Select(1))
     assert self.goals.events()[-2] == ("hold_select", 2)
     assert self.goals.events()[-1] == ("select", 1)
Beispiel #23
0
 def test_add_events(self):
     assert self.goals.events().pop() == ("add", 1, "Root", True)
     self.goals.accept(Add("Next"))
     assert self.goals.events()[-2] == ("add", 2, "Next", True)
     assert self.goals.events()[-1] == ("link", 1, 2, EdgeType.PARENT)
Beispiel #24
0
def goal_chain_11(goal_chain_10):
    """a → b → c → ... → j → k"""
    goals = goal_chain_10
    goals.accept_all(Select(10), Add("k"), Select(1))
    return goals
Beispiel #25
0
        return result

    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))
Beispiel #26
0
 def test_message_on_wrong_add(self):
     self.goals = self.build(clos_(1, "Root", select=selected))
     self.goals.accept(Add("Failed"))
     assert len(self.messages) == 1
Beispiel #27
0
 def emit_add(self, text):
     self.goals.accept(Add(text))
Beispiel #28
0
 def test_rename_goal(self):
     self.goals.accept_all(Add("Boom"), Select(2), Rename("A"))
     assert self.goals.q() == {1: {"name": "Root"}, 2: {"name": "A"}}
Beispiel #29
0
 def add_goal(self):
     event("add")
     self._accept(Add("a"))