1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
|
"""Tests for utility functions in libtmux."""
from __future__ import annotations
import re
import sys
import typing as t
import pytest
import libtmux
from libtmux._compat import LooseVersion
from libtmux.common import (
TMUX_MAX_VERSION,
TMUX_MIN_VERSION,
get_libtmux_version,
get_version,
has_gt_version,
has_gte_version,
has_lt_version,
has_lte_version,
has_minimum_version,
has_version,
session_check_name,
tmux_cmd,
)
from libtmux.exc import BadSessionName, LibTmuxException, TmuxCommandNotFound
if t.TYPE_CHECKING:
from libtmux.session import Session
version_regex = re.compile(r"([0-9]\.[0-9])|(master)")
def test_allows_master_version(monkeypatch: pytest.MonkeyPatch) -> None:
"""Assert get_version() works with builds from git trunk."""
class Hi:
stdout: t.ClassVar = ["tmux master"]
stderr = None
def mock_tmux_cmd(*args: t.Any, **kwargs: t.Any) -> Hi:
return Hi()
monkeypatch.setattr(libtmux.common, "tmux_cmd", mock_tmux_cmd)
assert has_minimum_version()
assert has_gte_version(TMUX_MIN_VERSION)
assert has_gt_version(TMUX_MAX_VERSION), "Greater than the max-supported version"
assert get_version() == f"{TMUX_MAX_VERSION}-master", (
"Is the latest supported version with -master appended"
)
def test_allows_next_version(monkeypatch: pytest.MonkeyPatch) -> None:
"""Assert get_version() supports next version."""
TMUX_NEXT_VERSION = "3.7"
class Hi:
stdout: t.ClassVar = [f"tmux next-{TMUX_NEXT_VERSION}"]
stderr = None
def mock_tmux_cmd(*args: t.Any, **kwargs: t.Any) -> Hi:
return Hi()
monkeypatch.setattr(libtmux.common, "tmux_cmd", mock_tmux_cmd)
assert has_minimum_version()
assert has_gte_version(TMUX_MIN_VERSION)
assert has_gt_version(TMUX_MAX_VERSION), "Greater than the max-supported version"
assert get_version() == TMUX_NEXT_VERSION
def test_get_version_openbsd(monkeypatch: pytest.MonkeyPatch) -> None:
"""Assert get_version() with OpenBSD versions."""
class Hi:
stderr: t.ClassVar = ["tmux: unknown option -- V"]
def mock_tmux_cmd(*args: t.Any, **kwargs: t.Any) -> Hi:
return Hi()
monkeypatch.setattr(libtmux.common, "tmux_cmd", mock_tmux_cmd)
monkeypatch.setattr(sys, "platform", "openbsd 5.2")
assert has_minimum_version()
assert has_gte_version(TMUX_MIN_VERSION)
assert has_gt_version(TMUX_MAX_VERSION), "Greater than the max-supported version"
assert get_version() == f"{TMUX_MAX_VERSION}-openbsd", (
"Is the latest supported version with -openbsd appended"
)
def test_get_version_too_low(monkeypatch: pytest.MonkeyPatch) -> None:
"""Assert get_version() raises if tmux version too low."""
class Hi:
stderr: t.ClassVar = ["tmux: unknown option -- V"]
def mock_tmux_cmd(*args: t.Any, **kwargs: t.Any) -> Hi:
return Hi()
monkeypatch.setattr(libtmux.common, "tmux_cmd", mock_tmux_cmd)
with pytest.raises(LibTmuxException) as exc_info:
get_version()
exc_info.match("does not meet the minimum tmux version requirement")
def test_ignores_letter_versions(monkeypatch: pytest.MonkeyPatch) -> None:
"""Tests version utilities ignores letters such as 1.8b.
See ticket https://github.com/tmux-python/tmuxp/issues/55.
In version 0.1.7 this is adjusted to use LooseVersion, in order to
allow letters.
"""
monkeypatch.setattr(libtmux.common, "TMUX_MIN_VERSION", "1.9a")
result = has_minimum_version()
assert result
monkeypatch.setattr(libtmux.common, "TMUX_MIN_VERSION", "1.8a")
result = has_minimum_version()
assert result
# Should not throw
assert isinstance(has_version("1.8"), bool)
assert isinstance(has_version("1.8a"), bool)
assert isinstance(has_version("1.9a"), bool)
def test_error_version_less_1_7(monkeypatch: pytest.MonkeyPatch) -> None:
"""Test raises if tmux version less than 1.7."""
def mock_get_version() -> LooseVersion:
return LooseVersion("1.7")
monkeypatch.setattr(libtmux.common, "get_version", mock_get_version)
with pytest.raises(LibTmuxException) as excinfo:
has_minimum_version()
excinfo.match(r"libtmux only supports")
with pytest.raises(LibTmuxException) as excinfo:
has_minimum_version()
excinfo.match(r"libtmux only supports")
def test_has_version() -> None:
"""Test has_version()."""
assert has_version(str(get_version()))
def test_has_gt_version() -> None:
"""Test has_gt_version()."""
assert has_gt_version("1.6")
assert has_gt_version("1.6b")
assert not has_gt_version("4.0")
assert not has_gt_version("4.0b")
def test_has_gte_version() -> None:
"""Test has_gte_version()."""
assert has_gte_version("1.6")
assert has_gte_version("1.6b")
assert has_gte_version(str(get_version()))
assert not has_gte_version("4.0")
assert not has_gte_version("4.0b")
def test_has_lt_version() -> None:
"""Test has_lt_version()."""
assert has_lt_version("4.0a")
assert has_lt_version("4.0")
assert not has_lt_version("1.7")
assert not has_lt_version(str(get_version()))
def test_has_lte_version() -> None:
"""Test has_lti_version()."""
assert has_lte_version("4.0a")
assert has_lte_version("4.0")
assert has_lte_version(str(get_version()))
assert not has_lte_version("1.7")
assert not has_lte_version("1.7b")
def test_tmux_cmd_raises_on_not_found(monkeypatch: pytest.MonkeyPatch) -> None:
"""Verify raises if tmux command not found."""
monkeypatch.setenv("PATH", "")
with pytest.raises(TmuxCommandNotFound):
tmux_cmd("-V")
def test_tmux_cmd_unicode(session: Session) -> None:
"""Verify tmux commands with unicode."""
session.cmd("new-window", "-t", 3, "-n", "юникод", "-F", "Ελληνικά")
class SessionCheckName(t.NamedTuple):
"""Test fixture for test_session_check_name()."""
session_name: str | None
raises: bool
exc_msg_regex: str | None
@pytest.mark.parametrize(
SessionCheckName._fields,
[
SessionCheckName("", True, "empty"),
SessionCheckName(None, True, "empty"),
SessionCheckName("my great session.", True, "contains periods"),
SessionCheckName("name: great session", True, "contains colons"),
SessionCheckName("new great session", False, None),
SessionCheckName("ajf8a3fa83fads,,,a", False, None),
],
)
def test_session_check_name(
session_name: str | None,
raises: bool,
exc_msg_regex: str | None,
) -> None:
"""Verify session_check_name()."""
if raises:
with pytest.raises(BadSessionName) as exc_info:
session_check_name(session_name)
if exc_msg_regex is not None:
assert exc_info.match(exc_msg_regex)
else:
session_check_name(session_name)
def test_get_libtmux_version() -> None:
"""Verify get_libtmux_version()."""
from libtmux.__about__ import __version__
version = get_libtmux_version()
assert isinstance(version, LooseVersion)
assert LooseVersion(__version__) == version
|