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
|
import os
import shutil
import signal
import subprocess
import pytest
import libqtile.config
import libqtile.confreader
import libqtile.layout
from libqtile.bar import Bar
from libqtile.widget.base import ORIENTATION_HORIZONTAL
@pytest.fixture(scope="function")
def fake_bar():
return FakeBar([])
class FakeBar(Bar):
def __init__(self, widgets, size=24, width=100, window=None, **config):
Bar.__init__(self, widgets, size, **config)
self.height = size
self.width = width
self.window = window
self.horizontal = ORIENTATION_HORIZONTAL
def draw(self):
pass
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_DIR = os.path.join(os.path.dirname(TEST_DIR), "data")
@pytest.fixture(scope="module")
def svg_img_as_pypath():
"Return the py.path object of a svg image"
import py
audio_volume_muted = os.path.join(
DATA_DIR,
"svg",
"audio-volume-muted.svg",
)
audio_volume_muted = py.path.local(audio_volume_muted)
return audio_volume_muted
@pytest.fixture(scope="module")
def fake_qtile():
import asyncio
def no_op(*args, **kwargs):
pass
class FakeQtile:
def __init__(self):
self.register_widget = no_op
# Widgets call call_soon(asyncio.create_task, self._config_async)
# at _configure. The coroutine needs to be run in a loop to suppress
# warnings
def call_soon(self, func, *args):
coroutines = [arg for arg in args if asyncio.iscoroutine(arg)]
if coroutines:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
for func in coroutines:
loop.run_until_complete(func)
loop.close()
return FakeQtile()
# Fixture that defines a minimal configurations for testing widgets.
# When used in a test, the function needs to receive a list of screens
# (including bar and widgets) as an argument. This config can then be
# passed to the manager to start.
@pytest.fixture(scope="function")
def minimal_conf_noscreen():
class MinimalConf(libqtile.confreader.Config):
auto_fullscreen = False
keys = []
mouse = []
groups = [libqtile.config.Group("a"), libqtile.config.Group("b")]
layouts = [libqtile.layout.stack.Stack(num_stacks=1)]
floating_layout = libqtile.resources.default_config.floating_layout
screens = []
reconfigure_screens = False
return MinimalConf
@pytest.fixture(scope="function")
def dbus(monkeypatch):
# for Github CI/Ubuntu, dbus-launch is provided by "dbus-x11" package
launcher = shutil.which("dbus-launch")
# If dbus-launch can't be found then tests will fail so we
# need to skip
if launcher is None:
pytest.skip("dbus-launch must be installed")
# dbus-launch prints two lines which should be set as
# environmental variables
result = subprocess.run(launcher, capture_output=True)
pid = None
for line in result.stdout.decode().splitlines():
# dbus server addresses can have multiple "=" so
# we use partition to split by the first one onle
var, _, val = line.partition("=")
# Use monkeypatch to set these variables so they are
# removed at end of test.
monkeypatch.setitem(os.environ, var, val)
# We want the pid so we can kill the process when the
# test is finished
if var == "DBUS_SESSION_BUS_PID":
try:
pid = int(val)
except ValueError:
pass
# Environment is set and dbus server should be running
yield
# Test is over so kill dbus session
if pid:
os.kill(pid, signal.SIGTERM)
|