1"Test redirector, coverage 100%."
2
3from idlelib.redirector import WidgetRedirector
4import unittest
5from test.support import requires
6from tkinter import Tk, Text, TclError
7from idlelib.idle_test.mock_idle import Func
8
9
10class InitCloseTest(unittest.TestCase):
11
12    @classmethod
13    def setUpClass(cls):
14        requires('gui')
15        cls.root = Tk()
16        cls.root.withdraw()
17        cls.text = Text(cls.root)
18
19    @classmethod
20    def tearDownClass(cls):
21        del cls.text
22        cls.root.destroy()
23        del cls.root
24
25    def test_init(self):
26        redir = WidgetRedirector(self.text)
27        self.assertEqual(redir.widget, self.text)
28        self.assertEqual(redir.tk, self.text.tk)
29        self.assertRaises(TclError, WidgetRedirector, self.text)
30        redir.close()  # restore self.tk, self.text
31
32    def test_close(self):
33        redir = WidgetRedirector(self.text)
34        redir.register('insert', Func)
35        redir.close()
36        self.assertEqual(redir._operations, {})
37        self.assertFalse(hasattr(self.text, 'widget'))
38
39
40class WidgetRedirectorTest(unittest.TestCase):
41
42    @classmethod
43    def setUpClass(cls):
44        requires('gui')
45        cls.root = Tk()
46        cls.root.withdraw()
47        cls.text = Text(cls.root)
48
49    @classmethod
50    def tearDownClass(cls):
51        del cls.text
52        cls.root.update_idletasks()
53        cls.root.destroy()
54        del cls.root
55
56    def setUp(self):
57        self.redir = WidgetRedirector(self.text)
58        self.func = Func()
59        self.orig_insert = self.redir.register('insert', self.func)
60        self.text.insert('insert', 'asdf')  # leaves self.text empty
61
62    def tearDown(self):
63        self.text.delete('1.0', 'end')
64        self.redir.close()
65
66    def test_repr(self):  # partly for 100% coverage
67        self.assertIn('Redirector', repr(self.redir))
68        self.assertIn('Original', repr(self.orig_insert))
69
70    def test_register(self):
71        self.assertEqual(self.text.get('1.0', 'end'), '\n')
72        self.assertEqual(self.func.args, ('insert', 'asdf'))
73        self.assertIn('insert', self.redir._operations)
74        self.assertIn('insert', self.text.__dict__)
75        self.assertEqual(self.text.insert, self.func)
76
77    def test_original_command(self):
78        self.assertEqual(self.orig_insert.operation, 'insert')
79        self.assertEqual(self.orig_insert.tk_call, self.text.tk.call)
80        self.orig_insert('insert', 'asdf')
81        self.assertEqual(self.text.get('1.0', 'end'), 'asdf\n')
82
83    def test_unregister(self):
84        self.assertIsNone(self.redir.unregister('invalid operation name'))
85        self.assertEqual(self.redir.unregister('insert'), self.func)
86        self.assertNotIn('insert', self.redir._operations)
87        self.assertNotIn('insert', self.text.__dict__)
88
89    def test_unregister_no_attribute(self):
90        del self.text.insert
91        self.assertEqual(self.redir.unregister('insert'), self.func)
92
93    def test_dispatch_intercept(self):
94        self.func.__init__(True)
95        self.assertTrue(self.redir.dispatch('insert', False))
96        self.assertFalse(self.func.args[0])
97
98    def test_dispatch_bypass(self):
99        self.orig_insert('insert', 'asdf')
100        # tk.call returns '' where Python would return None
101        self.assertEqual(self.redir.dispatch('delete', '1.0', 'end'), '')
102        self.assertEqual(self.text.get('1.0', 'end'), '\n')
103
104    def test_dispatch_error(self):
105        self.func.__init__(TclError())
106        self.assertEqual(self.redir.dispatch('insert', False), '')
107        self.assertEqual(self.redir.dispatch('invalid'), '')
108
109    def test_command_dispatch(self):
110        # Test that .__init__ causes redirection of tk calls
111        # through redir.dispatch
112        self.root.call(self.text._w, 'insert', 'hello')
113        self.assertEqual(self.func.args, ('hello',))
114        self.assertEqual(self.text.get('1.0', 'end'), '\n')
115        # Ensure that called through redir .dispatch and not through
116        # self.text.insert by having mock raise TclError.
117        self.func.__init__(TclError())
118        self.assertEqual(self.root.call(self.text._w, 'insert', 'boo'), '')
119
120
121if __name__ == '__main__':
122    unittest.main(verbosity=2)
123