summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-02-11 00:07:29 +0100
committerhut <hut@lavabit.com>2010-03-09 14:40:19 +0100
commite5c4477536790b8cd10d5ffd204f226ea4d2f73e (patch)
treec529962a9f43cf2f6aac0e8ba567b7d2b291192c
parent2feb26dea6e9e55cf6bc0933baefd9fad99f5507 (diff)
downloadranger-e5c4477536790b8cd10d5ffd204f226ea4d2f73e.tar.gz
keyparser: added test for directions as functions, cleanups
-rw-r--r--test/tc_newkeys.py93
1 files changed, 66 insertions, 27 deletions
diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py
index 56a3303e..613def5c 100644
--- a/test/tc_newkeys.py
+++ b/test/tc_newkeys.py
@@ -1,7 +1,6 @@
 # coding=utf-8
 if __name__ == '__main__': from __init__ import init; init()
 from unittest import TestCase, main
-#from pprint import pprint as print
 
 from inspect import isfunction, getargspec
 import inspect
@@ -12,9 +11,9 @@ except:
 
 FUNC = 'func'
 DIRECTION = 'direction'
+DIRARG = 'dir'
 DIRKEY = 9001
 ANYKEY = 9002
-QUANTIFIER = 'n'
 
 def to_string(i):
 	"""convert a ord'd integer to a string"""
@@ -56,6 +55,7 @@ class CommandArgs(object):
 		self.directions = keybuffer.directions
 		self.keys = str(keybuffer)
 		self.matches = keybuffer.matches
+		self.binding = keybuffer.command
 
 class KeyBuffer(object):
 	"""The evaluator and storage for pressed keys"""
@@ -87,6 +87,12 @@ class KeyBuffer(object):
 			self._do_eval_direction(key)
 
 	def _do_eval_direction(self, key):
+		# swap quant and direction_quant in bindings like '<dir>'
+		if self.quant is not None and self.command is None \
+		and self.direction_quant is None:
+			self.direction_quant = self.quant
+			self.quant = None
+
 		try:
 			assert isinstance(self.dir_tree_pointer, dict)
 			self.dir_tree_pointer = self.dir_tree_pointer[key]
@@ -225,12 +231,13 @@ class Keymap(object):
 		tree = self._tree
 		for char in generator:
 			try:
-				tree = tree[char]
+				newtree = tree[char]
+				if not isinstance(newtree, dict):
+					raise KeyError()
 			except KeyError:
-				tree[char] = dict()
-				tree = tree[char]
-			except TypeError:
-				raise TypeError("Attempting to override existing entry")
+				newtree = dict()
+				tree[char] = newtree
+			tree = newtree
 		return tree
 
 	def __getitem__(self, key):
@@ -265,6 +272,10 @@ class binding(object):
 				self.has_direction = actions['with_direction']
 			except KeyError:
 				self.has_direction = DIRECTION in argnames
+		try:
+			self.direction = self.actions[DIRARG]
+		except KeyError:
+			self.direction = None
 
 	def add_keys(self, keys):
 		assert isinstance(keys, set)
@@ -276,25 +287,6 @@ class binding(object):
 	def action(self, key):
 		return self.actions[key]
 
-def n(value):
-	""" return n or value """
-	def fnc(arg=None):
-		if arg is None or arg.n is None:
-			return value
-		return arg.n
-	return fnc
-
-def nd(arg):
-	""" n * direction """
-	if arg.n is None:
-		n = 1
-	else:
-		n = arg.n
-	if arg.direction is None:
-		dir = Direction(down=1)
-	else:
-		dir = arg.direction
-	return n * dir.down
 
 class PressTestCase(TestCase):
 	"""Some useful methods for the actual test"""
@@ -342,6 +334,13 @@ class Test(PressTestCase):
 		km = Keymap()
 		directions = Keymap()
 		kb = KeyBuffer(km, directions)
+		def n(value):
+			"""return n or value"""
+			def fnc(arg=None):
+				if arg is None or arg.n is None:
+					return value
+				return arg.n
+			return fnc
 		km.add(n(5), 'p')
 		press = self._mkpress(kb, km)
 		self.assertEqual(3, press('3p'))
@@ -353,6 +352,12 @@ class Test(PressTestCase):
 		kb = KeyBuffer(km, directions)
 		directions.add('j', dir=Direction(down=1))
 		directions.add('k', dir=Direction(down=-1))
+		def nd(arg):
+			""" n * direction """
+			n = arg.n is None and 1 or arg.n
+			dir = arg.direction is None and Direction(down=1) \
+					or arg.direction
+			return n * dir.down
 		km.add(nd, 'd}')
 		km.add('dd', func=nd, with_direction=False)
 
@@ -389,12 +394,15 @@ class Test(PressTestCase):
 		directions.add('j', dir=Direction(down=1))
 		directions.add('k', dir=Direction(down=-1))
 
+		directions.add('g.', dir=Direction(down=-1))
+
 		def cat(arg):
 			n = arg.n is None and 1 or arg.n
 			return ''.join(chr(c) for c in arg.matches) * n
 
 		km.add(cat, 'return.')
 		km.add(cat, 'cat4....')
+		km.add(cat, 'foo}.')
 
 		press = self._mkpress(kb, km)
 
@@ -403,12 +411,15 @@ class Test(PressTestCase):
 		self.assertEqual('abcdabcd', press('2cat4abcd'))
 		self.assertEqual('55555', press('5return5'))
 
+		self.assertEqual('x', press('foojx'))
+		self.assertPressFails(kb, 'fooggx')  # ANYKEY forbidden in DIRECTION
+
 		km.add(lambda _: Ellipsis, '.')
 		self.assertEqual('x', press('returnx'))
 		self.assertEqual('abcd', press('cat4abcd'))
 		self.assertEqual(Ellipsis, press('2cat4abcd'))
 		self.assertEqual(Ellipsis, press('5return5'))
-		self.assertEqual(Ellipsis, press('f'))
+		self.assertEqual(Ellipsis, press('g'))
 		self.assertEqual(Ellipsis, press('ß'))
 		self.assertEqual(Ellipsis, press('ア'))
 		self.assertEqual(Ellipsis, press('9'))
@@ -460,4 +471,32 @@ class Test(PressTestCase):
 		self.assertRaises(AssertionError, kb.simulate_press, 'xxx')
 		kb.clear()
 
+	def test_directions_as_functions(self):
+		km = Keymap()
+		directions = Keymap()
+		kb = KeyBuffer(km, directions)
+		press = self._mkpress(kb, km)
+
+		def move(arg):
+			return arg.direction.down
+
+		directions.add('j', dir=Direction(down=1))
+		directions.add('k', dir=Direction(down=-1))
+		km.add('}', func=move)
+
+		self.assertEqual(1, press('j'))
+		self.assertEqual(-1, press('k'))
+
+		km.add('k', func=lambda _: 'love')
+
+		self.assertEqual(1, press('j'))
+		self.assertEqual('love', press('k'))
+
+		self.assertEqual(40, press('40j'))
+
+		km.add('}}..', func=move)
+
+		self.assertEqual(40, press('40jkhl'))
+
+
 if __name__ == '__main__': main()
i">&nbsp;<br> <font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.gui.html"><font color="#ffffff">gui</font></a>.defaultui</strong></big></big></font></td ><td align=right valign=bottom ><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/work/ranger/ranger/gui/defaultui.py">/home/hut/work/ranger/ranger/gui/defaultui.py</a></font></td></tr></table> <p></p> <p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#ee77aa"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr> <tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><dl> <dt><font face="helvetica, arial"><a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>(<a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a>) </font></dt><dd> <dl> <dt><font face="helvetica, arial"><a href="ranger.gui.defaultui.html#DefaultUI">DefaultUI</a> </font></dt></dl> </dd> </dl> <p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#ffc8d8"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#000000" face="helvetica, arial"><a name="DefaultUI">class <strong>DefaultUI</strong></a>(<a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>)</font></td></tr> <tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><dl><dt>Method resolution order:</dt> <dd><a href="ranger.gui.defaultui.html#DefaultUI">DefaultUI</a></dd> <dd><a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a></dd> <dd><a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a></dd> <dd><a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a></dd> <dd><a href="ranger.shared.html#EnvironmentAware">ranger.shared.EnvironmentAware</a></dd> <dd><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a></dd> <dd><a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a></dd> <dd><a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a></dd> <dd><a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a></dd> <dd><a href="builtins.html#object">builtins.object</a></dd> </dl> <hr> Methods defined here:<br> <dl><dt><a name="DefaultUI-close_console"><strong>close_console</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-close_embedded_pager"><strong>close_embedded_pager</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-close_pager"><strong>close_pager</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-close_taskview"><strong>close_taskview</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-hint"><strong>hint</strong></a>(self, text<font color="#909090">=None</font>)</dt></dl> <dl><dt><a name="DefaultUI-notify"><strong>notify</strong></a>(self, *a, **k)</dt></dl> <dl><dt><a name="DefaultUI-open_console"><strong>open_console</strong></a>(self, mode, string<font color="#909090">=''</font>)</dt></dl> <dl><dt><a name="DefaultUI-open_embedded_pager"><strong>open_embedded_pager</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-open_pager"><strong>open_pager</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-open_taskview"><strong>open_taskview</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-redraw_main_column"><strong>redraw_main_column</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-scroll"><strong>scroll</strong></a>(self, relative)</dt></dl> <dl><dt><a name="DefaultUI-setup"><strong>setup</strong></a>(self)</dt><dd><tt>Build&nbsp;up&nbsp;the&nbsp;<a href="ranger.gui.ui.html#UI">UI</a>&nbsp;by&nbsp;initializing&nbsp;widgets.</tt></dd></dl> <dl><dt><a name="DefaultUI-throbber"><strong>throbber</strong></a>(self, string<font color="#909090">='.'</font>, remove<font color="#909090">=False</font>)</dt></dl> <dl><dt><a name="DefaultUI-update_size"><strong>update_size</strong></a>(self)</dt><dd><tt>resize&nbsp;all&nbsp;widgets</tt></dd></dl> <hr> Methods inherited from <a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>:<br> <dl><dt><a name="DefaultUI-__init__"><strong>__init__</strong></a>(self, commandlist<font color="#909090">=None</font>, env<font color="#909090">=None</font>, fm<font color="#909090">=None</font>)</dt></dl> <dl><dt><a name="DefaultUI-destroy"><strong>destroy</strong></a>(self)</dt><dd><tt>Destroy&nbsp;all&nbsp;widgets&nbsp;and&nbsp;turn&nbsp;off&nbsp;curses</tt></dd></dl> <dl><dt><a name="DefaultUI-draw"><strong>draw</strong></a>(self)</dt><dd><tt>Erase&nbsp;the&nbsp;window,&nbsp;then&nbsp;draw&nbsp;all&nbsp;objects&nbsp;in&nbsp;the&nbsp;container</tt></dd></dl> <dl><dt><a name="DefaultUI-finalize"><strong>finalize</strong></a>(self)</dt><dd><tt>Finalize&nbsp;every&nbsp;object&nbsp;in&nbsp;container&nbsp;and&nbsp;refresh&nbsp;the&nbsp;window</tt></dd></dl> <dl><dt><a name="DefaultUI-get_next_key"><strong>get_next_key</strong></a>(self)</dt><dd><tt>Waits&nbsp;for&nbsp;key&nbsp;input&nbsp;and&nbsp;returns&nbsp;the&nbsp;pressed&nbsp;key</tt></dd></dl> <dl><dt><a name="DefaultUI-handle_key"><strong>handle_key</strong></a>(self, key)</dt><dd><tt>Handles&nbsp;key&nbsp;input</tt></dd></dl> <dl><dt><a name="DefaultUI-handle_mouse"><strong>handle_mouse</strong></a>(self)</dt><dd><tt>Handles&nbsp;mouse&nbsp;input</tt></dd></dl> <dl><dt><a name="DefaultUI-initialize"><strong>initialize</strong></a>(self)</dt><dd><tt>initialize&nbsp;curses,&nbsp;then&nbsp;call&nbsp;setup&nbsp;(at&nbsp;the&nbsp;first&nbsp;time)&nbsp;and&nbsp;resize.</tt></dd></dl> <dl><dt><a name="DefaultUI-redraw"><strong>redraw</strong></a>(self)</dt><dd><tt>Redraw&nbsp;all&nbsp;widgets</tt></dd></dl> <dl><dt><a name="DefaultUI-redraw_window"><strong>redraw_window</strong></a>(self)</dt><dd><tt>Redraw&nbsp;the&nbsp;window.&nbsp;This&nbsp;only&nbsp;calls&nbsp;self.<strong>win</strong>.redrawwin().</tt></dd></dl> <dl><dt><a name="DefaultUI-set_load_mode"><strong>set_load_mode</strong></a>(self, boolean)</dt></dl> <dl><dt><a name="DefaultUI-suspend"><strong>suspend</strong></a>(self)</dt><dd><tt>Turn&nbsp;off&nbsp;curses</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.gui.ui.html#UI">ranger.gui.ui.UI</a>:<br> <dl><dt><strong>is_set_up</strong> = False</dl> <dl><dt><strong>load_mode</strong> = False</dl> <dl><dt><strong>mousemask</strong> = 268435455</dl> <hr> Methods inherited from <a href="ranger.gui.displayable.html#DisplayableContainer">ranger.gui.displayable.DisplayableContainer</a>:<br> <dl><dt><a name="DefaultUI-add_child"><strong>add_child</strong></a>(self, obj)</dt><dd><tt>Add&nbsp;the&nbsp;objects&nbsp;to&nbsp;the&nbsp;container.</tt></dd></dl> <dl><dt><a name="DefaultUI-click"><strong>click</strong></a>(self, event)</dt><dd><tt>Recursively&nbsp;called&nbsp;on&nbsp;objects&nbsp;in&nbsp;container</tt></dd></dl> <dl><dt><a name="DefaultUI-poke"><strong>poke</strong></a>(self)</dt><dd><tt>Recursively&nbsp;called&nbsp;on&nbsp;objects&nbsp;in&nbsp;container</tt></dd></dl> <dl><dt><a name="DefaultUI-press"><strong>press</strong></a>(self, key)</dt><dd><tt>Recursively&nbsp;called&nbsp;on&nbsp;objects&nbsp;in&nbsp;container</tt></dd></dl> <dl><dt><a name="DefaultUI-remove_child"><strong>remove_child</strong></a>(self, obj)</dt><dd><tt>Remove&nbsp;the&nbsp;object&nbsp;from&nbsp;the&nbsp;container.</tt></dd></dl> <hr> Methods inherited from <a href="ranger.gui.displayable.html#Displayable">ranger.gui.displayable.Displayable</a>:<br> <dl><dt><a name="DefaultUI-__contains__"><strong>__contains__</strong></a>(self, item)</dt><dd><tt>Is&nbsp;item&nbsp;inside&nbsp;the&nbsp;boundaries?<br> item&nbsp;can&nbsp;be&nbsp;an&nbsp;iterable&nbsp;like&nbsp;[y,&nbsp;x]&nbsp;or&nbsp;an&nbsp;object&nbsp;with&nbsp;x&nbsp;and&nbsp;y&nbsp;methods.</tt></dd></dl> <dl><dt><a name="DefaultUI-__nonzero__"><strong>__nonzero__</strong></a>(self)</dt><dd><tt>Always&nbsp;True</tt></dd></dl> <dl><dt><a name="DefaultUI-__str__"><strong>__str__</strong></a>(self)</dt></dl> <dl><dt><a name="DefaultUI-contains_point"><strong>contains_point</strong></a>(self, y, x)</dt><dd><tt>Test&nbsp;whether&nbsp;the&nbsp;point&nbsp;(with&nbsp;absolute&nbsp;coordinates)&nbsp;lies<br> within&nbsp;the&nbsp;boundaries&nbsp;of&nbsp;this&nbsp;object.</tt></dd></dl> <dl><dt><a name="DefaultUI-resize"><strong>resize</strong></a>(self, y, x, hei<font color="#909090">=None</font>, wid<font color="#909090">=None</font>)</dt><dd><tt>Resize&nbsp;the&nbsp;widget</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.shared.html#EnvironmentAware">ranger.shared.EnvironmentAware</a>:<br> <dl><dt><strong>env</strong> = None</dl> <hr> Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br> <dl><dt><strong>fm</strong> = None</dl> <hr> Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a>:<br> <dl><dt><strong>__dict__</strong></dt> <dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd> </dl> <dl><dt><strong>__weakref__</strong></dt> <dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd> </dl> <hr> Methods inherited from <a href="ranger.gui.curses_shortcuts.html#CursesShortcuts">ranger.gui.curses_shortcuts.CursesShortcuts</a>:<br> <dl><dt><a name="DefaultUI-addnstr"><strong>addnstr</strong></a>(self, *args)</dt></dl> <dl><dt><a name="DefaultUI-addstr"><strong>addstr</strong></a>(self, *args)</dt></dl> <dl><dt><a name="DefaultUI-color"><strong>color</strong></a>(self, keylist<font color="#909090">=None</font>, *keys)</dt><dd><tt>Change&nbsp;the&nbsp;colors&nbsp;from&nbsp;now&nbsp;on.</tt></dd></dl> <dl><dt><a name="DefaultUI-color_at"><strong>color_at</strong></a>(self, y, x, wid, keylist<font color="#909090">=None</font>, *keys)</dt><dd><tt>Change&nbsp;the&nbsp;colors&nbsp;at&nbsp;the&nbsp;specified&nbsp;position</tt></dd></dl> <dl><dt><a name="DefaultUI-color_reset"><strong>color_reset</strong></a>(self)</dt><dd><tt>Change&nbsp;the&nbsp;colors&nbsp;to&nbsp;the&nbsp;default&nbsp;colors</tt></dd></dl> <hr> Data and other attributes inherited from <a href="ranger.shared.settings.html#SettingsAware">ranger.shared.settings.SettingsAware</a>:<br> <dl><dt><strong>settings</strong> = &lt;ranger.ext.openstruct.OpenStruct object at 0x7f20a718ad90&gt;</dl> </td></tr></table></td></tr></table><p> <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section"> <tr bgcolor="#55aa55"> <td colspan=3 valign=bottom>&nbsp;<br> <font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr> <tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td> <td width="100%"><strong>RATIO</strong> = (3, 3, 12, 9)</td></tr></table> </body></html>