Coverage for src/robotide/controller/cellinfo.py: 91%

123 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16from ..action.shortcut import localize_shortcuts 1ab

17from ..utils import highlightmatcher, html_escape 1ab

18 

19CTRL_LABEL = localize_shortcuts('CtrlCmd') 1ab

20 

21 

22class CellInfo(object): 1ab

23 

24 def __init__(self, cell_content, cell_position, for_loop=False): 1ab

25 self._cell_content = cell_content 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

26 self._cell_position = cell_position 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

27 self.for_loop = for_loop 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

28 

29 @property 1ab

30 def content_type(self): 1ab

31 return self._cell_content.type 1qrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmTUVWXgcfdehi23456j

32 

33 @property 1ab

34 def cell_type(self): 1ab

35 return self._cell_position.type 1qrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYVWXgcfdehij

36 

37 @property 1ab

38 def source(self): 1ab

39 return self._cell_content.source 1e

40 

41 @property 1ab

42 def arg_name(self): 1ab

43 return self._cell_position.argument_name 1cd

44 

45 def has_error(self): 1ab

46 return self.argument_missing() or self.too_many_arguments() 1nkolmpj

47 

48 def argument_missing(self): 1ab

49 return self.cell_type == CellType.MANDATORY \ 1nkolmpcdj

50 and self.content_type in [ContentType.EMPTY, ContentType.COMMENTED] 

51 

52 def too_many_arguments(self): 1ab

53 return self.cell_type == CellType.MUST_BE_EMPTY \ 1klmpfj

54 and self.content_type not in \ 

55 [ContentType.EMPTY, ContentType.COMMENTED] 

56 

57 def matches(self, value): 1ab

58 return highlightmatcher.highlight_matcher(value, 123456j

59 self._cell_content.value) 

60 

61 

62def tip_message(cell): 1ab

63 if not cell: 63 ↛ 64line 63 didn't jump to line 64 because the condition on line 63 was never true1gcfdehi

64 return '' 

65 tip = _TooltipMessage(cell) # if not cell.for_loop else _ForLoopTooltipMessage(cell) 1gcfdehi

66 return html_escape(str(tip)).replace('\n', '<br />') 1gcfdehi

67 

68 

69class _TooltipMessage(object): 1ab

70 

71 TOO_MANY_ARGUMENTS = "Too many arguments" 1ab

72 KEYWORD_NOT_FOUND = \ 1ab

73 "Keyword not found! For possible corrections press <%s>" % CTRL_LABEL 

74 VARIABLE_ASSIGMENT = "Variable assignment" 1ab

75 UNKNOWN_VARIABLE = "\n\nUnknown variable" 1ab

76 

77 ARGUMENT = "Argument: %s" 1ab

78 OPTIONAL_ARGUMENT = "Optional argument: %s" 1ab

79 MISSING_ARGUMENT = "Missing argument: %s" 1ab

80 

81 KEYWORD = "Keyword from: %s\n\n" + ("Press <%s> for details" % CTRL_LABEL) 1ab

82 

83 def __init__(self, cell): 1ab

84 self.message = self._get_message(cell) 1gcfdehi

85 

86 def _get_message(self, cell): 1ab

87 message = '' if cell.content_type != ContentType.UNKNOWN_VARIABLE \ 1gcfdehi

88 else self.UNKNOWN_VARIABLE 

89 handlers = { 1gcfdehi

90 CellType.ASSIGN: self._assign, 

91 CellType.KEYWORD: self._keyword, 

92 CellType.MANDATORY: self._mandatory, 

93 CellType.OPTIONAL: self._optional, 

94 CellType.MUST_BE_EMPTY: self._must_be_empty, 

95 CellType.UNKNOWN: self._unknown, 

96 CellType.END: self._keyword, 

97 CellType.FOR: self._keyword, 

98 CellType.VAR: self._assign 

99 } 

100 return (handlers[cell.cell_type](cell) + message).strip() 1gcfdehi

101 

102 def _must_be_empty(self, cell): 1ab

103 if cell.too_many_arguments(): 103 ↛ 105line 103 didn't jump to line 105 because the condition on line 103 was always true1f

104 return self.TOO_MANY_ARGUMENTS 1f

105 return '' 

106 

107 def _mandatory(self, cell): 1ab

108 if cell.argument_missing(): 108 ↛ 109line 108 didn't jump to line 109 because the condition on line 108 was never true1cd

109 return self.MISSING_ARGUMENT % cell.arg_name 

110 return self.ARGUMENT % cell.arg_name 1cd

111 

112 def _optional(self, cell): 1ab

113 return self.OPTIONAL_ARGUMENT % cell.arg_name 

114 

115 def _keyword(self, cell): 1ab

116 if cell.content_type == ContentType.STRING: 1eh

117 return self.KEYWORD_NOT_FOUND 1h

118 if cell.content_type in ContentType.KEYWORDS: 118 ↛ 120line 118 didn't jump to line 120 because the condition on line 118 was always true1e

119 return self.KEYWORD % cell.source 1e

120 return '' 

121 

122 def _assign(self, cell): 1ab

123 _ = cell 

124 return self.VARIABLE_ASSIGMENT 

125 

126 @staticmethod 1ab

127 def _unknown(cell): 1ab

128 _ = cell 1gi

129 return '' 1gi

130 

131 def __nonzero__(self): 1ab

132 return bool(self.message) 

133 

134 def __str__(self): 1ab

135 return self.message 1gcfdehi

136 

137 

138class CellContent(object): 1ab

139 

140 def __init__(self, ctype, value, source=None): 1ab

141 self.type = ctype 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

142 self.value = value 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

143 self.source = source 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

144 

145 

146class CellPosition(object): 1ab

147 

148 def __init__(self, ctype, argument_name): 1ab

149 self.type = ctype 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

150 self.argument_name = argument_name 1aqrstuvwxyzABCDEFGHIJKLMNOPQRSnkolmpTUYZ01VWXgcfdehij

151 

152 

153class ContentType: 1ab

154 USER_KEYWORD = 'USER_KEYWORD' 1ab

155 LIBRARY_KEYWORD = 'LIBRARY_KEYWORD' 1ab

156 END = 'END' 1ab

157 FOR = 'FOR' 1ab

158 IF = 'IF' 1ab

159 ELSE = 'ELSE' 1ab

160 ELSEIF = 'ELSE IF' 1ab

161 WHILE = 'WHILE' 1ab

162 TRY = 'TRY' 1ab

163 EXCEPT = 'EXCEPT' 1ab

164 BREAK = 'BREAK' 1ab

165 CONTINUE = 'CONTINUE' 1ab

166 VAR = 'VAR' 1ab

167 KEYWORDS = (USER_KEYWORD, LIBRARY_KEYWORD, END, FOR, IF, ELSE, ELSEIF, WHILE, TRY, EXCEPT, BREAK, CONTINUE, VAR) 1ab

168 VARIABLE = 'VARIABLE' 1ab

169 UNKNOWN_VARIABLE = 'UNKNOWN_VARIABLE' 1ab

170 COMMENTED = 'COMMENTED' 1ab

171 STRING = 'STRING' 1ab

172 EMPTY = 'EMPTY' 1ab

173 

174 

175class CellType: 1ab

176 ASSIGN = 'ASSIGN' 1ab

177 KEYWORD = 'KEYWORD' 1ab

178 MANDATORY = 'MANDATORY' 1ab

179 OPTIONAL = 'OPTIONAL' 1ab

180 MUST_BE_EMPTY = 'MUST_BE_EMPTY' 1ab

181 UNKNOWN = 'UNKNOWN' 1ab

182 FOR = 'KEYWORD' 1ab

183 END = 'KEYWORD' 1ab

184 IF = 'KEYWORD' 1ab

185 ELSE = 'KEYWORD' 1ab

186 ELSEIF = 'KEYWORD' 1ab

187 WHILE = 'KEYWORD' 1ab

188 TRY = 'KEYWORD' 1ab

189 EXCEPT = 'KEYWORD' 1ab

190 BREAK = 'KEYWORD' 1ab

191 CONTINUE = 'KEYWORD' 1ab

192 VAR = 'ASSIGN' 1ab

193 

194 

195UPPERCASE_KWS = [ContentType.END, ContentType.FOR, ContentType.IF, ContentType.ELSE, 1ab

196 ContentType.ELSEIF, ContentType.WHILE, ContentType.TRY, ContentType.EXCEPT, 

197 ContentType.BREAK, ContentType.CONTINUE, ContentType.VAR, 'IN', 'IN RANGE', 'IN ENUMERATE', 'IN ZIP']