summary refs log tree commit diff stats
path: root/test/tc_newkeys.py
diff options
context:
space:
mode:
authorhut <hut@lavabit.com>2010-04-14 20:01:47 +0200
committerhut <hut@lavabit.com>2010-04-14 20:01:47 +0200
commitef18cd85cd48117dd8bd36325887bb2a7cc49653 (patch)
treeca320ae025cc0426527f62b27c08ebbc406b0590 /test/tc_newkeys.py
parent681d9f6adf185f1c3adf0801da3d3baac99e1ea7 (diff)
parent5a8c735198079d928a7611b1f9c5aa7bf6d62a1e (diff)
downloadranger-ef18cd85cd48117dd8bd36325887bb2a7cc49653.tar.gz
Merge branch 'newkey' into devel
Diffstat (limited to 'test/tc_newkeys.py')
-rw-r--r--test/tc_newkeys.py594
1 files changed, 594 insertions, 0 deletions
diff --git a/test/tc_newkeys.py b/test/tc_newkeys.py
new file mode 100644
index 00000000..c06c2894
--- /dev/null
+++ b/test/tc_newkeys.py
@@ -0,0 +1,594 @@
+# coding=utf-8
+# Copyright (C) 2009, 2010  Roman Zimbelmann <romanz@lavabit.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if __name__ == '__main__': from __init__ import init; init()
+from unittest import TestCase, main
+
+from ranger.ext.tree import Tree
+from ranger.container.keymap import *
+
+import sys
+
+class PressTestCase(TestCase):
+	"""Some useful methods for the actual test"""
+	def _mkpress(self, keybuffer, _=0):
+		def press(keys):
+			keybuffer.clear()
+			match = keybuffer.simulate_press(keys)
+			self.assertFalse(keybuffer.failure,
+					"parsing keys '"+keys+"' did fail!")
+			self.assertTrue(keybuffer.done,
+					"parsing keys '"+keys+"' did not complete!")
+			arg = CommandArgs(None, None, keybuffer)
+			self.assert_(match.function, "No function found! " + \
+					str(match.__dict__))
+			return match.function(arg)
+		return press
+
+	def assertPressFails(self, kb, keys):
+		kb.clear()
+		kb.simulate_press(keys)
+		self.assertTrue(kb.failure, "Keypress did not fail as expected")
+		kb.clear()
+
+	def assertPressIncomplete(self, kb, keys):
+		kb.clear()
+		kb.simulate_press(keys)
+		self.assertFalse(kb.failure, "Keypress failed, expected incomplete")
+		self.assertFalse(kb.done, "Keypress done which was unexpected")
+		kb.clear()
+
+class Test(PressTestCase):
+	"""The test cases"""
+	def test_passive_action(self):
+		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.map('ppp', n(5))
+		km.map('pp<bg>', n(8))
+		km.map('pp<dir>', n(2))
+		directions.map('j', dir=Direction(down=1))
+
+		press = self._mkpress(kb, km)
+		self.assertEqual(5, press('ppp'))
+		self.assertEqual(3, press('3ppp'))
+
+		self.assertEqual(2, press('ppj'))
+
+		kb.clear()
+		match = kb.simulate_press('pp')
+		args = CommandArgs(0, 0, kb)
+		self.
parse/0: instruction: 1
parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
parse/0:   product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]}
parse/0: label: {
parse/0: instruction: 1
parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
parse/0:   product: {name: "2", value: 0, type: 1, properties: ["2": "integer"]}
parse/0: instruction: 32
parse/0: label: {
parse/0: instruction: 1
parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
parse/0:   product: {name: "3", value: 0, type: 1, properties: ["3": "integer"]}
parse/0: label: }
parse/0: instruction: 1
parse/0:   ingredient: {name: "0", value: 0, type: 0, properties: ["0": "literal"]}
parse/0:   product: {name: "4", value: 0, type: 1, properties: ["4": "integer"]}
parse/0: label: }
brace/0: 1000: push (open, 1)
brace/0: 1000: push (open, 4)
brace/0: push (close, 6)
brace/0: push (close, 8)
after-brace/0: recipe main
after-brace/0: copy ...
after-brace/0: copy ...
after-brace/0: jump 4:offset
after-brace/0: copy ...
after-brace/0: copy ...
'add'>+ u.set('aaaX', 0) + u.set('bbbC', 'Yes') + u.set('bbbD', None) + u.set('bbbE', 15) + u.set('bbbF', 16) + u.set('bQ', 22) + u.set('bR', 23) + u.set('ffff', 1337) + return u + + # test 1 + t = Tree('a') + u = Tree('b') + merged = t.merge(u, copy=True) + self.assertEqual('b', merged._tree) + + # test 2 + t = Tree('a') + u = makeTreeA() + merged = t.merge(u, copy=True) + self.assertEqual(u._tree, merged._tree) + + # test 3 + t = makeTreeA() + u = makeTreeB() + v = t.merge(u, copy=True) + + self.assertEqual(0, v['aaaX']) + self.assertEqual(2, v['aaaY']) + self.assertEqual(3, v['aaaZ']) + self.assertEqual(11, v['bbbA']) + self.assertEqual('Yes', v['bbbC']) + self.assertEqual(None, v['bbbD']) + self.assertEqual(15, v['bbbE']) + self.assertEqual(16, v['bbbF']) + self.assertRaises(KeyError, t.__getitem__, 'bbbG') + self.assertEqual(21, v['bP']) + self.assertEqual(22, v['bQ']) + self.assertEqual(23, v['bR']) + self.assertEqual(1337, v['ffff']) + + # merge shouldn't be destructive + self.assertEqual(makeTreeA()._tree, t._tree) + self.assertEqual(makeTreeB()._tree, u._tree) + + v['fff'].replace('Lolz') + self.assertEqual('Lolz', v['fff']) + + v['aaa'].replace('Very bad') + v.plow('qqqqqqq').replace('eww.') + + self.assertEqual(makeTreeA()._tree, t._tree) + self.assertEqual(makeTreeB()._tree, u._tree) + + def test_add(self): + c = KeyMap() + c.map('aa', 'b', lambda *_: 'lolz') + self.assert_(c['aa'].function(), 'lolz') + @c.map('a', 'c') + def test(): + return 5 + self.assert_(c['b'].function(), 'lolz') + self.assert_(c['c'].function(), 5) + self.assert_(c['a'].function(), 5) + + def test_quantifier(self): + 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.map('p', n(5)) + press = self._mkpress(kb, km) + self.assertEqual(5, press('p')) + self.assertEqual(3, press('3p')) + self.assertEqual(6223, press('6223p')) + + def test_direction(self): + km = KeyMap() + directions = KeyMap() + kb = KeyBuffer(km, directions) + directions.map('j', dir=Direction(down=1)) + directions.map('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.map('d<dir>', nd) + km.map('dd', func=nd) + + press = self._mkpress(kb, km) + + self.assertPressIncomplete(kb, 'd') + self.assertEqual( 1, press('dj')) + self.assertEqual( 3, press('3ddj')) + self.assertEqual( 15, press('3d5j')) + self.assertEqual(-15, press('3d5k')) + # supporting this kind of key combination would be too confusing: + # self.assertEqual( 15, press('3d5d')) + self.assertEqual( 3, press('3dd')) + self.assertEqual( 33, press('33dd')) + self.assertEqual( 1, press('dd')) + + km.map('x<dir>', nd) + km.map('xxxx', func=nd) + + self.assertEqual(1, press('xxxxj')) + self.assertEqual(1, press('xxxxjsomeinvalitchars')) + + # these combinations should break: + self.assertPressFails(kb, 'xxxj') + self.assertPressFails(kb, 'xxj') + self.assertPressFails(kb, 'xxkldfjalksdjklsfsldkj') + self.assertPressFails(kb, 'xyj') + self.assertPressIncomplete(kb, 'x') # direction missing + + def test_any_key(self): + km = KeyMap() + directions = KeyMap() + kb = KeyBuffer(km, directions) + directions.map('j', dir=Direction(down=1)) + directions.map('k', dir=Direction(down=-1)) + + directions.map('g<any>', 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.map('return<any>', cat) + km.map('cat4<any><any><any><any>', cat) + km.map('foo<dir><any>', cat) + + press = self._mkpress(kb, km) + + self.assertEqual('x', press('returnx')) + self.assertEqual('abcd', press('cat4abcd')) + self.assertEqual('abcdabcd', press('2cat4abcd')) + self.assertEqual('55555', press('5return5')) + + self.assertEqual('x', press('foojx')) + self.assertPressFails(kb, 'fooggx') # ANYKEY forbidden in DIRECTION + + km.map('<any>', 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('g')) + self.assertEqual(Ellipsis, press('ß')) + self.assertEqual(Ellipsis, press('ア')) + self.assertEqual(Ellipsis, press('9')) + + def test_multiple_directions(self): + km = KeyMap() + directions = KeyMap() + kb = KeyBuffer(km, directions) + directions.map('j', dir=Direction(down=1)) + directions.map('k', dir=Direction(down=-1)) + + def add_dirs(arg): + return sum(dir.down() for dir in arg.directions) + + km.map('x<dir>y<dir>', add_dirs) + km.map('four<dir><dir><dir><dir>', add_dirs) + + press = self._mkpress(kb, km) + + self.assertEqual(2, press('xjyj')) + self.assertEqual(0, press('fourjkkj')) + self.assertEqual(2, press('four2j4k2j2j')) + self.assertEqual(10, press('four1j2j3j4j')) + self.assertEqual(10, press('four1j2j3j4jafslkdfjkldj')) + + def test_corruptions(self): + km = KeyMap() + directions = KeyMap() + kb = KeyBuffer(km, directions) + press = self._mkpress(kb, km) + directions.map('j', dir=Direction(down=1)) + directions.map('k', dir=Direction(down=-1)) + km.map('xxx', lambda _: 1) + + self.assertEqual(1, press('xxx')) + + # corrupt the tree + tup = tuple(translate_keys('xxx')) + x = ord('x') + km._tree[x][x][x] = "Boo" + + self.assertPressFails(kb, 'xxy') + self.assertPressFails(kb, 'xzy') + self.assertPressIncomplete(kb, 'xx') + self.assertPressIncomplete(kb, 'x') + if not sys.flags.optimize: + 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.map('j', dir=Direction(down=1)) + directions.map('s', alias='j') + directions.map('k', dir=Direction(down=-1)) + km.map('<dir>', func=move) + + self.assertEqual(1, press('j')) + self.assertEqual(1, press('j')) + self.assertEqual(1, press('j')) + self.assertEqual(1, press('j')) + self.assertEqual(1, press('j')) + self.assertEqual(1, press('s')) + self.assertEqual(1, press('s')) + self.assertEqual(1, press('s')) + self.assertEqual(1, press('s')) + self.assertEqual(1, press('s')) + self.assertEqual(-1, press('k')) + self.assertEqual(-1, press('k')) + self.assertEqual(-1, press('k')) + + km.map('k', func=lambda _: 'love') + + self.assertEqual(1, press('j')) + self.assertEqual('love', press('k')) + + self.assertEqual(1, press('40j')) + self.assertEqual(40, kb.quant) + + km.map('<dir><dir><any><any>', func=move) + + self.assertEqual(1, press('40jkhl')) + self.assertEqual(40, kb.quant) + + def test_tree_deep_copy(self): + t = Tree() + s = t.plow('abcd') + s.replace('X') + u = t.copy() + self.assertEqual(t._tree, u._tree) + s = t.traverse('abc') + s.replace('Y') + self.assertNotEqual(t._tree, u._tree) + + def test_keymanager(self): + def func(arg): + return 5 + def getdown(arg): + return arg.direction.down() + + buffer = KeyBuffer(None, None) + press = self._mkpress(buffer) + keymanager = KeyManager(buffer, ['foo', 'bar']) + + map = keymanager.get_context('foo') + map('a', func) + map('b', func) + map = keymanager.get_context('bar') + map('c', func) + map('<dir>', getdown) + + keymanager.dir('foo', 'j', down=1) + keymanager.dir('bar', 'j', down=1) + + keymanager.use_context('foo') + self.assertEqual(5, press('a')) + self.assertEqual(5, press('b')) + self.assertPressFails(buffer, 'c') + + keymanager.use_context('bar') + self.assertPressFails(buffer, 'a') + self.assertPressFails(buffer, 'b') + self.assertEqual(5, press('c')) + self.assertEqual(1, press('j')) + keymanager.use_context('foo') + keymanager.use_context('foo') + keymanager.use_context('foo') + keymanager.use_context('bar') + keymanager.use_context('foo') + keymanager.use_context('bar') + keymanager.use_context('bar') + self.assertEqual(1, press('j')) + + def test_alias_to_direction(self): + def func(arg): + return arg.direction.down() + + km = KeyMapWithDirections() + kb = KeyBuffer(km, km.directions) + press = self._mkpress(kb) + + km.map('<dir>', func) + km.map('d<dir>', func) + km.dir('j', down=42) + km.dir('k', alias='j') + self.assertEqual(42, press('j')) + + km.dir('o', alias='j') + km.dir('ick', alias='j') + self.assertEqual(42, press('o')) + self.assertEqual(42, press('dj')) + self.assertEqual(42, press('dk')) + self.assertEqual(42, press('do')) + self.assertEqual(42, press('dick')) + self.assertPressFails(kb, 'dioo') + + def test_both_directory_and_any_key(self): + def func(arg): + return arg.direction.down() + def func2(arg): + return "yay" + + km = KeyMap() + directions = KeyMap() + kb = KeyBuffer(km, directions) + press = self._mkpress(kb) + + km.map('abc<dir>', func) + directions.map('j', dir=Direction(down=42)) + self.assertEqual(42, press('abcj')) + + km.unmap('abc<dir>') + + km.map('abc<any>', func2) + self.assertEqual("yay", press('abcd')) + + km.map('abc<dir>', func) + + km.map('abc<any>', func2) + self.assertEqual("yay", press('abcd')) + + def test_map_collision(self): + def add_dirs(arg): + return sum(dir.down() for dir in arg.directions) + def return5(_): + return 5 + + + directions = KeyMap() + directions.map('gg', dir=Direction(down=1)) + + + km = KeyMap() + km.map('gh', return5) + km.map('agh', return5) + km.map('a<dir>', add_dirs) + + kb = KeyBuffer(km, directions) + press = self._mkpress(kb, km) + + self.assertEqual(5, press('gh')) + self.assertEqual(5, press('agh')) +# self.assertPressFails(kb, 'agh') + self.assertEqual(1, press('agg')) + + def test_keymap_with_dir(self): + def func(arg): + return arg.direction.down() + + km = KeyMapWithDirections() + kb = KeyBuffer(km, km.directions) + + press = self._mkpress(kb) + + km.map('abc<dir>', func) + km.dir('j', down=42) + self.assertEqual(42, press('abcj')) + +if __name__ == '__main__': main()