Skip to content

Commit a6d9688

Browse files
authored
CLI Tests: Refactor to tests/cli (#858)
2 parents bf0c47b + 742ef33 commit a6d9688

File tree

11 files changed

+1447
-1403
lines changed

11 files changed

+1447
-1403
lines changed

CHANGES

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ $ pipx install --suffix=@next 'tmuxp' --pip-args '\--pre' --force
1919

2020
<!-- Maintainers, insert changes / features for the next release here -->
2121

22+
### Internal improvements
23+
24+
- CLI Tests: Refactor `tests/cli` (#858)
25+
26+
- Fix resolution of direcotries
27+
2228
## tmuxp 1.23.0 (_yanked_, 2022-12-28)
2329

2430
_Yanked release: `tmuxp load` issues, see #856_

tests/cli/__init__.py

Whitespace-only changes.

tests/cli/test_cli.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import argparse
2+
import os
3+
import pathlib
4+
import typing as t
5+
6+
import pytest
7+
8+
import libtmux
9+
from libtmux.server import Server
10+
from tmuxp import cli
11+
from tmuxp.cli.import_config import get_teamocil_dir, get_tmuxinator_dir
12+
from tmuxp.cli.load import _reattach, load_plugins
13+
from tmuxp.cli.utils import tmuxp_echo
14+
from tmuxp.config_reader import ConfigReader
15+
from tmuxp.workspace import loader
16+
from tmuxp.workspace.builder import WorkspaceBuilder
17+
from tmuxp.workspace.finders import find_workspace_file
18+
19+
from ..fixtures import utils as test_utils
20+
21+
if t.TYPE_CHECKING:
22+
import _pytest.capture
23+
24+
25+
def test_creates_config_dir_not_exists(tmp_path: pathlib.Path) -> None:
26+
"""cli.startup() creates config dir if not exists."""
27+
28+
cli.startup(tmp_path)
29+
assert os.path.exists(tmp_path)
30+
31+
32+
@pytest.mark.parametrize(
33+
"cli_args",
34+
[
35+
(["--help"]),
36+
(["-h"]),
37+
],
38+
)
39+
def test_help(
40+
cli_args: t.List[str],
41+
tmp_path: pathlib.Path,
42+
monkeypatch: pytest.MonkeyPatch,
43+
capsys: pytest.CaptureFixture,
44+
) -> None:
45+
try:
46+
cli.cli(cli_args)
47+
except SystemExit:
48+
pass
49+
result = capsys.readouterr()
50+
51+
assert "usage: tmuxp [-h] [--version] [--log-level log-level]" in result.out
52+
53+
54+
def test_resolve_behavior(
55+
tmp_path: pathlib.Path, monkeypatch: pytest.MonkeyPatch
56+
) -> None:
57+
expect = tmp_path
58+
monkeypatch.chdir(tmp_path)
59+
assert pathlib.Path("../").resolve() == pathlib.Path(os.path.dirname(expect))
60+
assert pathlib.Path(".").resolve() == expect
61+
assert pathlib.Path("./").resolve() == expect
62+
assert pathlib.Path(expect).resolve() == expect
63+
64+
65+
def test_get_tmuxinator_dir(monkeypatch: pytest.MonkeyPatch) -> None:
66+
assert get_tmuxinator_dir() == os.path.expanduser("~/.tmuxinator/")
67+
68+
monkeypatch.setenv("HOME", "/moo")
69+
assert get_tmuxinator_dir() == "/moo/.tmuxinator/"
70+
assert get_tmuxinator_dir() == os.path.expanduser("~/.tmuxinator/")
71+
72+
73+
def test_get_teamocil_dir(monkeypatch: pytest.MonkeyPatch) -> None:
74+
assert get_teamocil_dir() == os.path.expanduser("~/.teamocil/")
75+
76+
monkeypatch.setenv("HOME", "/moo")
77+
assert get_teamocil_dir() == "/moo/.teamocil/"
78+
assert get_teamocil_dir() == os.path.expanduser("~/.teamocil/")
79+
80+
81+
def test_pass_config_dir_ClickPath(
82+
tmp_path: pathlib.Path,
83+
monkeypatch: pytest.MonkeyPatch,
84+
capsys: pytest.CaptureFixture,
85+
) -> None:
86+
87+
configdir = tmp_path / "myconfigdir"
88+
configdir.mkdir()
89+
user_config_name = "myconfig"
90+
user_config = configdir / f"{user_config_name}.yaml"
91+
user_config.touch()
92+
93+
expect = str(user_config)
94+
95+
parser = argparse.ArgumentParser()
96+
parser.add_argument("workspace_file", type=str)
97+
98+
def config_cmd(workspace_file: str) -> None:
99+
tmuxp_echo(find_workspace_file(workspace_file, workspace_dir=configdir))
100+
101+
def check_cmd(config_arg) -> "_pytest.capture.CaptureResult":
102+
args = parser.parse_args([config_arg])
103+
config_cmd(workspace_file=args.workspace_file)
104+
return capsys.readouterr()
105+
106+
monkeypatch.chdir(configdir)
107+
108+
assert expect in check_cmd("myconfig").out
109+
assert expect in check_cmd("myconfig.yaml").out
110+
assert expect in check_cmd("./myconfig.yaml").out
111+
assert str(user_config) in check_cmd(str(configdir / "myconfig.yaml")).out
112+
113+
with pytest.raises(FileNotFoundError):
114+
assert "FileNotFoundError" in check_cmd(".tmuxp.json").out
115+
116+
117+
def test_reattach_plugins(
118+
monkeypatch_plugin_test_packages: None, server: "Server"
119+
) -> None:
120+
config_plugins = test_utils.read_workspace_file("workspace/builder/plugin_r.yaml")
121+
122+
sconfig = ConfigReader._load(format="yaml", content=config_plugins)
123+
sconfig = loader.expand(sconfig)
124+
125+
# open it detached
126+
builder = WorkspaceBuilder(
127+
sconf=sconfig, plugins=load_plugins(sconfig), server=server
128+
)
129+
builder.build()
130+
131+
try:
132+
_reattach(builder)
133+
except libtmux.exc.LibTmuxException:
134+
pass
135+
136+
assert builder.session is not None
137+
proc = builder.session.cmd("display-message", "-p", "'#S'")
138+
139+
assert proc.stdout[0] == "'plugin_test_r'"

tests/cli/test_convert.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import io
2+
import json
3+
import pathlib
4+
import typing as t
5+
6+
import pytest
7+
8+
from tmuxp import cli
9+
10+
11+
@pytest.mark.parametrize(
12+
"cli_args",
13+
[
14+
(["convert", "."]),
15+
(["convert", ".tmuxp.yaml"]),
16+
(["convert", ".tmuxp.yaml", "-y"]),
17+
(["convert", ".tmuxp.yml"]),
18+
(["convert", ".tmuxp.yml", "-y"]),
19+
],
20+
)
21+
def test_convert(
22+
cli_args: t.List[str],
23+
tmp_path: pathlib.Path,
24+
monkeypatch: pytest.MonkeyPatch,
25+
) -> None:
26+
# create dummy tmuxp yaml so we don't get yelled at
27+
filename = cli_args[1]
28+
if filename == ".":
29+
filename = ".tmuxp.yaml"
30+
file_ext = filename.rsplit(".", 1)[-1]
31+
assert file_ext in ["yaml", "yml"], file_ext
32+
workspace_file_path = tmp_path / filename
33+
workspace_file_path.write_text("\nsession_name: hello\n", encoding="utf-8")
34+
oh_my_zsh_path = tmp_path / ".oh-my-zsh"
35+
oh_my_zsh_path.mkdir()
36+
monkeypatch.setenv("HOME", str(tmp_path))
37+
38+
monkeypatch.chdir(tmp_path)
39+
40+
# If autoconfirm (-y) no need to prompt y
41+
input_args = "y\ny\n" if "-y" not in cli_args else ""
42+
43+
monkeypatch.setattr("sys.stdin", io.StringIO(input_args))
44+
try:
45+
cli.cli(cli_args)
46+
except SystemExit:
47+
pass
48+
tmuxp_json = tmp_path / ".tmuxp.json"
49+
assert tmuxp_json.exists()
50+
assert tmuxp_json.open().read() == json.dumps({"session_name": "hello"}, indent=2)
51+
52+
53+
@pytest.mark.parametrize(
54+
"cli_args",
55+
[
56+
(["convert", "."]),
57+
(["convert", ".tmuxp.json"]),
58+
(["convert", ".tmuxp.json", "-y"]),
59+
],
60+
)
61+
def test_convert_json(
62+
cli_args: t.List[str],
63+
tmp_path: pathlib.Path,
64+
monkeypatch: pytest.MonkeyPatch,
65+
) -> None:
66+
# create dummy tmuxp yaml so we don't get yelled at
67+
json_config = tmp_path / ".tmuxp.json"
68+
json_config.write_text('{"session_name": "hello"}', encoding="utf-8")
69+
oh_my_zsh_path = tmp_path / ".oh-my-zsh"
70+
oh_my_zsh_path.mkdir()
71+
monkeypatch.setenv("HOME", str(tmp_path))
72+
73+
monkeypatch.chdir(tmp_path)
74+
75+
# If autoconfirm (-y) no need to prompt y
76+
input_args = "y\ny\n" if "-y" not in cli_args else ""
77+
78+
monkeypatch.setattr("sys.stdin", io.StringIO(input_args))
79+
try:
80+
cli.cli(cli_args)
81+
except SystemExit:
82+
pass
83+
84+
tmuxp_yaml = tmp_path / ".tmuxp.yaml"
85+
assert tmuxp_yaml.exists()
86+
assert tmuxp_yaml.open().read() == "session_name: hello\n"

tests/cli/test_debug_info.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import pathlib
2+
3+
import pytest
4+
5+
from tmuxp import cli
6+
7+
8+
def test_debug_info_cli(
9+
monkeypatch: pytest.MonkeyPatch,
10+
tmp_path: pathlib.Path,
11+
capsys: pytest.CaptureFixture,
12+
) -> None:
13+
monkeypatch.setenv("SHELL", "/bin/bash")
14+
15+
cli.cli(["debug-info"])
16+
cli_output = capsys.readouterr().out
17+
assert "environment" in cli_output
18+
assert "python version" in cli_output
19+
assert "system PATH" in cli_output
20+
assert "tmux version" in cli_output
21+
assert "libtmux version" in cli_output
22+
assert "tmuxp version" in cli_output
23+
assert "tmux path" in cli_output
24+
assert "tmuxp path" in cli_output
25+
assert "shell" in cli_output
26+
assert "tmux session" in cli_output
27+
assert "tmux windows" in cli_output
28+
assert "tmux panes" in cli_output
29+
assert "tmux global options" in cli_output
30+
assert "tmux window options" in cli_output

tests/cli/test_freeze.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import io
2+
import pathlib
3+
import typing as t
4+
5+
import pytest
6+
7+
from libtmux.server import Server
8+
from tmuxp import cli
9+
from tmuxp.config_reader import ConfigReader
10+
11+
12+
@pytest.mark.parametrize(
13+
"cli_args,inputs",
14+
[
15+
(["freeze", "myfrozensession"], ["y\n", "./la.yaml\n", "y\n"]),
16+
( # Exists
17+
["freeze", "myfrozensession"],
18+
["y\n", "./exists.yaml\n", "./la.yaml\n", "y\n"],
19+
),
20+
( # Imply current session if not entered
21+
["freeze"],
22+
["y\n", "./la.yaml\n", "y\n"],
23+
),
24+
(["freeze"], ["y\n", "./exists.yaml\n", "./la.yaml\n", "y\n"]), # Exists
25+
],
26+
)
27+
def test_freeze(
28+
server: "Server",
29+
cli_args: t.List[str],
30+
inputs: t.List[str],
31+
tmp_path: pathlib.Path,
32+
monkeypatch: pytest.MonkeyPatch,
33+
) -> None:
34+
monkeypatch.setenv("HOME", str(tmp_path))
35+
exists_yaml = tmp_path / "exists.yaml"
36+
exists_yaml.touch()
37+
38+
server.new_session(session_name="myfirstsession")
39+
server.new_session(session_name="myfrozensession")
40+
41+
# Assign an active pane to the session
42+
second_session = server.sessions[1]
43+
first_pane_on_second_session_id = second_session.windows[0].panes[0].pane_id
44+
assert first_pane_on_second_session_id
45+
monkeypatch.setenv("TMUX_PANE", first_pane_on_second_session_id)
46+
47+
monkeypatch.chdir(tmp_path)
48+
# Use tmux server (socket name) used in the test
49+
assert server.socket_name is not None
50+
cli_args = cli_args + ["-L", server.socket_name]
51+
52+
monkeypatch.setattr("sys.stdin", io.StringIO("".join(inputs)))
53+
try:
54+
cli.cli(cli_args)
55+
except SystemExit:
56+
pass
57+
58+
yaml_config_path = tmp_path / "la.yaml"
59+
assert yaml_config_path.exists()
60+
61+
yaml_config = yaml_config_path.open().read()
62+
frozen_config = ConfigReader._load(format="yaml", content=yaml_config)
63+
64+
assert frozen_config["session_name"] == "myfrozensession"
65+
66+
67+
@pytest.mark.parametrize(
68+
"cli_args,inputs",
69+
[
70+
( # Overwrite
71+
["freeze", "mysession", "--force"],
72+
["\n", "\n", "y\n", "./exists.yaml\n", "y\n"],
73+
),
74+
( # Imply current session if not entered
75+
["freeze", "--force"],
76+
["\n", "\n", "y\n", "./exists.yaml\n", "y\n"],
77+
),
78+
],
79+
)
80+
def test_freeze_overwrite(
81+
server: "Server",
82+
cli_args: t.List[str],
83+
inputs: t.List[str],
84+
tmp_path: pathlib.Path,
85+
monkeypatch: pytest.MonkeyPatch,
86+
) -> None:
87+
monkeypatch.setenv("HOME", str(tmp_path))
88+
exists_yaml = tmp_path / "exists.yaml"
89+
exists_yaml.touch()
90+
91+
server.new_session(session_name="mysession")
92+
93+
monkeypatch.chdir(tmp_path)
94+
# Use tmux server (socket name) used in the test
95+
assert server.socket_name is not None
96+
cli_args = cli_args + ["-L", server.socket_name]
97+
98+
monkeypatch.setattr("sys.stdin", io.StringIO("".join(inputs)))
99+
try:
100+
cli.cli(cli_args)
101+
except SystemExit:
102+
pass
103+
104+
yaml_config_path = tmp_path / "exists.yaml"
105+
assert yaml_config_path.exists()

0 commit comments

Comments
 (0)