test_outwin.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "Test outwin, coverage 76%."
  2. from idlelib import outwin
  3. import unittest
  4. from test.support import requires
  5. from tkinter import Tk, Text
  6. from idlelib.idle_test.mock_tk import Mbox_func
  7. from idlelib.idle_test.mock_idle import Func
  8. from unittest import mock
  9. class OutputWindowTest(unittest.TestCase):
  10. @classmethod
  11. def setUpClass(cls):
  12. requires('gui')
  13. root = cls.root = Tk()
  14. root.withdraw()
  15. w = cls.window = outwin.OutputWindow(None, None, None, root)
  16. cls.text = w.text = Text(root)
  17. @classmethod
  18. def tearDownClass(cls):
  19. cls.window.close()
  20. del cls.text, cls.window
  21. cls.root.destroy()
  22. del cls.root
  23. def setUp(self):
  24. self.text.delete('1.0', 'end')
  25. def test_ispythonsource(self):
  26. # OutputWindow overrides ispythonsource to always return False.
  27. w = self.window
  28. self.assertFalse(w.ispythonsource('test.txt'))
  29. self.assertFalse(w.ispythonsource(__file__))
  30. def test_window_title(self):
  31. self.assertEqual(self.window.top.title(), 'Output')
  32. def test_maybesave(self):
  33. w = self.window
  34. eq = self.assertEqual
  35. w.get_saved = Func()
  36. w.get_saved.result = False
  37. eq(w.maybesave(), 'no')
  38. eq(w.get_saved.called, 1)
  39. w.get_saved.result = True
  40. eq(w.maybesave(), 'yes')
  41. eq(w.get_saved.called, 2)
  42. del w.get_saved
  43. def test_write(self):
  44. eq = self.assertEqual
  45. delete = self.text.delete
  46. get = self.text.get
  47. write = self.window.write
  48. # No new line - insert stays on same line.
  49. delete('1.0', 'end')
  50. test_text = 'test text'
  51. eq(write(test_text), len(test_text))
  52. eq(get('1.0', '1.end'), 'test text')
  53. eq(get('insert linestart', 'insert lineend'), 'test text')
  54. # New line - insert moves to next line.
  55. delete('1.0', 'end')
  56. test_text = 'test text\n'
  57. eq(write(test_text), len(test_text))
  58. eq(get('1.0', '1.end'), 'test text')
  59. eq(get('insert linestart', 'insert lineend'), '')
  60. # Text after new line is tagged for second line of Text widget.
  61. delete('1.0', 'end')
  62. test_text = 'test text\nLine 2'
  63. eq(write(test_text), len(test_text))
  64. eq(get('1.0', '1.end'), 'test text')
  65. eq(get('2.0', '2.end'), 'Line 2')
  66. eq(get('insert linestart', 'insert lineend'), 'Line 2')
  67. # Test tags.
  68. delete('1.0', 'end')
  69. test_text = 'test text\n'
  70. test_text2 = 'Line 2\n'
  71. eq(write(test_text, tags='mytag'), len(test_text))
  72. eq(write(test_text2, tags='secondtag'), len(test_text2))
  73. eq(get('mytag.first', 'mytag.last'), test_text)
  74. eq(get('secondtag.first', 'secondtag.last'), test_text2)
  75. eq(get('1.0', '1.end'), test_text.rstrip('\n'))
  76. eq(get('2.0', '2.end'), test_text2.rstrip('\n'))
  77. def test_writelines(self):
  78. eq = self.assertEqual
  79. get = self.text.get
  80. writelines = self.window.writelines
  81. writelines(('Line 1\n', 'Line 2\n', 'Line 3\n'))
  82. eq(get('1.0', '1.end'), 'Line 1')
  83. eq(get('2.0', '2.end'), 'Line 2')
  84. eq(get('3.0', '3.end'), 'Line 3')
  85. eq(get('insert linestart', 'insert lineend'), '')
  86. def test_goto_file_line(self):
  87. eq = self.assertEqual
  88. w = self.window
  89. text = self.text
  90. w.flist = mock.Mock()
  91. gfl = w.flist.gotofileline = Func()
  92. showerror = w.showerror = Mbox_func()
  93. # No file/line number.
  94. w.write('Not a file line')
  95. self.assertIsNone(w.goto_file_line())
  96. eq(gfl.called, 0)
  97. eq(showerror.title, 'No special line')
  98. # Current file/line number.
  99. w.write(f'{str(__file__)}: 42: spam\n')
  100. w.write(f'{str(__file__)}: 21: spam')
  101. self.assertIsNone(w.goto_file_line())
  102. eq(gfl.args, (str(__file__), 21))
  103. # Previous line has file/line number.
  104. text.delete('1.0', 'end')
  105. w.write(f'{str(__file__)}: 42: spam\n')
  106. w.write('Not a file line')
  107. self.assertIsNone(w.goto_file_line())
  108. eq(gfl.args, (str(__file__), 42))
  109. del w.flist.gotofileline, w.showerror
  110. class ModuleFunctionTest(unittest.TestCase):
  111. @classmethod
  112. def setUp(cls):
  113. outwin.file_line_progs = None
  114. def test_compile_progs(self):
  115. outwin.compile_progs()
  116. for pat, regex in zip(outwin.file_line_pats, outwin.file_line_progs):
  117. self.assertEqual(regex.pattern, pat)
  118. @mock.patch('builtins.open')
  119. def test_file_line_helper(self, mock_open):
  120. flh = outwin.file_line_helper
  121. test_lines = (
  122. (r'foo file "testfile1", line 42, bar', ('testfile1', 42)),
  123. (r'foo testfile2(21) bar', ('testfile2', 21)),
  124. (r' testfile3 : 42: foo bar\n', (' testfile3 ', 42)),
  125. (r'foo testfile4.py :1: ', ('foo testfile4.py ', 1)),
  126. ('testfile5: \u19D4\u19D2: ', ('testfile5', 42)),
  127. (r'testfile6: 42', None), # only one `:`
  128. (r'testfile7 42 text', None) # no separators
  129. )
  130. for line, expected_output in test_lines:
  131. self.assertEqual(flh(line), expected_output)
  132. if expected_output:
  133. mock_open.assert_called_with(expected_output[0])
  134. if __name__ == '__main__':
  135. unittest.main(verbosity=2)