def test_pane_differences(capsys):
    """
    Test getting differences between panes
    """
    panes1 = [Pane("pane1", "p", SPLIT_HORIZONTAL).set_number(0)]
    panes2 = [Pane("pane2", "p2", SPLIT_VERTICAL).set_number(1)]

    window1 = Window("win1", "window")
    window1.panes = panes1
    window2 = Window("win2", "window2")
    window2.panes = panes2

    expected = {
        "single": [
            {
                "direction": {"expected": SPLIT_HORIZONTAL, "actual": SPLIT_VERTICAL,},
                "split_from": {},
                "start_dir": {},
            }
        ]
    }
    actual = {"single": window1.get_pane_differences(window2.panes)}

    panes1.append(Pane("pane3", "p", SPLIT_HORIZONTAL))
    panes2.append(Pane("pane4", "p", SPLIT_HORIZONTAL))
    panes1[-1].set_target("pane1")
    panes2[-1].set_target("pane2")

    expected["multi"] = deepcopy(expected["single"])
    expected["multi"].append(
        {"split_from": {"expected": "pane1", "actual": "pane2"}, "start_dir": {}}
    )
    actual["multi"] = window1.get_pane_differences(window2.panes)

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #2
0
def test_get_split_command(capsys):
    """
    Tests the command to generate the split works correctly
    """
    pane = Pane("identity", type("Window", (object, ), {"number": 1}),
                SPLIT_VERTICAL)

    expected = {}
    actual = {}

    window = type("FakeWindow", (object, ), {"number": 1})
    (Pane("pane1", window,
          SPLIT_HORIZONTAL).set_session_name("session").set_number(1))

    expected["empty"] = "split-window -{0}".format(SPLIT_VERTICAL)
    actual["empty"] = pane.get_split_command()

    pane.set_start_dir('-c "home"')
    expected["with_dir"] = "split-window -{0} {1}".format(
        SPLIT_VERTICAL, '-c "home"')
    actual["with_dir"] = pane.get_split_command()

    pane.set_session_name("session").set_number(0).set_target("pane1")
    expected["all"] = "split-window -{0} -t {2} {1}".format(
        SPLIT_VERTICAL, '-c "home"', get_pane_syntax("session", 1, 1))
    actual["all"] = pane.get_split_command()

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #3
0
def test_get_sets(capsys):
    """
    Test setting and getting of attributes
    """
    (Pane("target", "fake_window",
          None).set_session_name("session").set_number(0))
    pane = Pane("identity", "fake_window", SPLIT_VERTICAL, True)
    pane.set_number(5).set_session_name("session").set_target(
        "target").set_start_dir("dir").set_size(30, 40)

    properties = {
        "identity": "identity",
        "number": 5,
        "window": "fake_window",
        "direction": SPLIT_VERTICAL,
        "split_from": "target",
        "session_name": "session",
        "start_dir": "dir",
        "command": "",
        "width": 30,
        "height": 40,
        "is_first": True,
    }

    assert_objects_equal(properties, pane, properties.keys(), capsys)
Example #4
0
    def add_pane(self, pane: Pane) -> "Window":
        """
        Adds a pane to this window

        Parameters
        ----------
        pane : Pane
            The pane to add to the window

        Returns
        -------
        This instance
        """
        self.panes.append(pane)
        if pane.split_from is not None:
            parent_pane_number = self.objects.get_pane_by_id(
                pane.split_from).number
        # Tmux numbers panes left-to-right & top-down, order dependent on initial split
        # Each time a pane is split, the number increases by one from where it was split
        # Thus, anything equal to or larger than the initial pane will increase by one
        # This emulates that logic in the cached panes here
        if pane.split_from is not None:
            for window_pane in self.panes:
                if window_pane.number >= parent_pane_number + 1:
                    window_pane.number = window_pane.number + 1
            pane.number = parent_pane_number + 1

        return self
def test_add_pane(capsys):
    """
    Test adding a pane
    """
    window = Window("id", "name").set_number(1)
    expected = {"init": []}
    actual = {"init": deepcopy(window.panes)}

    pane = (
        Pane("identity", window, SPLIT_HORIZONTAL)
        .set_session_name("session")
        .set_number(0)
    )
    window.add_pane(pane)

    expected["single"] = 1
    actual["single"] = window.get_pane_count()

    pane2 = (
        Pane("identity2", window, SPLIT_HORIZONTAL)
        .set_session_name("session")
        .set_number(2)
        .set_target("identity")
    )
    window.add_pane(pane2)
    expected["get"] = {"id": id(pane), "num": 1}
    actual["get"] = {"id": id(window.get_pane(0)), "num": pane2.number}

    pane3 = (
        Pane("identity3", window, SPLIT_HORIZONTAL)
        .set_session_name("session")
        .set_number(2)
        .set_target("identity")
    )
    window.add_pane(pane3)
    expected["inserted"] = 1
    actual["inserted"] = pane3.number
    expected["previous"] = 2
    actual["previous"] = pane2.number

    expected["middle"] = id(pane2)
    actual["middle"] = id(window.get_pane(1))

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #6
0
    def add_simple_pane(self, win_id: str, parent_id: str = None) -> None:
        """
        Adds a pane to this window

        Parameters
        ----------
        win_id : str
            The window ID to prefix this pane with
        parent_id = None : str
            Optionally, the ID of this pane's parent
        """
        if parent_id:
            number = self.objects.get_pane_by_id(parent_id).number + 1
        else:
            number = 0

        debug("Window", "add_simple_pane", "Adding pane: " + str(number))
        # The layout is a single pane
        pane = Pane(win_id + str(number), self, None, True)
        self.panes_added += 1
        # All that's left after the comma is the pane number
        pane.set_number(number)
        self.panes.append(pane)
Example #7
0
def test_get_target(capsys):
    """
    Verify getting of target works as expected
    """
    window = type("FakeWindow", (object, ), {"number": 1})
    pane = (Pane("identity1", window,
                 SPLIT_VERTICAL).set_session_name("session").set_number(1))

    pane2 = (Pane("identity2", window,
                  SPLIT_VERTICAL).set_session_name("session").set_number(2))

    expected = {"none": None}
    actual = {"none": pane.get_target()}

    pane.set_target("identity2")
    expected["target"] = get_pane_syntax("session", 1, 2)
    actual["target"] = pane.get_target()

    pane2.set_number(3)

    expected[""] = get_pane_syntax("session", 1, 3)
    actual[""] = pane2.get_target(True)

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #8
0
def test_pane_creation(capsys):
    """
    Test that a pane that is created has the proper attributes
    """
    pane = Pane("identity", "fake_window", SPLIT_HORIZONTAL)
    properties = {
        "identity": "identity",
        "window": "fake_window",
        "direction": SPLIT_HORIZONTAL,
        "split_from": None,
        "command": "",
        "width": 0,
        "height": 0,
        "is_first": False,
    }

    assert_objects_equal(properties, pane, properties.keys(), capsys)
Example #9
0
def test_get_command(capsys):
    """
    Verify getting the command works
    """
    pane = Pane("identity", "fake_window", SPLIT_VERTICAL)

    expected = {"none": ""}
    actual = {"none": pane.get_run_command()}

    pane.set_command("foo")
    expected["cmd"] = 'send-keys "foo" "C-m"'
    actual["cmd"] = pane.get_run_command()

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #10
0
    def add_pane_by_layout(self,
                           layout: str,
                           pane_number: int,
                           direction: str,
                           parent_identity: str = None) -> None:
        """
        Adds a new pane, using the layout to fill in details

        Parameters
        ----------
        layout : string
            The layout string for the pane
            Will be in the following format:
              <size>,<offset_left>,<offset_top>
        pane_number : number
            The number of the pane, from the layout
        direction : string
            The direction this pane should be split from the previous one
        parent_identity : string
            The identity of the parent pane
            Used to re-order panes, if needed
        """
        size = parse_size(layout.split(",")[0])
        pane_id = "win{0}pane{1}".format(self.number, self.panes_added)
        pane = (Pane(pane_id, self, direction,
                     self.panes_added == 0).set_session_name(
                         self.session_name).set_size(
                             100 * size["width"] / self.base_width,
                             100 * size["height"] / self.base_height,
                         ))

        parent = None
        try:
            parent = self.objects.get_pane_by_id(parent_identity)
            parent_number = parent.number
        except NameError:
            parent_number = None

        pane_number = (parent_number +
                       1 if parent_number is not None else self.panes_added)

        if parent_number is not None and self.panes_added > pane_number:
            debug(
                "Window",
                "add_pane",
                "Incrementing pane numbers above {0}".format(pane_number),
            )
            for pane_to_check in self.panes:
                if pane_to_check.number >= pane_number:
                    pane_to_check.set_number(pane_to_check.number + 1)

        pane.set_number(pane_number)

        if self.last_pane is not None and parent_number is None:
            pane.set_target(self.last_pane)
        elif parent:
            pane.set_target(parent.identity)

        self.last_pane = pane.identity
        self.panes_added += 1
        self.panes.append(pane)
        debug(
            "Window",
            "add_pane",
            "Adding pane number {0} for parent {1} with size {2}".format(
                pane_number, parent_number, size),
        )
Example #11
0
def test_command_quoting(capsys):
    """
    Verify commands are escaped properly
    """
    pane = Pane("identity", "fake_window", SPLIT_VERTICAL)
    pane.set_command("foo")

    expected = {}
    actual = {}
    expected["command1"] = '"foo" "C-m"'
    actual["command1"] = pane.command

    pane.set_command("foo", False)
    expected["command2"] = '"foo"'
    actual["command2"] = pane.command

    pane.set_command('echo "foo"')
    expected["command3"] = '"echo \\"foo\\"" "C-m"'
    actual["command3"] = pane.command

    pane.set_command("echo 'foo'")
    expected["command4"] = '"echo \'foo\'" "C-m"'
    actual["command4"] = pane.command

    pane.set_command('"echo \\"things\\"" "C-m"')
    expected["already_quoted"] = '"echo \\"things\\"" "C-m"'
    actual["already_quoted"] = pane.command

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #12
0
def test_differences(capsys):
    """
    Test differences between panes
    """
    pane1 = Pane("identity1", "fake_window", SPLIT_VERTICAL)
    pane2 = Pane("identity2", "fake_window", SPLIT_VERTICAL)

    expected = {"none": {}}
    actual = {"none": pane1.get_difference(pane2)}

    pane2 = Pane("identity3", "fake_window", SPLIT_HORIZONTAL)
    expected["dir"] = {
        "direction": {
            "expected": SPLIT_VERTICAL,
            "actual": SPLIT_HORIZONTAL
        }
    }
    actual["dir"] = pane1.get_difference(pane2)

    pane2 = Pane("identity4", "fake_window", SPLIT_VERTICAL)
    pane1.set_size(10, 20)
    pane2.set_size(30, 40)
    expected["size"] = {
        "width": {
            "expected": 10,
            "actual": 30
        },
        "height": {
            "expected": 20,
            "actual": 40
        },
    }
    actual["size"] = pane1.get_difference(pane2)

    assert_objects_equal(expected, actual, expected.keys(), capsys)
Example #13
0
def test_size_command(capsys):
    """
    Check the size command works appropriately
    """
    window = type("FakeWindow", (object, ), {"number": 1})
    target = get_pane_syntax("s", 1, 1)
    pane = Pane("identity1", window,
                SPLIT_VERTICAL).set_session_name("s").set_number(1)
    expected = {"none": ""}
    actual = {"none": pane.get_size_command()}

    pane.set_size(10)
    expected["width"] = "resize-pane -t {0} -x {1} ".format(target, 10)
    actual["width"] = pane.get_size_command()

    pane.set_size(10, 20)
    expected["both"] = "resize-pane -t {0} -x {1} -y {2}".format(
        target, 10, 20)
    actual["both"] = pane.get_size_command()

    pane = (Pane("identity2", window,
                 SPLIT_VERTICAL).set_session_name("s").set_number(1).set_size(
                     0, 20))
    expected["both"] = "resize-pane -t {0}  -y {1}".format(target, 20)
    actual["both"] = pane.get_size_command()

    assert_objects_equal(expected, actual, expected.keys(), capsys)
    def add_pane(
        self,
        identity: str,
        split_dir: str,
        window: str = None,
        split_from: str = None,
        working_directory: str = None,
    ) -> "TmuxBuilder":
        """
        Adds a new pane to target or current window

        Parameters
        ----------
        identity : string
            A unique ID for this pane
        split_dir : string
            The direction to split the window, either 'h' (horizontal) or 'v' (vertical)
        window : string|None
            The window ID to create the pane in, defaults to the current window
        split_from : string|None
            The pane ID to split this one from
        working_directory : string|None
            The working directory to set for this pane

        Returns
        -------
        This instance
        """
        if split_dir not in [None, "h", "v"]:
            raise ValueError(
                'Invalid split direction specified: must be "v" or "h"!')

        if split_from:
            target = self.objects.get_pane_by_id(split_from)
            window = target.window
        else:
            window = self.__coalesce_window(window)
            target = None

        panes = window.get_pane_count()

        start_dir = None
        if working_directory:
            start_dir = format_working_directory(working_directory)
        elif window.start_dir:
            start_dir = window.start_dir
        else:
            start_dir = format_working_directory(self.start_dir)

        pane = (Pane(identity, window, split_dir,
                     panes == 0).set_number(panes).set_session_name(
                         self.session_name).set_start_dir(start_dir))

        if split_from:
            pane.set_target(split_from)

        window.add_pane(pane)

        # The index of the current pane, not the number
        self.current_pane = window.get_pane_count() - 1
        return self