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