| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent cf312cf commit cd85453
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -18,7 +18,7 @@ The idle directory, idlelib, has over 60 xyz.py files. The idle_test | |||
| 18 | 18 | subdirectory contains test_xyz.py for each implementation file xyz.py. | |
| 19 | 19 | To add a test for abc.py, open idle_test/template.py and immediately | |
| 20 | 20 | Save As test_abc.py. Insert 'abc' on the first line, and replace | |
| 21 | - 'zzdummy' with 'abc. | ||
| 21 | + 'zzdummy' with 'abc'. | ||
| 22 | 22 | ||
| 23 | 23 | Remove the imports of requires and tkinter if not needed. Otherwise, | |
| 24 | 24 | add to the tkinter imports as needed. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | "Test , coverage %." | |
| 2 | 2 | ||
| 3 | + from idlelib import zzdummy # Replace with the module to test. | ||
| 3 | 4 | import unittest | |
| 4 | 5 | from test.support import requires | |
| 5 | 6 | from tkinter import Tk | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -454,9 +454,6 @@ def test_get_extension_keys(self): | |||
| 454 | 454 | self.assertEqual(idleConf.GetExtensionKeys('ZzDummy'), | |
| 455 | 455 | {'<<z-in>>': ['<Control-Shift-KeyRelease-Insert>']}) | |
| 456 | 456 | userextn.remove_section('ZzDummy') | |
| 457 | - # need option key test | ||
| 458 | - ## key = ['<Option-Key-2>'] if sys.platform == 'darwin' else ['<Alt-Key-2>'] | ||
| 459 | - ## eq(conf.GetExtensionKeys('ZoomHeight'), {'<<zoom-height>>': key}) | ||
| 460 | 457 | ||
| 461 | 458 | def test_get_extension_bindings(self): | |
| 462 | 459 | userextn.read_string(''' | |
@@ -491,19 +488,27 @@ def test_get_keybinding(self): | |||
| 491 | 488 | def test_get_current_keyset(self): | |
| 492 | 489 | current_platform = sys.platform | |
| 493 | 490 | conf = self.mock_config() | |
| 494 | - | ||
| 495 | - # Ensure that platform isn't darwin | ||
| 496 | - sys.platform = 'some-linux' | ||
| 497 | - self.assertEqual(conf.GetCurrentKeySet(), conf.GetKeySet(conf.CurrentKeys())) | ||
| 498 | - | ||
| 499 | - # This should not be the same, since replace <Alt- to <Option-. | ||
| 500 | - # Above depended on config-extensions.def having Alt keys, | ||
| 501 | - # which is no longer true. | ||
| 502 | - # sys.platform = 'darwin' | ||
| 503 | - # self.assertNotEqual(conf.GetCurrentKeySet(), conf.GetKeySet(conf.CurrentKeys())) | ||
| 504 | - | ||
| 505 | - # Restore platform | ||
| 506 | - sys.platform = current_platform | ||
| 491 | + try: | ||
| 492 | + # Ensure that platform isn't darwin | ||
| 493 | + sys.platform = 'some-linux' | ||
| 494 | + self.assertEqual(conf.GetCurrentKeySet(), | ||
| 495 | + conf.GetKeySet(conf.CurrentKeys())) | ||
| 496 | + | ||
| 497 | + # On darwin, '<Alt-' is replaced with '<Option-'. Add an | ||
| 498 | + # extension binding, as the default key sets have no Alt keys. | ||
| 499 | + conf.defaultCfg['extensions'].add_section('Foobar') | ||
| 500 | + conf.defaultCfg['extensions'].add_section('Foobar_cfgBindings') | ||
| 501 | + conf.defaultCfg['extensions'].set('Foobar', 'enable', 'True') | ||
| 502 | + conf.defaultCfg['extensions'].set('Foobar_cfgBindings', 'newfoo', | ||
| 503 | + '<Alt-Shift-Key-F12>') | ||
| 504 | + self.assertEqual(conf.GetKeySet(conf.CurrentKeys())['<<newfoo>>'], | ||
| 505 | + ['<Alt-Shift-Key-F12>']) | ||
| 506 | + sys.platform = 'darwin' | ||
| 507 | + self.assertEqual(conf.GetCurrentKeySet()['<<newfoo>>'], | ||
| 508 | + ['<Option-Shift-Key-F12>']) | ||
| 509 | + finally: | ||
| 510 | + # Restore platform | ||
| 511 | + sys.platform = current_platform | ||
| 507 | 512 | ||
| 508 | 513 | def test_get_keyset(self): | |
| 509 | 514 | conf = self.mock_config() | |
@@ -762,8 +767,29 @@ def test_save_default(self): # Cover 2nd and 3rd false branches. | |||
| 762 | 767 | changes = self.changes | |
| 763 | 768 | changes.add_option('main', 'Indent', 'use-spaces', '1') | |
| 764 | 769 | # save_option returns False; cfg_type_changed remains False. | |
| 770 | + self.assertFalse(changes.save_all()) | ||
| 771 | + self.assertFalse(usermain.has_option('Indent', 'use-spaces')) | ||
| 772 | + self.assertEqual(changes, self.empty) | ||
| 765 | 773 | ||
| 766 | - # TODO: test that save_all calls usercfg Saves. | ||
| 774 | + def test_save_all_saves_files(self): | ||
| 775 | + eq = self.assertEqual | ||
| 776 | + changes = self.changes | ||
| 777 | + for config in testcfg.values(): | ||
| 778 | + config.Save = Func() | ||
| 779 | + try: | ||
| 780 | + # 'main', 'highlight' and 'keys' are saved even if unchanged. | ||
| 781 | + self.assertFalse(changes.save_all()) | ||
| 782 | + eq([testcfg[cfgtype].Save.called | ||
| 783 | + for cfgtype in ('main', 'highlight', 'keys', 'extensions')], | ||
| 784 | + [1, 1, 1, 0]) | ||
| 785 | + # A changed configuration type is saved too. | ||
| 786 | + changes.add_option('extensions', 'Esec', 'eitem', 'eval') | ||
| 787 | + self.assertTrue(changes.save_all()) | ||
| 788 | + eq(testcfg['extensions'].Save.called, 1) | ||
| 789 | + finally: | ||
| 790 | + for config in testcfg.values(): | ||
| 791 | + del config.Save | ||
| 792 | + userextn.remove_section('Esec') | ||
| 767 | 793 | ||
| 768 | 794 | def test_delete_section(self): | |
| 769 | 795 | changes = self.load() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -3,6 +3,7 @@ | |||
| 3 | 3 | Half the class creates dialog, half works with user customizations. | |
| 4 | 4 | """ | |
| 5 | 5 | from idlelib import configdialog | |
| 6 | + from idlelib.editor import EditorWindow | ||
| 6 | 7 | from test.support import requires | |
| 7 | 8 | requires('gui') | |
| 8 | 9 | import unittest | |
@@ -50,14 +51,28 @@ def tearDownModule(): | |||
| 50 | 51 | root = dialog = None | |
| 51 | 52 | ||
| 52 | 53 | ||
| 53 | - @unittest.skip('Empty tests') | ||
| 54 | 54 | class ConfigDialogTest(unittest.TestCase): | |
| 55 | + # The methods tested here are mocked out in the tests below. | ||
| 56 | + | ||
| 57 | + def setUp(self): | ||
| 58 | + self.parent = dialog.parent | ||
| 59 | + self.instance = mock.create_autospec(EditorWindow, instance=True) | ||
| 60 | + dialog.parent = mock.Mock(instance_dict={self.instance: []}) | ||
| 61 | + | ||
| 62 | + def tearDown(self): | ||
| 63 | + dialog.parent = self.parent | ||
| 55 | 64 | ||
| 56 | 65 | def test_deactivate_current_config(self): | |
| 57 | - pass | ||
| 66 | + dialog.deactivate_current_config() | ||
| 67 | + self.instance.RemoveKeybindings.assert_called_once_with() | ||
| 58 | 68 | ||
| 59 | - def activate_config_changes(self): | ||
| 60 | - pass | ||
| 69 | + def test_activate_config_changes(self): | ||
| 70 | + dialog.activate_config_changes() | ||
| 71 | + for name in ('ResetColorizer', 'ResetFont', 'set_notabs_indentwidth', | ||
| 72 | + 'ApplyKeybindings', 'reset_help_menu_entries', | ||
| 73 | + 'update_cursor_blink'): | ||
| 74 | + with self.subTest(name=name): | ||
| 75 | + getattr(self.instance, name).assert_called_once_with() | ||
| 61 | 76 | ||
| 62 | 77 | ||
| 63 | 78 | class ButtonTest(unittest.TestCase): | |
@@ -1296,13 +1311,123 @@ def test_context(self): | |||
| 1296 | 1311 | self.assertEqual(extpage, {'CodeContext': {'maxlines': '1'}}) | |
| 1297 | 1312 | ||
| 1298 | 1313 | ||
| 1299 | - #unittest.skip("Nothing here yet TODO") | ||
| 1300 | 1314 | class ExtPageTest(unittest.TestCase): | |
| 1301 | - """Test that the help source list works correctly.""" | ||
| 1315 | + """Test that the extension page works correctly. | ||
| 1316 | + | ||
| 1317 | + The page loads the options of each extension from the default and | ||
| 1318 | + user config files, displays those of the selected extension, and | ||
| 1319 | + saves the changed ones to the user config file. ZzDummy is the | ||
| 1320 | + only extension shipped with IDLE. | ||
| 1321 | + """ | ||
| 1302 | 1322 | @classmethod | |
| 1303 | 1323 | def setUpClass(cls): | |
| 1304 | - page = dialog.extpage | ||
| 1324 | + page = cls.page = dialog.extpage | ||
| 1305 | 1325 | dialog.note.select(page) | |
| 1326 | + page.update() | ||
| 1327 | + | ||
| 1328 | + def setUp(self): | ||
| 1329 | + # Restore the option vars changed by the previous test. | ||
| 1330 | + self.page.load_extensions() | ||
| 1331 | + | ||
| 1332 | + def tearDown(self): | ||
| 1333 | + self.page.ext_userCfg.remove_section('ZzDummy') | ||
| 1334 | + | ||
| 1335 | + def test_load_extensions(self): | ||
| 1336 | + eq = self.assertEqual | ||
| 1337 | + extensions = self.page.extensions | ||
| 1338 | + eq(list(extensions), sorted(idleConf.GetExtensions(active_only=False))) | ||
| 1339 | + opts = extensions['ZzDummy'] | ||
| 1340 | + # The 'enable' options come first, the others follow, both sorted. | ||
| 1341 | + eq([opt['name'] for opt in opts], | ||
| 1342 | + ['enable', 'enable_editor', 'enable_shell', 'z-text']) | ||
| 1343 | + eq([opt['type'] for opt in opts], ['bool', 'bool', 'bool', None]) | ||
| 1344 | + eq([opt['default'] for opt in opts], ['False', 'True', 'False', 'Z']) | ||
| 1345 | + eq([opt['value'] for opt in opts], [False, True, False, 'Z']) | ||
| 1346 | + for opt in opts: | ||
| 1347 | + with self.subTest(name=opt['name']): | ||
| 1348 | + eq(opt['var'].get(), str(opt['value'])) | ||
| 1349 | + | ||
| 1350 | + def test_load_extensions_enable_first(self): | ||
| 1351 | + # The 'enable' options come first even if they sort last. | ||
| 1352 | + page = self.page | ||
| 1353 | + page.ext_userCfg.SetOption('ZzDummy', 'a-text', 'A') | ||
| 1354 | + page.load_extensions() | ||
| 1355 | + self.assertEqual([opt['name'] for opt in page.extensions['ZzDummy']], | ||
| 1356 | + ['enable', 'enable_editor', 'enable_shell', | ||
| 1357 | + 'a-text', 'z-text']) | ||
| 1358 | + | ||
| 1359 | + def test_load_extensions_user_value(self): | ||
| 1360 | + # A user option overrides the default value, but not the default. | ||
| 1361 | + page = self.page | ||
| 1362 | + page.ext_userCfg.SetOption('ZzDummy', 'z-text', 'user') | ||
| 1363 | + page.load_extensions() | ||
| 1364 | + opt = page.extensions['ZzDummy'][-1] | ||
| 1365 | + self.assertEqual(opt['name'], 'z-text') | ||
| 1366 | + self.assertEqual(opt['default'], 'Z') | ||
| 1367 | + self.assertEqual(opt['value'], 'user') | ||
| 1368 | + self.assertEqual(opt['var'].get(), 'user') | ||
| 1369 | + | ||
| 1370 | + def test_extension_selected(self): | ||
| 1371 | + eq = self.assertEqual | ||
| 1372 | + page = self.page | ||
| 1373 | + frame = page.config_frame['ZzDummy'] | ||
| 1374 | + # Deselecting hides the options of the current extension. | ||
| 1375 | + page.extension_list.selection_clear(0, 'end') | ||
| 1376 | + page.extension_selected(None) | ||
| 1377 | + eq(page.current_extension, None) | ||
| 1378 | + eq(page.details_frame.cget('text'), '') | ||
| 1379 | + eq(frame.winfo_manager(), '') | ||
| 1380 | + # Selecting shows the options of the selected extension. | ||
| 1381 | + page.extension_list.selection_set(0) | ||
| 1382 | + page.extension_selected(None) | ||
| 1383 | + eq(page.current_extension, 'ZzDummy') | ||
| 1384 | + eq(page.details_frame.cget('text'), 'ZzDummy') | ||
| 1385 | + eq(frame.winfo_manager(), 'grid') | ||
| 1386 | + | ||
| 1387 | + def test_set_extension_value_changed(self): | ||
| 1388 | + page = self.page | ||
| 1389 | + opt = page.extensions['ZzDummy'][-1] # z-text, default 'Z'. | ||
| 1390 | + opt['var'].set('user') | ||
| 1391 | + self.assertTrue(page.set_extension_value('ZzDummy', opt)) | ||
| 1392 | + self.assertEqual(page.ext_userCfg.Get('ZzDummy', 'z-text'), 'user') | ||
| 1393 | + # Saving the same value again is not a change. | ||
| 1394 | + self.assertFalse(page.set_extension_value('ZzDummy', opt)) | ||
| 1395 | + | ||
| 1396 | + def test_set_extension_value_default(self): | ||
| 1397 | + page = self.page | ||
| 1398 | + opt = page.extensions['ZzDummy'][-1] | ||
| 1399 | + # The default value is not saved in the user config file. | ||
| 1400 | + opt['var'].set('Z') | ||
| 1401 | + self.assertFalse(page.set_extension_value('ZzDummy', opt)) | ||
| 1402 | + self.assertFalse(page.ext_userCfg.has_option('ZzDummy', 'z-text')) | ||
| 1403 | + # Setting it back to the default removes the user option. | ||
| 1404 | + page.ext_userCfg.SetOption('ZzDummy', 'z-text', 'user') | ||
| 1405 | + self.assertTrue(page.set_extension_value('ZzDummy', opt)) | ||
| 1406 | + self.assertFalse(page.ext_userCfg.has_option('ZzDummy', 'z-text')) | ||
| 1407 | + | ||
| 1408 | + def test_set_extension_value_empty(self): | ||
| 1409 | + # An empty value is replaced with the default. | ||
| 1410 | + page = self.page | ||
| 1411 | + opt = page.extensions['ZzDummy'][-1] | ||
| 1412 | + opt['var'].set(' ') | ||
| 1413 | + self.assertFalse(page.set_extension_value('ZzDummy', opt)) | ||
| 1414 | + self.assertEqual(opt['var'].get(), 'Z') | ||
| 1415 | + | ||
| 1416 | + def test_save_all_changed_extensions(self): | ||
| 1417 | + page = self.page | ||
| 1418 | + page.ext_userCfg.Save = Func() | ||
| 1419 | + try: | ||
| 1420 | + # Nothing is saved if nothing is changed. | ||
| 1421 | + page.save_all_changed_extensions() | ||
| 1422 | + self.assertEqual(page.ext_userCfg.Save.called, 0) | ||
| 1423 | + page.extensions['ZzDummy'][0]['var'].set('True') | ||
| 1424 | + page.extensions['ZzDummy'][-1]['var'].set('user') | ||
| 1425 | + page.save_all_changed_extensions() | ||
| 1426 | + self.assertEqual(page.ext_userCfg.Save.called, 1) | ||
| 1427 | + self.assertEqual(page.ext_userCfg.Get('ZzDummy', 'enable'), 'True') | ||
| 1428 | + self.assertEqual(page.ext_userCfg.Get('ZzDummy', 'z-text'), 'user') | ||
| 1429 | + finally: | ||
| 1430 | + del page.ext_userCfg.Save | ||
| 1306 | 1431 | ||
| 1307 | 1432 | ||
| 1308 | 1433 | class HelpSourceTest(unittest.TestCase): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -211,20 +211,24 @@ def test_searcher(self): | |||
| 211 | 211 | self.assertEqual(actual_pair, expected_pair) | |
| 212 | 212 | ||
| 213 | 213 | ||
| 214 | - @unittest.skip('Empty test') | ||
| 215 | 214 | class RMenuTest(unittest.TestCase): | |
| 215 | + # Test selection-rclick interaction in right_click_event and | ||
| 216 | + # rmenu_check_copy(cut) status settings. These are part of the rmenu | ||
| 217 | + # functions common to all text windows with context windows. | ||
| 216 | 218 | ||
| 217 | 219 | @classmethod | |
| 218 | 220 | def setUpClass(cls): | |
| 219 | 221 | requires('gui') | |
| 220 | 222 | cls.root = Tk() | |
| 221 | 223 | cls.root.withdraw() | |
| 222 | 224 | cls.window = Editor(root=cls.root) | |
| 225 | + cls.text = cls.window.text | ||
| 226 | + cls.window.rmenu = cls.DummyRMenu | ||
| 223 | 227 | ||
| 224 | 228 | @classmethod | |
| 225 | 229 | def tearDownClass(cls): | |
| 226 | 230 | cls.window._close() | |
| 227 | - del cls.window | ||
| 231 | + del cls.window, cls.text | ||
| 228 | 232 | cls.root.update_idletasks() | |
| 229 | 233 | for id in cls.root.after_info(): | |
| 230 | 234 | cls.root.after_cancel(id) | |
@@ -234,8 +238,54 @@ def tearDownClass(cls): | |||
| 234 | 238 | class DummyRMenu: | |
| 235 | 239 | def tk_popup(x, y): pass | |
| 236 | 240 | ||
| 237 | - def test_rclick(self): | ||
| 238 | - pass | ||
| 241 | + def click(self): | ||
| 242 | + """Simulate a right click at(text pixel 0,0). | ||
| 243 | + """ | ||
| 244 | + Event = namedtuple('Event', ['x', 'y', 'x_root', 'y_root']) | ||
| 245 | + event = Event(0, 0, 0, 0) | ||
| 246 | + self.assertEqual(self.window.right_menu_event(event), 'break') | ||
| 247 | + # This assertion should be moved to a new method that also | ||
| 248 | + # text that dummy rmenu.tk_popup is called. | ||
| 249 | + | ||
| 250 | + def test_rclick_not_in_a_selection(self): | ||
| 251 | + # Like left click, 'insert' moves to click and any selection is deleted. | ||
| 252 | + eq = self.assertEqual | ||
| 253 | + text = self.text | ||
| 254 | + insert(text, 'one two three') | ||
| 255 | + # Selection exists but not clicked. | ||
| 256 | + text.tag_add('sel', '1.4', '1.7') # 'two' selected. | ||
| 257 | + text.mark_set('insert', '1.7') # Outside of selection. | ||
| 258 | + self.click() | ||
| 259 | + eq(text.tag_ranges('sel'), ()) | ||
| 260 | + eq(text.index('insert'), '1.0') | ||
| 261 | + # No selection to click, same result. | ||
| 262 | + text.mark_set('insert', '1.8') | ||
| 263 | + index = self.click() | ||
| 264 | + eq(text.tag_ranges('sel'), ()) | ||
| 265 | + eq(text.index('insert'), '1.0') | ||
| 266 | + | ||
| 267 | + def test_rclick_inside_selection(self): | ||
| 268 | + # Unlike left click, selection is not deleted. | ||
| 269 | + eq = self.assertEqual | ||
| 270 | + text = self.text | ||
| 271 | + insert(text, 'one two three') # 'insert' at 1.13. | ||
| 272 | + # The selection contains the clicked character. | ||
| 273 | + text.tag_add('sel', '1.0', '1.3') # Select 'one'. | ||
| 274 | + text.mark_set('insert', '1.3') # If select rightward, 'insert' at 1.3. | ||
| 275 | + self.click() | ||
| 276 | + eq((text.index('sel.first'), text.index('sel.last')), ('1.0', '1.3')) | ||
| 277 | + eq(text.index('insert'), '1.3') | ||
| 278 | + | ||
| 279 | + def test_rmenu_check_copy(self): | ||
| 280 | + # copy and cut only valid for click inside selection. | ||
| 281 | + eq = self.assertEqual | ||
| 282 | + text = self.text | ||
| 283 | + insert(text, 'one two three') | ||
| 284 | + eq(self.window.rmenu_check_copy(), 'disabled') | ||
| 285 | + eq(self.window.rmenu_check_cut(), 'disabled') | ||
| 286 | + text.tag_add('sel', '1.0', '1.3') # Includes '1.0' click. | ||
| 287 | + eq(self.window.rmenu_check_copy(), 'normal') | ||
| 288 | + eq(self.window.rmenu_check_cut(), 'normal') | ||
| 239 | 289 | ||
| 240 | 290 | ||
| 241 | 291 | if __name__ == '__main__': | |
| Back | FazBrowse Home | New Git URL |
0 commit comments