Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for the get-tree script #29

Merged
merged 1 commit into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
all: format test lint typecheck

test:
poetry run pytest --cov
poetry run pytest --cov -m "not e2e"

format:
# reformat all files
Expand Down
20 changes: 19 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ mypy = "^0.812"
flake8-annotations = "^2.6.2"
codecov = "^2.1.11"
pytest = "^6"
pytest-mock = "^3.6.1"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand All @@ -44,7 +45,6 @@ omit = [
# top-level scripts
"src/magic_tiler/magic_tiler.py",
"src/magic_tiler/get_window_sizes.py",
"src/magic_tiler/get_tree.py",
]

[tool.coverage.report]
Expand All @@ -62,3 +62,6 @@ get-tree = "magic_tiler.get_tree:main"
[tool.pytest.ini_options]
addopts = "--exitfirst --verbosity=2"
log_file_level = "DEBUG"
markers = [
'e2e',
]
25 changes: 16 additions & 9 deletions src/magic_tiler/get_tree.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import click
import i3ipc

from magic_tiler.utils import interfaces
from magic_tiler.utils import sway


def print_tree(window_manager: interfaces.TilingWindowManager) -> None:
for node in window_manager.get_tree():
click.echo(click.style(node.name, fg="green", bold=True))
click.echo(f"x, y: ({node.rect.x}, {node.rect.y})")
click.echo(f"width, height: ({node.rect.width}, {node.rect.height})")
click.echo(f"gaps: {node.gaps}")
click.echo("marks: ", nl=False)
click.echo(click.style(f"{node.marks}", fg="cyan"))
click.echo()


@click.command()
def main() -> None:
i3 = i3ipc.Connection()
current_workspace = i3.get_tree().find_focused().workspace()
for node in current_workspace.descendants():
print(node.name)
print(f"x, y: ({node.rect.x}, {node.rect.y})")
print(f"width, height: ({node.rect.width}, {node.rect.height})")
print(f"gaps: {node.gaps}")
print()
window_manager = sway.Sway()
print_tree(window_manager)
6 changes: 5 additions & 1 deletion src/magic_tiler/utils/interfaces.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import abc
from typing import Dict
from typing import Dict, List

from magic_tiler.utils import dtos
from magic_tiler.utils import tree
Expand Down Expand Up @@ -36,6 +36,10 @@ def num_workspace_windows(self) -> int:
"""Count the windows on the current workspace"""
pass

@abc.abstractmethod
def get_tree(self) -> List:
pass


class ConfigReader(object):
@abc.abstractmethod
Expand Down
24 changes: 15 additions & 9 deletions src/magic_tiler/utils/sway.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ def get_window_sizes(self) -> Dict[Tuple, Dict[str, float]]:
for window in self._get_windows_in_current_workspace()
}

def get_tree(self) -> List:
current_workspace = self._get_focused_window().workspace()
return current_workspace.descendants()

def _get_focused_window(self) -> i3ipc.Con:
tree = self._sway.get_tree()
focused = tree.find_focused()
Expand All @@ -81,15 +85,7 @@ def _get_window(self, mark: str) -> i3ipc.Con:
return windows[0]

def _get_windows_in_current_workspace(self) -> List[i3ipc.Con]:
workspaces = self._sway.get_workspaces()
for workspace in workspaces:
if workspace.focused:
if workspace.num == -1:
raise RuntimeError("The current workspace is a named workspace")
current_workspace_num = workspace.num
break
else:
raise RuntimeError("There is no current workspace")
current_workspace_num = self._get_current_workspace_num()
windows_in_current_workspace = []
for container in self._sway.get_tree().leaves():
logging.debug(
Expand All @@ -100,6 +96,16 @@ def _get_windows_in_current_workspace(self) -> List[i3ipc.Con]:
windows_in_current_workspace.append(container)
return windows_in_current_workspace

def _get_current_workspace_num(self) -> i3ipc.Con:
workspaces = self._sway.get_workspaces()
for workspace in workspaces:
if workspace.focused:
if workspace.num == -1:
raise RuntimeError("The current workspace is a named workspace")
return workspace.num
else:
raise RuntimeError("There is no current workspace")

@property
def num_workspace_windows(self) -> int:
"""Get the number of windows open on the current workspace
Expand Down
7 changes: 7 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import click.testing
import pytest


@pytest.fixture(scope="session")
def click_runner():
return click.testing.CliRunner()
50 changes: 49 additions & 1 deletion tests/fakes.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Dict
from typing import Dict, List, NamedTuple, Optional

from magic_tiler.utils import dtos
from magic_tiler.utils import interfaces
from magic_tiler.utils import tree

Expand Down Expand Up @@ -36,3 +37,50 @@ def __init__(self, config_dict: Dict) -> None:

def to_dict(self) -> Dict:
return self._config_dict


class FakeRect(NamedTuple):
x: int
y: int
width: int
height: int


class FakeNode(NamedTuple):
name: str
rect: FakeRect
gaps: Optional[str]
marks: List


class FakeWindowManager(interfaces.TilingWindowManager):
def __init__(self, tree: Optional[List[FakeNode]] = None):
if tree:
self._tree = tree

def make_window(self, window_details: dtos.WindowDetails) -> None:
pass

def resize_width(
self, target_window: dtos.WindowDetails, container_percentage: int
) -> None:
pass

def resize_height(
self, target_window: dtos.WindowDetails, container_percentage: int
) -> None:
pass

def focus(self, target_window: dtos.WindowDetails) -> None:
pass

def split(self, split_type: str) -> None:
pass

@property
def num_workspace_windows(self) -> int:
"""Count the windows on the current workspace"""
pass

def get_tree(self) -> List[FakeNode]:
return self._tree
43 changes: 43 additions & 0 deletions tests/test_get_tree.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import pytest

from magic_tiler import get_tree
from tests import fakes


@pytest.fixture
def mock_window_manager(mocker):
return mocker.patch("magic_tiler.utils.sway.Sway")


@pytest.fixture
def mock_print_tree(mocker):
mock = mocker.patch("magic_tiler.get_tree.print_tree")
mock.return_value = """
Alacritty
x, y: (803, 294)
width, height: (787, 846)
gaps: None
marks: ['tests']
"""
return mock


@pytest.mark.e2e
def test_get_tree(click_runner):
result = click_runner.invoke(get_tree.main)
assert result.exit_code == 0


def test_click_handles_options(click_runner, mock_window_manager, mock_print_tree):
click_runner.invoke(get_tree.main)
mock_print_tree.assert_called_once_with(mock_window_manager())


def test_print_tree_runs():
tree = [
fakes.FakeNode("alacritty", fakes.FakeRect(0, 0, 100, 200), None, ["editor"]),
fakes.FakeNode("alacritty", fakes.FakeRect(0, 0, 100, 200), None, ["editor"]),
fakes.FakeNode("alacritty", fakes.FakeRect(0, 0, 100, 200), None, ["editor"]),
]
window_manager = fakes.FakeWindowManager(tree=tree)
get_tree.print_tree(window_manager)
3 changes: 3 additions & 0 deletions tests/test_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ def focus(self, target_window: dtos.WindowDetails) -> None:
def split(self, split_type: str) -> None:
self._calls.append(WindowManagerCall("split", arg=split_type))

def get_tree(self):
pass


class LayoutTestCase(NamedTuple):
config: Dict
Expand Down