11import os
22import unittest
33from itertools import islice
4- from mock import Mock
4+ from mock import Mock , MagicMock
55try :
66 from unittest import skip
77except ImportError :
@@ -111,8 +111,11 @@ class TestMatchesIterator(unittest.TestCase):
111111
112112 def setUp (self ):
113113 self .matches = ['bobby' , 'bobbies' , 'bobberina' ]
114- self .matches_iterator = repl .MatchesIterator (current_word = 'bob' ,
115- matches = self .matches )
114+ self .matches_iterator = repl .MatchesIterator ()
115+ self .matches_iterator .current_word = 'bob'
116+ self .matches_iterator .orig_line = 'bob'
117+ self .matches_iterator .orig_cursor_offset = len ('bob' )
118+ self .matches_iterator .matches = self .matches
116119
117120 def test_next (self ):
118121 self .assertEqual (self .matches_iterator .next (), self .matches [0 ])
@@ -156,12 +159,32 @@ def test_update(self):
156159 self .assertEqual (list (slice ), self .matches )
157160
158161 newmatches = ['string' , 'str' , 'set' ]
159- self .matches_iterator .update ('s' , newmatches )
162+ completer = Mock ()
163+ completer .locate .return_value = (0 , 1 , 's' )
164+ self .matches_iterator .update (1 , 's' , newmatches , completer )
160165
161166 newslice = islice (newmatches , 0 , 3 )
162167 self .assertNotEqual (list (slice ), self .matches )
163168 self .assertEqual (list (newslice ), newmatches )
164169
170+ def test_cur_line (self ):
171+ completer = Mock ()
172+ completer .locate .return_value = (0 ,
173+ self .matches_iterator .orig_cursor_offset ,
174+ self .matches_iterator .orig_line )
175+ self .matches_iterator .completer = completer
176+
177+ with self .assertRaises (ValueError ):
178+ self .matches_iterator .cur_line ()
179+
180+ self .assertEqual (self .matches_iterator .next (), self .matches [0 ])
181+ self .assertEqual (self .matches_iterator .cur_line (),
182+ (len (self .matches [0 ]), self .matches [0 ]))
183+
184+ def test_is_cseq (self ):
185+ self .assertTrue (self .matches_iterator .is_cseq ())
186+
187+
165188class TestArgspec (unittest .TestCase ):
166189 def setUp (self ):
167190 self .repl = FakeRepl ()
@@ -227,43 +250,45 @@ def test_nonexistent_name(self):
227250 self .setInputLine ("spamspamspam(" )
228251 self .assertFalse (self .repl .get_args ())
229252
253+
230254class TestRepl (unittest .TestCase ):
231255
256+ def setInputLine (self , line ):
257+ """Set current input line of the test REPL."""
258+ self .repl .current_line = line
259+ self .repl .cursor_offset = len (line )
260+
232261 def setUp (self ):
233262 self .repl = FakeRepl ()
234263
235264 def test_current_string (self ):
236- self .repl . input_line = 'a = "2"'
265+ self .setInputLine ( 'a = "2"' )
237266 self .repl .cpos = 0 #TODO factor cpos out of repl.Repl
238267 self .assertEqual (self .repl .current_string (), '"2"' )
239268
240- self .repl . input_line = 'a = "2" + 2'
269+ self .setInputLine ( 'a = "2" + 2' )
241270 self .assertEqual (self .repl .current_string (), '' )
242271
243- # TODO: figure out how to capture whether foobar is in globals
244- @skip ('not working yet' )
245272 def test_push (self ):
246273 self .repl = FakeRepl ()
247274 self .repl .push ("foobar = 2" )
248- self .repl .push ( " \" foobar\" in globals().keys()" )
275+ self .assertEqual ( self . repl .interp . locals [ ' foobar' ], 2 )
249276
250277 # COMPLETE TESTS
251278 # 1. Global tests
252279 def test_simple_global_complete (self ):
253280 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SIMPLE })
254- self .repl .input_line = "d"
255- self .repl .current_word = "d"
281+ self .setInputLine ("d" )
256282
257283 self .assertTrue (self .repl .complete ())
258- self .assertTrue (hasattr (self .repl .matches_iter ,'matches' ))
259- self .assertEqual (self .repl .completer .matches ,
284+ self .assertTrue (hasattr (self .repl .matches_iter , 'matches' ))
285+ self .assertEqual (self .repl .matches_iter .matches ,
260286 ['def' , 'del' , 'delattr(' , 'dict(' , 'dir(' , 'divmod(' ])
261287
262288 @skip ("disabled while non-simple completion is disabled" )
263289 def test_substring_global_complete (self ):
264290 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SUBSTRING })
265- self .repl .input_line = "time"
266- self .repl .current_word = "time"
291+ self .setInputLine ("time" )
267292
268293 self .assertTrue (self .repl .complete ())
269294 self .assertTrue (hasattr (self .repl .completer ,'matches' ))
@@ -273,8 +298,7 @@ def test_substring_global_complete(self):
273298 @skip ("disabled while non-simple completion is disabled" )
274299 def test_fuzzy_global_complete (self ):
275300 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .FUZZY })
276- self .repl .input_line = "doc"
277- self .repl .current_word = "doc"
301+ self .setInputLine ("doc" )
278302
279303 self .assertTrue (self .repl .complete ())
280304 self .assertTrue (hasattr (self .repl .completer ,'matches' ))
@@ -284,8 +308,7 @@ def test_fuzzy_global_complete(self):
284308 # 2. Attribute tests
285309 def test_simple_attribute_complete (self ):
286310 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SIMPLE })
287- self .repl .input_line = "Foo.b"
288- self .repl .current_word = "Foo.b"
311+ self .setInputLine ("Foo.b" )
289312
290313 code = "class Foo():\n \t def bar(self):\n \t \t pass\n "
291314 for line in code .split ("\n " ):
@@ -299,8 +322,7 @@ def test_simple_attribute_complete(self):
299322 @skip ("disabled while non-simple completion is disabled" )
300323 def test_substring_attribute_complete (self ):
301324 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SUBSTRING })
302- self .repl .input_line = "Foo.az"
303- self .repl .current_word = "Foo.az"
325+ self .setInputLine ("Foo.az" )
304326
305327 code = "class Foo():\n \t def baz(self):\n \t \t pass\n "
306328 for line in code .split ("\n " ):
@@ -314,8 +336,7 @@ def test_substring_attribute_complete(self):
314336 @skip ("disabled while non-simple completion is disabled" )
315337 def test_fuzzy_attribute_complete (self ):
316338 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .FUZZY })
317- self .repl .input_line = "Foo.br"
318- self .repl .current_word = "Foo.br"
339+ self .setInputLine ("Foo.br" )
319340
320341 code = "class Foo():\n \t def bar(self):\n \t \t pass\n "
321342 for line in code .split ("\n " ):
@@ -329,8 +350,7 @@ def test_fuzzy_attribute_complete(self):
329350 # 3. Edge Cases
330351 def test_updating_namespace_complete (self ):
331352 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SIMPLE })
332- self .repl .input_line = "foo"
333- self .repl .current_word = "foo"
353+ self .setInputLine ("foo" )
334354 self .repl .push ("foobar = 2" )
335355
336356 self .assertTrue (self .repl .complete ())
@@ -340,8 +360,7 @@ def test_updating_namespace_complete(self):
340360
341361 def test_file_should_not_appear_in_complete (self ):
342362 self .repl = FakeRepl ({'autocomplete_mode' : autocomplete .SIMPLE })
343- self .repl .input_line = "_"
344- self .repl .current_word = "_"
363+ self .setInputLine ("_" )
345364 self .assertTrue (self .repl .complete ())
346365 self .assertTrue (hasattr (self .repl .matches_iter ,'matches' ))
347366 self .assertTrue ('__file__' not in self .repl .matches_iter .matches )
@@ -375,42 +394,23 @@ def test_addstr(self):
375394class TestCliReplTab (unittest .TestCase ):
376395
377396 def setUp (self ):
378-
379- def setup_matches (tab = False ):
380-
381- if self .repl .cw () and len (self .repl .cw ().split ('.' )) == 1 :
382- self .repl .matches = ["foobar" , "foofoobar" ]
383- else :
384- self .repl .matches = ["Foo.foobar" , "Foo.foofoobar" ]
385-
386- self .repl .matches_iter = repl .MatchesIterator ()
387- self .repl .matches_iter .update (self .repl .cw (), self .repl .matches )
388-
389397 self .repl = FakeCliRepl ()
390398
391- # Stub out CLIRepl attributes
392- self .repl .buffer = []
393- self .repl .argspec = Mock ()
399+ # 3 Types of tab complete
400+ def test_simple_tab_complete (self ):
401+ self .repl .matches_iter = MagicMock ()
402+ self .repl .matches_iter .__nonzero__ .return_value = False
403+ self .repl .complete = Mock ()
394404 self .repl .print_line = Mock ()
405+ self .repl .matches_iter .is_cseq .return_value = False
395406 self .repl .show_list = Mock ()
407+ self .repl .argspec = Mock ()
408+ self .repl .matches_iter .cur_line .return_value = (None , "foobar" )
396409
397- # Stub out complete
398- self .repl .complete = Mock ()
399- self .repl .complete .return_value = True
400- self .repl .complete .side_effect = setup_matches
401- self .repl .matches_iter = None
402-
403- # Stub out the config logic
404- self .repl .config = Mock ()
405- self .repl .config .tab_length = 4
406- self .repl .config .auto_display_list = True
407- self .repl .config .list_win_visible = True
408- self .repl .config .autocomplete_mode = autocomplete .SIMPLE
409-
410- # 3 Types of tab complete
411- def test_simple_tab_complete (self ):
412410 self .repl .s = "foo"
413411 self .repl .tab ()
412+ self .assertTrue (self .repl .complete .called )
413+ self .repl .complete .assert_called_with (tab = True )
414414 self .assertEqual (self .repl .s , "foobar" )
415415
416416 @skip ("disabled while non-simple completion is disabled" )
@@ -434,33 +434,27 @@ def test_normal_tab(self):
434434 """make sure pressing the tab key will
435435 still in some cases add a tab"""
436436 self .repl .s = ""
437+ self .repl .config = Mock ()
438+ self .repl .config .tab_length = 4
439+ self .repl .complete = Mock ()
440+ self .repl .print_line = Mock ()
437441 self .repl .tab ()
438442 self .assertEqual (self .repl .s , " " )
439443
440444 def test_back_parameter (self ):
445+ self .repl .matches_iter = Mock ()
446+ self .repl .matches_iter .matches = True
447+ self .repl .matches_iter .previous .return_value = "previtem"
448+ self .repl .matches_iter .is_cseq .return_value = False
449+ self .repl .show_list = Mock ()
450+ self .repl .argspec = Mock ()
451+ self .repl .matches_iter .cur_line .return_value = (None , "previtem" )
452+ self .repl .print_line = Mock ()
441453 self .repl .s = "foo"
454+ self .repl .cpos = 0
442455 self .repl .tab (back = True )
443- self .assertEqual (self .repl .s , "foofoobar" )
444-
445- def test_nth_forward (self ):
446- """make sure that pressing tab twice will fist expand
447- and then cycle to the first match"""
448- self .repl .s = "f"
449- self .repl .tab ()
450- self .repl .tab ()
451- self .assertEqual (self .repl .s , "foobar" )
452-
453- def test_current_word (self ):
454- """Complete should not be affected by words that precede it."""
455- self .repl .s = "import f"
456- self .repl .tab ()
457- self .assertEqual (self .repl .s , "import foo" )
458-
459- self .repl .tab ()
460- self .assertEqual (self .repl .s , "import foobar" )
461-
462- self .repl .tab ()
463- self .assertEqual (self .repl .s , "import foofoobar" )
456+ self .assertTrue (self .repl .matches_iter .previous .called )
457+ self .assertTrue (self .repl .s , "previtem" )
464458
465459 # Attribute Tests
466460 @skip ("disabled while non-simple completion is disabled" )
@@ -484,6 +478,11 @@ def test_fuzzy_attribute_tab_complete2(self):
484478 # Expand Tests
485479 def test_simple_expand (self ):
486480 self .repl .s = "f"
481+ self .cpos = 0
482+ self .repl .matches_iter = Mock ()
483+ self .repl .matches_iter .is_cseq .return_value = True
484+ self .repl .matches_iter .substitute_cseq .return_value = (3 , "foo" )
485+ self .repl .print_line = Mock ()
487486 self .repl .tab ()
488487 self .assertEqual (self .repl .s , "foo" )
489488
@@ -499,6 +498,5 @@ def test_fuzzy_expand(self):
499498 pass
500499
501500
502-
503501if __name__ == '__main__' :
504502 unittest .main ()
0 commit comments