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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

81 statements  

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. 

7 

8Run these tests using unittest or pytest from the command line. 

9See g.run_unit_tests and g.run_coverage_tests. 

10 

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 

19 

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. 

25 

26 This method is expensive (0.5 sec) only the first time it is called. 

27 

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 g.app.leoID = 'TestLeoId' # 2022/03/06: Use a standard user id for all tests. 

50 g.app.nodeIndices = leoNodes.NodeIndices(g.app.leoID) 

51 g.app.config = leoConfig.GlobalConfigManager() 

52 g.app.db = g.NullObject('g.app.db') # type:ignore 

53 g.app.pluginsController = g.NullObject('g.app.pluginsController') # type:ignore 

54 g.app.commander_cacher = g.NullObject('g.app.commander_cacher') # type:ignore 

55 if gui_name == 'null': 

56 g.app.gui = NullGui() 

57 elif gui_name == 'qt': 

58 g.app.gui = LeoQtGui() 

59 else: 

60 raise TypeError(f"create_gui: unknown gui_name: {gui_name!r}") 

61 t3 = time.process_time() 

62 # Create a dummy commander, to do the imports in c.initObjects. 

63 # Always use a null gui to avoid screen flash. 

64 # setUp will create another commander. 

65 c = leoCommands.Commands(fileName=None, gui=g.app.gui) 

66 # Create minimal config dictionaries. 

67 settings_d, bindings_d = lm.createDefaultSettingsDicts() 

68 lm.globalSettingsDict = settings_d 

69 lm.globalBindingsDict = bindings_d 

70 c.config.settingsDict = settings_d 

71 c.config.bindingsDict = bindings_d 

72 assert g.unitTesting is True # Defensive. 

73 t4 = time.process_time() 

74 # Trace times. This trace happens only once: 

75 # imports: 0.016 

76 # gui: 0.000 

77 # commander: 0.469 

78 # total: 0.484 

79 if trace and t4 - t3 > 0.1: 

80 print('create_app:\n' 

81 f" imports: {(t2-t1):.3f}\n" 

82 f" gui: {(t3-t2):.3f}\n" 

83 f"commander: {(t4-t2):.3f}\n" 

84 f" total: {(t4-t1):.3f}\n") 

85 return c 

86#@+node:ekr.20210902014907.1: ** class LeoUnitTest(unittest.TestCase) 

87class LeoUnitTest(unittest.TestCase): 

88 """ 

89 The base class for all unit tests in Leo. 

90 

91 Contains setUp/tearDown methods and various utilites. 

92 """ 

93 #@+others 

94 #@+node:ekr.20210901140855.2: *3* LeoUnitTest.setUp, tearDown & setUpClass 

95 @classmethod 

96 def setUpClass(cls): 

97 create_app(gui_name='null') 

98 

99 def setUp(self): 

100 """ 

101 Create a commander using a **null** gui, regardless of g.app.gui. 

102 Create the nodes in the commander. 

103 """ 

104 # Do the import here to avoid circular dependencies. 

105 from leo.core import leoCommands 

106 from leo.core.leoGui import NullGui 

107 # Set g.unitTesting *early*, for guards. 

108 g.unitTesting = True 

109 # Create a new commander for each test. 

110 # This is fast, because setUpClass has done all the imports. 

111 self.c = c = leoCommands.Commands(fileName=None, gui=NullGui()) 

112 # Init the 'root' and '@settings' nodes. 

113 self.root_p = c.rootPosition() 

114 self.root_p.h = 'root' 

115 self.settings_p = self.root_p.insertAfter() 

116 self.settings_p.h = '@settings' 

117 # Select the 'root' node. 

118 c.selectPosition(self.root_p) 

119 

120 def tearDown(self): 

121 self.c = None 

122 #@+node:ekr.20210830151601.1: *3* LeoUnitTest.create_test_outline 

123 def create_test_outline(self): 

124 p = self.c.p 

125 # Create the following outline: 

126 # 

127 # root 

128 # child clone a 

129 # node clone 1 

130 # child b 

131 # child clone a 

132 # node clone 1 

133 # child c 

134 # node clone 1 

135 # child clone a 

136 # node clone 1 

137 # child b 

138 # child clone a 

139 # node clone 1 

140 assert p == self.root_p 

141 assert p.h == 'root' 

142 # Child a 

143 child_clone_a = p.insertAsLastChild() 

144 child_clone_a.h = 'child clone a' 

145 node_clone_1 = child_clone_a.insertAsLastChild() 

146 node_clone_1.h = 'node clone 1' 

147 # Child b 

148 child_b = p.insertAsLastChild() 

149 child_b.h = 'child b' 

150 # Clone 'child clone a' 

151 clone = child_clone_a.clone() 

152 clone.moveToLastChildOf(child_b) 

153 # Child c 

154 child_c = p.insertAsLastChild() 

155 child_c.h = 'child c' 

156 # Clone 'node clone 1' 

157 clone = node_clone_1.clone() 

158 clone.moveToLastChildOf(child_c) 

159 # Clone 'child clone a' 

160 clone = child_clone_a.clone() 

161 clone.moveToLastChildOf(p) 

162 # Clone 'child b' 

163 clone = child_b.clone() 

164 clone.moveToLastChildOf(p) 

165 #@-others 

166#@-others 

167#@-leo