From 9669045ea10ccb36b5cf4571c866e8f938299373 Mon Sep 17 00:00:00 2001 From: jstenar <> Date: Tue, 4 Apr 2006 21:19:34 +0000 Subject: [PATCH] pyreadline-refactor: Started on tests for emacsmode and lineeditor --- pyreadline/lineeditor/history.py | 34 ++- pyreadline/lineeditor/lineobj.py | 6 +- pyreadline/lineeditor/wordmatcher.py | 5 +- pyreadline/modes/basemode.py | 8 +- pyreadline/modes/emacs.py | 36 ++- pyreadline/modes/vi.py | 5 +- pyreadline/test/common.py | 62 +++++ pyreadline/test/emacs_test.py | 160 +++++++++++ pyreadline/test/lineeditor_test.py | 390 +++++++++++++++++++++++++++ pyreadline/test/vi_test.py | 43 +-- 10 files changed, 684 insertions(+), 65 deletions(-) create mode 100644 pyreadline/test/common.py create mode 100644 pyreadline/test/emacs_test.py create mode 100644 pyreadline/test/lineeditor_test.py diff --git a/pyreadline/lineeditor/history.py b/pyreadline/lineeditor/history.py index a37ac7a..4aadff4 100644 --- a/pyreadline/lineeditor/history.py +++ b/pyreadline/lineeditor/history.py @@ -27,6 +27,8 @@ class LineHistory(object): self.history_length=100 self.history_cursor=0 self.history_filename=os.path.expanduser('~/.history') + self.lastcommand=None + self.query="" def get_history_length(self): return self.history_length @@ -74,6 +76,7 @@ class LineHistory(object): if self.history_cursor > 0: self.history_cursor -= 1 current.set_line(self.history[self.history_cursor].get_line_text()) + current.point=lineobj.EndOfLine def next_history(self,current): # (C-n) '''Move forward through the history list, fetching the next command. ''' @@ -154,34 +157,49 @@ class LineHistory(object): for a string supplied by the user.''' self._non_i_search(1,current) - def _search(self, direction,partial): - query = partial[0:partial.point].get_line_text() + def _search(self, direction, partial): + if (self.lastcommand != self.history_search_forward and + self.lastcommand != self.history_search_backward): + self.query = ''.join(partial[0:partial.point].get_line_text()) + hcstart=self.history_cursor hc = self.history_cursor + direction +# print hc,hcstart,self.query while (direction < 0 and hc >= 0) or (direction > 0 and hc < len(self.history)): h = self.history[hc] - if not query: + if not self.query: self.history_cursor = hc - result=lineobj.ReadLineTextBuffer(h,point=partial.point) + result=lineobj.ReadLineTextBuffer(h,point=len(h.get_line_text())) return result - elif h.get_line_text().startswith(query) and h != partial.get_line_text(): + elif h.get_line_text().startswith(self.query) and h != partial.get_line_text(): self.history_cursor = hc result=lineobj.ReadLineTextBuffer(h,point=partial.point) return result hc += direction else: - return lineobj.ReadLineTextBuffer(query,point=partial.point) + if hc>=len(self.history) and not self.query: + return lineobj.ReadLineTextBuffer("",point=0) + elif self.history[hcstart].get_line_text().startswith(self.query) and self.query: + return lineobj.ReadLineTextBuffer(self.history[hcstart],point=partial.point) + else: + return lineobj.ReadLineTextBuffer(partial,point=partial.point) + return lineobj.ReadLineTextBuffer(self.query,point=min(len(self.query),partial.point)) def history_search_forward(self,partial): # () '''Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.''' - return self._search(1,partial) + q= self._search(1,partial) + return q def history_search_backward(self,partial): # () '''Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.''' - return self._search(-1,partial) + q= self._search(-1,partial) + return q + + + if __name__=="__main__": q=LineHistory() RL=lineobj.ReadLineTextBuffer diff --git a/pyreadline/lineeditor/lineobj.py b/pyreadline/lineeditor/lineobj.py index 49e5ac1..50c2d25 100644 --- a/pyreadline/lineeditor/lineobj.py +++ b/pyreadline/lineeditor/lineobj.py @@ -13,6 +13,7 @@ import pyreadline.clipboard as clipboard class NotAWordError(IndexError): pass + def quote_char(c): if ord(c)>0: return c @@ -63,7 +64,7 @@ class WordStart(LinePositioner): else: return line.point else: - raise NotInWord + raise NotAWordError("Point is not in a word") WordStart=WordStart() class WordEnd(LinePositioner): @@ -151,6 +152,7 @@ class TextLine(object): self.undo_stack=[] self.overwrite=False if isinstance(txtstr,TextLine): #copy + self.line_buffer=txtstr.line_buffer[:] if point is None: self.point=txtstr.point else: @@ -159,7 +161,6 @@ class TextLine(object): self.mark=txtstr.mark else: self.mark=mark - self.line_buffer=txtstr.line_buffer[:] else: self._insert_text(txtstr) if point is None: @@ -211,6 +212,7 @@ class TextLine(object): def set_point(self,value): if isinstance(value,LinePositioner): value=value(self) + assert (value <= len(self.line_buffer)) if value>len(self.line_buffer): value=len(self.line_buffer) self._point=value diff --git a/pyreadline/lineeditor/wordmatcher.py b/pyreadline/lineeditor/wordmatcher.py index a23fcfe..7a01108 100644 --- a/pyreadline/lineeditor/wordmatcher.py +++ b/pyreadline/lineeditor/wordmatcher.py @@ -58,9 +58,10 @@ def is_word_token(str): return not is_non_word_token(str) def is_non_word_token(str): - assert(len(str)==1) - if str in " \t\n": + if len(str)!=1 or str in " \t\n": return True + else: + return False def next_start_segment(str,is_segment): str="".join(str) diff --git a/pyreadline/modes/basemode.py b/pyreadline/modes/basemode.py index c120d79..2ae734b 100644 --- a/pyreadline/modes/basemode.py +++ b/pyreadline/modes/basemode.py @@ -6,7 +6,7 @@ # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #***************************************************************************** -import os,re,math +import os,re,math,glob import pyreadline.logger as logger from pyreadline.logger import log from pyreadline.keysyms import key_text_to_keyinfo @@ -43,6 +43,10 @@ class BaseMode(object): first_prompt=property(*_gs("first_prompt")) prompt=property(*_gs("prompt")) paste_line_buffer=property(*_gs("paste_line_buffer")) + completer_delims=property(*_gs("completer_delims")) + show_all_if_ambiguous=property(*_gs("show_all_if_ambiguous")) + mark_directories=property(*_gs("mark_directories")) + completer=property(*_gs("completer")) console=property(_g("console")) insert_text=property(_g("insert_text")) @@ -126,7 +130,7 @@ class BaseMode(object): break text = ''.join(buf[self.begidx:self.endidx]) log('file complete text="%s"' % text) - completions = glob(os.path.expanduser(text) + '*') + completions = glob.glob(os.path.expanduser(text) + '*') if self.mark_directories == 'on': mc = [] for f in completions: diff --git a/pyreadline/modes/emacs.py b/pyreadline/modes/emacs.py index eadeeb1..2e3cab4 100644 --- a/pyreadline/modes/emacs.py +++ b/pyreadline/modes/emacs.py @@ -14,14 +14,22 @@ import pyreadline.lineeditor.lineobj as lineobj import pyreadline.lineeditor.history as history import basemode + + class EmacsMode(basemode.BaseMode): mode="emacs" def __init__(self,rlobj): super(EmacsMode,self).__init__(rlobj) + self._keylog=(lambda x,y: None) + self.previous_func=None def __repr__(self): return "" + def add_key_logger(self,logfun): + """logfun should be function that takes disp_fun and line_buffer object """ + self._keylog=logfun + def _readline_from_keyboard(self): c=self.console while 1: @@ -42,6 +50,7 @@ class EmacsMode(basemode.BaseMode): r = None if dispatch_func: r = dispatch_func(event) + self._keylog(dispatch_func,self.l_buffer) self.l_buffer.push_undo() self.previous_func = dispatch_func @@ -94,7 +103,8 @@ class EmacsMode(basemode.BaseMode): def previous_history(self, e): # (C-p) '''Move back through the history list, fetching the previous command. ''' self._history.previous_history(self.l_buffer) - + self.l_buffer.point=lineobj.EndOfLine + def next_history(self, e): # (C-n) '''Move forward through the history list, fetching the next command. ''' self._history.next_history(self.l_buffer) @@ -112,6 +122,9 @@ class EmacsMode(basemode.BaseMode): c = self.console line = self.get_line_buffer() query = '' + if (self.previous_func != self.history_search_forward and + self.previous_func != self.history_search_backward): + self.query = ''.join(self.line_buffer[0:self.point].get_line_text()) hc_start = self._history.history_cursor #+ direction while 1: x, y = self.prompt_end_pos @@ -154,15 +167,11 @@ class EmacsMode(basemode.BaseMode): def reverse_search_history(self, e): # (C-r) '''Search backward starting at the current line and moving up through the history as necessary. This is an incremental search.''' -# print "HEJ" -# self.console.bell() self._i_search(self._history.reverse_search_history, -1, e) def forward_search_history(self, e): # (C-s) '''Search forward starting at the current line and moving down through the the history as necessary. This is an incremental search.''' -# print "HEJ" -# self.console.bell() self._i_search(self._history.forward_search_history, 1, e) @@ -182,13 +191,26 @@ class EmacsMode(basemode.BaseMode): '''Search forward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.''' - self.l_buffer=self._history.history_search_forward(self.l_buffer) + if self.previous_func and hasattr(self._history,self.previous_func.__name__): + self._history.lastcommand=getattr(self._history,self.previous_func.__name__) + else: + self._history.lastcommand=None + q=self._history.history_search_forward(self.l_buffer) + self.l_buffer=q + self.l_buffer.point=q.point def history_search_backward(self, e): # () '''Search backward through the history for the string of characters between the start of the current line and the point. This is a non-incremental search. By default, this command is unbound.''' - self.l_buffer=self._history.history_search_backward(self.l_buffer) + if self.previous_func and hasattr(self._history,self.previous_func.__name__): + self._history.lastcommand=getattr(self._history,self.previous_func.__name__) + else: + self._history.lastcommand=None + q=self._history.history_search_backward(self.l_buffer) + self.l_buffer=q + self.l_buffer.point=q.point + def yank_nth_arg(self, e): # (M-C-y) '''Insert the first argument to the previous command (usually the diff --git a/pyreadline/modes/vi.py b/pyreadline/modes/vi.py index 103e65f..a828bb9 100644 --- a/pyreadline/modes/vi.py +++ b/pyreadline/modes/vi.py @@ -245,8 +245,8 @@ class ViMode(basemode.BaseMode): def vi_undo_assign (self): tpl_undo = self._vi_undo_stack [self._vi_undo_cursor] - self.l_buffer.point = tpl_undo [0] self.l_buffer.line_buffer = tpl_undo [1][:] + self.l_buffer.point = tpl_undo [0] def vi_redo (self, e): if self._vi_undo_cursor >= len(self._vi_undo_stack)-1: @@ -620,7 +620,8 @@ class ViCommand: def key_slash (self, char): self.readline.vi_save_line () - self.readline.l_buffer.point, self.readline.l_buffer.line_buffer = 1, ['/'] + self.readline.l_buffer.line_buffer=['/'] + self.readline.l_buffer.point= 1 self.state = _VI_SEARCH def key_star (self, char): diff --git a/pyreadline/test/common.py b/pyreadline/test/common.py new file mode 100644 index 0000000..5ddf14b --- /dev/null +++ b/pyreadline/test/common.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +#***************************************************************************** +# Copyright (C) 2006 Michael Graz. +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#***************************************************************************** +from pyreadline.modes.emacs import * +from pyreadline import keysyms +from pyreadline.lineeditor import lineobj + +class MockReadline: + def __init__ (self): + self.l_buffer=lineobj.ReadLineTextBuffer("") + self._history=history.LineHistory() + + def add_history (self, line): + self._history.add_history (lineobj.TextLine (line)) + + def _print_prompt (self): + pass + + def _bell (self): + pass + + def insert_text(self, string): + '''Insert text into the command line.''' + self.l_buffer.insert_text(string) + + +class MockConsole: + def __init__ (self): + self.bell_count = 0 + self.text = '' + + def size (self): + return (1, 1) + + def cursor(self, visible=None, size=None): + pass + + def bell (self): + self.bell_count += 1 + + def write (self, text): + self.text += text + + + + +class Event: + def __init__ (self, char): + self.char = char + +def keytext_to_keyinfo_and_event (keytext): + keyinfo = keysyms.key_text_to_keyinfo (keytext) + if len(keytext) == 3 and keytext[0] == '"' and keytext[2] == '"': + event = Event (keytext[1]) + else: + event = Event (chr (keyinfo [3])) + return keyinfo, event + diff --git a/pyreadline/test/emacs_test.py b/pyreadline/test/emacs_test.py new file mode 100644 index 0000000..8f65b29 --- /dev/null +++ b/pyreadline/test/emacs_test.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +#***************************************************************************** +# Copyright (C) 2006 Michael Graz. +# Copyright (C) 2006 Michael Graz. +# +# Distributed under the terms of the BSD License. The full license is in +# the file COPYING, distributed as part of this software. +#***************************************************************************** + +import sys, unittest +import pdb +sys.path.append ('../..') +from pyreadline.modes.emacs import * +from pyreadline import keysyms +from pyreadline.lineeditor import lineobj + +from common import * +#---------------------------------------------------------------------- + +class EmacsModeTest (EmacsMode): + def __init__ (self): + EmacsMode.__init__ (self, MockReadline()) + self.mock_console = MockConsole () + self.init_editing_mode (None) + self.lst_completions = [] + self.completer = self.mock_completer + self.completer_delims = ' ' + self.tabstop = 4 + + def get_mock_console (self): + return self.mock_console + console = property (get_mock_console) + + def _set_line (self, text): + self.l_buffer.set_line (text) + + def get_line (self): + return self.l_buffer.get_line_text () + line = property (get_line) + + def get_line_cursor (self): + return self.l_buffer.point + line_cursor = property (get_line_cursor) + + def input (self, keytext): + if keytext[0] == '"' and keytext[-1] == '"': + lst_key = ['"%s"' % c for c in keytext[1:-1]] + else: + lst_key = [keytext] + for key in lst_key: + keyinfo, event = keytext_to_keyinfo_and_event (key) + dispatch_func = self.key_dispatch.get(keyinfo,self.self_insert) + dispatch_func (event) + self.previous_func=dispatch_func + def accept_line (self, e): + if EmacsMode.accept_line (self, e): + # simulate return + # self.add_history (self.line) + self.l_buffer.reset_line () + + def mock_completer (self, text, state): + return self.lst_completions [state] + +#---------------------------------------------------------------------- + +class Tests (unittest.TestCase): + + def test_keyinfo (self): + keyinfo, event = keytext_to_keyinfo_and_event ('"d"') + self.assertEqual ('d', event.char) + keyinfo, event = keytext_to_keyinfo_and_event ('"D"') + self.assertEqual ('D', event.char) + keyinfo, event = keytext_to_keyinfo_and_event ('"$"') + self.assertEqual ('$', event.char) + keyinfo, event = keytext_to_keyinfo_and_event ('Escape') + self.assertEqual ('\x1b', event.char) + + + def test_history_1 (self): + r = EmacsModeTest () + r.add_history ('aa') + r.add_history ('bbb') + self.assertEqual (r.line, '') + r.input ('Up') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 3) + r.input ('Up') + self.assertEqual (r.line, 'aa') + self.assertEqual (r.line_cursor, 2) + r.input ('Up') + self.assertEqual (r.line, 'aa') + self.assertEqual (r.line_cursor, 2) + r.input ('Down') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 3) + r.input ('Down') + self.assertEqual (r.line, '') + self.assertEqual (r.line_cursor, 0) + + def test_history_2 (self): + r = EmacsModeTest () + r.add_history ('aaaa') + r.add_history ('aaba') + r.add_history ('aaca') + r.add_history ('akca') + r.add_history ('bbb') + r.add_history ('ako') + self.assertEqual (r.line, '') + r.input ('"a"') + r.input ('Up') + self.assertEqual (r.line, 'ako') + self.assertEqual (r.line_cursor, 1) + r.input ('Up') + self.assertEqual (r.line, 'akca') + self.assertEqual (r.line_cursor, 1) + r.input ('Up') + self.assertEqual (r.line, 'aaca') + self.assertEqual (r.line_cursor, 1) + r.input ('Up') + self.assertEqual (r.line, 'aaba') + self.assertEqual (r.line_cursor, 1) + r.input ('Up') + self.assertEqual (r.line, 'aaaa') + self.assertEqual (r.line_cursor, 1) + r.input ('Right') + self.assertEqual (r.line, 'aaaa') + self.assertEqual (r.line_cursor, 2) + r.input ('Down') + self.assertEqual (r.line, 'aaba') + self.assertEqual (r.line_cursor, 2) + r.input ('Down') + self.assertEqual (r.line, 'aaca') + self.assertEqual (r.line_cursor, 2) + r.input ('Down') + self.assertEqual (r.line, 'aaca') + self.assertEqual (r.line_cursor, 2) + r.input ('Left') + r.input ('Left') + r.input ('Down') + r.input ('Down') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 3) + r.input ('Left') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 2) + r.input ('Down') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 2) + r.input ('Up') + self.assertEqual (r.line, 'bbb') + self.assertEqual (r.line_cursor, 2) + +#---------------------------------------------------------------------- +# utility functions + +#---------------------------------------------------------------------- + +if __name__ == '__main__': + unittest.main() + diff --git a/pyreadline/test/lineeditor_test.py b/pyreadline/test/lineeditor_test.py new file mode 100644 index 0000000..2e4dd0f --- /dev/null +++ b/pyreadline/test/lineeditor_test.py @@ -0,0 +1,390 @@ +# Copyright (C) 2006 Michael Graz. + +import sys, unittest +sys.path.append ('../..') +#from pyreadline.modes.vi import * +#from pyreadline import keysyms +from pyreadline.lineeditor import lineobj + +#---------------------------------------------------------------------- + + +#---------------------------------------------------------------------- + +class Test_copy (unittest.TestCase): + def test_copy1 (self): + l=lineobj.ReadLineTextBuffer("first second") + q=l.copy() + self.assertEqual(q.get_line_text(),l.get_line_text()) + self.assertEqual(q.point,l.point) + self.assertEqual(q.mark,l.mark) + + def test_copy2 (self): + l=lineobj.ReadLineTextBuffer("first second",point=5) + q=l.copy() + self.assertEqual(q.get_line_text(),l.get_line_text()) + self.assertEqual(q.point,l.point) + self.assertEqual(q.mark,l.mark) + + +class Test_linepos (unittest.TestCase): + t="test text" + def test_NextChar (self): + t=self.t + l=lineobj.ReadLineTextBuffer(t) + for i in range(len(t)): + self.assertEqual(i,l.point) + l.point=lineobj.NextChar + #advance past end of buffer + l.point=lineobj.NextChar + self.assertEqual(len(t),l.point) + + def test_PrevChar (self): + t=self.t + l=lineobj.ReadLineTextBuffer(t,point=len(t)) + for i in range(len(t)): + self.assertEqual(len(t)-i,l.point) + l.point=lineobj.PrevChar + #advance past beginning of buffer + l.point=lineobj.PrevChar + self.assertEqual(0,l.point) + + def test_EndOfLine (self): + t=self.t + l=lineobj.ReadLineTextBuffer(t,point=len(t)) + for i in range(len(t)): + l.point=i + l.point=lineobj.EndOfLine + self.assertEqual(len(t),l.point) + + def test_StartOfLine (self): + t=self.t + l=lineobj.ReadLineTextBuffer(t,point=len(t)) + for i in range(len(t)): + l.point=i + l.point=lineobj.StartOfLine + self.assertEqual(0,l.point) + + +class Tests_linepos2(Test_linepos): + t="kajkj" + +class Tests_linepos3(Test_linepos): + t="" + + +class Test_movement (unittest.TestCase): + def test_NextChar (self): + cmd=lineobj.NextChar + tests=[ + # "First" + (cmd, + "First", + "# ", + " # "), + (cmd, + "First", + " # ", + " #"), + (cmd, + "First", + " #", + " #"), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_PrevChar (self): + cmd=lineobj.PrevChar + tests=[ + # "First" + (cmd, + "First", + " #", + " # "), + (cmd, + "First", + " # ", + "# "), + (cmd, + "First", + "# ", + "# "), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + + + def test_PrevWordStart (self): + cmd=lineobj.PrevWordStart + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + " #", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + "# "), + (cmd, + "First Second Third", + "# ", + "# "), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_NextWordStart (self): + cmd=lineobj.NextWordStart + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + " #"), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_NextWordEnd (self): + cmd=lineobj.NextWordEnd + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + " #"), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_PrevWordEnd (self): + cmd=lineobj.PrevWordEnd + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + " #", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + "# "), + (cmd, + "First Second Third", + "# ", + "# "), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_WordEnd_1 (self): + cmd=lineobj.WordEnd + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + " # "), + (cmd, + "First Second Third", + " # ", + " # "), + (cmd, + "First Second Third", + " # ", + " #"), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_WordEnd_2 (self): + cmd=lineobj.WordEnd + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + " # "), + (cmd, + "First Second Third", + " # "), + (cmd, + "First Second Third", + " #"), + ] + + for cmd,text,init_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + self.assertRaises(lineobj.NotAWordError,cmd,l) + + + def test_WordStart_1 (self): + cmd=lineobj.WordStart + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + "# "), + (cmd, + "First Second Third", + " # ", + "# "), + (cmd, + "First Second Third", + " # ", + " # "), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_WordStart_2 (self): + cmd=lineobj.WordStart + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + " # "), + (cmd, + "First Second Third", + " # "), + (cmd, + "First Second Third", + " #"), + ] + + for cmd,text,init_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + self.assertRaises(lineobj.NotAWordError,cmd,l) + + + def test_StartOfLine (self): + cmd=lineobj.StartOfLine + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + "# "), + (cmd, + "First Second Third", + " # ", + "# "), + (cmd, + "First Second Third", + " #", + "# "), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_EndOfLine (self): + cmd=lineobj.EndOfLine + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + "# ", + " #"), + (cmd, + "First Second Third", + " # ", + " #"), + (cmd, + "First Second Third", + " #", + " #"), + ] + for cmd,text,init_point,expected_point in tests: + l=lineobj.ReadLineTextBuffer(text,get_point_pos(init_point)) + l.point=cmd + self.assertEqual(get_point_pos(expected_point),l.point) + + def test_Point(self): + cmd=lineobj.Point + tests=[ + # "First Second Third" + (cmd, + "First Second Third", + 0), + (cmd, + "First Second Third", + 12), + (cmd, + "First Second Third", + 18), + ] + for cmd,text,p in tests: + l=lineobj.ReadLineTextBuffer(text,p) + self.assertEqual(p,cmd(l)) + + +#---------------------------------------------------------------------- +# utility functions + +def get_point_pos(pstr): + return pstr.index("#") + +def get_mark_pos(mstr): + try: + return mstr.index("#") + except ValueError: + return -1 +#---------------------------------------------------------------------- + +if __name__ == '__main__': + unittest.main() + + l=lineobj.ReadLineTextBuffer("First Second Third") \ No newline at end of file diff --git a/pyreadline/test/vi_test.py b/pyreadline/test/vi_test.py index 848354d..6f04145 100644 --- a/pyreadline/test/vi_test.py +++ b/pyreadline/test/vi_test.py @@ -12,6 +12,7 @@ from pyreadline.modes.vi import * from pyreadline import keysyms from pyreadline.lineeditor import lineobj +from common import * #---------------------------------------------------------------------- class ViModeTest (ViMode): @@ -59,37 +60,6 @@ class ViModeTest (ViMode): def mock_completer (self, text, state): return self.lst_completions [state] -class MockReadline: - def __init__ (self): - self.l_buffer=lineobj.ReadLineTextBuffer("") - self._history=history.LineHistory() - - def add_history (self, line): - self._history.add_history (lineobj.TextLine (line)) - - def _print_prompt (self): - pass - - def _bell (self): - pass - -class MockConsole: - def __init__ (self): - self.bell_count = 0 - self.text = '' - - def size (self): - return (1, 1) - - def cursor(self, visible=None, size=None): - pass - - def bell (self): - self.bell_count += 1 - - def write (self, text): - self.text += text - class ViExternalEditorTest (ViExternalEditor): def __init__ (self, line): import StringIO @@ -2149,17 +2119,6 @@ class Tests (unittest.TestCase): #---------------------------------------------------------------------- # utility functions -class Event: - def __init__ (self, char): - self.char = char - -def keytext_to_keyinfo_and_event (keytext): - keyinfo = keysyms.key_text_to_keyinfo (keytext) - if len(keytext) == 3 and keytext[0] == '"' and keytext[2] == '"': - event = Event (keytext[1]) - else: - event = Event (chr (keyinfo [3])) - return keyinfo, event #----------------------------------------------------------------------