|
3 | 3 | import pathlib
|
4 | 4 | import textwrap
|
5 | 5 | import time
|
| 6 | +import typing as t |
6 | 7 |
|
7 | 8 | import pytest
|
8 | 9 |
|
9 | 10 | import kaptan
|
10 | 11 |
|
11 | 12 | import libtmux
|
12 |
| -from libtmux import Window |
13 | 13 | from libtmux.common import has_gte_version, has_lt_version
|
14 | 14 | from libtmux.test import retry_until, temp_session
|
| 15 | +from libtmux.window import Window |
15 | 16 | from tmuxp import config, exc
|
16 | 17 | from tmuxp.cli.load import load_plugins
|
17 | 18 | from tmuxp.workspacebuilder import WorkspaceBuilder
|
18 | 19 |
|
19 | 20 | from .constants import EXAMPLE_PATH, FIXTURE_PATH
|
20 | 21 | from .fixtures import utils as test_utils
|
21 | 22 |
|
| 23 | +if t.TYPE_CHECKING: |
| 24 | + from libtmux.server import Server |
| 25 | + |
22 | 26 |
|
23 | 27 | def test_split_windows(session):
|
24 | 28 | yaml_config = test_utils.read_config_file("workspacebuilder/two_pane.yaml")
|
@@ -1209,11 +1213,100 @@ def height(p):
|
1209 | 1213 | def width(p):
|
1210 | 1214 | return int(p._info["pane_width"])
|
1211 | 1215 |
|
1212 |
| - assert height(main_horizontal_pane) > height(panes[0]) |
| 1216 | + main_horizontal_pane_height = height(main_horizontal_pane) |
| 1217 | + pane_heights = [height(pane) for pane in panes] |
| 1218 | + # TODO: When libtmux has new pane formatters added, use that to detect top / bottom |
| 1219 | + assert all( |
| 1220 | + main_horizontal_pane_height != pane_height for pane_height in pane_heights |
| 1221 | + ), "The top row should not be the same size as the bottom row (even though it can)" |
| 1222 | + assert all( |
| 1223 | + pane_heights[0] == pane_height for pane_height in pane_heights |
| 1224 | + ), "The bottom row should be uniform height" |
1213 | 1225 | assert width(main_horizontal_pane) > width(panes[0])
|
1214 | 1226 |
|
1215 | 1227 | def is_almost_equal(x, y):
|
1216 | 1228 | return abs(x - y) <= 1
|
1217 | 1229 |
|
1218 | 1230 | assert is_almost_equal(height(panes[0]), height(panes[1]))
|
1219 | 1231 | assert is_almost_equal(width(panes[0]), width(panes[1]))
|
| 1232 | + |
| 1233 | + |
| 1234 | +class DefaultSizeNamespaceFixture(t.NamedTuple): |
| 1235 | + test_id: str |
| 1236 | + TMUXP_DEFAULT_SIZE: t.Optional[str] |
| 1237 | + raises: bool |
| 1238 | + confoverrides: t.Dict[str, t.Any] |
| 1239 | + |
| 1240 | + |
| 1241 | +DEFAULT_SIZE_FIXTURES = [ |
| 1242 | + DefaultSizeNamespaceFixture( |
| 1243 | + test_id="default-behavior", |
| 1244 | + TMUXP_DEFAULT_SIZE=None, |
| 1245 | + raises=False, |
| 1246 | + confoverrides={}, |
| 1247 | + ), |
| 1248 | + DefaultSizeNamespaceFixture( |
| 1249 | + test_id="v1.13.1 default-size-breaks", |
| 1250 | + TMUXP_DEFAULT_SIZE=None, |
| 1251 | + raises=True, |
| 1252 | + confoverrides={"options": {"default-size": "80x24"}}, |
| 1253 | + ), |
| 1254 | + DefaultSizeNamespaceFixture( |
| 1255 | + test_id="v1.13.1-option-workaround", |
| 1256 | + TMUXP_DEFAULT_SIZE=None, |
| 1257 | + raises=False, |
| 1258 | + confoverrides={"options": {"default-size": "800x600"}}, |
| 1259 | + ), |
| 1260 | +] |
| 1261 | + |
| 1262 | + |
| 1263 | +@pytest.mark.parametrize( |
| 1264 | + DefaultSizeNamespaceFixture._fields, |
| 1265 | + DEFAULT_SIZE_FIXTURES, |
| 1266 | + ids=[f.test_id for f in DEFAULT_SIZE_FIXTURES], |
| 1267 | +) |
| 1268 | +@pytest.mark.skipif(has_lt_version("2.9"), reason="default-size only applies there") |
| 1269 | +def test_issue_800_default_size_many_windows( |
| 1270 | + server: "Server", |
| 1271 | + monkeypatch: pytest.MonkeyPatch, |
| 1272 | + test_id: str, |
| 1273 | + TMUXP_DEFAULT_SIZE: t.Optional[str], |
| 1274 | + raises: bool, |
| 1275 | + confoverrides: t.Dict[str, t.Any], |
| 1276 | +) -> None: |
| 1277 | + """Recreate default-size issue. |
| 1278 | +
|
| 1279 | + v1.13.1 added a default-size, but this can break building workspaces with |
| 1280 | + a lot of panes. |
| 1281 | +
|
| 1282 | + See also: https://github.com/tmux-python/tmuxp/issues/800 |
| 1283 | + """ |
| 1284 | + yaml_config = test_utils.read_config_file( |
| 1285 | + "regressions/issue_800_default_size_many_windows.yaml" |
| 1286 | + ) |
| 1287 | + sconfig = kaptan.Kaptan(handler="yaml") |
| 1288 | + sconfig = sconfig.import_config(yaml_config).get() |
| 1289 | + sconfig = config.expand(sconfig) |
| 1290 | + sconfig = config.trickle(sconfig) |
| 1291 | + |
| 1292 | + if isinstance(confoverrides, dict): |
| 1293 | + for k, v in confoverrides.items(): |
| 1294 | + sconfig[k] = v |
| 1295 | + |
| 1296 | + if TMUXP_DEFAULT_SIZE is not None: |
| 1297 | + monkeypatch.setenv("TMUXP_DEFAULT_SIZE", TMUXP_DEFAULT_SIZE) |
| 1298 | + |
| 1299 | + builder = WorkspaceBuilder(sconf=sconfig, server=server) |
| 1300 | + |
| 1301 | + if raises: |
| 1302 | + with pytest.raises(Exception): |
| 1303 | + builder.build() |
| 1304 | + |
| 1305 | + builder.session.kill_session() |
| 1306 | + |
| 1307 | + with pytest.raises(libtmux.exc.LibTmuxException, match="no space for new pane"): |
| 1308 | + builder.build() |
| 1309 | + return |
| 1310 | + |
| 1311 | + builder.build() |
| 1312 | + assert len(server.list_sessions()) == 1 |
0 commit comments