Hide keyboard shortcuts

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. 

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 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. 

91 

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') 

99 

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) 

120 

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