Merge branch 'unit-test-refactoring'
This commit is contained in:
commit
ca9712770a
30 changed files with 888 additions and 681 deletions
|
@ -1,3 +1,10 @@
|
|||
[run]
|
||||
omit =
|
||||
tests/*
|
||||
*mock*
|
||||
*funcsigs*
|
||||
*pbr*
|
||||
*six*
|
||||
/usr/lib*
|
||||
|
||||
[report]
|
||||
|
|
|
@ -25,8 +25,6 @@ class print_usage(argparse.Action):
|
|||
self.print_modules()
|
||||
elif value == "themes":
|
||||
self.print_themes()
|
||||
else:
|
||||
parser.print_help()
|
||||
sys.exit(0)
|
||||
|
||||
def print_themes(self):
|
||||
|
|
|
@ -52,6 +52,9 @@ class Module(object):
|
|||
"""By default, update() is a NOP"""
|
||||
pass
|
||||
|
||||
def update_all(self):
|
||||
self.update(self._widgets)
|
||||
|
||||
def parameter(self, name, default=None):
|
||||
"""Return the config parameter 'name' for this module"""
|
||||
name = "{}.{}".format(self.name, name)
|
||||
|
|
|
@ -53,9 +53,7 @@ class Module(bumblebee.engine.Module):
|
|||
def __init__(self, engine, config):
|
||||
widget = bumblebee.output.Widget(full_text=self.updates)
|
||||
super(Module, self).__init__(engine, config, widget)
|
||||
|
||||
self._next_check = 0
|
||||
widget
|
||||
|
||||
def updates(self, widget):
|
||||
result = []
|
||||
|
|
|
@ -22,7 +22,7 @@ class Module(bumblebee.engine.Module):
|
|||
self._load = [0, 0, 0]
|
||||
try:
|
||||
self._cpus = multiprocessing.cpu_count()
|
||||
except multiprocessing.NotImplementedError as e:
|
||||
except NotImplementedError as e:
|
||||
self._cpus = 1
|
||||
engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE,
|
||||
cmd="gnome-system-monitor")
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
import bumblebee.engine
|
||||
|
||||
ALIASES = [ "test-alias" ]
|
||||
|
||||
class Module(bumblebee.engine.Module):
|
||||
def __init__(self, engine, config):
|
||||
super(Module, self).__init__(engine, config,
|
||||
|
|
|
@ -90,11 +90,6 @@ class Theme(object):
|
|||
"""Return the SBW"""
|
||||
return self._get(widget, "separator-block-width", None)
|
||||
|
||||
def loads(self, data):
|
||||
"""Initialize the theme from a JSON string"""
|
||||
theme = json.loads(data)
|
||||
self._init(theme)
|
||||
|
||||
def _load_icons(self, name):
|
||||
"""Load icons for a theme"""
|
||||
path = "{}/icons/".format(theme_path())
|
||||
|
|
|
@ -15,6 +15,8 @@ def execute(cmd, wait=True):
|
|||
out, _ = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError("{} exited with {}".format(cmd, proc.returncode))
|
||||
if type(out) == str:
|
||||
return out
|
||||
return out.decode("utf-8")
|
||||
return None
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
echo "testing with $(python2 -V 2>&1)"
|
||||
python2 $(which nosetests) --rednose -v tests/
|
||||
python2 $(which nosetests) --rednose -v --with-coverage --cover-erase tests/
|
||||
|
||||
if [ $? == 0 ]; then
|
||||
echo
|
||||
|
||||
echo "testing with $(python3 -V 2>&1)"
|
||||
python3 $(which nosetests-3) --rednose -v tests/
|
||||
python3 $(which nosetests-3) --rednose -v --with-coverage --cover-erase tests/
|
||||
fi
|
||||
|
|
141
tests/mocks.py
Normal file
141
tests/mocks.py
Normal file
|
@ -0,0 +1,141 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import mock
|
||||
import json
|
||||
import shlex
|
||||
import random
|
||||
import subprocess
|
||||
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.output import Widget
|
||||
from bumblebee.config import Config
|
||||
|
||||
def rand(cnt):
|
||||
return "".join(random.choice("abcdefghijklmnopqrstuvwxyz0123456789") for i in range(cnt))
|
||||
|
||||
def setup_test(test, Module):
|
||||
test._stdin, test._select, test.stdin, test.select = epoll_mock("bumblebee.input")
|
||||
|
||||
test.popen = MockPopen()
|
||||
|
||||
test.config = Config()
|
||||
test.input = I3BarInput()
|
||||
test.engine = mock.Mock()
|
||||
test.engine.input = test.input
|
||||
test.input.need_event = True
|
||||
test.module = Module(engine=test.engine, config={ "config": test.config })
|
||||
for widget in test.module.widgets():
|
||||
widget.link_module(test.module)
|
||||
test.anyWidget = widget
|
||||
|
||||
def teardown_test(test):
|
||||
test._stdin.stop()
|
||||
test._select.stop()
|
||||
test.popen.cleanup()
|
||||
|
||||
def epoll_mock(module=""):
|
||||
if len(module) > 0: module = "{}.".format(module)
|
||||
|
||||
stdin = mock.patch("{}sys.stdin".format(module))
|
||||
select = mock.patch("{}select".format(module))
|
||||
epoll = mock.Mock()
|
||||
|
||||
stdin_mock = stdin.start()
|
||||
select_mock = select.start()
|
||||
|
||||
stdin_mock.fileno.return_value = 1
|
||||
select_mock.epoll.return_value = epoll
|
||||
epoll.poll.return_value = [(stdin_mock.fileno.return_value, 100)]
|
||||
|
||||
return stdin, select, stdin_mock, select_mock
|
||||
|
||||
def mouseEvent(stdin, button, inp, module=None, instance=None):
|
||||
stdin.readline.return_value = json.dumps({
|
||||
"name": module.id if module else rand(10),
|
||||
"button": button,
|
||||
"instance": instance
|
||||
})
|
||||
inp.start()
|
||||
inp.stop()
|
||||
stdin.readline.assert_any_call()
|
||||
|
||||
class MockPopen(object):
|
||||
def __init__(self, module=""):
|
||||
if len(module) > 0: module = "{}.".format(module)
|
||||
self._patch = mock.patch("{}subprocess.Popen".format(module))
|
||||
self._popen = self._patch.start()
|
||||
self.mock = mock.Mock()
|
||||
# for a nicer, more uniform interface
|
||||
self.mock.popen = self._popen
|
||||
# for easier command execution checks
|
||||
self.mock.popen.assert_call = self.assert_call
|
||||
self._popen.return_value = self.mock
|
||||
|
||||
self.mock.communicate.return_value = [ "", None ]
|
||||
self.mock.returncode = 0
|
||||
|
||||
def assert_call(self, cmd):
|
||||
self.mock.popen.assert_any_call(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
|
||||
def cleanup(self):
|
||||
self._patch.stop()
|
||||
|
||||
class MockInput(object):
|
||||
def __init__(self):
|
||||
self._callbacks = {}
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def get_callback(self, uid):
|
||||
return self._callbacks.get(uid, None)
|
||||
|
||||
def register_callback(self, obj, button, cmd):
|
||||
if not obj:
|
||||
return
|
||||
self._callbacks[obj.id] = {
|
||||
"button": button,
|
||||
"command": cmd,
|
||||
}
|
||||
|
||||
class MockOutput(object):
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def draw(self, widget, engine, module):
|
||||
engine.stop()
|
||||
|
||||
def begin(self):
|
||||
pass
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def end(self):
|
||||
pass
|
||||
|
||||
class MockEngine(object):
|
||||
def __init__(self):
|
||||
self.input = MockInput()
|
||||
|
||||
class MockWidget(Widget):
|
||||
def __init__(self, text):
|
||||
super(MockWidget, self).__init__(text)
|
||||
self.module = None
|
||||
self.attr_state = ["state-default"]
|
||||
self.id = rand(10)
|
||||
|
||||
self.full_text(text)
|
||||
|
||||
# def state(self):
|
||||
# return self.attr_state
|
||||
|
||||
def update(self, widgets):
|
||||
pass
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -1,68 +1,108 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import sys
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
from contextlib import contextmanager
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from bumblebee.modules.battery import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen
|
||||
|
||||
class MockOpen(object):
|
||||
def __init__(self):
|
||||
self._value = ""
|
||||
|
||||
def returns(self, value):
|
||||
self._value = value
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, a, b, c):
|
||||
pass
|
||||
|
||||
def read(self):
|
||||
return self._value
|
||||
from bumblebee.config import Config
|
||||
|
||||
class TestBatteryModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
self._stdout = mock.patch("sys.stdout", new_callable=StringIO)
|
||||
self._exists = mock.patch("bumblebee.modules.battery.os.path.exists")
|
||||
self._open = mock.patch("bumblebee.modules.battery.open", create=True)
|
||||
|
||||
self.stdout = self._stdout.start()
|
||||
self.exists = self._exists.start()
|
||||
self.open = self._open.start()
|
||||
self.file = mock.Mock()
|
||||
self.file.__enter__ = lambda x: self.file
|
||||
self.file.__exit__ = lambda x, a, b, c: ""
|
||||
self.open.return_value = self.file
|
||||
|
||||
self.exists.return_value = True
|
||||
self.engine = mock.Mock()
|
||||
self.config = Config()
|
||||
self.module = Module(engine=self.engine, config={"config":self.config})
|
||||
|
||||
self.config.set("battery.critical", "20")
|
||||
self.config.set("battery.warning", "25")
|
||||
self.criticalValue = "19"
|
||||
self.warningValue = "21"
|
||||
self.normalValue = "26"
|
||||
self.chargedValue = "96"
|
||||
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
||||
self.anyWidget = widget
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
def tearDown(self):
|
||||
self._stdout.stop()
|
||||
self._exists.stop()
|
||||
self._open.stop()
|
||||
|
||||
def test_format(self):
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100%"))
|
||||
|
||||
@mock.patch("os.path.exists")
|
||||
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins"))
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_critical(self, mock_output, mock_open, mock_exists):
|
||||
mock_open.return_value = MockOpen()
|
||||
mock_open.return_value.returns("19")
|
||||
mock_exists.return_value = True
|
||||
self.config.set("battery.critical", "20")
|
||||
self.config.set("battery.warning", "25")
|
||||
self.module.update(self.module.widgets())
|
||||
self.assertTrue("critical" in self.module.widgets()[0].state())
|
||||
def test_critical(self):
|
||||
self.file.read.return_value = self.criticalValue
|
||||
self.module.update_all()
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
|
||||
@mock.patch("os.path.exists")
|
||||
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins"))
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_warning(self, mock_output, mock_open, mock_exists):
|
||||
mock_open.return_value = MockOpen()
|
||||
mock_exists.return_value = True
|
||||
mock_open.return_value.returns("22")
|
||||
self.config.set("battery.critical", "20")
|
||||
self.config.set("battery.warning", "25")
|
||||
self.module.update(self.module.widgets())
|
||||
self.assertTrue("warning" in self.module.widgets()[0].state())
|
||||
def test_warning(self):
|
||||
self.file.read.return_value = self.warningValue
|
||||
self.module.update_all()
|
||||
self.assertTrue("warning" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_normal(self):
|
||||
self.file.read.return_value = self.normalValue
|
||||
self.module.update_all()
|
||||
self.assertTrue(not "warning" in self.module.state(self.anyWidget))
|
||||
self.assertTrue(not "critical" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_overload(self):
|
||||
self.file.read.return_value = "120"
|
||||
self.module.update_all()
|
||||
self.assertTrue(not "warning" in self.module.state(self.anyWidget))
|
||||
self.assertTrue(not "critical" in self.module.state(self.anyWidget))
|
||||
self.assertEquals(self.module.capacity(self.anyWidget), "100%")
|
||||
|
||||
def test_ac(self):
|
||||
self.exists.return_value = False
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.capacity(self.anyWidget), "ac")
|
||||
self.assertTrue("AC" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_error(self):
|
||||
self.file.read.side_effect = IOError("failed to read")
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.capacity(self.anyWidget), "n/a")
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
self.assertTrue("unknown" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_charging(self):
|
||||
self.file.read.return_value = self.chargedValue
|
||||
self.module.update_all()
|
||||
self.assertTrue("charged" in self.module.state(self.anyWidget))
|
||||
self.file.read.return_value = self.normalValue
|
||||
self.module.update_all()
|
||||
self.assertTrue("charging" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_discharging(self):
|
||||
for limit in [ 10, 25, 50, 80, 100 ]:
|
||||
value = limit - 1
|
||||
self.file.read.return_value = str(value)
|
||||
self.module.update_all()
|
||||
self.file.read.return_value = "Discharging"
|
||||
self.assertTrue("discharging-{}".format(limit) in self.module.state(self.anyWidget))
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,56 +1,47 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import WHEEL_UP, WHEEL_DOWN
|
||||
from bumblebee.modules.brightness import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent
|
||||
|
||||
class TestBrightnessModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
||||
mocks.setup_test(self, Module)
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
def tearDown(self):
|
||||
mocks.teardown_test(self)
|
||||
|
||||
def test_format(self):
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100%"))
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheel_up(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_UP,
|
||||
"xbacklight +2%"
|
||||
)
|
||||
def test_wheel_up(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=WHEEL_UP, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("xbacklight +2%")
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheel_down(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_DOWN,
|
||||
"xbacklight -2%"
|
||||
)
|
||||
def test_wheel_down(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("xbacklight -2%")
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_custom_step(self, mock_input, mock_output, mock_select):
|
||||
def test_custom_step(self):
|
||||
self.config.set("brightness.step", "10")
|
||||
module = Module(engine=self.engine, config={ "config": self.config })
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
module, bumblebee.input.WHEEL_DOWN,
|
||||
"xbacklight -10%"
|
||||
)
|
||||
module = Module(engine=self.engine, config={"config": self.config})
|
||||
mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=module)
|
||||
self.popen.assert_call("xbacklight -10%")
|
||||
|
||||
def test_update(self):
|
||||
self.popen.mock.communicate.return_value = ("20.0", None)
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.brightness(self.anyWidget), "020%")
|
||||
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -4,18 +4,50 @@ import json
|
|||
import unittest
|
||||
import mock
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.config import Config
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.caffeine import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen
|
||||
|
||||
class TestCaffeineModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.engine.input.need_valid_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
for widget in self.module.widgets():
|
||||
widget.link_module(self.module)
|
||||
mocks.setup_test(self, Module)
|
||||
|
||||
self.xset_active = " timeout: 0 cycle: 123"
|
||||
self.xset_inactive = " timeout: 600 cycle: 123"
|
||||
|
||||
def tearDown(self):
|
||||
mocks.teardown_test(self)
|
||||
|
||||
def test_text(self):
|
||||
self.assertEquals(self.module.caffeine(self.anyWidget), "")
|
||||
|
||||
def test_active(self):
|
||||
self.popen.mock.communicate.return_value = (self.xset_active, None)
|
||||
self.assertTrue(not "deactivated" in self.module.state(self.anyWidget))
|
||||
self.assertTrue("activated" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_inactive(self):
|
||||
self.popen.mock.communicate.return_value = (self.xset_inactive, None)
|
||||
self.assertTrue("deactivated" in self.module.state(self.anyWidget))
|
||||
self.popen.mock.communicate.return_value = ("no text", None)
|
||||
self.assertTrue("deactivated" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_toggle(self):
|
||||
self.popen.mock.communicate.return_value = (self.xset_active, None)
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("xset s default")
|
||||
self.popen.assert_call("notify-send \"Out of coffee\"")
|
||||
|
||||
self.popen.mock.communicate.return_value = (self.xset_inactive, None)
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("xset s off")
|
||||
self.popen.assert_call("notify-send \"Consuming caffeine\"")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,38 +1,93 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.cmus import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, MockEpoll
|
||||
|
||||
class TestCmusModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.module = Module(engine=self.engine, config={"config": MockConfig()})
|
||||
mocks.setup_test(self, Module)
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_read_song(self, mock_output):
|
||||
rv = mock.Mock()
|
||||
rv.configure_mock(**{
|
||||
"communicate.return_value": ("out", None)
|
||||
})
|
||||
mock_output.return_value = rv
|
||||
self.module.update(self.module.widgets())
|
||||
assertPopen(mock_output, "cmus-remote -Q")
|
||||
self.songTemplate = """
|
||||
status {status}
|
||||
file /path/to/file
|
||||
duration {duration}
|
||||
position {position}
|
||||
tag title {title}
|
||||
tag artist {artist}
|
||||
tag album {album}
|
||||
tag tracknumber 1
|
||||
tag date 1984
|
||||
tag comment comment
|
||||
"""
|
||||
|
||||
def test_widgets(self):
|
||||
self.assertTrue(len(self.module.widgets()), 5)
|
||||
def tearDown(self):
|
||||
mocks.teardown_test(self)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_interaction(self, mock_input, mock_output, mock_select):
|
||||
def test_read_song(self):
|
||||
self.popen.mock.communicate.return_value = ("song", None)
|
||||
self.module.update_all()
|
||||
self.popen.assert_call("cmus-remote -Q")
|
||||
|
||||
def test_handle_runtimeerror(self):
|
||||
self.popen.mock.communicate.side_effect = RuntimeError("error loading song")
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.description(self.anyWidget), " - /")
|
||||
|
||||
def test_format(self):
|
||||
self.popen.mock.communicate.return_value = (self.songTemplate.format(
|
||||
artist="an artist", title="a title", duration="100", position="20",
|
||||
album="an album", status="irrelevant"
|
||||
), None)
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.description(self.anyWidget),
|
||||
"an artist - a title 00:20/01:40"
|
||||
)
|
||||
|
||||
def test_repeat(self):
|
||||
self.popen.mock.communicate.return_value = ("set repeat false", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("repeat-off" in self.module.state(self.module.widget("cmus.repeat")))
|
||||
self.popen.mock.communicate.return_value = ("set repeat true", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("repeat-on" in self.module.state(self.module.widget("cmus.repeat")))
|
||||
|
||||
def test_shuffle(self):
|
||||
self.popen.mock.communicate.return_value = ("set shuffle false", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("shuffle-off" in self.module.state(self.module.widget("cmus.shuffle")))
|
||||
self.popen.mock.communicate.return_value = ("set shuffle true", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("shuffle-on" in self.module.state(self.module.widget("cmus.shuffle")))
|
||||
|
||||
def test_prevnext(self):
|
||||
self.assertTrue("prev" in self.module.state(self.module.widget("cmus.prev")))
|
||||
self.assertTrue("next" in self.module.state(self.module.widget("cmus.next")))
|
||||
|
||||
def test_main(self):
|
||||
self.popen.mock.communicate.return_value = ("status paused", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("paused" in self.module.state(self.module.widget("cmus.main")))
|
||||
|
||||
self.popen.mock.communicate.return_value = ("status playing", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("playing" in self.module.state(self.module.widget("cmus.main")))
|
||||
|
||||
self.popen.mock.communicate.return_value = ("status stopped", None)
|
||||
self.module.update_all()
|
||||
self.assertTrue("stopped" in self.module.state(self.module.widget("cmus.main")))
|
||||
|
||||
def test_widget(self):
|
||||
self.assertEquals(len(self.module.widgets()), 5)
|
||||
|
||||
for idx, val in enumerate(["prev", "main", "next", "shuffle", "repeat"]):
|
||||
self.assertEquals(self.module.widgets()[idx].name, "cmus.{}".format(val))
|
||||
|
||||
def test_interaction(self):
|
||||
events = [
|
||||
{"widget": "cmus.shuffle", "action": "cmus-remote -S"},
|
||||
{"widget": "cmus.repeat", "action": "cmus-remote -R"},
|
||||
|
@ -40,19 +95,8 @@ class TestCmusModule(unittest.TestCase):
|
|||
{"widget": "cmus.prev", "action": "cmus-remote -r"},
|
||||
{"widget": "cmus.main", "action": "cmus-remote -u"},
|
||||
]
|
||||
|
||||
mock_input.fileno.return_value = 1
|
||||
mock_select.return_value = MockEpoll()
|
||||
|
||||
for event in events:
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": self.module.id,
|
||||
"button": bumblebee.input.LEFT_MOUSE,
|
||||
"instance": self.module.widget(event["widget"]).id
|
||||
})
|
||||
self.engine.input.start()
|
||||
self.engine.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
assertPopen(mock_output, event["action"])
|
||||
mocks.mouseEvent(stdin=self.stdin, inp=self.input, module=self.module, instance=self.module.widget(event["widget"]).id, button=LEFT_MOUSE)
|
||||
self.popen.assert_call(event["action"])
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,48 +1,45 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.cpu import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class TestCPUModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
mocks.setup_test(self, Module)
|
||||
self._psutil = mock.patch("bumblebee.modules.cpu.psutil")
|
||||
self.psutil = self._psutil.start()
|
||||
|
||||
@mock.patch("sys.stdout")
|
||||
def test_format(self, mock_output):
|
||||
def tearDown(self):
|
||||
self._psutil.stop()
|
||||
mocks.teardown_test(self)
|
||||
|
||||
def test_format(self):
|
||||
self.psutil.cpu_percent.return_value = 21.0
|
||||
self.module.update_all()
|
||||
for widget in self.module.widgets():
|
||||
self.assertEquals(len(widget.full_text()), len("100.00%"))
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
def test_leftclick(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("gnome-system-monitor")
|
||||
|
||||
@mock.patch("psutil.cpu_percent")
|
||||
def test_warning(self, mock_psutil):
|
||||
def test_warning(self):
|
||||
self.config.set("cpu.critical", "20")
|
||||
self.config.set("cpu.warning", "18")
|
||||
mock_psutil.return_value = 19.0
|
||||
assertStateContains(self, self.module, "warning")
|
||||
self.psutil.cpu_percent.return_value = 19.0
|
||||
self.module.update_all()
|
||||
self.assertTrue("warning" in self.module.state(self.anyWidget))
|
||||
|
||||
@mock.patch("psutil.cpu_percent")
|
||||
def test_critical(self, mock_psutil):
|
||||
def test_critical(self):
|
||||
self.config.set("cpu.critical", "20")
|
||||
self.config.set("cpu.warning", "19")
|
||||
mock_psutil.return_value = 21.0
|
||||
assertStateContains(self, self.module, "critical")
|
||||
self.psutil.cpu_percent.return_value = 21.0
|
||||
self.module.update_all()
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.disk import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertStateContains, MockEpoll
|
||||
|
||||
class MockVFS(object):
|
||||
def __init__(self, perc):
|
||||
|
@ -17,40 +16,32 @@ class MockVFS(object):
|
|||
|
||||
class TestDiskModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
mocks.setup_test(self, Module)
|
||||
self._os = mock.patch("bumblebee.modules.disk.os")
|
||||
self.os = self._os.start()
|
||||
self.config.set("disk.path", "somepath")
|
||||
self.module = Module(engine=self.engine, config={"config": self.config})
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": self.module.id,
|
||||
"button": bumblebee.input.LEFT_MOUSE,
|
||||
"instance": None
|
||||
})
|
||||
mock_select.return_value = MockEpoll()
|
||||
self.engine.input.start()
|
||||
self.engine.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
assertPopen(mock_output, "nautilus {}".format(self.module.parameter("path")))
|
||||
def tearDown(self):
|
||||
self._os.stop()
|
||||
mocks.teardown_test(self)
|
||||
|
||||
@mock.patch("os.statvfs")
|
||||
def test_warning(self, mock_stat):
|
||||
def test_leftclick(self):
|
||||
module = Module(engine=self.engine, config={"config":self.config})
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=module)
|
||||
self.popen.assert_call("nautilus {}".format(self.module.parameter("path")))
|
||||
|
||||
def test_warning(self):
|
||||
self.config.set("disk.critical", "80")
|
||||
self.config.set("disk.warning", "70")
|
||||
mock_stat.return_value = MockVFS(75.0)
|
||||
assertStateContains(self, self.module, "warning")
|
||||
self.os.statvfs.return_value = MockVFS(75.0)
|
||||
self.module.update_all()
|
||||
self.assertTrue("warning" in self.module.state(self.anyWidget))
|
||||
|
||||
@mock.patch("os.statvfs")
|
||||
def test_critical(self, mock_stat):
|
||||
def test_critical(self):
|
||||
self.config.set("disk.critical", "80")
|
||||
self.config.set("disk.warning", "70")
|
||||
mock_stat.return_value = MockVFS(85.0)
|
||||
assertStateContains(self, self.module, "critical")
|
||||
self.os.statvfs.return_value = MockVFS(85.0)
|
||||
self.module.update_all()
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,47 +1,57 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.load import Module
|
||||
from tests.util import MockEngine, MockConfig, assertStateContains, assertMouseEvent
|
||||
|
||||
class TestLoadModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
mocks.setup_test(self, Module)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
self._mp = mock.patch("bumblebee.modules.load.multiprocessing")
|
||||
self._os = mock.patch("bumblebee.modules.load.os")
|
||||
|
||||
@mock.patch("multiprocessing.cpu_count")
|
||||
@mock.patch("os.getloadavg")
|
||||
def test_warning(self, mock_loadavg, mock_cpucount):
|
||||
self.mp = self._mp.start()
|
||||
self.os = self._os.start()
|
||||
|
||||
self.mp.cpu_count.return_value = 1
|
||||
|
||||
def tearDown(self):
|
||||
self._mp.stop()
|
||||
self._os.stop()
|
||||
mocks.teardown_test(self)
|
||||
|
||||
def test_leftclick(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("gnome-system-monitor")
|
||||
|
||||
def test_load_format(self):
|
||||
self.os.getloadavg.return_value = [ 5.9, 1.2, 0.8 ]
|
||||
self.module.update_all()
|
||||
self.assertEquals(self.module.load(self.anyWidget), "5.90/1.20/0.80")
|
||||
|
||||
def test_warning(self):
|
||||
self.config.set("load.critical", "1")
|
||||
self.config.set("load.warning", "0.8")
|
||||
mock_cpucount.return_value = 1
|
||||
mock_loadavg.return_value = [ 0.9, 0, 0 ]
|
||||
assertStateContains(self, self.module, "warning")
|
||||
self.os.getloadavg.return_value = [ 0.9, 0, 0 ]
|
||||
self.module.update_all()
|
||||
self.assertTrue("warning" in self.module.state(self.anyWidget))
|
||||
|
||||
@mock.patch("multiprocessing.cpu_count")
|
||||
@mock.patch("os.getloadavg")
|
||||
def test_critical(self, mock_loadavg, mock_cpucount):
|
||||
def test_critical(self):
|
||||
self.config.set("load.critical", "1")
|
||||
self.config.set("load.warning", "0.8")
|
||||
mock_cpucount.return_value = 1
|
||||
mock_loadavg.return_value = [ 1.1, 0, 0 ]
|
||||
assertStateContains(self, self.module, "critical")
|
||||
self.os.getloadavg.return_value = [ 1.1, 0, 0 ]
|
||||
self.module.update_all()
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_assume_single_core(self):
|
||||
self.mp.cpu_count.side_effect = NotImplementedError
|
||||
module = Module(engine=self.engine, config={"config": mock.Mock() })
|
||||
self.assertEquals(1, module._cpus)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE
|
||||
from bumblebee.modules.memory import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class VirtualMemory(object):
|
||||
def __init__(self, percent):
|
||||
|
@ -15,33 +14,39 @@ class VirtualMemory(object):
|
|||
|
||||
class TestMemoryModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
mocks.setup_test(self, Module)
|
||||
self._psutil = mock.patch("bumblebee.modules.memory.psutil")
|
||||
self.psutil = self._psutil.start()
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"gnome-system-monitor"
|
||||
)
|
||||
def tearDown(self):
|
||||
self._psutil.stop()
|
||||
mocks.teardown_test(self)
|
||||
|
||||
@mock.patch("psutil.virtual_memory")
|
||||
def test_warning(self, mock_vmem):
|
||||
def test_leftclick(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("gnome-system-monitor")
|
||||
|
||||
def test_warning(self):
|
||||
self.config.set("memory.critical", "80")
|
||||
self.config.set("memory.warning", "70")
|
||||
mock_vmem.return_value = VirtualMemory(75)
|
||||
assertStateContains(self, self.module, "warning")
|
||||
self.psutil.virtual_memory.return_value = VirtualMemory(75)
|
||||
self.module.update_all()
|
||||
self.assertTrue("warning" in self.module.state(self.anyWidget))
|
||||
|
||||
@mock.patch("psutil.virtual_memory")
|
||||
def test_critical(self, mock_vmem):
|
||||
def test_critical(self):
|
||||
self.config.set("memory.critical", "80")
|
||||
self.config.set("memory.warning", "70")
|
||||
mock_vmem.return_value = VirtualMemory(85)
|
||||
assertStateContains(self, self.module, "critical")
|
||||
self.psutil.virtual_memory.return_value = VirtualMemory(81)
|
||||
self.module.update_all()
|
||||
self.assertTrue("critical" in self.module.state(self.anyWidget))
|
||||
|
||||
def test_usage(self):
|
||||
rv = VirtualMemory(50)
|
||||
rv.total = 1000
|
||||
rv.available = 500
|
||||
self.psutil.virtual_memory.return_value = rv
|
||||
self.module.update_all()
|
||||
self.assertEquals("500.00B/1000.00B (50.00%)", self.module.memory_usage(self.anyWidget))
|
||||
self.assertEquals(None, self.module.state(self.anyWidget))
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,56 +1,34 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import LEFT_MOUSE, RIGHT_MOUSE, WHEEL_UP, WHEEL_DOWN
|
||||
from bumblebee.modules.pulseaudio import Module
|
||||
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
|
||||
|
||||
class TestPulseAudioModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = MockEngine()
|
||||
self.engine.input = I3BarInput()
|
||||
self.engine.input.need_event = True
|
||||
self.config = MockConfig()
|
||||
self.module = Module(engine=self.engine, config={ "config": self.config })
|
||||
mocks.setup_test(self, Module)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_leftclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.LEFT_MOUSE,
|
||||
"pactl set-source-mute @DEFAULT_SOURCE@ toggle"
|
||||
)
|
||||
def tearDown(self):
|
||||
mocks.teardown_test(self)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_rightclick(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.RIGHT_MOUSE,
|
||||
"pavucontrol"
|
||||
)
|
||||
def test_leftclick(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("pactl set-source-mute @DEFAULT_SOURCE@ toggle")
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheelup(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_UP,
|
||||
"pactl set-source-volume @DEFAULT_SOURCE@ +2%"
|
||||
)
|
||||
def test_rightclick(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=RIGHT_MOUSE, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("pavucontrol")
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_wheeldown(self, mock_input, mock_output, mock_select):
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self.engine,
|
||||
self.module, bumblebee.input.WHEEL_DOWN,
|
||||
"pactl set-source-volume @DEFAULT_SOURCE@ -2%"
|
||||
)
|
||||
def test_wheelup(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=WHEEL_UP, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("pactl set-source-volume @DEFAULT_SOURCE@ +2%")
|
||||
|
||||
def test_wheeldown(self):
|
||||
mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=self.module)
|
||||
self.popen.assert_call("pactl set-source-volume @DEFAULT_SOURCE@ -2%")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -13,9 +13,20 @@ from bumblebee.engine import all_modules
|
|||
|
||||
class TestConfig(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._stdout = mock.patch("bumblebee.config.sys.stdout", new_callable=StringIO)
|
||||
self._stderr = mock.patch("bumblebee.config.sys.stderr", new_callable=StringIO)
|
||||
|
||||
self.stdout = self._stdout.start()
|
||||
self.stderr = self._stderr.start()
|
||||
|
||||
self.defaultConfig = Config()
|
||||
self.someSimpleModules = ["foo", "bar", "baz"]
|
||||
self.someAliasModules = ["foo:a", "bar:b", "baz:c"]
|
||||
self.someTheme = "some-theme"
|
||||
|
||||
def tearDown(self):
|
||||
self._stdout.stop()
|
||||
self._stderr.stop()
|
||||
|
||||
def test_no_modules_by_default(self):
|
||||
self.assertEquals(self.defaultConfig.modules(), [])
|
||||
|
@ -33,20 +44,34 @@ class TestConfig(unittest.TestCase):
|
|||
"name": x.split(":")[1],
|
||||
} for x in self.someAliasModules])
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
@mock.patch("sys.exit")
|
||||
def test_list_themes(self, exit, stdout):
|
||||
cfg = Config(["-l", "themes"])
|
||||
result = stdout.getvalue()
|
||||
def test_parameters(self):
|
||||
cfg = Config(["-m", "module", "-p", "module.key=value"])
|
||||
self.assertEquals(cfg.get("module.key"), "value")
|
||||
|
||||
def test_theme(self):
|
||||
cfg = Config(["-t", self.someTheme])
|
||||
self.assertEquals(cfg.theme(), self.someTheme)
|
||||
|
||||
def test_notheme(self):
|
||||
self.assertEquals(self.defaultConfig.theme(), "default")
|
||||
|
||||
def test_list_themes(self):
|
||||
with self.assertRaises(SystemExit):
|
||||
cfg = Config(["-l", "themes"])
|
||||
result = self.stdout.getvalue()
|
||||
for theme in themes():
|
||||
self.assertTrue(theme in result)
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
@mock.patch("sys.exit")
|
||||
def test_list_modules(self, exit, stdout):
|
||||
cfg = Config(["-l", "modules"])
|
||||
result = stdout.getvalue()
|
||||
def test_list_modules(self):
|
||||
with self.assertRaises(SystemExit):
|
||||
cfg = Config(["-l", "modules"])
|
||||
result = self.stdout.getvalue()
|
||||
for module in all_modules():
|
||||
self.assertTrue(module["name"] in result)
|
||||
|
||||
def test_invalid_list(self):
|
||||
with self.assertRaises(SystemExit):
|
||||
cfg = Config(["-l", "invalid"])
|
||||
self.assertTrue("invalid choice" in "".join(self.stderr.getvalue()))
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -8,13 +8,15 @@ from bumblebee.engine import Engine
|
|||
from bumblebee.config import Config
|
||||
import bumblebee.input
|
||||
|
||||
from tests.util import MockOutput, MockInput
|
||||
from tests.mocks import MockOutput, MockInput
|
||||
|
||||
class TestEngine(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.engine = Engine(config=Config(), output=MockOutput(), inp=MockInput())
|
||||
self.singleWidgetModule = [{"module": "test", "name": "a"}]
|
||||
self.testModule = "test"
|
||||
self.testAlias = "test-alias"
|
||||
self.singleWidgetModule = [{"module": self.testModule, "name": "a"}]
|
||||
self.singleWidgetAlias = [{"module": self.testAlias, "name": "a" }]
|
||||
self.invalidModule = "no-such-module"
|
||||
self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule)
|
||||
self.testModules = [
|
||||
|
@ -54,6 +56,11 @@ class TestEngine(unittest.TestCase):
|
|||
except Exception as e:
|
||||
self.fail(e)
|
||||
|
||||
def test_aliases(self):
|
||||
modules = self.engine.load_modules(self.singleWidgetAlias)
|
||||
self.assertEquals(len(modules), 1)
|
||||
self.assertEquals(modules[0].__module__, self.testModuleSpec)
|
||||
|
||||
def test_custom_cmd(self):
|
||||
testmodules = [
|
||||
{ "name": "test", "button": "test.left-click", "action": "echo" },
|
||||
|
|
|
@ -1,129 +1,110 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import unittest
|
||||
import json
|
||||
import subprocess
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import bumblebee.input
|
||||
from bumblebee.input import I3BarInput
|
||||
from tests.util import MockWidget, MockModule, assertPopen, assertMouseEvent, MockEpoll
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.input import I3BarInput, LEFT_MOUSE, RIGHT_MOUSE
|
||||
|
||||
class TestI3BarInput(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.input = I3BarInput()
|
||||
self.input.need_event = True
|
||||
self.anyModule = MockModule()
|
||||
self.anyWidget = MockWidget("test")
|
||||
self.anyModule.id = "test-module"
|
||||
|
||||
self._stdin = mock.patch("bumblebee.input.sys.stdin")
|
||||
self.stdin = self._stdin.start()
|
||||
self._select = mock.patch("bumblebee.input.select")
|
||||
self.select = self._select.start()
|
||||
self.popen = mocks.MockPopen()
|
||||
|
||||
self.stdin.fileno.return_value = 1
|
||||
epoll = mock.Mock()
|
||||
self.select.epoll.return_value = epoll
|
||||
|
||||
epoll.poll.return_value = [(self.stdin.fileno.return_value, 2)]
|
||||
|
||||
self.anyModule = mock.Mock()
|
||||
self.anyModule.id = mocks.rand(10)
|
||||
self.anotherModule = mock.Mock()
|
||||
self.anotherModule.id = mocks.rand(10)
|
||||
self.anyWidget = mocks.MockWidget("some-widget")
|
||||
self.anotherWidget = mocks.MockWidget("another-widget")
|
||||
self.anyData = self.invalidData = "any data"
|
||||
self.invalidEvent = json.dumps({"name": None, "instance": None, "button": 1})
|
||||
self.incompleteEvent = json.dumps({"button": 1})
|
||||
self.anyCommand = "this is a command with arguments"
|
||||
|
||||
self._called = 0
|
||||
|
||||
def tearDown(self):
|
||||
self._stdin.stop()
|
||||
self._select.stop()
|
||||
self.popen.cleanup()
|
||||
|
||||
def callback(self, event):
|
||||
self._called += 1
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_basic_read_event(self, mock_input, mock_select):
|
||||
mock_input.readline.return_value = "somedata"
|
||||
mock_input.fileno.return_value = 1
|
||||
mock_select.return_value = MockEpoll()
|
||||
def calls(self):
|
||||
rv = self._called
|
||||
self._called = 0
|
||||
return rv
|
||||
|
||||
def test_read_event(self):
|
||||
self.stdin.readline.return_value = self.anyData
|
||||
self.input.start()
|
||||
self.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
self.stdin.readline.assert_any_call()
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_ignore_invalid_data(self, mock_input, mock_select):
|
||||
mock_select.return_value = MockEpoll()
|
||||
mock_input.readline.return_value = "garbage"
|
||||
self.input.start()
|
||||
self.assertEquals(self.input.alive(), True)
|
||||
self.assertEquals(self.input.stop(), True)
|
||||
mock_input.readline.assert_any_call()
|
||||
def test_ignore_invalid_input(self):
|
||||
for data in [ self.invalidData, self.incompleteEvent, self.invalidEvent ]:
|
||||
self.stdin.readline.return_value = data
|
||||
self.input.start()
|
||||
self.assertEquals(self.input.alive(), True)
|
||||
self.assertEquals(self.input.stop(), True)
|
||||
self.stdin.readline.assert_any_call()
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_ignore_invalid_event(self, mock_input, mock_select):
|
||||
mock_select.return_value = MockEpoll()
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": None,
|
||||
"instance": None,
|
||||
"button": 1,
|
||||
})
|
||||
self.input.start()
|
||||
self.assertEquals(self.input.alive(), True)
|
||||
self.assertEquals(self.input.stop(), True)
|
||||
mock_input.readline.assert_any_call()
|
||||
def test_global_callback(self):
|
||||
self.input.register_callback(None, button=LEFT_MOUSE, cmd=self.callback)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin)
|
||||
self.assertTrue(self.calls() > 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_ignore_partial_event(self, mock_input, mock_select):
|
||||
mock_select.return_value = MockEpoll()
|
||||
self.input.register_callback(None, button=1, cmd=self.callback)
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"button": 1,
|
||||
})
|
||||
self.input.start()
|
||||
self.assertEquals(self.input.alive(), True)
|
||||
self.assertEquals(self.input.stop(), True)
|
||||
mock_input.readline.assert_any_call()
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_global_callback(self, mock_input, mock_select):
|
||||
self.input.register_callback(None, button=1, cmd=self.callback)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, None,
|
||||
bumblebee.input.LEFT_MOUSE, None, "someinstance")
|
||||
self.assertTrue(self._called > 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_remove_global_callback(self, mock_input, mock_select):
|
||||
self.input.register_callback(None, button=1, cmd=self.callback)
|
||||
def test_remove_global_callback(self):
|
||||
self.test_global_callback()
|
||||
self.input.deregister_callbacks(None)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, None,
|
||||
bumblebee.input.LEFT_MOUSE, None, "someinstance")
|
||||
self.assertTrue(self._called == 0)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin)
|
||||
self.assertTrue(self.calls() == 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_global_callback_button_missmatch(self, mock_input, mock_select):
|
||||
self.input.register_callback(self.anyModule, button=1, cmd=self.callback)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, None,
|
||||
bumblebee.input.RIGHT_MOUSE, None, "someinstance")
|
||||
self.assertTrue(self._called == 0)
|
||||
def test_global_callback_wrong_button(self):
|
||||
self.input.register_callback(None, button=LEFT_MOUSE, cmd=self.callback)
|
||||
mocks.mouseEvent(button=RIGHT_MOUSE, inp=self.input, stdin=self.stdin)
|
||||
self.assertTrue(self.calls() == 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_module_callback(self, mock_input, mock_select):
|
||||
self.input.register_callback(self.anyModule, button=1, cmd=self.callback)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, self.anyModule,
|
||||
bumblebee.input.LEFT_MOUSE, None)
|
||||
self.assertTrue(self._called > 0)
|
||||
def test_module_callback(self):
|
||||
self.input.register_callback(self.anyModule, button=LEFT_MOUSE, cmd=self.callback)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyModule)
|
||||
self.assertTrue(self.calls() > 0)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anotherModule)
|
||||
self.assertTrue(self.calls() == 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_remove_module_callback(self, mock_input, mock_select):
|
||||
self.input.register_callback(self.anyModule, button=1, cmd=self.callback)
|
||||
def test_remove_module_callback(self):
|
||||
self.test_module_callback()
|
||||
self.input.deregister_callbacks(self.anyModule)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, None,
|
||||
bumblebee.input.LEFT_MOUSE, None, self.anyWidget.id)
|
||||
self.assertTrue(self._called == 0)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyModule)
|
||||
self.assertTrue(self.calls() == 0)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_widget_callback(self, mock_input, mock_select):
|
||||
self.input.register_callback(self.anyWidget, button=1, cmd=self.callback)
|
||||
assertMouseEvent(mock_input, None, mock_select, self, None,
|
||||
bumblebee.input.LEFT_MOUSE, None, self.anyWidget.id)
|
||||
self.assertTrue(self._called > 0)
|
||||
def test_widget_callback(self):
|
||||
self.input.register_callback(self.anyWidget, button=LEFT_MOUSE, cmd=self.callback)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyWidget)
|
||||
self.assertTrue(self.calls() > 0)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anotherWidget)
|
||||
self.assertTrue(self.calls() == 0)
|
||||
|
||||
def test_widget_cmd_callback(self):
|
||||
self.input.register_callback(self.anyWidget, button=LEFT_MOUSE, cmd=self.anyCommand)
|
||||
mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyWidget)
|
||||
self.popen.assert_call(self.anyCommand)
|
||||
|
||||
@mock.patch("select.epoll")
|
||||
@mock.patch("subprocess.Popen")
|
||||
@mock.patch("sys.stdin")
|
||||
def test_widget_cmd_callback(self, mock_input, mock_output, mock_select):
|
||||
self.input.register_callback(self.anyWidget, button=1, cmd="echo")
|
||||
assertMouseEvent(mock_input, mock_output, mock_select, self, None,
|
||||
bumblebee.input.LEFT_MOUSE, "echo", self.anyWidget.id)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,104 +1,131 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import json
|
||||
import unittest
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.output import I3BarOutput
|
||||
from tests.util import MockWidget, MockTheme, MockModule
|
||||
|
||||
class TestI3BarOutput(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.theme = MockTheme()
|
||||
self.theme = mock.Mock()
|
||||
self.theme.separator_fg.return_value = "#123456"
|
||||
self.theme.separator_bg.return_value = "#000000"
|
||||
self.theme.separator.return_value = ""
|
||||
self.theme.prefix.return_value = ""
|
||||
self.theme.suffix.return_value = ""
|
||||
self.theme.separator_block_width.return_value = 1
|
||||
self.theme.fg.return_value = "#ababab"
|
||||
self.theme.bg.return_value = "#ababab"
|
||||
self.output = I3BarOutput(self.theme)
|
||||
|
||||
self._stdout = mock.patch("bumblebee.output.sys.stdout", new_callable=StringIO)
|
||||
self.stdout = self._stdout.start()
|
||||
|
||||
self.anyWidget = mocks.MockWidget("some text")
|
||||
self.anyModule = mock.Mock()
|
||||
self.anyModule.id = mocks.rand(10)
|
||||
self.anyModule.name = mocks.rand(10)
|
||||
|
||||
self.expectedStart = json.dumps({"version": 1, "click_events": True}) + "[\n"
|
||||
self.expectedStop = "]\n"
|
||||
self.someWidget = MockWidget("foo bar baz")
|
||||
self.anyModule = MockModule(None, None)
|
||||
self.anyColor = "#ababab"
|
||||
self.anotherColor = "#cccccc"
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_start(self, stdout):
|
||||
self.anyColor = "#ffffff"
|
||||
self.anotherColor = "#cdcdcd"
|
||||
|
||||
def tearDown(self):
|
||||
self._stdout.stop()
|
||||
|
||||
def test_start(self):
|
||||
self.output.start()
|
||||
self.assertEquals(self.expectedStart, stdout.getvalue())
|
||||
self.assertEquals(self.expectedStart, self.stdout.getvalue())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_stop(self, stdout):
|
||||
def test_stop(self):
|
||||
self.output.stop()
|
||||
self.assertEquals(self.expectedStop, stdout.getvalue())
|
||||
self.assertEquals(self.expectedStop, self.stdout.getvalue())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_draw_single_widget(self, stdout):
|
||||
self.output.draw(self.someWidget, self.anyModule)
|
||||
def test_draw_single_widget(self):
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], self.someWidget.full_text())
|
||||
result = json.loads(self.stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], self.anyWidget.full_text())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_draw_multiple_widgets(self, stdout):
|
||||
for widget in [self.someWidget, self.someWidget]:
|
||||
self.output.draw(widget, self.anyModule)
|
||||
def test_draw_multiple_widgets(self):
|
||||
for i in range(4):
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())
|
||||
result = json.loads(self.stdout.getvalue())
|
||||
for res in result:
|
||||
self.assertEquals(res["full_text"], self.someWidget.full_text())
|
||||
self.assertEquals(res["full_text"], self.anyWidget.full_text())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_begin(self, stdout):
|
||||
def test_begin(self):
|
||||
self.output.begin()
|
||||
self.assertEquals("", stdout.getvalue())
|
||||
self.assertEquals("", self.stdout.getvalue())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_end(self, stdout):
|
||||
def test_end(self):
|
||||
self.output.end()
|
||||
self.assertEquals(",\n", stdout.getvalue())
|
||||
self.assertEquals(",\n", self.stdout.getvalue())
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_prefix(self, stdout):
|
||||
self.theme.attr_prefix = " - "
|
||||
self.output.draw(self.someWidget, self.anyModule)
|
||||
def test_prefix(self):
|
||||
self.theme.prefix.return_value = " - "
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], "{}{}".format(
|
||||
self.theme.prefix(self.someWidget), self.someWidget.full_text())
|
||||
)
|
||||
result = json.loads(self.stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], " - {}".format(self.anyWidget.full_text()))
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_suffix(self, stdout):
|
||||
self.theme.attr_suffix = " - "
|
||||
self.output.draw(self.someWidget, self.anyModule)
|
||||
def test_suffix(self):
|
||||
self.theme.suffix.return_value = " - "
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], "{}{}".format(
|
||||
self.someWidget.full_text(), self.theme.suffix(self.someWidget))
|
||||
)
|
||||
result = json.loads(self.stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], "{} - ".format(self.anyWidget.full_text()))
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_bothfix(self, stdout):
|
||||
self.theme.attr_suffix = " - "
|
||||
self.theme.attr_prefix = " * "
|
||||
self.output.draw(self.someWidget, self.anyModule)
|
||||
def test_bothfix(self):
|
||||
self.theme.prefix.return_value = "*"
|
||||
self.theme.suffix.return_value = " - "
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], "{}{}{}".format(
|
||||
self.theme.prefix(self.someWidget),
|
||||
self.someWidget.full_text(),
|
||||
self.theme.suffix(self.someWidget)
|
||||
))
|
||||
result = json.loads(self.stdout.getvalue())[0]
|
||||
self.assertEquals(result["full_text"], "*{} - ".format(self.anyWidget.full_text()))
|
||||
|
||||
@mock.patch("sys.stdout", new_callable=StringIO)
|
||||
def test_colors(self, stdout):
|
||||
self.theme.attr_fg = self.anyColor
|
||||
self.theme.attr_bg = self.anotherColor
|
||||
self.output.draw(self.someWidget, self.anyModule)
|
||||
def test_colors(self):
|
||||
self.theme.fg.return_value = self.anyColor
|
||||
self.theme.bg.return_value = self.anotherColor
|
||||
self.output.draw(self.anyWidget, self.anyModule)
|
||||
self.output.flush()
|
||||
result = json.loads(stdout.getvalue())[0]
|
||||
result = json.loads(self.stdout.getvalue())[0]
|
||||
self.assertEquals(result["color"], self.anyColor)
|
||||
self.assertEquals(result["background"], self.anotherColor)
|
||||
|
||||
def test_widget_link(self):
|
||||
self.anyWidget.link_module(self.anyModule)
|
||||
self.assertEquals(self.anyWidget._module, self.anyModule)
|
||||
self.assertEquals(self.anyWidget.module, self.anyModule.name)
|
||||
|
||||
def test_unlinked_widget_state(self):
|
||||
state = self.anyWidget.state()
|
||||
self.assertTrue(type(state) == list)
|
||||
|
||||
def test_linked_widget_state(self):
|
||||
self.anyWidget.link_module(self.anyModule)
|
||||
for lst in [ "samplestate", ["a", "b", "c"], [] ]:
|
||||
self.anyModule.state.return_value = lst
|
||||
state = self.anyWidget.state()
|
||||
self.assertEquals(type(state), list)
|
||||
if type(lst) is not list: lst = [lst]
|
||||
self.assertEquals(state, lst)
|
||||
|
||||
def test_widget_fulltext(self):
|
||||
self.anyWidget.full_text("some text")
|
||||
self.assertEquals(self.anyWidget.full_text(), "some text")
|
||||
self.anyWidget.full_text(lambda x: "callable fulltext")
|
||||
self.assertEquals(self.anyWidget.full_text(), "callable fulltext")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -4,14 +4,17 @@ import unittest
|
|||
|
||||
from bumblebee.engine import Module
|
||||
from bumblebee.config import Config
|
||||
from tests.util import MockWidget
|
||||
from tests.mocks import MockWidget
|
||||
|
||||
class TestModule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.widget = MockWidget("foo")
|
||||
self.widgetName = "foo"
|
||||
self.widget = MockWidget(self.widgetName)
|
||||
self.config = Config()
|
||||
self.anyWidgetName = "random-widget-name"
|
||||
self.noSuchModule = "this-module-does-not-exist"
|
||||
self.moduleWithoutWidgets = Module(engine=None, widgets=None)
|
||||
self.moduleWithOneWidget = Module(engine=None, widgets=self.widget)
|
||||
self.moduleWithOneWidget = Module(engine=None, widgets=self.widget, config={"config": self.config})
|
||||
self.moduleWithMultipleWidgets = Module(engine=None,
|
||||
widgets=[self.widget, self.widget, self.widget]
|
||||
)
|
||||
|
@ -41,6 +44,40 @@ class TestModule(unittest.TestCase):
|
|||
for widget in self.moduleWithMultipleWidgets.widgets():
|
||||
self.assertEquals(widget, self.widget)
|
||||
|
||||
def test_retrieve_widget_by_name(self):
|
||||
widget = MockWidget(self.anyWidgetName)
|
||||
widget.name = self.anyWidgetName
|
||||
module = Module(engine=None, widgets=[self.widget, widget, self.widget])
|
||||
retrievedWidget = module.widget(self.anyWidgetName)
|
||||
self.assertEquals(retrievedWidget, widget)
|
||||
|
||||
def test_retrieve_widget_by_id(self):
|
||||
widget = MockWidget(self.anyWidgetName)
|
||||
widget.id = self.anyWidgetName
|
||||
module = Module(engine=None, widgets=[self.widget, widget, self.widget])
|
||||
retrievedWidget = module.widget_by_id(self.anyWidgetName)
|
||||
self.assertEquals(retrievedWidget, widget)
|
||||
|
||||
def test_retrieve_missing_widget(self):
|
||||
module = self.moduleWithMultipleWidgets
|
||||
|
||||
widget = module.widget(self.noSuchModule)
|
||||
self.assertEquals(widget, None)
|
||||
|
||||
widget = module.widget_by_id(self.noSuchModule)
|
||||
self.assertEquals(widget, None)
|
||||
|
||||
def test_threshold(self):
|
||||
module = self.moduleWithOneWidget
|
||||
module.name = self.widgetName
|
||||
|
||||
self.config.set("{}.critical".format(self.widgetName), 10.0)
|
||||
self.config.set("{}.warning".format(self.widgetName), 8.0)
|
||||
self.assertEquals("critical", module.threshold_state(10.1, 0, 0))
|
||||
self.assertEquals("warning", module.threshold_state(10.0, 0, 0))
|
||||
self.assertEquals(None, module.threshold_state(8.0, 0, 0))
|
||||
self.assertEquals(None, module.threshold_state(7.9, 0, 0))
|
||||
|
||||
def test_parameters(self):
|
||||
self.assertEquals(self.anyModule.parameter(self.anyKey), self.anyValue)
|
||||
self.assertEquals(self.anotherModule.parameter(self.anyKey), self.anotherValue)
|
||||
|
@ -48,3 +85,5 @@ class TestModule(unittest.TestCase):
|
|||
def test_default_parameters(self):
|
||||
self.assertEquals(self.anyModule.parameter(self.emptyKey), None)
|
||||
self.assertEquals(self.anyModule.parameter(self.emptyKey, self.anyValue), self.anyValue)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,53 +1,54 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import mock
|
||||
import unittest
|
||||
import importlib
|
||||
import mock
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.engine import all_modules
|
||||
from bumblebee.output import Widget
|
||||
from bumblebee.config import Config
|
||||
from tests.util import assertWidgetAttributes, MockEngine
|
||||
|
||||
class MockCommunicate(object):
|
||||
def __init__(self):
|
||||
self.returncode = 0
|
||||
|
||||
def communicate(self):
|
||||
return (str.encode("1"), "error")
|
||||
|
||||
class TestGenericModules(unittest.TestCase):
|
||||
@mock.patch("subprocess.Popen")
|
||||
def setUp(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
engine = MockEngine()
|
||||
def setUp(self):
|
||||
engine = mock.Mock()
|
||||
engine.input = mock.Mock()
|
||||
config = Config()
|
||||
self.objects = {}
|
||||
|
||||
self.popen = mocks.MockPopen()
|
||||
self.popen.mock.communicate.return_value = (str.encode("1"), "error")
|
||||
self.popen.mock.returncode = 0
|
||||
|
||||
self._platform = mock.patch("bumblebee.modules.kernel.platform")
|
||||
self.platform = self._platform.start()
|
||||
self.platform.release.return_value = "unknown linux v1"
|
||||
|
||||
for mod in all_modules():
|
||||
cls = importlib.import_module("bumblebee.modules.{}".format(mod["name"]))
|
||||
name = "bumblebee.modules.{}".format(mod["name"])
|
||||
cls = importlib.import_module(name)
|
||||
self.objects[mod["name"]] = getattr(cls, "Module")(engine, {"config": config})
|
||||
for widget in self.objects[mod["name"]].widgets():
|
||||
self.assertEquals(widget.get("variable", None), None)
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_widgets(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
def tearDown(self):
|
||||
self._platform.stop()
|
||||
self.popen.cleanup()
|
||||
|
||||
def test_widgets(self):
|
||||
for mod in self.objects:
|
||||
widgets = self.objects[mod].widgets()
|
||||
for widget in widgets:
|
||||
widget.link_module(self.objects[mod])
|
||||
self.assertEquals(widget.module, mod)
|
||||
assertWidgetAttributes(self, widget)
|
||||
self.assertTrue(isinstance(widget, Widget))
|
||||
self.assertTrue(hasattr(widget, "full_text"))
|
||||
widget.set("variable", "value")
|
||||
self.assertEquals(widget.get("variable", None), "value")
|
||||
self.assertTrue(isinstance(widget.full_text(), str) or isinstance(widget.full_text(), unicode))
|
||||
|
||||
@mock.patch("subprocess.Popen")
|
||||
def test_update(self, mock_output):
|
||||
mock_output.return_value = MockCommunicate()
|
||||
rv = mock.Mock()
|
||||
rv.configure_mock(**{
|
||||
"communicate.return_value": ("out", None)
|
||||
})
|
||||
def test_update(self):
|
||||
for mod in self.objects:
|
||||
widgets = self.objects[mod].widgets()
|
||||
self.objects[mod].update(widgets)
|
|
@ -22,3 +22,5 @@ class TestStore(unittest.TestCase):
|
|||
def test_get_invalid_with_default_value(self):
|
||||
result = self.store.get(self.unsetKey, self.anyValue)
|
||||
self.assertEquals(result, self.anyValue)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
# pylint: disable=C0103,C0111,W0703
|
||||
|
||||
import mock
|
||||
import unittest
|
||||
from bumblebee.theme import Theme
|
||||
from bumblebee.error import ThemeLoadError
|
||||
from tests.util import MockWidget
|
||||
from tests.mocks import MockWidget
|
||||
|
||||
class TestTheme(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.nonexistentThemeName = "no-such-theme"
|
||||
self.invalidThemeName = "test_invalid"
|
||||
self.validThemeName = "test"
|
||||
self.validThemeSeparator = " * "
|
||||
self.themedWidget = MockWidget("bla")
|
||||
self.theme = Theme(self.validThemeName)
|
||||
self.cycleTheme = Theme("test_cycle")
|
||||
self.anyModule = mock.Mock()
|
||||
self.anyWidget = MockWidget("bla")
|
||||
self.anotherWidget = MockWidget("blub")
|
||||
|
||||
self.anyModule.state.return_value = "state-default"
|
||||
|
||||
self.anyWidget.link_module(self.anyModule)
|
||||
self.themedWidget.link_module(self.anyModule)
|
||||
|
||||
data = self.theme.data()
|
||||
self.widgetTheme = "test-widget"
|
||||
self.themedWidget.module = self.widgetTheme
|
||||
|
@ -102,14 +110,25 @@ class TestTheme(unittest.TestCase):
|
|||
self.assertEquals(theme.fg(self.anyWidget), data["defaults"]["fg"])
|
||||
self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["bg"])
|
||||
|
||||
self.anyWidget.attr_state = ["critical"]
|
||||
self.anyModule.state.return_value = "critical"
|
||||
self.assertEquals(theme.fg(self.anyWidget), data["defaults"]["critical"]["fg"])
|
||||
self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["critical"]["bg"])
|
||||
|
||||
self.themedWidget.attr_state = ["critical"]
|
||||
self.assertEquals(theme.fg(self.themedWidget), data[self.widgetTheme]["critical"]["fg"])
|
||||
# if elements are missing in the state theme, they are taken from the
|
||||
# widget theme instead (i.e. no fallback to a more general state theme)
|
||||
self.assertEquals(theme.bg(self.themedWidget), data[self.widgetTheme]["bg"])
|
||||
|
||||
def test_separator(self):
|
||||
self.assertEquals(self.validThemeSeparator, self.theme.separator(self.anyWidget))
|
||||
|
||||
def test_list(self):
|
||||
theme = self.theme
|
||||
data = theme.data()[self.widgetTheme]["cycle-test"]["fg"]
|
||||
self.anyModule.state.return_value = "cycle-test"
|
||||
self.assertTrue(len(data) > 1)
|
||||
|
||||
for idx in range(0, len(data)):
|
||||
self.assertEquals(theme.fg(self.themedWidget), data[idx])
|
||||
self.assertEquals(theme.fg(self.themedWidget), data[0])
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,18 +1,27 @@
|
|||
# pylint: disable=C0103,C0111
|
||||
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
import tests.mocks as mocks
|
||||
|
||||
from bumblebee.util import *
|
||||
|
||||
class TestUtil(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.popen = mocks.MockPopen("bumblebee.util")
|
||||
self.some_command_with_args = "sample-command -a -b -c"
|
||||
self.some_utf8 = "some string".encode("utf-8")
|
||||
|
||||
def tearDown(self):
|
||||
self.popen.cleanup()
|
||||
|
||||
def test_bytefmt(self):
|
||||
value = 10
|
||||
display = 10
|
||||
units = [ "B", "KiB", "MiB", "GiB" ]
|
||||
for unit in units:
|
||||
self.assertEquals(bytefmt(value), "{:.2f}{}".format(display, unit))
|
||||
value *= 1024
|
||||
self.assertEquals(bytefmt(value), "{:.2f}GiB".format(display*1024))
|
||||
self.assertEquals(bytefmt(10), "10.00B")
|
||||
self.assertEquals(bytefmt(15*1024), "15.00KiB")
|
||||
self.assertEquals(bytefmt(20*1024*1024), "20.00MiB")
|
||||
self.assertEquals(bytefmt(22*1024*1024*1024), "22.00GiB")
|
||||
self.assertEquals(bytefmt(35*1024*1024*1024*1024), "35840.00GiB")
|
||||
|
||||
def test_durationfmt(self):
|
||||
self.assertEquals(durationfmt(00), "00:00")
|
||||
|
@ -22,4 +31,26 @@ class TestUtil(unittest.TestCase):
|
|||
self.assertEquals(durationfmt(3600), "01:00:00")
|
||||
self.assertEquals(durationfmt(7265), "02:01:05")
|
||||
|
||||
def test_execute(self):
|
||||
execute(self.some_command_with_args)
|
||||
self.assertTrue(self.popen.mock.popen.called)
|
||||
self.popen.mock.popen.assert_call(self.some_command_with_args)
|
||||
self.assertTrue(self.popen.mock.communicate.called)
|
||||
|
||||
def test_execute_nowait(self):
|
||||
execute(self.some_command_with_args, False)
|
||||
self.assertTrue(self.popen.mock.popen.called)
|
||||
self.popen.mock.popen.assert_call(self.some_command_with_args)
|
||||
self.assertFalse(self.popen.mock.communicate.called)
|
||||
|
||||
def test_execute_utf8(self):
|
||||
self.popen.mock.communicate.return_value = [ self.some_utf8, None ]
|
||||
self.test_execute()
|
||||
|
||||
def test_execute_error(self):
|
||||
self.popen.mock.returncode = 1
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
execute(self.some_command_with_args)
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
162
tests/util.py
162
tests/util.py
|
@ -1,162 +0,0 @@
|
|||
# pylint: disable=C0103,C0111,W0613
|
||||
|
||||
import json
|
||||
import shlex
|
||||
import subprocess
|
||||
|
||||
from bumblebee.output import Widget
|
||||
|
||||
def assertWidgetAttributes(test, widget):
|
||||
test.assertTrue(isinstance(widget, Widget))
|
||||
test.assertTrue(hasattr(widget, "full_text"))
|
||||
|
||||
def assertPopen(output, cmd):
|
||||
res = shlex.split(cmd)
|
||||
output.assert_any_call(res,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT
|
||||
)
|
||||
|
||||
def assertStateContains(test, module, state):
|
||||
for widget in module.widgets():
|
||||
widget.link_module(module)
|
||||
module.update(module.widgets())
|
||||
test.assertTrue(state in module.widgets()[0].state())
|
||||
|
||||
class MockEpoll(object):
|
||||
def register(self, fileno, event):
|
||||
pass
|
||||
|
||||
def poll(self, timeout):
|
||||
return [(1,2)]
|
||||
|
||||
def unregister(self, fileno):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
pass
|
||||
|
||||
def assertMouseEvent(mock_input, mock_output, mock_select, engine, module, button, cmd, instance_id=None):
|
||||
mock_input.readline.return_value = json.dumps({
|
||||
"name": module.id if module else "test",
|
||||
"button": button,
|
||||
"instance": instance_id
|
||||
})
|
||||
mock_input.fileno.return_value = 1
|
||||
mock_select.return_value = MockEpoll()
|
||||
engine.input.start()
|
||||
engine.input.stop()
|
||||
mock_input.readline.assert_any_call()
|
||||
if cmd:
|
||||
assertPopen(mock_output, cmd)
|
||||
|
||||
class MockInput(object):
|
||||
def __init__(self):
|
||||
self._callbacks = {}
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def get_callback(self, uid):
|
||||
return self._callbacks.get(uid, None)
|
||||
|
||||
def register_callback(self, obj, button, cmd):
|
||||
if not obj:
|
||||
return
|
||||
self._callbacks[obj.id] = {
|
||||
"button": button,
|
||||
"command": cmd,
|
||||
}
|
||||
|
||||
class MockEngine(object):
|
||||
def __init__(self):
|
||||
self.input = MockInput()
|
||||
|
||||
class MockConfig(object):
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
|
||||
def get(self, name, default):
|
||||
if name in self._data:
|
||||
return self._data[name]
|
||||
return default
|
||||
|
||||
def set(self, name, value):
|
||||
self._data[name] = value
|
||||
|
||||
class MockOutput(object):
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def draw(self, widget, engine, module):
|
||||
engine.stop()
|
||||
|
||||
def begin(self):
|
||||
pass
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def end(self):
|
||||
pass
|
||||
|
||||
class MockModule(object):
|
||||
def __init__(self, engine=None, config=None):
|
||||
self.id = None
|
||||
|
||||
class MockWidget(Widget):
|
||||
def __init__(self, text):
|
||||
super(MockWidget, self).__init__(text)
|
||||
self._text = text
|
||||
self.module = None
|
||||
self.attr_state = ["state-default"]
|
||||
self.id = "none"
|
||||
|
||||
def state(self):
|
||||
return self.attr_state
|
||||
|
||||
def update(self, widgets):
|
||||
pass
|
||||
|
||||
def full_text(self):
|
||||
return self._text
|
||||
|
||||
class MockTheme(object):
|
||||
def __init__(self):
|
||||
self.attr_prefix = None
|
||||
self.attr_suffix = None
|
||||
self.attr_fg = None
|
||||
self.attr_bg = None
|
||||
self.attr_separator = None
|
||||
self.attr_separator_block_width = 0
|
||||
|
||||
def padding(self, widget):
|
||||
return ""
|
||||
|
||||
def reset(self):
|
||||
pass
|
||||
|
||||
def separator_block_width(self, widget):
|
||||
return self.attr_separator_block_width
|
||||
|
||||
def separator(self, widget):
|
||||
return self.attr_separator
|
||||
|
||||
def prefix(self, widget, default=None):
|
||||
return self.attr_prefix
|
||||
|
||||
def suffix(self, widget, default=None):
|
||||
return self.attr_suffix
|
||||
|
||||
def fg(self, widget):
|
||||
return self.attr_fg
|
||||
|
||||
def bg(self, widget):
|
||||
return self.attr_bg
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
@ -17,6 +17,9 @@
|
|||
"bg": "#222222",
|
||||
"critical": {
|
||||
"fg": "#bababa"
|
||||
},
|
||||
"cycle-test": {
|
||||
"fg": [ "#000000", "#111111" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue