(root)/
Python-3.12.0/
Lib/
idlelib/
idle_test/
test_textview.py
       1  """Test textview, coverage 100%.
       2  
       3  Since all methods and functions create (or destroy) a ViewWindow, which
       4  is a widget containing a widget, etcetera, all tests must be gui tests.
       5  Using mock Text would not change this.  Other mocks are used to retrieve
       6  information about calls.
       7  """
       8  from idlelib import textview as tv
       9  from test.support import requires
      10  requires('gui')
      11  
      12  import os
      13  import unittest
      14  from tkinter import Tk, TclError, CHAR, NONE, WORD
      15  from tkinter.ttk import Button
      16  from idlelib.idle_test.mock_idle import Func
      17  from idlelib.idle_test.mock_tk import Mbox_func
      18  
      19  def setUpModule():
      20      global root
      21      root = Tk()
      22      root.withdraw()
      23  
      24  def tearDownModule():
      25      global root
      26      root.update_idletasks()
      27      root.destroy()
      28      del root
      29  
      30  # If we call ViewWindow or wrapper functions with defaults
      31  # modal=True, _utest=False, test hangs on call to wait_window.
      32  # Have also gotten tk error 'can't invoke "event" command'.
      33  
      34  
      35  class ESC[4;38;5;81mVW(ESC[4;38;5;149mtvESC[4;38;5;149m.ESC[4;38;5;149mViewWindow):  # Used in ViewWindowTest.
      36      transient = Func()
      37      grab_set = Func()
      38      wait_window = Func()
      39  
      40  
      41  # Call wrapper class VW with mock wait_window.
      42  class ESC[4;38;5;81mViewWindowTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      43  
      44      def setUp(self):
      45          VW.transient.__init__()
      46          VW.grab_set.__init__()
      47          VW.wait_window.__init__()
      48  
      49      def test_init_modal(self):
      50          view = VW(root, 'Title', 'test text')
      51          self.assertTrue(VW.transient.called)
      52          self.assertTrue(VW.grab_set.called)
      53          self.assertTrue(VW.wait_window.called)
      54          view.ok()
      55  
      56      def test_init_nonmodal(self):
      57          view = VW(root, 'Title', 'test text', modal=False)
      58          self.assertFalse(VW.transient.called)
      59          self.assertFalse(VW.grab_set.called)
      60          self.assertFalse(VW.wait_window.called)
      61          view.ok()
      62  
      63      def test_ok(self):
      64          view = VW(root, 'Title', 'test text', modal=False)
      65          view.destroy = Func()
      66          view.ok()
      67          self.assertTrue(view.destroy.called)
      68          del view.destroy  # Unmask real function.
      69          view.destroy()
      70  
      71  
      72  class ESC[4;38;5;81mAutoHideScrollbarTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      73      # Method set is tested in ScrollableTextFrameTest
      74      def test_forbidden_geometry(self):
      75          scroll = tv.AutoHideScrollbar(root)
      76          self.assertRaises(TclError, scroll.pack)
      77          self.assertRaises(TclError, scroll.place)
      78  
      79  
      80  class ESC[4;38;5;81mScrollableTextFrameTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      81  
      82      @classmethod
      83      def setUpClass(cls):
      84          cls.root = root = Tk()
      85          root.withdraw()
      86  
      87      @classmethod
      88      def tearDownClass(cls):
      89          cls.root.update_idletasks()
      90          cls.root.destroy()
      91          del cls.root
      92  
      93      def make_frame(self, wrap=NONE, **kwargs):
      94          frame = tv.ScrollableTextFrame(self.root, wrap=wrap, **kwargs)
      95          def cleanup_frame():
      96              frame.update_idletasks()
      97              frame.destroy()
      98          self.addCleanup(cleanup_frame)
      99          return frame
     100  
     101      def test_line1(self):
     102          frame = self.make_frame()
     103          frame.text.insert('1.0', 'test text')
     104          self.assertEqual(frame.text.get('1.0', '1.end'), 'test text')
     105  
     106      def test_horiz_scrollbar(self):
     107          # The horizontal scrollbar should be shown/hidden according to
     108          # the 'wrap' setting: It should only be shown when 'wrap' is
     109          # set to NONE.
     110  
     111          # wrap = NONE -> with horizontal scrolling
     112          frame = self.make_frame(wrap=NONE)
     113          self.assertEqual(frame.text.cget('wrap'), NONE)
     114          self.assertIsNotNone(frame.xscroll)
     115  
     116          # wrap != NONE -> no horizontal scrolling
     117          for wrap in [CHAR, WORD]:
     118              with self.subTest(wrap=wrap):
     119                  frame = self.make_frame(wrap=wrap)
     120                  self.assertEqual(frame.text.cget('wrap'), wrap)
     121                  self.assertIsNone(frame.xscroll)
     122  
     123  
     124  class ESC[4;38;5;81mViewFrameTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     125  
     126      @classmethod
     127      def setUpClass(cls):
     128          cls.root = root = Tk()
     129          root.withdraw()
     130          cls.frame = tv.ViewFrame(root, 'test text')
     131  
     132      @classmethod
     133      def tearDownClass(cls):
     134          del cls.frame
     135          cls.root.update_idletasks()
     136          cls.root.destroy()
     137          del cls.root
     138  
     139      def test_line1(self):
     140          get = self.frame.text.get
     141          self.assertEqual(get('1.0', '1.end'), 'test text')
     142  
     143  
     144  # Call ViewWindow with modal=False.
     145  class ESC[4;38;5;81mViewFunctionTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     146  
     147      @classmethod
     148      def setUpClass(cls):
     149          cls.orig_error = tv.showerror
     150          tv.showerror = Mbox_func()
     151  
     152      @classmethod
     153      def tearDownClass(cls):
     154          tv.showerror = cls.orig_error
     155          del cls.orig_error
     156  
     157      def test_view_text(self):
     158          view = tv.view_text(root, 'Title', 'test text', modal=False)
     159          self.assertIsInstance(view, tv.ViewWindow)
     160          self.assertIsInstance(view.viewframe, tv.ViewFrame)
     161          view.viewframe.ok()
     162  
     163      def test_view_file(self):
     164          view = tv.view_file(root, 'Title', __file__, 'ascii', modal=False)
     165          self.assertIsInstance(view, tv.ViewWindow)
     166          self.assertIsInstance(view.viewframe, tv.ViewFrame)
     167          get = view.viewframe.textframe.text.get
     168          self.assertIn('Test', get('1.0', '1.end'))
     169          view.ok()
     170  
     171      def test_bad_file(self):
     172          # Mock showerror will be used; view_file will return None.
     173          view = tv.view_file(root, 'Title', 'abc.xyz', 'ascii', modal=False)
     174          self.assertIsNone(view)
     175          self.assertEqual(tv.showerror.title, 'File Load Error')
     176  
     177      def test_bad_encoding(self):
     178          p = os.path
     179          fn = p.abspath(p.join(p.dirname(__file__), '..', 'CREDITS.txt'))
     180          view = tv.view_file(root, 'Title', fn, 'ascii', modal=False)
     181          self.assertIsNone(view)
     182          self.assertEqual(tv.showerror.title, 'Unicode Decode Error')
     183  
     184      def test_nowrap(self):
     185          view = tv.view_text(root, 'Title', 'test', modal=False, wrap='none')
     186          text_widget = view.viewframe.textframe.text
     187          self.assertEqual(text_widget.cget('wrap'), 'none')
     188  
     189  
     190  # Call ViewWindow with _utest=True.
     191  class ESC[4;38;5;81mButtonClickTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     192  
     193      def setUp(self):
     194          self.view = None
     195          self.called = False
     196  
     197      def tearDown(self):
     198          if self.view:
     199              self.view.destroy()
     200  
     201      def test_view_text_bind_with_button(self):
     202          def _command():
     203              self.called = True
     204              self.view = tv.view_text(root, 'TITLE_TEXT', 'COMMAND', _utest=True)
     205          button = Button(root, text='BUTTON', command=_command)
     206          button.invoke()
     207          self.addCleanup(button.destroy)
     208  
     209          self.assertEqual(self.called, True)
     210          self.assertEqual(self.view.title(), 'TITLE_TEXT')
     211          self.assertEqual(self.view.viewframe.textframe.text.get('1.0', '1.end'),
     212                           'COMMAND')
     213  
     214      def test_view_file_bind_with_button(self):
     215          def _command():
     216              self.called = True
     217              self.view = tv.view_file(root, 'TITLE_FILE', __file__,
     218                                       encoding='ascii', _utest=True)
     219          button = Button(root, text='BUTTON', command=_command)
     220          button.invoke()
     221          self.addCleanup(button.destroy)
     222  
     223          self.assertEqual(self.called, True)
     224          self.assertEqual(self.view.title(), 'TITLE_FILE')
     225          get = self.view.viewframe.textframe.text.get
     226          with open(__file__) as f:
     227              self.assertEqual(get('1.0', '1.end'), f.readline().strip())
     228              f.readline()
     229              self.assertEqual(get('3.0', '3.end'), f.readline().strip())
     230  
     231  
     232  if __name__ == '__main__':
     233      unittest.main(verbosity=2)