diff options
-rw-r--r-- | ranger/container/bookmarks.py | 4 | ||||
-rw-r--r-- | ranger/gui/defaultui.py | 6 | ||||
-rw-r--r-- | ranger/gui/displayable.py | 39 | ||||
-rw-r--r-- | ranger/gui/ui.py | 7 | ||||
-rw-r--r-- | test/__init__.py | 21 | ||||
-rw-r--r-- | test/tc_directory.py | 8 | ||||
-rw-r--r-- | test/tc_displayable.py | 122 | ||||
-rw-r--r-- | test/tc_ui.py | 61 | ||||
-rw-r--r-- | test/test.py | 5 |
9 files changed, 249 insertions, 24 deletions
diff --git a/ranger/container/bookmarks.py b/ranger/container/bookmarks.py index bf41150c..d57ff4a9 100644 --- a/ranger/container/bookmarks.py +++ b/ranger/container/bookmarks.py @@ -1,4 +1,3 @@ -from ranger import log, trace import string import re import os @@ -112,9 +111,6 @@ Useful if two instances are running which define different bookmarks. else: real = None - log(key, current, original, real) -# trace() - if current == original and current != real: continue diff --git a/ranger/gui/defaultui.py b/ranger/gui/defaultui.py index b9758e8d..5b32690d 100644 --- a/ranger/gui/defaultui.py +++ b/ranger/gui/defaultui.py @@ -1,8 +1,8 @@ RATIO = ( 3, 3, 12, 9 ) -from ranger.gui.ui import UI as SuperClass -class DefaultUI(SuperClass): +from ranger.gui.ui import UI +class DefaultUI(UI): def setup(self): """Build up the UI by initializing widgets.""" from ranger.gui.widgets.filelistcontainer import FileListContainer @@ -20,7 +20,7 @@ class DefaultUI(SuperClass): def update_size(self): """resize all widgets""" - SuperClass.update_size(self) + UI.update_size(self) y, x = self.env.termsize self.filelist_container.resize(1, 0, y-2, x) diff --git a/ranger/gui/displayable.py b/ranger/gui/displayable.py index a19633b5..ef0260dc 100644 --- a/ranger/gui/displayable.py +++ b/ranger/gui/displayable.py @@ -6,12 +6,19 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware): win = None colorscheme = None - def __init__(self, win): + def __init__(self, win, env=None, fm=None, settings=None): + if env is not None: + self.env = env + if fm is not None: + self.fm = fm + if settings is not None: + self.settings = settings + self.x = 0 self.y = 0 self.wid = 0 self.hei = 0 - self.colorscheme = self.env.settings.colorscheme + self.colorscheme = self.settings.colorscheme if win is not None: self.win = win @@ -24,13 +31,11 @@ class Displayable(EnvironmentAware, FileManagerAware, SettingsAware): """Is item inside the boundaries? item can be an iterable like [y, x] or an object with x and y methods.""" try: - y, x = item - except ValueError: - return False - except TypeError: + y, x = item.y, item.x + except AttributeError: try: - y, x = item.y, item.x - except AttributeError: + y, x = item + except (ValueError, TypeError): return False return self.contains_point(y, x) @@ -93,6 +98,9 @@ Override this!""" wid = wid or maxx - x hei = hei or maxy - y + if x < 0 or y < 0: + raise OutOfBoundsException("Starting point below zero!") + if x + wid > maxx and y + hei > maxy: raise OutOfBoundsException("X and Y out of bounds!") @@ -110,7 +118,14 @@ Override this!""" class DisplayableContainer(Displayable): container = None - def __init__(self, win): + def __init__(self, win, env=None, fm=None, settings=None): + if env is not None: + self.env = env + if fm is not None: + self.fm = fm + if settings is not None: + self.settings = settings + Displayable.__init__(self, win) self.container = [] @@ -152,7 +167,7 @@ class DisplayableContainer(Displayable): def click(self, event): """Recursively called on objects in container""" focused_obj = self.get_focused_obj() - if focused_obj and focused_obj.click(key): + if focused_obj and focused_obj.click(event): return True for displayable in self.container: @@ -162,8 +177,8 @@ class DisplayableContainer(Displayable): return False - def add_obj(self, obj): - self.container.append(obj) + def add_obj(self, *objs): + self.container.extend(objs) def destroy(self): """Recursively called on objects in container""" diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index 4b473021..3840a978 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -7,10 +7,15 @@ from ranger.container import CommandList class UI(DisplayableContainer): is_set_up = False mousemask = curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION - def __init__(self, commandlist = None): + def __init__(self, commandlist=None, env=None, fm=None): import os os.environ['ESCDELAY'] = '25' # don't know a cleaner way + if env is not None: + self.env = env + if fm is not None: + self.fm = fm + if commandlist is None: self.commandlist = CommandList() self.settings.keys.initialize_commands(self.commandlist) diff --git a/test/__init__.py b/test/__init__.py index 500d3383..3043ba18 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -6,3 +6,24 @@ __all__ = [ x[0:x.index('.')] \ def init(): sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..'))) + +class Fake(object): + def __getattr__(self, attrname): + if not hasattr(self, attrname): + setattr(self, attrname, Fake()) + return self.__dict__[attrname] + + def __call__(self, *_): + return Fake() + + def __clear__(self): + self.__dict__.clear() + + def __iter__(self): + return iter(()) + +class OK(Exception): + pass + +def raise_ok(*_, **__): + raise OK() diff --git a/test/tc_directory.py b/test/tc_directory.py index 676ec0fe..11c94b3b 100644 --- a/test/tc_directory.py +++ b/test/tc_directory.py @@ -48,11 +48,11 @@ class Test1(unittest.TestCase): for name in assumed_filenames: f = File(name) f.load() - equal = 0 for dirfile in dir.files: - if (f.__dict__ == dirfile.__dict__): - equal += 1 - self.assertEqual(equal, 1) + if (f.path == dirfile.path and f.stat == dirfile.stat): + break + else: + self.fail("couldn't find file {0}".format(name)) def test_nonexistant_dir(self): dir = Directory(NONEXISTANT_DIR) diff --git a/test/tc_displayable.py b/test/tc_displayable.py new file mode 100644 index 00000000..01be0c9c --- /dev/null +++ b/test/tc_displayable.py @@ -0,0 +1,122 @@ +if __name__ == '__main__': from __init__ import init; init() + +import unittest +import curses +from random import randint + +from ranger.gui.displayable import\ + Displayable, DisplayableContainer, OutOfBoundsException +from test import Fake, OK, raise_ok + +class TestDisplayable(unittest.TestCase): + def setUp(self): + self.win = Fake() + self.fm = Fake() + self.env = Fake() + self.settings = Fake() + self.disp = Displayable( win=self.win, + env=self.env, fm=self.fm, settings=self.settings) + + hei, wid = 100, 100 + self.env.termsize = (hei, wid) + + def tearDown(self): + self.disp.destroy() + + def test_colorscheme(self): + # Using a color method implies change of window attributes + disp = self.disp + + self.win.chgat = raise_ok + self.win.attrset = raise_ok + + self.assertRaises(OK, disp.color, 'a', 'b') + self.assertRaises(OK, disp.color_at, 0, 0, 0, 'a', 'b') + self.assertRaises(OK, disp.color_reset) + + def test_boundaries(self): + disp = self.disp + hei, wid = self.env.termsize + + self.assertRaises(OutOfBoundsException, disp.resize, 0, 0, hei + 1, wid) + self.assertRaises(OutOfBoundsException, disp.resize, 0, 0, hei, wid + 1) + self.assertRaises(OutOfBoundsException, disp.resize, -1, 0, hei, wid) + self.assertRaises(OutOfBoundsException, disp.resize, 0, -1, hei, wid) + + box = (randint(10, 20), randint(30, 40), \ + randint(30, 40), randint(10, 20)) + + def in_box(y, x): + return (x >= box[1] and x < box[1] + box[3]) and \ + (y >= box[0] and y < box[0] + box[2]) + + disp.resize(*box) + for y, x in zip(range(10), range(10)): + is_in_box = in_box(y, x) + + point1 = (y, x) + self.assertEqual(is_in_box, point1 in disp) + + point2 = Fake() + point2.x = x + point2.y = y + self.assertEqual(is_in_box, point2 in disp) + +class TestDisplayableContainer(unittest.TestCase): + def setUp(self): + self.win = Fake() + self.fm = Fake() + self.env = Fake() + self.settings = Fake() + + self.initdict = {'win': self.win, 'settings': self.settings, + 'fm': self.fm, 'env': self.env} + + self.disp = Displayable(**self.initdict) + self.disc = DisplayableContainer(**self.initdict) + self.disc.add_obj(self.disp) + + hei, wid = (100, 100) + self.env.termsize = (hei, wid) + + def tearDown(self): + self.disc.destroy() + + def test_container(self): + self.assertTrue(self.disp in self.disc.container) + + def test_click(self): + self.disp.click = raise_ok + + self.disc.resize(0, 0, 50, 50) + self.disp.resize(0, 0, 20, 20) + fakepos = Fake() + + fakepos.x = 10 + fakepos.y = 10 + self.assertRaises(OK, self.disc.click, fakepos) + + fakepos.x = 30 + fakepos.y = 10 + self.disc.click(fakepos) + + def test_focused_object(self): + d1 = Displayable(**self.initdict) + d2 = DisplayableContainer(**self.initdict) + d2.add_obj(*[Displayable(**self.initdict) for x in range(5)]) + d3 = DisplayableContainer(**self.initdict) + d3.add_obj(*[Displayable(**self.initdict) for x in range(5)]) + + self.disc.add_obj(d1, d2, d3) + + d3.container[3].focused = True + + self.assertEqual(self.disc.get_focused_obj(), d3.container[3]) + + d3.container[3].focused = False + d2.container[0].focused = True + + self.assertEqual(self.disc.get_focused_obj(), d2.container[0]) + +if __name__ == '__main__': + unittest.main() diff --git a/test/tc_ui.py b/test/tc_ui.py new file mode 100644 index 00000000..fbe51f64 --- /dev/null +++ b/test/tc_ui.py @@ -0,0 +1,61 @@ +if __name__ == '__main__': from __init__ import init; init() + +import unittest +import curses + +from ranger.gui import ui + +from test import Fake, OK, raise_ok + +ui.curses = Fake() + +class Test(unittest.TestCase): + def setUp(self): + + self.fm = Fake() + self.ui = ui.UI(env=Fake(), fm=self.fm) + + def fakesetup(): + self.ui.widget = Fake() + self.ui.add_obj(self.ui.widget) + self.ui.setup = fakesetup + + self.ui.initialize() + + def tearDown(self): + self.ui.destroy() + + def test_scrolling(self): + # test whether scrolling works + self.fm.scroll = raise_ok + self.ui.get_focused_obj = lambda: False + + ui.curses.getmouse = lambda: (0, 0, 0, 0, curses.BUTTON2_PRESSED) + self.assertRaises(OK, self.ui.handle_mouse) + + ui.curses.getmouse = lambda: (0, 0, 0, 0, curses.BUTTON4_PRESSED) + self.assertRaises(OK, self.ui.handle_mouse) + + def test_passing(self): + # Test whether certain method calls are passed to widgets + widget = self.ui.widget + + widget.draw = raise_ok + self.assertRaises(OK, self.ui.draw) + widget.__clear__() + + widget.finalize = raise_ok + self.assertRaises(OK, self.ui.finalize) + widget.__clear__() + + widget.press = raise_ok + random_key = 123 + self.assertRaises(OK, self.ui.handle_key, random_key) + widget.__clear__() + + widget.destroy = raise_ok + self.assertRaises(OK, self.ui.destroy) + widget.__clear__() + +if __name__ == '__main__': + unittest.main() diff --git a/test/test.py b/test/test.py new file mode 100644 index 00000000..bf285a47 --- /dev/null +++ b/test/test.py @@ -0,0 +1,5 @@ +"""Workaround to allow running single test cases directly""" +try: + from __init__ import init, Fake, OK, raise_ok +except: + from test import init, Fake, OK, raise_ok |