Merge branch 'unit-test-refactoring'

This commit is contained in:
Tobi-wan Kenobi 2017-03-05 14:20:39 +01:00
commit ca9712770a
30 changed files with 888 additions and 681 deletions

View file

@ -1,3 +1,10 @@
[run] [run]
omit = omit =
tests/* tests/*
*mock*
*funcsigs*
*pbr*
*six*
/usr/lib*
[report]

View file

@ -25,8 +25,6 @@ class print_usage(argparse.Action):
self.print_modules() self.print_modules()
elif value == "themes": elif value == "themes":
self.print_themes() self.print_themes()
else:
parser.print_help()
sys.exit(0) sys.exit(0)
def print_themes(self): def print_themes(self):

View file

@ -52,6 +52,9 @@ class Module(object):
"""By default, update() is a NOP""" """By default, update() is a NOP"""
pass pass
def update_all(self):
self.update(self._widgets)
def parameter(self, name, default=None): def parameter(self, name, default=None):
"""Return the config parameter 'name' for this module""" """Return the config parameter 'name' for this module"""
name = "{}.{}".format(self.name, name) name = "{}.{}".format(self.name, name)

View file

@ -53,9 +53,7 @@ class Module(bumblebee.engine.Module):
def __init__(self, engine, config): def __init__(self, engine, config):
widget = bumblebee.output.Widget(full_text=self.updates) widget = bumblebee.output.Widget(full_text=self.updates)
super(Module, self).__init__(engine, config, widget) super(Module, self).__init__(engine, config, widget)
self._next_check = 0 self._next_check = 0
widget
def updates(self, widget): def updates(self, widget):
result = [] result = []

View file

@ -22,7 +22,7 @@ class Module(bumblebee.engine.Module):
self._load = [0, 0, 0] self._load = [0, 0, 0]
try: try:
self._cpus = multiprocessing.cpu_count() self._cpus = multiprocessing.cpu_count()
except multiprocessing.NotImplementedError as e: except NotImplementedError as e:
self._cpus = 1 self._cpus = 1
engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE, engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE,
cmd="gnome-system-monitor") cmd="gnome-system-monitor")

View file

@ -5,6 +5,8 @@
import bumblebee.engine import bumblebee.engine
ALIASES = [ "test-alias" ]
class Module(bumblebee.engine.Module): class Module(bumblebee.engine.Module):
def __init__(self, engine, config): def __init__(self, engine, config):
super(Module, self).__init__(engine, config, super(Module, self).__init__(engine, config,

View file

@ -90,11 +90,6 @@ class Theme(object):
"""Return the SBW""" """Return the SBW"""
return self._get(widget, "separator-block-width", None) 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): def _load_icons(self, name):
"""Load icons for a theme""" """Load icons for a theme"""
path = "{}/icons/".format(theme_path()) path = "{}/icons/".format(theme_path())

View file

@ -15,6 +15,8 @@ def execute(cmd, wait=True):
out, _ = proc.communicate() out, _ = proc.communicate()
if proc.returncode != 0: if proc.returncode != 0:
raise RuntimeError("{} exited with {}".format(cmd, proc.returncode)) raise RuntimeError("{} exited with {}".format(cmd, proc.returncode))
if type(out) == str:
return out
return out.decode("utf-8") return out.decode("utf-8")
return None return None

View file

@ -1,11 +1,11 @@
#!/bin/sh #!/bin/sh
echo "testing with $(python2 -V 2>&1)" 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 if [ $? == 0 ]; then
echo echo
echo "testing with $(python3 -V 2>&1)" 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 fi

141
tests/mocks.py Normal file
View 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

View file

@ -1,68 +1,108 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import sys import sys
import json
import unittest
import mock 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 bumblebee.modules.battery import Module
from tests.util import MockEngine, MockConfig, assertPopen from bumblebee.config import Config
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
class TestBatteryModule(unittest.TestCase): class TestBatteryModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() self._stdout = mock.patch("sys.stdout", new_callable=StringIO)
self.config = MockConfig() 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.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(): for widget in self.module.widgets():
widget.link_module(self.module) widget.link_module(self.module)
self.anyWidget = widget
@mock.patch("sys.stdout") def tearDown(self):
def test_format(self, mock_output): self._stdout.stop()
self._exists.stop()
self._open.stop()
def test_format(self):
for widget in self.module.widgets(): for widget in self.module.widgets():
self.assertEquals(len(widget.full_text()), len("100%")) self.assertEquals(len(widget.full_text()), len("100%"))
@mock.patch("os.path.exists") def test_critical(self):
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins")) self.file.read.return_value = self.criticalValue
@mock.patch("subprocess.Popen") self.module.update_all()
def test_critical(self, mock_output, mock_open, mock_exists): self.assertTrue("critical" in self.module.state(self.anyWidget))
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())
@mock.patch("os.path.exists") def test_warning(self):
@mock.patch("{}.open".format("__builtin__" if sys.version_info[0] < 3 else "builtins")) self.file.read.return_value = self.warningValue
@mock.patch("subprocess.Popen") self.module.update_all()
def test_warning(self, mock_output, mock_open, mock_exists): self.assertTrue("warning" in self.module.state(self.anyWidget))
mock_open.return_value = MockOpen()
mock_exists.return_value = True def test_normal(self):
mock_open.return_value.returns("22") self.file.read.return_value = self.normalValue
self.config.set("battery.critical", "20") self.module.update_all()
self.config.set("battery.warning", "25") self.assertTrue(not "warning" in self.module.state(self.anyWidget))
self.module.update(self.module.widgets()) self.assertTrue(not "critical" in self.module.state(self.anyWidget))
self.assertTrue("warning" in self.module.widgets()[0].state())
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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,56 +1,47 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input try:
from bumblebee.input import I3BarInput 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 bumblebee.modules.brightness import Module
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent
class TestBrightnessModule(unittest.TestCase): class TestBrightnessModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
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)
@mock.patch("sys.stdout") def tearDown(self):
def test_format(self, mock_output): mocks.teardown_test(self)
def test_format(self):
for widget in self.module.widgets(): for widget in self.module.widgets():
self.assertEquals(len(widget.full_text()), len("100%")) self.assertEquals(len(widget.full_text()), len("100%"))
@mock.patch("select.epoll") def test_wheel_up(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=WHEEL_UP, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("xbacklight +2%")
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%"
)
@mock.patch("select.epoll") def test_wheel_down(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("xbacklight -2%")
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%"
)
@mock.patch("select.epoll") def test_custom_step(self):
@mock.patch("subprocess.Popen")
@mock.patch("sys.stdin")
def test_custom_step(self, mock_input, mock_output, mock_select):
self.config.set("brightness.step", "10") self.config.set("brightness.step", "10")
module = Module(engine=self.engine, config={"config": self.config}) module = Module(engine=self.engine, config={"config": self.config})
assertMouseEvent(mock_input, mock_output, mock_select, self.engine, mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=module)
module, bumblebee.input.WHEEL_DOWN, self.popen.assert_call("xbacklight -10%")
"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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -4,18 +4,50 @@ import json
import unittest import unittest
import mock import mock
import bumblebee.input try:
from bumblebee.input import I3BarInput 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 bumblebee.modules.caffeine import Module
from tests.util import MockEngine, MockConfig, assertPopen
class TestCaffeineModule(unittest.TestCase): class TestCaffeineModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput()
self.engine.input.need_event = True self.xset_active = " timeout: 0 cycle: 123"
self.engine.input.need_valid_event = True self.xset_inactive = " timeout: 600 cycle: 123"
self.config = MockConfig()
self.module = Module(engine=self.engine, config={ "config": self.config }) def tearDown(self):
for widget in self.module.widgets(): mocks.teardown_test(self)
widget.link_module(self.module)
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

View file

@ -1,38 +1,93 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE
from bumblebee.modules.cmus import Module from bumblebee.modules.cmus import Module
from tests.util import MockEngine, MockConfig, assertPopen, MockEpoll
class TestCmusModule(unittest.TestCase): class TestCmusModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput()
self.engine.input.need_event = True
self.module = Module(engine=self.engine, config={"config": MockConfig()})
@mock.patch("subprocess.Popen") self.songTemplate = """
def test_read_song(self, mock_output): status {status}
rv = mock.Mock() file /path/to/file
rv.configure_mock(**{ duration {duration}
"communicate.return_value": ("out", None) position {position}
}) tag title {title}
mock_output.return_value = rv tag artist {artist}
self.module.update(self.module.widgets()) tag album {album}
assertPopen(mock_output, "cmus-remote -Q") tag tracknumber 1
tag date 1984
tag comment comment
"""
def test_widgets(self): def tearDown(self):
self.assertTrue(len(self.module.widgets()), 5) mocks.teardown_test(self)
@mock.patch("select.epoll") def test_read_song(self):
@mock.patch("subprocess.Popen") self.popen.mock.communicate.return_value = ("song", None)
@mock.patch("sys.stdin") self.module.update_all()
def test_interaction(self, mock_input, mock_output, mock_select): 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 = [ events = [
{"widget": "cmus.shuffle", "action": "cmus-remote -S"}, {"widget": "cmus.shuffle", "action": "cmus-remote -S"},
{"widget": "cmus.repeat", "action": "cmus-remote -R"}, {"widget": "cmus.repeat", "action": "cmus-remote -R"},
@ -40,19 +95,8 @@ class TestCmusModule(unittest.TestCase):
{"widget": "cmus.prev", "action": "cmus-remote -r"}, {"widget": "cmus.prev", "action": "cmus-remote -r"},
{"widget": "cmus.main", "action": "cmus-remote -u"}, {"widget": "cmus.main", "action": "cmus-remote -u"},
] ]
mock_input.fileno.return_value = 1
mock_select.return_value = MockEpoll()
for event in events: for event in events:
mock_input.readline.return_value = json.dumps({ mocks.mouseEvent(stdin=self.stdin, inp=self.input, module=self.module, instance=self.module.widget(event["widget"]).id, button=LEFT_MOUSE)
"name": self.module.id, self.popen.assert_call(event["action"])
"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"])
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,48 +1,45 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE
from bumblebee.modules.cpu import Module from bumblebee.modules.cpu import Module
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
class TestCPUModule(unittest.TestCase): class TestCPUModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput() self._psutil = mock.patch("bumblebee.modules.cpu.psutil")
self.engine.input.need_event = True self.psutil = self._psutil.start()
self.config = MockConfig()
self.module = Module(engine=self.engine, config={ "config": self.config })
@mock.patch("sys.stdout") def tearDown(self):
def test_format(self, mock_output): 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(): for widget in self.module.widgets():
self.assertEquals(len(widget.full_text()), len("100.00%")) self.assertEquals(len(widget.full_text()), len("100.00%"))
@mock.patch("select.epoll") def test_leftclick(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("gnome-system-monitor")
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"
)
@mock.patch("psutil.cpu_percent") def test_warning(self):
def test_warning(self, mock_psutil):
self.config.set("cpu.critical", "20") self.config.set("cpu.critical", "20")
self.config.set("cpu.warning", "18") self.config.set("cpu.warning", "18")
mock_psutil.return_value = 19.0 self.psutil.cpu_percent.return_value = 19.0
assertStateContains(self, self.module, "warning") self.module.update_all()
self.assertTrue("warning" in self.module.state(self.anyWidget))
@mock.patch("psutil.cpu_percent") def test_critical(self):
def test_critical(self, mock_psutil):
self.config.set("cpu.critical", "20") self.config.set("cpu.critical", "20")
self.config.set("cpu.warning", "19") self.config.set("cpu.warning", "19")
mock_psutil.return_value = 21.0 self.psutil.cpu_percent.return_value = 21.0
assertStateContains(self, self.module, "critical") self.module.update_all()
self.assertTrue("critical" in self.module.state(self.anyWidget))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,13 +1,12 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE
from bumblebee.modules.disk import Module from bumblebee.modules.disk import Module
from tests.util import MockEngine, MockConfig, assertPopen, assertStateContains, MockEpoll
class MockVFS(object): class MockVFS(object):
def __init__(self, perc): def __init__(self, perc):
@ -17,40 +16,32 @@ class MockVFS(object):
class TestDiskModule(unittest.TestCase): class TestDiskModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput() self._os = mock.patch("bumblebee.modules.disk.os")
self.engine.input.need_event = True self.os = self._os.start()
self.config = MockConfig()
self.config.set("disk.path", "somepath") self.config.set("disk.path", "somepath")
self.module = Module(engine=self.engine, config={"config": self.config})
@mock.patch("select.epoll") def tearDown(self):
@mock.patch("subprocess.Popen") self._os.stop()
@mock.patch("sys.stdin") mocks.teardown_test(self)
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")))
@mock.patch("os.statvfs") def test_leftclick(self):
def test_warning(self, mock_stat): 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.critical", "80")
self.config.set("disk.warning", "70") self.config.set("disk.warning", "70")
mock_stat.return_value = MockVFS(75.0) self.os.statvfs.return_value = MockVFS(75.0)
assertStateContains(self, self.module, "warning") self.module.update_all()
self.assertTrue("warning" in self.module.state(self.anyWidget))
@mock.patch("os.statvfs") def test_critical(self):
def test_critical(self, mock_stat):
self.config.set("disk.critical", "80") self.config.set("disk.critical", "80")
self.config.set("disk.warning", "70") self.config.set("disk.warning", "70")
mock_stat.return_value = MockVFS(85.0) self.os.statvfs.return_value = MockVFS(85.0)
assertStateContains(self, self.module, "critical") self.module.update_all()
self.assertTrue("critical" in self.module.state(self.anyWidget))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,47 +1,57 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE
from bumblebee.modules.load import Module from bumblebee.modules.load import Module
from tests.util import MockEngine, MockConfig, assertStateContains, assertMouseEvent
class TestLoadModule(unittest.TestCase): class TestLoadModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput()
self.engine.input.need_event = True
self.config = MockConfig()
self.module = Module(engine=self.engine, config={ "config": self.config })
@mock.patch("select.epoll") self._mp = mock.patch("bumblebee.modules.load.multiprocessing")
@mock.patch("subprocess.Popen") self._os = mock.patch("bumblebee.modules.load.os")
@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"
)
@mock.patch("multiprocessing.cpu_count") self.mp = self._mp.start()
@mock.patch("os.getloadavg") self.os = self._os.start()
def test_warning(self, mock_loadavg, mock_cpucount):
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.critical", "1")
self.config.set("load.warning", "0.8") self.config.set("load.warning", "0.8")
mock_cpucount.return_value = 1 self.os.getloadavg.return_value = [ 0.9, 0, 0 ]
mock_loadavg.return_value = [ 0.9, 0, 0 ] self.module.update_all()
assertStateContains(self, self.module, "warning") self.assertTrue("warning" in self.module.state(self.anyWidget))
@mock.patch("multiprocessing.cpu_count") def test_critical(self):
@mock.patch("os.getloadavg")
def test_critical(self, mock_loadavg, mock_cpucount):
self.config.set("load.critical", "1") self.config.set("load.critical", "1")
self.config.set("load.warning", "0.8") self.config.set("load.warning", "0.8")
mock_cpucount.return_value = 1 self.os.getloadavg.return_value = [ 1.1, 0, 0 ]
mock_loadavg.return_value = [ 1.1, 0, 0 ] self.module.update_all()
assertStateContains(self, self.module, "critical") 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,13 +1,12 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE
from bumblebee.modules.memory import Module from bumblebee.modules.memory import Module
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
class VirtualMemory(object): class VirtualMemory(object):
def __init__(self, percent): def __init__(self, percent):
@ -15,33 +14,39 @@ class VirtualMemory(object):
class TestMemoryModule(unittest.TestCase): class TestMemoryModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput() self._psutil = mock.patch("bumblebee.modules.memory.psutil")
self.engine.input.need_event = True self.psutil = self._psutil.start()
self.config = MockConfig()
self.module = Module(engine=self.engine, config={ "config": self.config })
@mock.patch("select.epoll") def tearDown(self):
@mock.patch("subprocess.Popen") self._psutil.stop()
@mock.patch("sys.stdin") mocks.teardown_test(self)
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"
)
@mock.patch("psutil.virtual_memory") def test_leftclick(self):
def test_warning(self, mock_vmem): 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.critical", "80")
self.config.set("memory.warning", "70") self.config.set("memory.warning", "70")
mock_vmem.return_value = VirtualMemory(75) self.psutil.virtual_memory.return_value = VirtualMemory(75)
assertStateContains(self, self.module, "warning") self.module.update_all()
self.assertTrue("warning" in self.module.state(self.anyWidget))
@mock.patch("psutil.virtual_memory") def test_critical(self):
def test_critical(self, mock_vmem):
self.config.set("memory.critical", "80") self.config.set("memory.critical", "80")
self.config.set("memory.warning", "70") self.config.set("memory.warning", "70")
mock_vmem.return_value = VirtualMemory(85) self.psutil.virtual_memory.return_value = VirtualMemory(81)
assertStateContains(self, self.module, "critical") 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,56 +1,34 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json
import unittest
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from bumblebee.input import LEFT_MOUSE, RIGHT_MOUSE, WHEEL_UP, WHEEL_DOWN
from bumblebee.modules.pulseaudio import Module from bumblebee.modules.pulseaudio import Module
from tests.util import MockEngine, MockConfig, assertPopen, assertMouseEvent, assertStateContains
class TestPulseAudioModule(unittest.TestCase): class TestPulseAudioModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = MockEngine() mocks.setup_test(self, Module)
self.engine.input = I3BarInput()
self.engine.input.need_event = True
self.config = MockConfig()
self.module = Module(engine=self.engine, config={ "config": self.config })
@mock.patch("select.epoll") def tearDown(self):
@mock.patch("subprocess.Popen") mocks.teardown_test(self)
@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"
)
@mock.patch("select.epoll") def test_leftclick(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=LEFT_MOUSE, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("pactl set-source-mute @DEFAULT_SOURCE@ toggle")
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"
)
@mock.patch("select.epoll") def test_rightclick(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=RIGHT_MOUSE, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("pavucontrol")
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%"
)
@mock.patch("select.epoll") def test_wheelup(self):
@mock.patch("subprocess.Popen") mocks.mouseEvent(stdin=self.stdin, button=WHEEL_UP, inp=self.input, module=self.module)
@mock.patch("sys.stdin") self.popen.assert_call("pactl set-source-volume @DEFAULT_SOURCE@ +2%")
def test_wheeldown(self, mock_input, mock_output, mock_select):
assertMouseEvent(mock_input, mock_output, mock_select, self.engine, def test_wheeldown(self):
self.module, bumblebee.input.WHEEL_DOWN, mocks.mouseEvent(stdin=self.stdin, button=WHEEL_DOWN, inp=self.input, module=self.module)
"pactl set-source-volume @DEFAULT_SOURCE@ -2%" self.popen.assert_call("pactl set-source-volume @DEFAULT_SOURCE@ -2%")
)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -13,9 +13,20 @@ from bumblebee.engine import all_modules
class TestConfig(unittest.TestCase): class TestConfig(unittest.TestCase):
def setUp(self): 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.defaultConfig = Config()
self.someSimpleModules = ["foo", "bar", "baz"] self.someSimpleModules = ["foo", "bar", "baz"]
self.someAliasModules = ["foo:a", "bar:b", "baz:c"] 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): def test_no_modules_by_default(self):
self.assertEquals(self.defaultConfig.modules(), []) self.assertEquals(self.defaultConfig.modules(), [])
@ -33,20 +44,34 @@ class TestConfig(unittest.TestCase):
"name": x.split(":")[1], "name": x.split(":")[1],
} for x in self.someAliasModules]) } for x in self.someAliasModules])
@mock.patch("sys.stdout", new_callable=StringIO) def test_parameters(self):
@mock.patch("sys.exit") cfg = Config(["-m", "module", "-p", "module.key=value"])
def test_list_themes(self, exit, stdout): 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"]) cfg = Config(["-l", "themes"])
result = stdout.getvalue() result = self.stdout.getvalue()
for theme in themes(): for theme in themes():
self.assertTrue(theme in result) self.assertTrue(theme in result)
@mock.patch("sys.stdout", new_callable=StringIO) def test_list_modules(self):
@mock.patch("sys.exit") with self.assertRaises(SystemExit):
def test_list_modules(self, exit, stdout):
cfg = Config(["-l", "modules"]) cfg = Config(["-l", "modules"])
result = stdout.getvalue() result = self.stdout.getvalue()
for module in all_modules(): for module in all_modules():
self.assertTrue(module["name"] in result) 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -8,13 +8,15 @@ from bumblebee.engine import Engine
from bumblebee.config import Config from bumblebee.config import Config
import bumblebee.input import bumblebee.input
from tests.util import MockOutput, MockInput from tests.mocks import MockOutput, MockInput
class TestEngine(unittest.TestCase): class TestEngine(unittest.TestCase):
def setUp(self): def setUp(self):
self.engine = Engine(config=Config(), output=MockOutput(), inp=MockInput()) self.engine = Engine(config=Config(), output=MockOutput(), inp=MockInput())
self.singleWidgetModule = [{"module": "test", "name": "a"}]
self.testModule = "test" 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.invalidModule = "no-such-module"
self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule) self.testModuleSpec = "bumblebee.modules.{}".format(self.testModule)
self.testModules = [ self.testModules = [
@ -54,6 +56,11 @@ class TestEngine(unittest.TestCase):
except Exception as e: except Exception as e:
self.fail(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): def test_custom_cmd(self):
testmodules = [ testmodules = [
{ "name": "test", "button": "test.left-click", "action": "echo" }, { "name": "test", "button": "test.left-click", "action": "echo" },

View file

@ -1,129 +1,110 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import unittest
import json import json
import subprocess
import mock import mock
import unittest
import bumblebee.input import tests.mocks as mocks
from bumblebee.input import I3BarInput
from tests.util import MockWidget, MockModule, assertPopen, assertMouseEvent, MockEpoll from bumblebee.input import I3BarInput, LEFT_MOUSE, RIGHT_MOUSE
class TestI3BarInput(unittest.TestCase): class TestI3BarInput(unittest.TestCase):
def setUp(self): def setUp(self):
self.input = I3BarInput() self.input = I3BarInput()
self.input.need_event = True self.input.need_event = True
self.anyModule = MockModule()
self.anyWidget = MockWidget("test") self._stdin = mock.patch("bumblebee.input.sys.stdin")
self.anyModule.id = "test-module" 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 self._called = 0
def tearDown(self):
self._stdin.stop()
self._select.stop()
self.popen.cleanup()
def callback(self, event): def callback(self, event):
self._called += 1 self._called += 1
@mock.patch("select.epoll") def calls(self):
@mock.patch("sys.stdin") rv = self._called
def test_basic_read_event(self, mock_input, mock_select): self._called = 0
mock_input.readline.return_value = "somedata" return rv
mock_input.fileno.return_value = 1
mock_select.return_value = MockEpoll() def test_read_event(self):
self.stdin.readline.return_value = self.anyData
self.input.start() self.input.start()
self.input.stop() self.input.stop()
mock_input.readline.assert_any_call() self.stdin.readline.assert_any_call()
@mock.patch("select.epoll") def test_ignore_invalid_input(self):
@mock.patch("sys.stdin") for data in [ self.invalidData, self.incompleteEvent, self.invalidEvent ]:
def test_ignore_invalid_data(self, mock_input, mock_select): self.stdin.readline.return_value = data
mock_select.return_value = MockEpoll()
mock_input.readline.return_value = "garbage"
self.input.start() self.input.start()
self.assertEquals(self.input.alive(), True) self.assertEquals(self.input.alive(), True)
self.assertEquals(self.input.stop(), True) self.assertEquals(self.input.stop(), True)
mock_input.readline.assert_any_call() self.stdin.readline.assert_any_call()
@mock.patch("select.epoll") def test_global_callback(self):
@mock.patch("sys.stdin") self.input.register_callback(None, button=LEFT_MOUSE, cmd=self.callback)
def test_ignore_invalid_event(self, mock_input, mock_select): mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin)
mock_select.return_value = MockEpoll() self.assertTrue(self.calls() > 0)
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()
@mock.patch("select.epoll") def test_remove_global_callback(self):
@mock.patch("sys.stdin") self.test_global_callback()
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)
self.input.deregister_callbacks(None) self.input.deregister_callbacks(None)
assertMouseEvent(mock_input, None, mock_select, self, None, mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin)
bumblebee.input.LEFT_MOUSE, None, "someinstance") self.assertTrue(self.calls() == 0)
self.assertTrue(self._called == 0)
@mock.patch("select.epoll") def test_global_callback_wrong_button(self):
@mock.patch("sys.stdin") self.input.register_callback(None, button=LEFT_MOUSE, cmd=self.callback)
def test_global_callback_button_missmatch(self, mock_input, mock_select): mocks.mouseEvent(button=RIGHT_MOUSE, inp=self.input, stdin=self.stdin)
self.input.register_callback(self.anyModule, button=1, cmd=self.callback) self.assertTrue(self.calls() == 0)
assertMouseEvent(mock_input, None, mock_select, self, None,
bumblebee.input.RIGHT_MOUSE, None, "someinstance")
self.assertTrue(self._called == 0)
@mock.patch("select.epoll") def test_module_callback(self):
@mock.patch("sys.stdin") self.input.register_callback(self.anyModule, button=LEFT_MOUSE, cmd=self.callback)
def test_module_callback(self, mock_input, mock_select): mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyModule)
self.input.register_callback(self.anyModule, button=1, cmd=self.callback) self.assertTrue(self.calls() > 0)
assertMouseEvent(mock_input, None, mock_select, self, self.anyModule, mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anotherModule)
bumblebee.input.LEFT_MOUSE, None) self.assertTrue(self.calls() == 0)
self.assertTrue(self._called > 0)
@mock.patch("select.epoll") def test_remove_module_callback(self):
@mock.patch("sys.stdin") self.test_module_callback()
def test_remove_module_callback(self, mock_input, mock_select):
self.input.register_callback(self.anyModule, button=1, cmd=self.callback)
self.input.deregister_callbacks(self.anyModule) self.input.deregister_callbacks(self.anyModule)
assertMouseEvent(mock_input, None, mock_select, self, None, mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyModule)
bumblebee.input.LEFT_MOUSE, None, self.anyWidget.id) self.assertTrue(self.calls() == 0)
self.assertTrue(self._called == 0)
@mock.patch("select.epoll") def test_widget_callback(self):
@mock.patch("sys.stdin") self.input.register_callback(self.anyWidget, button=LEFT_MOUSE, cmd=self.callback)
def test_widget_callback(self, mock_input, mock_select): mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anyWidget)
self.input.register_callback(self.anyWidget, button=1, cmd=self.callback) self.assertTrue(self.calls() > 0)
assertMouseEvent(mock_input, None, mock_select, self, None, mocks.mouseEvent(button=LEFT_MOUSE, inp=self.input, stdin=self.stdin, module=self.anotherWidget)
bumblebee.input.LEFT_MOUSE, None, self.anyWidget.id) self.assertTrue(self.calls() == 0)
self.assertTrue(self._called > 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,104 +1,131 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import json import json
import unittest
import mock import mock
import unittest
try: try:
from StringIO import StringIO from StringIO import StringIO
except ImportError: except ImportError:
from io import StringIO from io import StringIO
import tests.mocks as mocks
from bumblebee.output import I3BarOutput from bumblebee.output import I3BarOutput
from tests.util import MockWidget, MockTheme, MockModule
class TestI3BarOutput(unittest.TestCase): class TestI3BarOutput(unittest.TestCase):
def setUp(self): 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.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.expectedStart = json.dumps({"version": 1, "click_events": True}) + "[\n"
self.expectedStop = "]\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) self.anyColor = "#ffffff"
def test_start(self, stdout): self.anotherColor = "#cdcdcd"
def tearDown(self):
self._stdout.stop()
def test_start(self):
self.output.start() 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):
def test_stop(self, stdout):
self.output.stop() 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):
def test_draw_single_widget(self, stdout): self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(self.someWidget, self.anyModule)
self.output.flush() self.output.flush()
result = json.loads(stdout.getvalue())[0] result = json.loads(self.stdout.getvalue())[0]
self.assertEquals(result["full_text"], self.someWidget.full_text()) self.assertEquals(result["full_text"], self.anyWidget.full_text())
@mock.patch("sys.stdout", new_callable=StringIO) def test_draw_multiple_widgets(self):
def test_draw_multiple_widgets(self, stdout): for i in range(4):
for widget in [self.someWidget, self.someWidget]: self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(widget, self.anyModule)
self.output.flush() self.output.flush()
result = json.loads(stdout.getvalue()) result = json.loads(self.stdout.getvalue())
for res in result: 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):
def test_begin(self, stdout):
self.output.begin() self.output.begin()
self.assertEquals("", stdout.getvalue()) self.assertEquals("", self.stdout.getvalue())
@mock.patch("sys.stdout", new_callable=StringIO) def test_end(self):
def test_end(self, stdout):
self.output.end() 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):
def test_prefix(self, stdout): self.theme.prefix.return_value = " - "
self.theme.attr_prefix = " - " self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(self.someWidget, self.anyModule)
self.output.flush() self.output.flush()
result = json.loads(stdout.getvalue())[0] result = json.loads(self.stdout.getvalue())[0]
self.assertEquals(result["full_text"], "{}{}".format( self.assertEquals(result["full_text"], " - {}".format(self.anyWidget.full_text()))
self.theme.prefix(self.someWidget), self.someWidget.full_text())
)
@mock.patch("sys.stdout", new_callable=StringIO) def test_suffix(self):
def test_suffix(self, stdout): self.theme.suffix.return_value = " - "
self.theme.attr_suffix = " - " self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(self.someWidget, self.anyModule)
self.output.flush() self.output.flush()
result = json.loads(stdout.getvalue())[0] result = json.loads(self.stdout.getvalue())[0]
self.assertEquals(result["full_text"], "{}{}".format( self.assertEquals(result["full_text"], "{} - ".format(self.anyWidget.full_text()))
self.someWidget.full_text(), self.theme.suffix(self.someWidget))
)
@mock.patch("sys.stdout", new_callable=StringIO) def test_bothfix(self):
def test_bothfix(self, stdout): self.theme.prefix.return_value = "*"
self.theme.attr_suffix = " - " self.theme.suffix.return_value = " - "
self.theme.attr_prefix = " * " self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(self.someWidget, self.anyModule)
self.output.flush() self.output.flush()
result = json.loads(stdout.getvalue())[0] result = json.loads(self.stdout.getvalue())[0]
self.assertEquals(result["full_text"], "{}{}{}".format( self.assertEquals(result["full_text"], "*{} - ".format(self.anyWidget.full_text()))
self.theme.prefix(self.someWidget),
self.someWidget.full_text(),
self.theme.suffix(self.someWidget)
))
@mock.patch("sys.stdout", new_callable=StringIO) def test_colors(self):
def test_colors(self, stdout): self.theme.fg.return_value = self.anyColor
self.theme.attr_fg = self.anyColor self.theme.bg.return_value = self.anotherColor
self.theme.attr_bg = self.anotherColor self.output.draw(self.anyWidget, self.anyModule)
self.output.draw(self.someWidget, self.anyModule)
self.output.flush() 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["color"], self.anyColor)
self.assertEquals(result["background"], self.anotherColor) 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -4,14 +4,17 @@ import unittest
from bumblebee.engine import Module from bumblebee.engine import Module
from bumblebee.config import Config from bumblebee.config import Config
from tests.util import MockWidget from tests.mocks import MockWidget
class TestModule(unittest.TestCase): class TestModule(unittest.TestCase):
def setUp(self): def setUp(self):
self.widget = MockWidget("foo") self.widgetName = "foo"
self.widget = MockWidget(self.widgetName)
self.config = Config() self.config = Config()
self.anyWidgetName = "random-widget-name"
self.noSuchModule = "this-module-does-not-exist"
self.moduleWithoutWidgets = Module(engine=None, widgets=None) 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, self.moduleWithMultipleWidgets = Module(engine=None,
widgets=[self.widget, self.widget, self.widget] widgets=[self.widget, self.widget, self.widget]
) )
@ -41,6 +44,40 @@ class TestModule(unittest.TestCase):
for widget in self.moduleWithMultipleWidgets.widgets(): for widget in self.moduleWithMultipleWidgets.widgets():
self.assertEquals(widget, self.widget) 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): def test_parameters(self):
self.assertEquals(self.anyModule.parameter(self.anyKey), self.anyValue) self.assertEquals(self.anyModule.parameter(self.anyKey), self.anyValue)
self.assertEquals(self.anotherModule.parameter(self.anyKey), self.anotherValue) self.assertEquals(self.anotherModule.parameter(self.anyKey), self.anotherValue)
@ -48,3 +85,5 @@ class TestModule(unittest.TestCase):
def test_default_parameters(self): def test_default_parameters(self):
self.assertEquals(self.anyModule.parameter(self.emptyKey), None) self.assertEquals(self.anyModule.parameter(self.emptyKey), None)
self.assertEquals(self.anyModule.parameter(self.emptyKey, self.anyValue), self.anyValue) self.assertEquals(self.anyModule.parameter(self.emptyKey, self.anyValue), self.anyValue)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,53 +1,54 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import mock
import unittest import unittest
import importlib import importlib
import mock
import tests.mocks as mocks
from bumblebee.engine import all_modules from bumblebee.engine import all_modules
from bumblebee.output import Widget
from bumblebee.config import Config 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): class TestGenericModules(unittest.TestCase):
@mock.patch("subprocess.Popen") def setUp(self):
def setUp(self, mock_output): engine = mock.Mock()
mock_output.return_value = MockCommunicate() engine.input = mock.Mock()
engine = MockEngine()
config = Config() config = Config()
self.objects = {} 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(): 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}) self.objects[mod["name"]] = getattr(cls, "Module")(engine, {"config": config})
for widget in self.objects[mod["name"]].widgets(): for widget in self.objects[mod["name"]].widgets():
self.assertEquals(widget.get("variable", None), None) self.assertEquals(widget.get("variable", None), None)
@mock.patch("subprocess.Popen") def tearDown(self):
def test_widgets(self, mock_output): self._platform.stop()
mock_output.return_value = MockCommunicate() self.popen.cleanup()
def test_widgets(self):
for mod in self.objects: for mod in self.objects:
widgets = self.objects[mod].widgets() widgets = self.objects[mod].widgets()
for widget in widgets: for widget in widgets:
widget.link_module(self.objects[mod]) widget.link_module(self.objects[mod])
self.assertEquals(widget.module, mod) self.assertEquals(widget.module, mod)
assertWidgetAttributes(self, widget) self.assertTrue(isinstance(widget, Widget))
self.assertTrue(hasattr(widget, "full_text"))
widget.set("variable", "value") widget.set("variable", "value")
self.assertEquals(widget.get("variable", None), "value") self.assertEquals(widget.get("variable", None), "value")
self.assertTrue(isinstance(widget.full_text(), str) or isinstance(widget.full_text(), unicode)) self.assertTrue(isinstance(widget.full_text(), str) or isinstance(widget.full_text(), unicode))
@mock.patch("subprocess.Popen") def test_update(self):
def test_update(self, mock_output):
mock_output.return_value = MockCommunicate()
rv = mock.Mock()
rv.configure_mock(**{
"communicate.return_value": ("out", None)
})
for mod in self.objects: for mod in self.objects:
widgets = self.objects[mod].widgets() widgets = self.objects[mod].widgets()
self.objects[mod].update(widgets) self.objects[mod].update(widgets)

View file

@ -22,3 +22,5 @@ class TestStore(unittest.TestCase):
def test_get_invalid_with_default_value(self): def test_get_invalid_with_default_value(self):
result = self.store.get(self.unsetKey, self.anyValue) result = self.store.get(self.unsetKey, self.anyValue)
self.assertEquals(result, self.anyValue) self.assertEquals(result, self.anyValue)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,21 +1,29 @@
# pylint: disable=C0103,C0111,W0703 # pylint: disable=C0103,C0111,W0703
import mock
import unittest import unittest
from bumblebee.theme import Theme from bumblebee.theme import Theme
from bumblebee.error import ThemeLoadError from bumblebee.error import ThemeLoadError
from tests.util import MockWidget from tests.mocks import MockWidget
class TestTheme(unittest.TestCase): class TestTheme(unittest.TestCase):
def setUp(self): def setUp(self):
self.nonexistentThemeName = "no-such-theme" self.nonexistentThemeName = "no-such-theme"
self.invalidThemeName = "test_invalid" self.invalidThemeName = "test_invalid"
self.validThemeName = "test" self.validThemeName = "test"
self.validThemeSeparator = " * "
self.themedWidget = MockWidget("bla") self.themedWidget = MockWidget("bla")
self.theme = Theme(self.validThemeName) self.theme = Theme(self.validThemeName)
self.cycleTheme = Theme("test_cycle") self.cycleTheme = Theme("test_cycle")
self.anyModule = mock.Mock()
self.anyWidget = MockWidget("bla") self.anyWidget = MockWidget("bla")
self.anotherWidget = MockWidget("blub") 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() data = self.theme.data()
self.widgetTheme = "test-widget" self.widgetTheme = "test-widget"
self.themedWidget.module = self.widgetTheme 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.fg(self.anyWidget), data["defaults"]["fg"])
self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["bg"]) 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.fg(self.anyWidget), data["defaults"]["critical"]["fg"])
self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["critical"]["bg"]) 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"]) self.assertEquals(theme.fg(self.themedWidget), data[self.widgetTheme]["critical"]["fg"])
# if elements are missing in the state theme, they are taken from the # 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) # widget theme instead (i.e. no fallback to a more general state theme)
self.assertEquals(theme.bg(self.themedWidget), data[self.widgetTheme]["bg"]) 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,18 +1,27 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import mock
import unittest import unittest
import tests.mocks as mocks
from bumblebee.util import * from bumblebee.util import *
class TestUtil(unittest.TestCase): 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): def test_bytefmt(self):
value = 10 self.assertEquals(bytefmt(10), "10.00B")
display = 10 self.assertEquals(bytefmt(15*1024), "15.00KiB")
units = [ "B", "KiB", "MiB", "GiB" ] self.assertEquals(bytefmt(20*1024*1024), "20.00MiB")
for unit in units: self.assertEquals(bytefmt(22*1024*1024*1024), "22.00GiB")
self.assertEquals(bytefmt(value), "{:.2f}{}".format(display, unit)) self.assertEquals(bytefmt(35*1024*1024*1024*1024), "35840.00GiB")
value *= 1024
self.assertEquals(bytefmt(value), "{:.2f}GiB".format(display*1024))
def test_durationfmt(self): def test_durationfmt(self):
self.assertEquals(durationfmt(00), "00:00") self.assertEquals(durationfmt(00), "00:00")
@ -22,4 +31,26 @@ class TestUtil(unittest.TestCase):
self.assertEquals(durationfmt(3600), "01:00:00") self.assertEquals(durationfmt(3600), "01:00:00")
self.assertEquals(durationfmt(7265), "02:01:05") 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 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -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

View file

@ -17,6 +17,9 @@
"bg": "#222222", "bg": "#222222",
"critical": { "critical": {
"fg": "#bababa" "fg": "#bababa"
},
"cycle-test": {
"fg": [ "#000000", "#111111" ]
} }
} }
} }