| 
									
										
										
										
											2018-06-15 18:20:55 -04:00
										 |  |  | "Test browser, coverage 90%." | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-15 18:20:55 -04:00
										 |  |  | from idlelib import browser | 
					
						
							|  |  |  | from test.support import requires | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from unittest import mock | 
					
						
							|  |  |  | from idlelib.idle_test.mock_idle import Func | 
					
						
							| 
									
										
										
										
											2022-07-30 06:42:13 +02:00
										 |  |  | from idlelib.util import py_extensions | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  | from collections import deque | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | import os.path | 
					
						
							|  |  |  | import pyclbr | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  | from tkinter import Tk | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  | from idlelib.tree import TreeNode | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  | class ModuleBrowserTest(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def setUpClass(cls): | 
					
						
							|  |  |  |         requires('gui') | 
					
						
							|  |  |  |         cls.root = Tk() | 
					
						
							|  |  |  |         cls.root.withdraw() | 
					
						
							| 
									
										
										
										
											2017-09-30 19:54:28 -04:00
										 |  |  |         cls.mb = browser.ModuleBrowser(cls.root, __file__, _utest=True) | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def tearDownClass(cls): | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         cls.mb.close() | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  |         cls.root.update_idletasks() | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         cls.root.destroy() | 
					
						
							| 
									
										
										
										
											2017-09-30 19:54:28 -04:00
										 |  |  |         del cls.root, cls.mb | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_init(self): | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         mb = self.mb | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         eq = self.assertEqual | 
					
						
							| 
									
										
										
										
											2017-09-30 19:54:28 -04:00
										 |  |  |         eq(mb.path, __file__) | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         eq(pyclbr._modules, {}) | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         self.assertIsInstance(mb.node, TreeNode) | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  |         self.assertIsNotNone(browser.file_open) | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_settitle(self): | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         mb = self.mb | 
					
						
							| 
									
										
										
										
											2017-09-30 19:54:28 -04:00
										 |  |  |         self.assertIn(os.path.basename(__file__), mb.top.title()) | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         self.assertEqual(mb.top.iconname(), 'Module Browser') | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_rootnode(self): | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         mb = self.mb | 
					
						
							|  |  |  |         rn = mb.rootnode() | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         self.assertIsInstance(rn, browser.ModuleBrowserTreeItem) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_close(self): | 
					
						
							| 
									
										
										
										
											2017-09-23 16:46:01 -04:00
										 |  |  |         mb = self.mb | 
					
						
							|  |  |  |         mb.top.destroy = Func() | 
					
						
							|  |  |  |         mb.node.destroy = Func() | 
					
						
							|  |  |  |         mb.close() | 
					
						
							|  |  |  |         self.assertTrue(mb.top.destroy.called) | 
					
						
							|  |  |  |         self.assertTrue(mb.node.destroy.called) | 
					
						
							|  |  |  |         del mb.top.destroy, mb.node.destroy | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-30 06:42:13 +02:00
										 |  |  |     def test_is_browseable_extension(self): | 
					
						
							|  |  |  |         path = "/path/to/file" | 
					
						
							|  |  |  |         for ext in py_extensions: | 
					
						
							|  |  |  |             with self.subTest(ext=ext): | 
					
						
							|  |  |  |                 filename = f'{path}{ext}' | 
					
						
							|  |  |  |                 actual = browser.is_browseable_extension(filename) | 
					
						
							|  |  |  |                 expected = ext not in browser.browseable_extension_blocklist | 
					
						
							|  |  |  |                 self.assertEqual(actual, expected) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  | # Nested tree same as in test_pyclbr.py except for supers on C0. C1. | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | mb = pyclbr | 
					
						
							|  |  |  | module, fname = 'test', 'test.py' | 
					
						
							| 
									
										
										
										
											2021-02-01 09:38:44 -08:00
										 |  |  | C0 = mb.Class(module, 'C0', ['base'], fname, 1, end_lineno=9) | 
					
						
							|  |  |  | F1 = mb._nest_function(C0, 'F1', 3, 5) | 
					
						
							|  |  |  | C1 = mb._nest_class(C0, 'C1', 6, 9, ['']) | 
					
						
							|  |  |  | C2 = mb._nest_class(C1, 'C2', 7, 9) | 
					
						
							|  |  |  | F3 = mb._nest_function(C2, 'F3', 9, 9) | 
					
						
							|  |  |  | f0 = mb.Function(module, 'f0', fname, 11, end_lineno=15) | 
					
						
							|  |  |  | f1 = mb._nest_function(f0, 'f1', 12, 14) | 
					
						
							|  |  |  | f2 = mb._nest_function(f1, 'f2', 13, 13) | 
					
						
							|  |  |  | c1 = mb._nest_class(f0, 'c1', 15, 15) | 
					
						
							| 
									
										
										
										
											2019-06-01 17:03:22 -04:00
										 |  |  | mock_pyclbr_tree = {'C0': C0, 'f0': f0} | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  | # Adjust C0.name, C1.name so tests do not depend on order. | 
					
						
							|  |  |  | browser.transform_children(mock_pyclbr_tree, 'test')  # C0(base) | 
					
						
							|  |  |  | browser.transform_children(C0.children)  # C1() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # The class below checks that the calls above are correct | 
					
						
							|  |  |  | # and that duplicate calls have no effect. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class TransformChildrenTest(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |     def test_transform_module_children(self): | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         eq = self.assertEqual | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         transform = browser.transform_children | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         # Parameter matches tree module. | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         tcl = list(transform(mock_pyclbr_tree, 'test')) | 
					
						
							| 
									
										
										
										
											2019-06-01 17:03:22 -04:00
										 |  |  |         eq(tcl, [C0, f0]) | 
					
						
							|  |  |  |         eq(tcl[0].name, 'C0(base)') | 
					
						
							|  |  |  |         eq(tcl[1].name, 'f0') | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         # Check that second call does not change suffix. | 
					
						
							|  |  |  |         tcl = list(transform(mock_pyclbr_tree, 'test')) | 
					
						
							| 
									
										
										
										
											2019-06-01 17:03:22 -04:00
										 |  |  |         eq(tcl[0].name, 'C0(base)') | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         # Nothing to traverse if parameter name isn't same as tree module. | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         tcl = list(transform(mock_pyclbr_tree, 'different name')) | 
					
						
							|  |  |  |         eq(tcl, []) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_transform_node_children(self): | 
					
						
							|  |  |  |         eq = self.assertEqual | 
					
						
							|  |  |  |         transform = browser.transform_children | 
					
						
							|  |  |  |         # Class with two children, one name altered. | 
					
						
							|  |  |  |         tcl = list(transform(C0.children)) | 
					
						
							|  |  |  |         eq(tcl, [F1, C1]) | 
					
						
							|  |  |  |         eq(tcl[0].name, 'F1') | 
					
						
							|  |  |  |         eq(tcl[1].name, 'C1()') | 
					
						
							|  |  |  |         tcl = list(transform(C0.children)) | 
					
						
							|  |  |  |         eq(tcl[1].name, 'C1()') | 
					
						
							|  |  |  |         # Function with two children. | 
					
						
							|  |  |  |         eq(list(transform(f0.children)), [f1, c1]) | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ModuleBrowserTreeItemTest(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def setUpClass(cls): | 
					
						
							|  |  |  |         cls.mbt = browser.ModuleBrowserTreeItem(fname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_init(self): | 
					
						
							|  |  |  |         self.assertEqual(self.mbt.file, fname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_gettext(self): | 
					
						
							|  |  |  |         self.assertEqual(self.mbt.GetText(), fname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_geticonname(self): | 
					
						
							|  |  |  |         self.assertEqual(self.mbt.GetIconName(), 'python') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_isexpandable(self): | 
					
						
							|  |  |  |         self.assertTrue(self.mbt.IsExpandable()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_listchildren(self): | 
					
						
							|  |  |  |         save_rex = browser.pyclbr.readmodule_ex | 
					
						
							|  |  |  |         save_tc = browser.transform_children | 
					
						
							|  |  |  |         browser.pyclbr.readmodule_ex = Func(result=mock_pyclbr_tree) | 
					
						
							|  |  |  |         browser.transform_children = Func(result=[f0, C0]) | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  |             self.assertEqual(self.mbt.listchildren(), [f0, C0]) | 
					
						
							|  |  |  |         finally: | 
					
						
							|  |  |  |             browser.pyclbr.readmodule_ex = save_rex | 
					
						
							|  |  |  |             browser.transform_children = save_tc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_getsublist(self): | 
					
						
							|  |  |  |         mbt = self.mbt | 
					
						
							|  |  |  |         mbt.listchildren = Func(result=[f0, C0]) | 
					
						
							|  |  |  |         sub0, sub1 = mbt.GetSubList() | 
					
						
							|  |  |  |         del mbt.listchildren | 
					
						
							|  |  |  |         self.assertIsInstance(sub0, browser.ChildBrowserTreeItem) | 
					
						
							|  |  |  |         self.assertIsInstance(sub1, browser.ChildBrowserTreeItem) | 
					
						
							|  |  |  |         self.assertEqual(sub0.name, 'f0') | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         self.assertEqual(sub1.name, 'C0(base)') | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  |     @mock.patch('idlelib.browser.file_open') | 
					
						
							|  |  |  |     def test_ondoubleclick(self, fopen): | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         mbt = self.mbt | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with mock.patch('os.path.exists', return_value=False): | 
					
						
							|  |  |  |             mbt.OnDoubleClick() | 
					
						
							|  |  |  |             fopen.assert_not_called() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with mock.patch('os.path.exists', return_value=True): | 
					
						
							|  |  |  |             mbt.OnDoubleClick() | 
					
						
							|  |  |  |             fopen.assert_called() | 
					
						
							|  |  |  |             fopen.called_with(fname) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ChildBrowserTreeItemTest(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def setUpClass(cls): | 
					
						
							|  |  |  |         CBT = browser.ChildBrowserTreeItem | 
					
						
							|  |  |  |         cls.cbt_f1 = CBT(f1) | 
					
						
							|  |  |  |         cls.cbt_C1 = CBT(C1) | 
					
						
							|  |  |  |         cls.cbt_F1 = CBT(F1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @classmethod | 
					
						
							|  |  |  |     def tearDownClass(cls): | 
					
						
							|  |  |  |         del cls.cbt_C1, cls.cbt_f1, cls.cbt_F1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_init(self): | 
					
						
							|  |  |  |         eq = self.assertEqual | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         eq(self.cbt_C1.name, 'C1()') | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         self.assertFalse(self.cbt_C1.isfunction) | 
					
						
							|  |  |  |         eq(self.cbt_f1.name, 'f1') | 
					
						
							|  |  |  |         self.assertTrue(self.cbt_f1.isfunction) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_gettext(self): | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         self.assertEqual(self.cbt_C1.GetText(), 'class C1()') | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         self.assertEqual(self.cbt_f1.GetText(), 'def f1(...)') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_geticonname(self): | 
					
						
							|  |  |  |         self.assertEqual(self.cbt_C1.GetIconName(), 'folder') | 
					
						
							|  |  |  |         self.assertEqual(self.cbt_f1.GetIconName(), 'python') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_isexpandable(self): | 
					
						
							|  |  |  |         self.assertTrue(self.cbt_C1.IsExpandable()) | 
					
						
							|  |  |  |         self.assertTrue(self.cbt_f1.IsExpandable()) | 
					
						
							|  |  |  |         self.assertFalse(self.cbt_F1.IsExpandable()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_getsublist(self): | 
					
						
							|  |  |  |         eq = self.assertEqual | 
					
						
							|  |  |  |         CBT = browser.ChildBrowserTreeItem | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         f1sublist = self.cbt_f1.GetSubList() | 
					
						
							|  |  |  |         self.assertIsInstance(f1sublist[0], CBT) | 
					
						
							|  |  |  |         eq(len(f1sublist), 1) | 
					
						
							|  |  |  |         eq(f1sublist[0].name, 'f2') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         eq(self.cbt_F1.GetSubList(), []) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-22 19:05:25 -05:00
										 |  |  |     @mock.patch('idlelib.browser.file_open') | 
					
						
							|  |  |  |     def test_ondoubleclick(self, fopen): | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |         goto = fopen.return_value.gotoline = mock.Mock() | 
					
						
							|  |  |  |         self.cbt_F1.OnDoubleClick() | 
					
						
							|  |  |  |         fopen.assert_called() | 
					
						
							|  |  |  |         goto.assert_called() | 
					
						
							|  |  |  |         goto.assert_called_with(self.cbt_F1.obj.lineno) | 
					
						
							|  |  |  |         # Failure test would have to raise OSError or AttributeError. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NestedChildrenTest(unittest.TestCase): | 
					
						
							|  |  |  |     "Test that all the nodes in a nested tree are added to the BrowserTree." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_nested(self): | 
					
						
							|  |  |  |         queue = deque() | 
					
						
							|  |  |  |         actual_names = [] | 
					
						
							|  |  |  |         # The tree items are processed in breadth first order. | 
					
						
							|  |  |  |         # Verify that processing each sublist hits every node and | 
					
						
							|  |  |  |         # in the right order. | 
					
						
							| 
									
										
										
										
											2017-09-23 14:19:23 -04:00
										 |  |  |         expected_names = ['f0', 'C0(base)', | 
					
						
							| 
									
										
										
										
											2017-09-22 16:08:44 -04:00
										 |  |  |                           'f1', 'c1', 'F1', 'C1()', | 
					
						
							|  |  |  |                           'f2', 'C2', | 
					
						
							|  |  |  |                           'F3'] | 
					
						
							|  |  |  |         CBT = browser.ChildBrowserTreeItem | 
					
						
							|  |  |  |         queue.extend((CBT(f0), CBT(C0))) | 
					
						
							|  |  |  |         while queue: | 
					
						
							|  |  |  |             cb = queue.popleft() | 
					
						
							|  |  |  |             sublist = cb.GetSubList() | 
					
						
							|  |  |  |             queue.extend(sublist) | 
					
						
							|  |  |  |             self.assertIn(cb.name, cb.GetText()) | 
					
						
							|  |  |  |             self.assertIn(cb.GetIconName(), ('python', 'folder')) | 
					
						
							|  |  |  |             self.assertIs(cb.IsExpandable(), sublist != []) | 
					
						
							|  |  |  |             actual_names.append(cb.name) | 
					
						
							|  |  |  |         self.assertEqual(actual_names, expected_names) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     unittest.main(verbosity=2) |