Coverage for C:\leo.repo\leo-editor\leo\core\leoTest2.py : 96%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2#@+leo-ver=5-thin
3#@+node:ekr.20201129023817.1: * @file leoTest2.py
4#@@first
5"""
6Support for Leo's new unit tests, contained in leo/unittests/test_*.py.
8Run these tests using unittest or pytest from the command line.
9See g.run_unit_tests and g.run_coverage_tests.
11This file also contains classes that convert @test nodes in unitTest.leo to
12tests in leo/unittest. Eventually these classes will move to scripts.leo.
13"""
14import time
15import unittest
16import warnings
17from leo.core import leoGlobals as g
18from leo.core import leoApp
20#@+others
21#@+node:ekr.20201130195111.1: ** function.create_app
22def create_app(gui_name='null'):
23 """
24 Create the Leo application, g.app, the Gui, g.app.gui, and a commander.
26 This method is expensive (0.5 sec) only the first time it is called.
28 Thereafter, recreating g.app, g.app.gui, and new commands is fast.
29 """
30 trace = False
31 t1 = time.process_time()
32 #
33 # Set g.unitTesting *early*, for guards, to suppress the splash screen, etc.
34 g.unitTesting = True
35 # Create g.app now, to avoid circular dependencies.
36 g.app = leoApp.LeoApp()
37 # Late imports.
38 warnings.simplefilter("ignore")
39 from leo.core import leoConfig
40 from leo.core import leoNodes
41 from leo.core import leoCommands
42 from leo.core.leoGui import NullGui
43 if gui_name == 'qt':
44 from leo.plugins.qt_gui import LeoQtGui
45 t2 = time.process_time()
46 g.app.recentFilesManager = leoApp.RecentFilesManager()
47 g.app.loadManager = lm = leoApp.LoadManager()
48 lm.computeStandardDirectories()
49 if not g.app.setLeoID(useDialog=False, verbose=True):
50 raise ValueError("unable to set LeoID.")
51 g.app.nodeIndices = leoNodes.NodeIndices(g.app.leoID)
52 g.app.config = leoConfig.GlobalConfigManager()
53 g.app.db = g.NullObject('g.app.db') # type:ignore
54 g.app.pluginsController = g.NullObject('g.app.pluginsController') # type:ignore
55 g.app.commander_cacher = g.NullObject('g.app.commander_cacher') # type:ignore
56 if gui_name == 'null':
57 g.app.gui = NullGui()
58 elif gui_name == 'qt':
59 g.app.gui = LeoQtGui()
60 else:
61 raise TypeError(f"create_gui: unknown gui_name: {gui_name!r}")
62 t3 = time.process_time()
63 # Create a dummy commander, to do the imports in c.initObjects.
64 # Always use a null gui to avoid screen flash.
65 # setUp will create another commander.
66 c = leoCommands.Commands(fileName=None, gui=g.app.gui)
67 # Create minimal config dictionaries.
68 settings_d, bindings_d = lm.createDefaultSettingsDicts()
69 lm.globalSettingsDict = settings_d
70 lm.globalBindingsDict = bindings_d
71 c.config.settingsDict = settings_d
72 c.config.bindingsDict = bindings_d
73 assert g.unitTesting is True # Defensive.
74 t4 = time.process_time()
75 # Trace times. This trace happens only once:
76 # imports: 0.016
77 # gui: 0.000
78 # commander: 0.469
79 # total: 0.484
80 if trace and t4 - t3 > 0.1:
81 print('create_app:\n'
82 f" imports: {(t2-t1):.3f}\n"
83 f" gui: {(t3-t2):.3f}\n"
84 f"commander: {(t4-t2):.3f}\n"
85 f" total: {(t4-t1):.3f}\n")
86 return c
87#@+node:ekr.20210902014907.1: ** class LeoUnitTest(unittest.TestCase)
88class LeoUnitTest(unittest.TestCase):
89 """
90 The base class for all unit tests in Leo.
92 Contains setUp/tearDown methods and various utilites.
93 """
94 #@+others
95 #@+node:ekr.20210901140855.2: *3* LeoUnitTest.setUp, tearDown & setUpClass
96 @classmethod
97 def setUpClass(cls):
98 create_app(gui_name='null')
100 def setUp(self):
101 """
102 Create a commander using a **null** gui, regardless of g.app.gui.
103 Create the nodes in the commander.
104 """
105 # Do the import here to avoid circular dependencies.
106 from leo.core import leoCommands
107 from leo.core.leoGui import NullGui
108 # Set g.unitTesting *early*, for guards.
109 g.unitTesting = True
110 # Create a new commander for each test.
111 # This is fast, because setUpClass has done all the imports.
112 self.c = c = leoCommands.Commands(fileName=None, gui=NullGui())
113 # Init the 'root' and '@settings' nodes.
114 self.root_p = c.rootPosition()
115 self.root_p.h = 'root'
116 self.settings_p = self.root_p.insertAfter()
117 self.settings_p.h = '@settings'
118 # Select the 'root' node.
119 c.selectPosition(self.root_p)
121 def tearDown(self):
122 self.c = None
123 #@+node:ekr.20210830151601.1: *3* LeoUnitTest.create_test_outline
124 def create_test_outline(self):
125 p = self.c.p
126 # Create the following outline:
127 #
128 # root
129 # child clone a
130 # node clone 1
131 # child b
132 # child clone a
133 # node clone 1
134 # child c
135 # node clone 1
136 # child clone a
137 # node clone 1
138 # child b
139 # child clone a
140 # node clone 1
141 assert p == self.root_p
142 assert p.h == 'root'
143 # Child a
144 child_clone_a = p.insertAsLastChild()
145 child_clone_a.h = 'child clone a'
146 node_clone_1 = child_clone_a.insertAsLastChild()
147 node_clone_1.h = 'node clone 1'
148 # Child b
149 child_b = p.insertAsLastChild()
150 child_b.h = 'child b'
151 # Clone 'child clone a'
152 clone = child_clone_a.clone()
153 clone.moveToLastChildOf(child_b)
154 # Child c
155 child_c = p.insertAsLastChild()
156 child_c.h = 'child c'
157 # Clone 'node clone 1'
158 clone = node_clone_1.clone()
159 clone.moveToLastChildOf(child_c)
160 # Clone 'child clone a'
161 clone = child_clone_a.clone()
162 clone.moveToLastChildOf(p)
163 # Clone 'child b'
164 clone = child_b.clone()
165 clone.moveToLastChildOf(p)
166 #@-others
167#@-others
168#@-leo