X Tutup
Skip to content

Commit 0f6ce9c

Browse files
tests passing in Python 2
1 parent c24bb29 commit 0f6ce9c

File tree

3 files changed

+80
-82
lines changed

3 files changed

+80
-82
lines changed

bpython/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1437,7 +1437,7 @@ def tab(self, back=False):
14371437
# 3. check to see if we can expand the current word
14381438
if self.matches_iter.is_cseq():
14391439
#TODO resolve this error-prone situation:
1440-
# can't assign at same time to self.s and self.cursor_offest
1440+
# can't assign at same time to self.s and self.cursor_offset
14411441
# because for cursor_offset
14421442
# property to work correctly, self.s must already be set
14431443
temp_cursor_offset, self.s = self.matches_iter.substitute_cseq()

bpython/repl.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ class MatchesIterator(object):
272272
A MatchesIterator can be `clear`ed to reset match iteration, and
273273
`update`ed to set what matches will be iterated over."""
274274

275-
def __init__(self, current_word='', matches=[]):
276-
self.current_word = current_word # word being replaced in the original line of text
277-
self.matches = list(matches) # possible replacements for current_word
275+
def __init__(self):
276+
self.current_word = '' # word being replaced in the original line of text
277+
self.matches = None # possible replacements for current_word
278278
self.index = -1 # which word is currently replacing the current word
279279
self.orig_cursor_offset = None # cursor position in the original line
280280
self.orig_line = None # original line (before match replacements)

bpython/test/test_repl.py

Lines changed: 76 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import unittest
33
from itertools import islice
4-
from mock import Mock
4+
from mock import Mock, MagicMock
55
try:
66
from unittest import skip
77
except 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+
165188
class 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+
230254
class 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\tdef bar(self):\n\t\tpass\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\tdef baz(self):\n\t\tpass\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\tdef bar(self):\n\t\tpass\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):
375394
class 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-
503501
if __name__ == '__main__':
504502
unittest.main()

0 commit comments

Comments
 (0)
X Tutup