1"Test zzdummy, coverage 100%."
2
3from idlelib import zzdummy
4import unittest
5from test.support import requires
6from tkinter import Tk, Text
7from unittest import mock
8from idlelib import config
9from idlelib import editor
10from idlelib import format
11
12
13usercfg = zzdummy.idleConf.userCfg
14testcfg = {
15    'main': config.IdleUserConfParser(''),
16    'highlight': config.IdleUserConfParser(''),
17    'keys': config.IdleUserConfParser(''),
18    'extensions': config.IdleUserConfParser(''),
19}
20code_sample = """\
21
22class C1():
23    # Class comment.
24    def __init__(self, a, b):
25        self.a = a
26        self.b = b
27"""
28
29
30class DummyEditwin:
31    get_selection_indices = editor.EditorWindow.get_selection_indices
32    def __init__(self, root, text):
33        self.root = root
34        self.top = root
35        self.text = text
36        self.fregion = format.FormatRegion(self)
37        self.text.undo_block_start = mock.Mock()
38        self.text.undo_block_stop = mock.Mock()
39
40
41class ZZDummyTest(unittest.TestCase):
42
43    @classmethod
44    def setUpClass(cls):
45        requires('gui')
46        root = cls.root = Tk()
47        root.withdraw()
48        text = cls.text = Text(cls.root)
49        cls.editor = DummyEditwin(root, text)
50        zzdummy.idleConf.userCfg = testcfg
51
52    @classmethod
53    def tearDownClass(cls):
54        zzdummy.idleConf.userCfg = usercfg
55        del cls.editor, cls.text
56        cls.root.update_idletasks()
57        for id in cls.root.tk.call('after', 'info'):
58            cls.root.after_cancel(id)  # Need for EditorWindow.
59        cls.root.destroy()
60        del cls.root
61
62    def setUp(self):
63        text = self.text
64        text.insert('1.0', code_sample)
65        text.undo_block_start.reset_mock()
66        text.undo_block_stop.reset_mock()
67        zz = self.zz = zzdummy.ZzDummy(self.editor)
68        zzdummy.ZzDummy.ztext = '# ignore #'
69
70    def tearDown(self):
71        self.text.delete('1.0', 'end')
72        del self.zz
73
74    def checklines(self, text, value):
75        # Verify that there are lines being checked.
76        end_line = int(float(text.index('end')))
77
78        # Check each line for the starting text.
79        actual = []
80        for line in range(1, end_line):
81            txt = text.get(f'{line}.0', f'{line}.end')
82            actual.append(txt.startswith(value))
83        return actual
84
85    def test_init(self):
86        zz = self.zz
87        self.assertEqual(zz.editwin, self.editor)
88        self.assertEqual(zz.text, self.editor.text)
89
90    def test_reload(self):
91        self.assertEqual(self.zz.ztext, '# ignore #')
92        testcfg['extensions'].SetOption('ZzDummy', 'z-text', 'spam')
93        zzdummy.ZzDummy.reload()
94        self.assertEqual(self.zz.ztext, 'spam')
95
96    def test_z_in_event(self):
97        eq = self.assertEqual
98        zz = self.zz
99        text = zz.text
100        eq(self.zz.ztext, '# ignore #')
101
102        # No lines have the leading text.
103        expected = [False, False, False, False, False, False, False]
104        actual = self.checklines(text, zz.ztext)
105        eq(expected, actual)
106
107        text.tag_add('sel', '2.0', '4.end')
108        eq(zz.z_in_event(), 'break')
109        expected = [False, True, True, True, False, False, False]
110        actual = self.checklines(text, zz.ztext)
111        eq(expected, actual)
112
113        text.undo_block_start.assert_called_once()
114        text.undo_block_stop.assert_called_once()
115
116    def test_z_out_event(self):
117        eq = self.assertEqual
118        zz = self.zz
119        text = zz.text
120        eq(self.zz.ztext, '# ignore #')
121
122        # Prepend text.
123        text.tag_add('sel', '2.0', '5.end')
124        zz.z_in_event()
125        text.undo_block_start.reset_mock()
126        text.undo_block_stop.reset_mock()
127
128        # Select a few lines to remove text.
129        text.tag_remove('sel', '1.0', 'end')
130        text.tag_add('sel', '3.0', '4.end')
131        eq(zz.z_out_event(), 'break')
132        expected = [False, True, False, False, True, False, False]
133        actual = self.checklines(text, zz.ztext)
134        eq(expected, actual)
135
136        text.undo_block_start.assert_called_once()
137        text.undo_block_stop.assert_called_once()
138
139    def test_roundtrip(self):
140        # Insert and remove to all code should give back original text.
141        zz = self.zz
142        text = zz.text
143
144        text.tag_add('sel', '1.0', 'end-1c')
145        zz.z_in_event()
146        zz.z_out_event()
147
148        self.assertEqual(text.get('1.0', 'end-1c'), code_sample)
149
150
151if __name__ == '__main__':
152    unittest.main(verbosity=2)
153