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