test_browser.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. "Test browser, coverage 90%."
  2. from idlelib import browser
  3. from test.support import requires
  4. import unittest
  5. from unittest import mock
  6. from idlelib.idle_test.mock_idle import Func
  7. from collections import deque
  8. import os.path
  9. import pyclbr
  10. from tkinter import Tk
  11. from idlelib.tree import TreeNode
  12. class ModuleBrowserTest(unittest.TestCase):
  13. @classmethod
  14. def setUpClass(cls):
  15. requires('gui')
  16. cls.root = Tk()
  17. cls.root.withdraw()
  18. cls.mb = browser.ModuleBrowser(cls.root, __file__, _utest=True)
  19. @classmethod
  20. def tearDownClass(cls):
  21. cls.mb.close()
  22. cls.root.update_idletasks()
  23. cls.root.destroy()
  24. del cls.root, cls.mb
  25. def test_init(self):
  26. mb = self.mb
  27. eq = self.assertEqual
  28. eq(mb.path, __file__)
  29. eq(pyclbr._modules, {})
  30. self.assertIsInstance(mb.node, TreeNode)
  31. self.assertIsNotNone(browser.file_open)
  32. def test_settitle(self):
  33. mb = self.mb
  34. self.assertIn(os.path.basename(__file__), mb.top.title())
  35. self.assertEqual(mb.top.iconname(), 'Module Browser')
  36. def test_rootnode(self):
  37. mb = self.mb
  38. rn = mb.rootnode()
  39. self.assertIsInstance(rn, browser.ModuleBrowserTreeItem)
  40. def test_close(self):
  41. mb = self.mb
  42. mb.top.destroy = Func()
  43. mb.node.destroy = Func()
  44. mb.close()
  45. self.assertTrue(mb.top.destroy.called)
  46. self.assertTrue(mb.node.destroy.called)
  47. del mb.top.destroy, mb.node.destroy
  48. # Nested tree same as in test_pyclbr.py except for supers on C0. C1.
  49. mb = pyclbr
  50. module, fname = 'test', 'test.py'
  51. C0 = mb.Class(module, 'C0', ['base'], fname, 1)
  52. F1 = mb._nest_function(C0, 'F1', 3)
  53. C1 = mb._nest_class(C0, 'C1', 6, [''])
  54. C2 = mb._nest_class(C1, 'C2', 7)
  55. F3 = mb._nest_function(C2, 'F3', 9)
  56. f0 = mb.Function(module, 'f0', fname, 11)
  57. f1 = mb._nest_function(f0, 'f1', 12)
  58. f2 = mb._nest_function(f1, 'f2', 13)
  59. c1 = mb._nest_class(f0, 'c1', 15)
  60. mock_pyclbr_tree = {'C0': C0, 'f0': f0}
  61. # Adjust C0.name, C1.name so tests do not depend on order.
  62. browser.transform_children(mock_pyclbr_tree, 'test') # C0(base)
  63. browser.transform_children(C0.children) # C1()
  64. # The class below checks that the calls above are correct
  65. # and that duplicate calls have no effect.
  66. class TransformChildrenTest(unittest.TestCase):
  67. def test_transform_module_children(self):
  68. eq = self.assertEqual
  69. transform = browser.transform_children
  70. # Parameter matches tree module.
  71. tcl = list(transform(mock_pyclbr_tree, 'test'))
  72. eq(tcl, [C0, f0])
  73. eq(tcl[0].name, 'C0(base)')
  74. eq(tcl[1].name, 'f0')
  75. # Check that second call does not change suffix.
  76. tcl = list(transform(mock_pyclbr_tree, 'test'))
  77. eq(tcl[0].name, 'C0(base)')
  78. # Nothing to traverse if parameter name isn't same as tree module.
  79. tcl = list(transform(mock_pyclbr_tree, 'different name'))
  80. eq(tcl, [])
  81. def test_transform_node_children(self):
  82. eq = self.assertEqual
  83. transform = browser.transform_children
  84. # Class with two children, one name altered.
  85. tcl = list(transform(C0.children))
  86. eq(tcl, [F1, C1])
  87. eq(tcl[0].name, 'F1')
  88. eq(tcl[1].name, 'C1()')
  89. tcl = list(transform(C0.children))
  90. eq(tcl[1].name, 'C1()')
  91. # Function with two children.
  92. eq(list(transform(f0.children)), [f1, c1])
  93. class ModuleBrowserTreeItemTest(unittest.TestCase):
  94. @classmethod
  95. def setUpClass(cls):
  96. cls.mbt = browser.ModuleBrowserTreeItem(fname)
  97. def test_init(self):
  98. self.assertEqual(self.mbt.file, fname)
  99. def test_gettext(self):
  100. self.assertEqual(self.mbt.GetText(), fname)
  101. def test_geticonname(self):
  102. self.assertEqual(self.mbt.GetIconName(), 'python')
  103. def test_isexpandable(self):
  104. self.assertTrue(self.mbt.IsExpandable())
  105. def test_listchildren(self):
  106. save_rex = browser.pyclbr.readmodule_ex
  107. save_tc = browser.transform_children
  108. browser.pyclbr.readmodule_ex = Func(result=mock_pyclbr_tree)
  109. browser.transform_children = Func(result=[f0, C0])
  110. try:
  111. self.assertEqual(self.mbt.listchildren(), [f0, C0])
  112. finally:
  113. browser.pyclbr.readmodule_ex = save_rex
  114. browser.transform_children = save_tc
  115. def test_getsublist(self):
  116. mbt = self.mbt
  117. mbt.listchildren = Func(result=[f0, C0])
  118. sub0, sub1 = mbt.GetSubList()
  119. del mbt.listchildren
  120. self.assertIsInstance(sub0, browser.ChildBrowserTreeItem)
  121. self.assertIsInstance(sub1, browser.ChildBrowserTreeItem)
  122. self.assertEqual(sub0.name, 'f0')
  123. self.assertEqual(sub1.name, 'C0(base)')
  124. @mock.patch('idlelib.browser.file_open')
  125. def test_ondoubleclick(self, fopen):
  126. mbt = self.mbt
  127. with mock.patch('os.path.exists', return_value=False):
  128. mbt.OnDoubleClick()
  129. fopen.assert_not_called()
  130. with mock.patch('os.path.exists', return_value=True):
  131. mbt.OnDoubleClick()
  132. fopen.assert_called()
  133. fopen.called_with(fname)
  134. class ChildBrowserTreeItemTest(unittest.TestCase):
  135. @classmethod
  136. def setUpClass(cls):
  137. CBT = browser.ChildBrowserTreeItem
  138. cls.cbt_f1 = CBT(f1)
  139. cls.cbt_C1 = CBT(C1)
  140. cls.cbt_F1 = CBT(F1)
  141. @classmethod
  142. def tearDownClass(cls):
  143. del cls.cbt_C1, cls.cbt_f1, cls.cbt_F1
  144. def test_init(self):
  145. eq = self.assertEqual
  146. eq(self.cbt_C1.name, 'C1()')
  147. self.assertFalse(self.cbt_C1.isfunction)
  148. eq(self.cbt_f1.name, 'f1')
  149. self.assertTrue(self.cbt_f1.isfunction)
  150. def test_gettext(self):
  151. self.assertEqual(self.cbt_C1.GetText(), 'class C1()')
  152. self.assertEqual(self.cbt_f1.GetText(), 'def f1(...)')
  153. def test_geticonname(self):
  154. self.assertEqual(self.cbt_C1.GetIconName(), 'folder')
  155. self.assertEqual(self.cbt_f1.GetIconName(), 'python')
  156. def test_isexpandable(self):
  157. self.assertTrue(self.cbt_C1.IsExpandable())
  158. self.assertTrue(self.cbt_f1.IsExpandable())
  159. self.assertFalse(self.cbt_F1.IsExpandable())
  160. def test_getsublist(self):
  161. eq = self.assertEqual
  162. CBT = browser.ChildBrowserTreeItem
  163. f1sublist = self.cbt_f1.GetSubList()
  164. self.assertIsInstance(f1sublist[0], CBT)
  165. eq(len(f1sublist), 1)
  166. eq(f1sublist[0].name, 'f2')
  167. eq(self.cbt_F1.GetSubList(), [])
  168. @mock.patch('idlelib.browser.file_open')
  169. def test_ondoubleclick(self, fopen):
  170. goto = fopen.return_value.gotoline = mock.Mock()
  171. self.cbt_F1.OnDoubleClick()
  172. fopen.assert_called()
  173. goto.assert_called()
  174. goto.assert_called_with(self.cbt_F1.obj.lineno)
  175. # Failure test would have to raise OSError or AttributeError.
  176. class NestedChildrenTest(unittest.TestCase):
  177. "Test that all the nodes in a nested tree are added to the BrowserTree."
  178. def test_nested(self):
  179. queue = deque()
  180. actual_names = []
  181. # The tree items are processed in breadth first order.
  182. # Verify that processing each sublist hits every node and
  183. # in the right order.
  184. expected_names = ['f0', 'C0(base)',
  185. 'f1', 'c1', 'F1', 'C1()',
  186. 'f2', 'C2',
  187. 'F3']
  188. CBT = browser.ChildBrowserTreeItem
  189. queue.extend((CBT(f0), CBT(C0)))
  190. while queue:
  191. cb = queue.popleft()
  192. sublist = cb.GetSubList()
  193. queue.extend(sublist)
  194. self.assertIn(cb.name, cb.GetText())
  195. self.assertIn(cb.GetIconName(), ('python', 'folder'))
  196. self.assertIs(cb.IsExpandable(), sublist != [])
  197. actual_names.append(cb.name)
  198. self.assertEqual(actual_names, expected_names)
  199. if __name__ == '__main__':
  200. unittest.main(verbosity=2)