@@ -35,10 +35,11 @@ def assert_paint(self, screen, cursor_row_col):
3535self .assertFSArraysEqual (array ,screen )
3636self .assertEqual (cursor_pos ,cursor_row_col )
3737
38- def assert_paint_ignoring_formatting (self ,screen ,cursor_row_col ):
38+ def assert_paint_ignoring_formatting (self ,screen ,cursor_row_col = None ):
3939array ,cursor_pos = self .repl .paint ()
4040self .assertFSArraysEqualIgnoringFormatting (array ,screen )
41- self .assertEqual (cursor_pos ,cursor_row_col )
41+ if cursor_row_col is not None :
42+ self .assertEqual (cursor_pos ,cursor_row_col )
4243
4344class TestCurtsiesPaintingSimple (TestCurtsiesPainting ):
4445
@@ -180,7 +181,6 @@ def test_inconsistent_history_doesnt_happen_if_onscreen(self):
180181u'>>> ' ]
181182self .assert_paint_ignoring_formatting (screen , (2 ,4 ))
182183
183- @skip ('for inconsistent history check' )
184184def test_rewind_inconsistent_history (self ):
185185self .enter ("1 + 1" )
186186self .enter ("2 + 2" )
@@ -202,8 +202,172 @@ def test_rewind_inconsistent_history(self):
202202u'4' ,
203203u'>>> ' ,
204204u'' ,
205- u'' ]
206- self .assert_paint_ignoring_formatting (screen , (5 ,4 ))
205+ u' ' ]
206+ self .assert_paint_ignoring_formatting (screen , (3 ,4 ))
207+ self .repl .scroll_offset += len (screen )- self .repl .height
208+ self .assert_paint_ignoring_formatting (screen [1 :- 2 ], (2 ,4 ))
209+ self .assert_paint_ignoring_formatting (screen [1 :- 2 ], (2 ,4 ))
210+
211+ def test_rewind_inconsistent_history_more_lines_same_screen (self ):
212+ self .repl .width = 60
213+ sys .a = 5
214+ self .enter ("import sys" )
215+ self .enter ("for i in range(sys.a): print(sys.a)" )
216+ self .enter ()
217+ self .enter ("1 + 1" )
218+ self .enter ("2 + 2" )
219+ screen = [u">>> import sys" ,
220+ u">>> for i in range(sys.a): print(sys.a)" ,
221+ u'... ' ,
222+ u'5' ,
223+ u'5' ,
224+ u'5' ,
225+ u'5' ,
226+ u'5' ,
227+ u'>>> 1 + 1' ,
228+ u'2' ,
229+ u'>>> 2 + 2' ,
230+ u'4' ,
231+ u'>>> ' ]
232+ self .assert_paint_ignoring_formatting (screen , (12 ,4 ))
233+ self .repl .scroll_offset += len (screen )- self .repl .height
234+ self .assert_paint_ignoring_formatting (screen [8 :], (4 ,4 ))
235+ sys .a = 6
236+ self .undo ()
237+ screen = [INCONSISTENT_HISTORY_MSG [:self .repl .width ],
238+ u'6' ,
239+ u'>>> 1 + 1' ,# everything will jump down a line - that's perfectly reasonable
240+ u'2' ,
241+ u'>>> ' ,
242+ u' ' ]
243+ self .assert_paint_ignoring_formatting (screen , (4 ,4 ))
244+ self .repl .scroll_offset += len (screen )- self .repl .height
245+ self .assert_paint_ignoring_formatting (screen [1 :- 1 ], (3 ,4 ))
246+
247+ def test_rewind_inconsistent_history_more_lines_lower_screen (self ):
248+ self .repl .width = 60
249+ sys .a = 5
250+ self .enter ("import sys" )
251+ self .enter ("for i in range(sys.a): print(sys.a)" )
252+ self .enter ()
253+ self .enter ("1 + 1" )
254+ self .enter ("2 + 2" )
255+ screen = [u">>> import sys" ,
256+ u">>> for i in range(sys.a): print(sys.a)" ,
257+ u'... ' ,
258+ u'5' ,
259+ u'5' ,
260+ u'5' ,
261+ u'5' ,
262+ u'5' ,
263+ u'>>> 1 + 1' ,
264+ u'2' ,
265+ u'>>> 2 + 2' ,
266+ u'4' ,
267+ u'>>> ' ]
268+ self .assert_paint_ignoring_formatting (screen , (12 ,4 ))
269+ self .repl .scroll_offset += len (screen )- self .repl .height
270+ self .assert_paint_ignoring_formatting (screen [8 :], (4 ,4 ))
271+ sys .a = 8
272+ self .undo ()
273+ screen = [INCONSISTENT_HISTORY_MSG [:self .repl .width ],
274+ u'8' ,
275+ u'8' ,
276+ u'8' ,
277+ u'>>> 1 + 1' ,
278+ u'2' ,
279+ u'>>> ' ]
280+ self .assert_paint_ignoring_formatting (screen )
281+ self .repl .scroll_offset += len (screen )- self .repl .height
282+ self .assert_paint_ignoring_formatting (screen [- 5 :])
283+
284+ def test_rewind_inconsistent_history_more_lines_raise_screen (self ):
285+ self .repl .width = 60
286+ sys .a = 5
287+ self .enter ("import sys" )
288+ self .enter ("for i in range(sys.a): print(sys.a)" )
289+ self .enter ()
290+ self .enter ("1 + 1" )
291+ self .enter ("2 + 2" )
292+ screen = [u">>> import sys" ,
293+ u">>> for i in range(sys.a): print(sys.a)" ,
294+ u'... ' ,
295+ u'5' ,
296+ u'5' ,
297+ u'5' ,
298+ u'5' ,
299+ u'5' ,
300+ u'>>> 1 + 1' ,
301+ u'2' ,
302+ u'>>> 2 + 2' ,
303+ u'4' ,
304+ u'>>> ' ]
305+ self .assert_paint_ignoring_formatting (screen , (12 ,4 ))
306+ self .repl .scroll_offset += len (screen )- self .repl .height
307+ self .assert_paint_ignoring_formatting (screen [8 :], (4 ,4 ))
308+ sys .a = 1
309+ self .undo ()
310+ screen = [INCONSISTENT_HISTORY_MSG [:self .repl .width ],
311+ u'1' ,
312+ u'>>> 1 + 1' ,
313+ u'2' ,
314+ u'>>> ' ,
315+ u' ' ]
316+ self .assert_paint_ignoring_formatting (screen )
317+ self .repl .scroll_offset += len (screen )- self .repl .height
318+ self .assert_paint_ignoring_formatting (screen [1 :- 1 ])
319+
320+ def test_rewind_history_not_quite_inconsistent (self ):
321+ self .repl .width = 50
322+ sys .a = 5
323+ self .enter ("for i in range(__import__('sys').a): print(i)" )
324+ self .enter ()
325+ self .enter ("1 + 1" )
326+ self .enter ("2 + 2" )
327+ screen = [u">>> for i in range(__import__('sys').a): print(i)" ,
328+ u'... ' ,
329+ u'0' ,
330+ u'1' ,
331+ u'2' ,
332+ u'3' ,
333+ u'4' ,
334+ u'>>> 1 + 1' ,
335+ u'2' ,
336+ u'>>> 2 + 2' ,
337+ u'4' ,
338+ u'>>> ' ]
339+ self .assert_paint_ignoring_formatting (screen , (11 ,4 ))
340+ self .repl .scroll_offset += len (screen )- self .repl .height
341+ self .assert_paint_ignoring_formatting (screen [7 :], (4 ,4 ))
342+ sys .a = 6
343+ self .undo ()
344+ screen = [u'5' ,
345+ u'>>> 1 + 1' ,# everything will jump down a line - that's perfectly reasonable
346+ u'2' ,
347+ u'>>> ' ,]
348+ self .assert_paint_ignoring_formatting (screen , (3 ,4 ))
349+
350+ def test_rewind_barely_consistent (self ):
351+ self .enter ("1 + 1" )
352+ self .enter ("2 + 2" )
353+ self .enter ("3 + 3" )
354+ screen = [u">>> 1 + 1" ,
355+ u'2' ,
356+ u'>>> 2 + 2' ,
357+ u'4' ,
358+ u'>>> 3 + 3' ,
359+ u'6' ,
360+ u'>>> ' ]
361+ self .assert_paint_ignoring_formatting (screen , (6 ,4 ))
362+ self .repl .scroll_offset += len (screen )- self .repl .height
363+ self .assert_paint_ignoring_formatting (screen [2 :], (4 ,4 ))
364+ self .repl .display_lines [2 ]= self .repl .display_lines [2 ]* 2
365+ self .undo ()
366+ screen = [u'>>> 2 + 2' ,
367+ u'4' ,
368+ u'>>> ' ]
369+ self .assert_paint_ignoring_formatting (screen , (2 ,4 ))
370+
207371
208372def test_clear_screen (self ):
209373self .enter ("1 + 1" )
@@ -258,3 +422,27 @@ def test_clear_screen_while_banner_visible(self):
258422u'' ,u'' ,u'' ,
259423u'STATUS_BAR ' ]
260424self .assert_paint_ignoring_formatting (screen , (3 ,4 ))
425+
426+ def test_cursor_stays_at_bottom_of_screen (self ):
427+ """infobox showing up during intermediate render was causing this to fail, #371"""
428+ self .repl .width = 50
429+ self .repl .current_line = "__import__('random').__name__"
430+ with output_to_repl (self .repl ):
431+ self .repl .on_enter ()
432+ screen = [u">>> __import__('random').__name__" ,
433+ u"'random'" ]
434+ self .assert_paint_ignoring_formatting (screen )
435+
436+ with output_to_repl (self .repl ):
437+ self .repl .process_event (self .refresh_requests .pop ())
438+ screen = [u">>> __import__('random').__name__" ,
439+ u"'random'" ,
440+ u"" ]
441+ self .assert_paint_ignoring_formatting (screen )
442+
443+ with output_to_repl (self .repl ):
444+ self .repl .process_event (self .refresh_requests .pop ())
445+ screen = [u">>> __import__('random').__name__" ,
446+ u"'random'" ,
447+ u">>> " ]
448+ self .assert_paint_ignoring_formatting (screen , (2 ,4 ))