|
| 1 | +"Test zzdummy, coverage 100%." |
| 2 | + |
| 3 | +from idlelib import zzdummy |
| 4 | +import unittest |
| 5 | +from test.support import requires |
| 6 | +from tkinter import Tk, Text |
| 7 | +from unittest import mock |
| 8 | +from idlelib import config |
| 9 | +from idlelib import editor |
| 10 | +from idlelib import format |
| 11 | + |
| 12 | + |
| 13 | +usercfg = zzdummy.idleConf.userCfg |
| 14 | +testcfg = { |
| 15 | + 'main': config.IdleUserConfParser(''), |
| 16 | + 'highlight': config.IdleUserConfParser(''), |
| 17 | + 'keys': config.IdleUserConfParser(''), |
| 18 | + 'extensions': config.IdleUserConfParser(''), |
| 19 | +} |
| 20 | +code_sample = """\ |
| 21 | +
|
| 22 | +class C1(): |
| 23 | + # Class comment. |
| 24 | + def __init__(self, a, b): |
| 25 | + self.a = a |
| 26 | + self.b = b |
| 27 | +""" |
| 28 | + |
| 29 | + |
| 30 | +class 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 | + |
| 41 | +class 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 | + |
| 151 | +if __name__ == '__main__': |
| 152 | + unittest.main(verbosity=2) |
0 commit comments