blob: 9b6444e0b6d063abf40c8c34f31a071a6dc2709e [file] [log] [blame]
# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Tests for pw_console.console_app"""
import logging
import unittest
from unittest.mock import MagicMock
from prompt_toolkit.application import create_app_session
from prompt_toolkit.output import ColorDepth
# inclusive-language: ignore
from prompt_toolkit.output import DummyOutput as FakeOutput
from pw_console.console_app import ConsoleApp
from pw_console.console_prefs import ConsolePrefs
from pw_console.window_manager import _WINDOW_SPLIT_ADJUST
from pw_console.window_list import _WINDOW_HEIGHT_ADJUST, DisplayMode
def _create_console_app(logger_count=2):
prefs = ConsolePrefs(project_file=False,
project_user_file=False,
user_file=False)
prefs.set_code_theme('default')
console_app = ConsoleApp(color_depth=ColorDepth.DEPTH_8_BIT, prefs=prefs)
console_app.focus_on_container = MagicMock()
loggers = {}
for i in range(logger_count):
loggers['Log{}'.format(i)] = [
logging.getLogger('test_log{}'.format(i))
]
for window_title, logger_instances in loggers.items():
console_app.add_log_handler(window_title, logger_instances)
return console_app
_WINDOW_MANAGER_WIDTH = 80
_WINDOW_MANAGER_HEIGHT = 30
_DEFAULT_WINDOW_WIDTH = 10
_DEFAULT_WINDOW_HEIGHT = 10
def _window_list_widths(window_manager):
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
return [
window_list.width.preferred
for window_list in window_manager.window_lists
]
def _window_list_heights(window_manager):
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
return [
window_list.height.preferred
for window_list in window_manager.window_lists
]
def _window_pane_widths(window_manager, window_list_index=0):
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
return [
pane.width.preferred
for pane in window_manager.window_lists[window_list_index].active_panes
]
def _window_pane_heights(window_manager, window_list_index=0):
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
return [
pane.height.preferred
for pane in window_manager.window_lists[window_list_index].active_panes
]
def _window_pane_counts(window_manager):
return [
len(window_list.active_panes)
for window_list in window_manager.window_lists
]
def window_pane_titles(window_manager):
return [[
pane.pane_title() + ' - ' + pane.pane_subtitle()
for pane in window_list.active_panes
] for window_list in window_manager.window_lists]
def target_list_and_pane(window_manager, list_index, pane_index):
# pylint: disable=protected-access
# Bypass prompt_toolkit has_focus()
pane = window_manager.window_lists[list_index].active_panes[pane_index]
# If the pane is in focus it will be visible.
pane.show_pane = True
window_manager._get_active_window_list_and_pane = (
MagicMock( # type: ignore
return_value=(
window_manager.window_lists[list_index],
window_manager.window_lists[list_index].
active_panes[pane_index],
)))
class TestWindowManager(unittest.TestCase):
# pylint: disable=protected-access
"""Tests for window management functions."""
def setUp(self):
self.maxDiff = None # pylint: disable=invalid-name
def test_find_window_list_and_pane(self) -> None:
"""Test getting the window list for a given pane."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=3)
window_manager = console_app.window_manager
self.assertEqual([4], _window_pane_counts(window_manager))
# Move 2 windows to the right into their own splits
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 1, 0)
window_manager.move_pane_right()
# 3 splits, first split has 2 windows
self.assertEqual([2, 1, 1], _window_pane_counts(window_manager))
# Move the first window in the first split left
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_left()
# 4 splits, each with their own window
self.assertEqual([1, 1, 1, 1], _window_pane_counts(window_manager))
# Move the first window to the right
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
# 3 splits, first split has 2 windows
self.assertEqual([2, 1, 1], _window_pane_counts(window_manager))
target_pane = window_manager.window_lists[2].active_panes[0]
result_window_list, result_pane_index = (
window_manager._find_window_list_and_pane_index(target_pane))
self.assertEqual(
(result_window_list, result_pane_index),
(window_manager.window_lists[2], 0),
)
window_manager.remove_pane(target_pane)
self.assertEqual([2, 1], _window_pane_counts(window_manager))
def test_window_list_moving_and_resizing(self) -> None:
"""Test window split movement resizing."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=3)
window_manager = console_app.window_manager
target_list_and_pane(window_manager, 0, 0)
# Should have one window list split of size 50.
self.assertEqual(
_window_list_widths(window_manager),
[_WINDOW_MANAGER_WIDTH],
)
# Move one pane to the right, creating a new window_list split.
window_manager.move_pane_right()
self.assertEqual(_window_list_widths(window_manager), [
int(_WINDOW_MANAGER_WIDTH / 2),
int(_WINDOW_MANAGER_WIDTH / 2),
])
# Move another pane to the right twice, creating a third
# window_list split.
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
# Above window pane is at a new location
target_list_and_pane(window_manager, 1, 0)
window_manager.move_pane_right()
# Should have 3 splits now
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3),
],
)
# Total of 4 active panes
self.assertEqual(len(list(window_manager.active_panes())), 4)
# Target the middle split
target_list_and_pane(window_manager, 1, 0)
# Shrink the middle split twice
window_manager.shrink_split()
window_manager.shrink_split()
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3) -
(2 * _WINDOW_SPLIT_ADJUST),
int(_WINDOW_MANAGER_WIDTH / 3) +
(2 * _WINDOW_SPLIT_ADJUST),
],
)
# Target the first split
target_list_and_pane(window_manager, 0, 0)
window_manager.reset_split_sizes()
# Shrink the first split twice
window_manager.shrink_split()
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 3) -
(1 * _WINDOW_SPLIT_ADJUST),
int(_WINDOW_MANAGER_WIDTH / 3) +
(1 * _WINDOW_SPLIT_ADJUST),
int(_WINDOW_MANAGER_WIDTH / 3),
],
)
# Target the third (last) split
target_list_and_pane(window_manager, 2, 0)
window_manager.reset_split_sizes()
# Shrink the third split once
window_manager.shrink_split()
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3) +
(1 * _WINDOW_SPLIT_ADJUST),
int(_WINDOW_MANAGER_WIDTH / 3) -
(1 * _WINDOW_SPLIT_ADJUST),
],
)
window_manager.reset_split_sizes()
# Enlarge the third split a few times.
window_manager.enlarge_split()
window_manager.enlarge_split()
window_manager.enlarge_split()
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3) -
(3 * _WINDOW_SPLIT_ADJUST),
int(_WINDOW_MANAGER_WIDTH / 3) +
(3 * _WINDOW_SPLIT_ADJUST),
],
)
# Target the middle split
target_list_and_pane(window_manager, 1, 0)
# Move the middle window pane left
window_manager.move_pane_left()
# This is called on the next render pass
window_manager.rebalance_window_list_sizes()
# Middle split should be removed
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 2) -
(3 * _WINDOW_SPLIT_ADJUST),
# This split is removed
int(_WINDOW_MANAGER_WIDTH / 2) +
(2 * _WINDOW_SPLIT_ADJUST),
],
)
# Revert sizes to default
window_manager.reset_split_sizes()
self.assertEqual(
_window_list_widths(window_manager),
[
int(_WINDOW_MANAGER_WIDTH / 2),
int(_WINDOW_MANAGER_WIDTH / 2),
],
)
def test_get_pane_titles(self) -> None:
"""Test window resizing."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=3)
window_manager = console_app.window_manager
list_pane_titles = [
# Remove mouse click handler partials in tup[2]
[(tup[0], tup[1]) for tup in window_list.get_pane_titles()]
for window_list in window_manager.window_lists
]
self.assertEqual(
list_pane_titles[0],
[('', ' '), ('class:window-tab-inactive', ' Log2 test_log2 '),
('', ' '), ('class:window-tab-inactive', ' Log1 test_log1 '),
('', ' '), ('class:window-tab-inactive', ' Log0 test_log0 '),
('', ' '), ('class:window-tab-inactive', ' Python Repl '),
('', ' ')],
)
def test_window_pane_movement_resizing(self) -> None:
"""Test window resizing."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=3)
window_manager = console_app.window_manager
# 4 panes, 3 for the loggers and 1 for the repl.
self.assertEqual(
len(window_manager.first_window_list().active_panes), 4)
def target_window_pane(index: int):
# Bypass prompt_toolkit has_focus()
window_manager._get_active_window_list_and_pane = (
MagicMock( # type: ignore
return_value=(
window_manager.window_lists[0],
window_manager.window_lists[0].active_panes[index],
)))
window_list = console_app.window_manager.first_window_list()
window_list.get_current_active_pane = (
MagicMock( # type: ignore
return_value=window_list.active_panes[index]))
# Target the first window pane
target_window_pane(0)
# Shrink the first pane
window_manager.shrink_pane()
self.assertEqual(
_window_pane_heights(window_manager),
[
_DEFAULT_WINDOW_HEIGHT - (1 * _WINDOW_HEIGHT_ADJUST),
_DEFAULT_WINDOW_HEIGHT + (1 * _WINDOW_HEIGHT_ADJUST),
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT,
],
)
# Reset pane sizes
window_manager.window_lists[0].current_window_list_height = (
4 * _DEFAULT_WINDOW_HEIGHT)
window_manager.reset_pane_sizes()
self.assertEqual(
_window_pane_heights(window_manager),
[
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT,
],
)
# Shrink last pane
target_window_pane(3)
window_manager.shrink_pane()
self.assertEqual(
_window_pane_heights(window_manager),
[
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT + (1 * _WINDOW_HEIGHT_ADJUST),
_DEFAULT_WINDOW_HEIGHT - (1 * _WINDOW_HEIGHT_ADJUST),
],
)
# Enlarge second pane
target_window_pane(1)
window_manager.reset_pane_sizes()
window_manager.enlarge_pane()
window_manager.enlarge_pane()
self.assertEqual(
_window_pane_heights(window_manager),
[
_DEFAULT_WINDOW_HEIGHT,
_DEFAULT_WINDOW_HEIGHT + (2 * _WINDOW_HEIGHT_ADJUST),
_DEFAULT_WINDOW_HEIGHT - (2 * _WINDOW_HEIGHT_ADJUST),
_DEFAULT_WINDOW_HEIGHT,
],
)
# Check window pane ordering
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log2 - test_log2',
'Log1 - test_log1',
'Log0 - test_log0',
'Python Repl - ',
],
],
)
target_window_pane(0)
window_manager.move_pane_down()
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log1 - test_log1',
'Log2 - test_log2',
'Log0 - test_log0',
'Python Repl - ',
],
],
)
target_window_pane(2)
window_manager.move_pane_up()
target_window_pane(1)
window_manager.move_pane_up()
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log0 - test_log0',
'Log1 - test_log1',
'Log2 - test_log2',
'Python Repl - ',
],
],
)
target_window_pane(0)
window_manager.move_pane_up()
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log0 - test_log0',
'Log1 - test_log1',
'Log2 - test_log2',
'Python Repl - ',
],
],
)
def test_focus_next_and_previous_pane(self) -> None:
"""Test switching focus to next and previous window panes."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=4)
window_manager = console_app.window_manager
window_manager.window_lists[0].set_display_mode(DisplayMode.STACK)
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log3 - test_log3',
'Log2 - test_log2',
'Log1 - test_log1',
'Log0 - test_log0',
'Python Repl - ',
],
],
)
# Scenario: Move between panes with a single stacked window list.
# Set the first pane in focus.
target_list_and_pane(window_manager, 0, 0)
# Switch focus to the next pane
window_manager.focus_next_pane()
# Pane index 1 should now be focused.
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[1])
console_app.focus_on_container.reset_mock()
# Set the first pane in focus.
target_list_and_pane(window_manager, 0, 0)
# Switch focus to the previous pane
window_manager.focus_previous_pane()
# Previous pane should wrap around to the last pane in the first
# window_list.
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[-1])
console_app.focus_on_container.reset_mock()
# Set the last pane in focus.
target_list_and_pane(window_manager, 0, 4)
# Switch focus to the next pane
window_manager.focus_next_pane()
# Next pane should wrap around to the first pane in the first
# window_list.
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[0])
console_app.focus_on_container.reset_mock()
# Scenario: Move between panes with a single tabbed window list.
# Switch to Tabbed view mode
window_manager.window_lists[0].set_display_mode(DisplayMode.TABBED)
# The set_display_mode call above will call focus_on_container once.
console_app.focus_on_container.reset_mock()
# Setup the switch_to_tab mock
window_manager.window_lists[0].switch_to_tab = MagicMock(
wraps=window_manager.window_lists[0].switch_to_tab)
# Set the first pane/tab in focus.
target_list_and_pane(window_manager, 0, 0)
# Switch focus to the next pane/tab
window_manager.focus_next_pane()
# Check switch_to_tab is called
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(1)
# And that focus_on_container is called only once
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[1])
console_app.focus_on_container.reset_mock()
window_manager.window_lists[0].switch_to_tab.reset_mock()
# Set the last pane/tab in focus.
target_list_and_pane(window_manager, 0, 4)
# Switch focus to the next pane/tab
window_manager.focus_next_pane()
# Check switch_to_tab is called
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(0)
# And that focus_on_container is called only once
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[0])
console_app.focus_on_container.reset_mock()
window_manager.window_lists[0].switch_to_tab.reset_mock()
# Set the first pane/tab in focus.
target_list_and_pane(window_manager, 0, 0)
# Switch focus to the prev pane/tab
window_manager.focus_previous_pane()
# Check switch_to_tab is called
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(4)
# And that focus_on_container is called only once
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[4])
console_app.focus_on_container.reset_mock()
window_manager.window_lists[0].switch_to_tab.reset_mock()
# Scenario: Move between multiple window lists with mixed stacked
# and tabbed view modes.
# Setup: Move two panes to the right into their own stacked
# window_list.
target_list_and_pane(window_manager, 0, 4)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 0, 3)
window_manager.move_pane_right()
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log3 - test_log3',
'Log2 - test_log2',
'Log1 - test_log1',
],
[
'Log0 - test_log0',
'Python Repl - ',
],
],
)
# Setup the switch_to_tab mock on the second window_list
window_manager.window_lists[1].switch_to_tab = MagicMock(
wraps=window_manager.window_lists[1].switch_to_tab)
# Set Log1 in focus
target_list_and_pane(window_manager, 0, 2)
window_manager.focus_next_pane()
# Log0 should now have focus
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[1].active_panes[0])
console_app.focus_on_container.reset_mock()
# Set Log0 in focus
target_list_and_pane(window_manager, 1, 0)
window_manager.focus_previous_pane()
# Log1 should now have focus
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[2])
# The first window list is in tabbed mode so switch_to_tab should be
# called once.
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(2)
# Reset
window_manager.window_lists[0].switch_to_tab.reset_mock()
console_app.focus_on_container.reset_mock()
# Set Python Repl in focus
target_list_and_pane(window_manager, 1, 1)
window_manager.focus_next_pane()
# Log3 should now have focus
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[0])
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(0)
# Reset
window_manager.window_lists[0].switch_to_tab.reset_mock()
console_app.focus_on_container.reset_mock()
# Set Log3 in focus
target_list_and_pane(window_manager, 0, 0)
window_manager.focus_next_pane()
# Log2 should now have focus
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[0].active_panes[1])
window_manager.window_lists[
0].switch_to_tab.assert_called_once_with(1)
# Reset
window_manager.window_lists[0].switch_to_tab.reset_mock()
console_app.focus_on_container.reset_mock()
# Set Python Repl in focus
target_list_and_pane(window_manager, 1, 1)
window_manager.focus_previous_pane()
# Log0 should now have focus
console_app.focus_on_container.assert_called_once_with(
window_manager.window_lists[1].active_panes[0])
# The second window list is in stacked mode so switch_to_tab should
# not be called.
window_manager.window_lists[1].switch_to_tab.assert_not_called()
# Reset
window_manager.window_lists[1].switch_to_tab.reset_mock()
console_app.focus_on_container.reset_mock()
def test_resize_vertical_splits(self) -> None:
"""Test resizing window splits."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=4)
window_manager = console_app.window_manager
# Required before moving windows
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
window_manager.create_root_container()
# Vertical split by default
self.assertTrue(window_manager.vertical_window_list_spliting())
# Move windows to create 3 splits
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 1, 1)
window_manager.move_pane_right()
# Check windows are where expected
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log1 - test_log1',
'Log0 - test_log0',
'Python Repl - ',
],
[
'Log2 - test_log2',
],
[
'Log3 - test_log3',
],
],
)
# Check initial split widths
widths = [
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3),
int(_WINDOW_MANAGER_WIDTH / 3),
]
self.assertEqual(_window_list_widths(window_manager), widths)
# Decrease size of first split
window_manager.adjust_split_size(window_manager.window_lists[0],
-4)
widths = [
widths[0] - (4 * _WINDOW_SPLIT_ADJUST),
widths[1] + (4 * _WINDOW_SPLIT_ADJUST),
widths[2],
]
self.assertEqual(_window_list_widths(window_manager), widths)
# Increase size of last split
widths = [
widths[0],
widths[1] - (4 * _WINDOW_SPLIT_ADJUST),
widths[2] + (4 * _WINDOW_SPLIT_ADJUST),
]
window_manager.adjust_split_size(window_manager.window_lists[2], 4)
self.assertEqual(_window_list_widths(window_manager), widths)
# Check heights are all the same
window_manager.rebalance_window_list_sizes()
heights = [
int(_WINDOW_MANAGER_HEIGHT),
int(_WINDOW_MANAGER_HEIGHT),
int(_WINDOW_MANAGER_HEIGHT),
]
self.assertEqual(_window_list_heights(window_manager), heights)
def test_resize_horizontal_splits(self) -> None:
"""Test resizing window splits."""
with create_app_session(output=FakeOutput()):
console_app = _create_console_app(logger_count=4)
window_manager = console_app.window_manager
# We want horizontal window splits
window_manager.vertical_window_list_spliting = (MagicMock(
return_value=False))
self.assertFalse(window_manager.vertical_window_list_spliting())
# Required before moving windows
window_manager.update_window_manager_size(_WINDOW_MANAGER_WIDTH,
_WINDOW_MANAGER_HEIGHT)
window_manager.create_root_container()
# Move windows to create 3 splits
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 0, 0)
window_manager.move_pane_right()
target_list_and_pane(window_manager, 1, 1)
window_manager.move_pane_right()
# Check windows are where expected
self.assertEqual(
window_pane_titles(window_manager),
[
[
'Log1 - test_log1',
'Log0 - test_log0',
'Python Repl - ',
],
[
'Log2 - test_log2',
],
[
'Log3 - test_log3',
],
],
)
# Check initial split widths
heights = [
int(_WINDOW_MANAGER_HEIGHT / 3),
int(_WINDOW_MANAGER_HEIGHT / 3),
int(_WINDOW_MANAGER_HEIGHT / 3),
]
self.assertEqual(_window_list_heights(window_manager), heights)
# Decrease size of first split
window_manager.adjust_split_size(window_manager.window_lists[0],
-4)
heights = [
heights[0] - (4 * _WINDOW_SPLIT_ADJUST),
heights[1] + (4 * _WINDOW_SPLIT_ADJUST),
heights[2],
]
self.assertEqual(_window_list_heights(window_manager), heights)
# Increase size of last split
heights = [
heights[0],
heights[1] - (4 * _WINDOW_SPLIT_ADJUST),
heights[2] + (4 * _WINDOW_SPLIT_ADJUST),
]
window_manager.adjust_split_size(window_manager.window_lists[2], 4)
self.assertEqual(_window_list_heights(window_manager), heights)
# Check widths are all the same
window_manager.rebalance_window_list_sizes()
widths = [
int(_WINDOW_MANAGER_WIDTH),
int(_WINDOW_MANAGER_WIDTH),
int(_WINDOW_MANAGER_WIDTH),
]
self.assertEqual(_window_list_widths(window_manager), widths)
if __name__ == '__main__':
unittest.main()