def test_automatic_rename_option(session): """With option automatic-rename: on.""" yaml_config = test_utils.read_config_file( "workspacebuilder/window_automatic_rename.yaml") s = session sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(yaml_config).get() # This should be a command guaranteed to be terminal name across systems portable_command = sconfig["windows"][0]["panes"][0]["shell_command"][0][ "cmd"] # If a command is like "man ls", get the command base name, "ls" if " " in portable_command: portable_command = portable_command.split(" ")[0] builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count assert len(s._windows) == window_count for w, wconf in builder.iter_create_windows(s): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size p = p assert len(s._windows), window_count assert isinstance(w, Window) assert w.show_window_option("automatic-rename") == "on" assert len(s._windows) == window_count window_count += 1 w.select_layout(wconf["layout"]) assert s.name != "tmuxp" w = s.windows[0] def check_window_name_mismatch() -> bool: session.server._update_windows() return w.name != portable_command assert retry_until(check_window_name_mismatch, 2, interval=0.25) pane_base_index = w.show_window_option("pane-base-index", g=True) w.select_pane(pane_base_index) def check_window_name_match() -> bool: session.server._update_windows() return w.name == portable_command assert retry_until( check_window_name_match, 2, interval=0.25), f"Window name {w.name} should be {portable_command}" w.select_pane("-D") assert retry_until(check_window_name_mismatch, 2, interval=0.25)
def test_function_times_out_no_rise(): ini = time() def never_true(): return False retry_until(never_true, 1, raises=False) end = time() assert abs((end - ini) - 1.0) < 0.01
def test_function_times_out(): ini = time() def never_true(): return False with pytest.raises(WaitTimeout): retry_until(never_true, 1) end = time() assert abs((end - ini) - 1.0) < 0.01
def test_load_workspace_enter( tmp_path: pathlib.Path, server: libtmux.Server, monkeypatch: pytest.MonkeyPatch, yaml, output, should_see, ): yaml_config = tmp_path / "simple.yaml" yaml_config.write_text( yaml, encoding="utf-8", ) sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(str(yaml_config)).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig, server=server) builder.build() session = builder.session pane = session.attached_pane def fn(): captured_pane = "\n".join(pane.capture_pane()) if should_see: return output in captured_pane else: return output not in captured_pane assert retry_until( fn, 1), f'Should{" " if should_see else "not "} output in captured pane'
def test_start_directory(session, tmp_path: pathlib.Path): yaml_config = test_utils.read_config_file( "workspacebuilder/start_directory.yaml") test_dir = tmp_path / "foo bar" test_dir.mkdir() test_config = yaml_config.format(TEST_DIR=test_dir) sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(test_config).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) assert session == builder.session dirs = ["/usr/bin", "/dev", str(test_dir), "/usr", "/usr"] for path, window in zip(dirs, session.windows): for p in window.panes: def f(): p.server._update_panes() pane_path = p.current_path return path in pane_path or pane_path == path # handle case with OS X adding /private/ to /tmp/ paths assert retry_until(f)
def assert_last_line(p, s): def f(): pane_out = p.cmd("capture-pane", "-p", "-J").stdout while not pane_out[-1].strip(): # delete trailing lines tmux 1.8 pane_out.pop() return len(pane_out) > 1 and pane_out[-2].strip() == s # Print output for easier debugging if assertion fails return retry_until(f, raises=False)
def test_retry_three_times(): ini = time() value = 0 def call_me_three_times(): nonlocal value if value == 2: return True value += 1 return False retry_until(call_me_three_times, 1) end = time() assert abs((end - ini) - 0.1) < 0.01
def test_suppress_history(session): yaml_config = test_utils.read_config_file( "workspacebuilder/suppress_history.yaml") sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) inHistoryWindow = session.find_where({"window_name": "inHistory"}) isMissingWindow = session.find_where({"window_name": "isMissing"}) def assertHistory(cmd, hist): return "inHistory" in cmd and cmd.endswith(hist) def assertIsMissing(cmd, hist): return "isMissing" in cmd and not cmd.endswith(hist) for w, window_name, assertCase in [ (inHistoryWindow, "inHistory", assertHistory), (isMissingWindow, "isMissing", assertIsMissing), ]: assert w.name == window_name w.select_window() p = w.attached_pane p.select_pane() # Print the last-in-history command in the pane p.cmd("send-keys", " fc -ln -1") p.cmd("send-keys", "Enter") buffer_name = "test" sent_cmd = None def f(): # from v0.7.4 libtmux session.cmd adds target -t self.id by default # show-buffer doesn't accept -t, use global cmd. # Get the contents of the pane p.cmd("capture-pane", "-b", buffer_name) captured_pane = session.server.cmd("show-buffer", "-b", buffer_name) session.server.cmd("delete-buffer", "-b", buffer_name) # Parse the sent and last-in-history commands sent_cmd = captured_pane.stdout[0].strip() history_cmd = captured_pane.stdout[-2].strip() return assertCase(sent_cmd, history_cmd) assert retry_until( f), f"Unknown sent command: [{sent_cmd}] in {assertCase}"
def test_pane_order(session): """Pane ordering based on position in config and ``pane_index``. Regression test for https://github.com/tmux-python/tmuxp/issues/15. """ yaml_config = test_utils.read_config_file( "workspacebuilder/pane_ordering.yaml").format( HOME=os.path.realpath(os.path.expanduser("~"))) # test order of `panes` (and pane_index) above against pane_dirs pane_paths = [ "/usr/bin", "/usr", "/etc", os.path.realpath(os.path.expanduser("~")), ] s = session sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) window_count = len(session._windows) # current window count assert len(s._windows) == window_count for w, wconf in builder.iter_create_windows(s): for p in builder.iter_create_panes(w, wconf): w.select_layout("tiled") # fix glitch with pane size assert len(s._windows) == window_count assert isinstance(w, Window) assert len(s._windows) == window_count window_count += 1 for w in session.windows: pane_base_index = w.show_window_option("pane-base-index", g=True) for p_index, p in enumerate(w.list_panes(), start=pane_base_index): assert int(p_index) == int(p.index) # pane-base-index start at base-index, pane_paths always start # at 0 since python list. pane_path = pane_paths[p_index - pane_base_index] def f(): p.server._update_panes() return p.current_path == pane_path assert retry_until(f)
def test_start_directory_relative(session, tmp_path: pathlib.Path): """Same as above test, but with relative start directory, mimicking loading it from a location of project file. Like:: $ tmuxp load ~/workspace/myproject/.tmuxp.yaml instead of:: $ cd ~/workspace/myproject/.tmuxp.yaml $ tmuxp load . """ yaml_config = test_utils.read_config_file( "workspacebuilder/start_directory_relative.yaml") test_dir = tmp_path / "foo bar" test_dir.mkdir() config_dir = tmp_path / "testRelConfigDir" config_dir.mkdir() test_config = yaml_config.format(TEST_DIR=test_dir) sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(test_config).get() # the second argument of os.getcwd() mimics the behavior # the CLI loader will do, but it passes in the config file's location. sconfig = config.expand(sconfig, config_dir) sconfig = config.trickle(sconfig) assert os.path.exists(config_dir) assert os.path.exists(test_dir) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) assert session == builder.session dirs = [ "/usr/bin", "/dev", str(test_dir), str(config_dir), str(config_dir) ] for path, window in zip(dirs, session.windows): for p in window.panes: def f(): p.server._update_panes() # Handle case where directories resolve to /private/ in OSX pane_path = p.current_path return path in pane_path or pane_path == path assert retry_until(f)
def test_window_shell(session): yaml_config = test_utils.read_config_file( "workspacebuilder/window_shell.yaml") s = session sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) builder = WorkspaceBuilder(sconf=sconfig) for w, wconf in builder.iter_create_windows(s): if "window_shell" in wconf: assert wconf["window_shell"] == "top" def f(): session.server._update_windows() return w["window_name"] != "top" retry_until(f) assert w.name != "top"
def test_focus_pane_index(session): yaml_config = test_utils.read_config_file( "workspacebuilder/focus_and_pane.yaml") sconfig = kaptan.Kaptan(handler="yaml") sconfig = sconfig.import_config(yaml_config).get() sconfig = config.expand(sconfig) sconfig = config.trickle(sconfig) builder = WorkspaceBuilder(sconf=sconfig) builder.build(session=session) assert session.attached_window.name == "focused window" pane_base_index = int( session.attached_window.show_window_option("pane-base-index", g=True)) if not pane_base_index: pane_base_index = 0 else: pane_base_index = int(pane_base_index) # get the pane index for each pane pane_base_indexes = [] for pane in session.attached_window.panes: pane_base_indexes.append(int(pane.index)) pane_indexes_should_be = [pane_base_index + x for x in range(0, 3)] assert pane_indexes_should_be == pane_base_indexes w = session.attached_window assert w.name != "man" pane_path = "/usr" p = None def f(): nonlocal p p = w.attached_pane p.server._update_panes() return p.current_path == pane_path assert retry_until(f) assert p.current_path == pane_path proc = session.cmd("show-option", "-gv", "base-index") base_index = int(proc.stdout[0]) session.server._update_windows() window3 = session.find_where({"window_index": str(base_index + 2)}) assert isinstance(window3, Window) p = None pane_path = "/" def f(): nonlocal p p = window3.attached_pane p.server._update_panes() return p.current_path == pane_path assert retry_until(f) assert p.current_path == pane_path