Best Python code snippet using autotest_python
checker.py
Source:checker.py
1from abc import ABCMeta, abstractmethod2from typing import Dict, List, Tuple3from . import violation4from .violation import Violation5from sqlint.config import Config6from sqlint.syntax_tree import SyntaxTree, Node7from sqlint.parser import Token8from sqlint.parser.keywords import format as format_keyword9class Checker(metaclass=ABCMeta):10 @staticmethod11 @abstractmethod12 def check(tree: SyntaxTree, config: Config) -> List[Violation]:13 pass14class IndentStepsChecker(Checker):15 @staticmethod16 def check(tree: SyntaxTree, config: Config) -> List[Violation]:17 # TODO: Enable users to ignore violation cases by config.18 # Checks whether indent steps are N times.19 indent_steps = config.indent_steps20 return IndentStepsChecker._check(tree, indent_steps)21 @staticmethod22 def _check(tree: SyntaxTree, indent_steps: int) -> List[Violation]:23 violation_list: List[Violation] = list()24 for leaf in tree.leaves:25 if leaf.indent % indent_steps != 0:26 v = violation.IndentStepsViolation(27 tree=leaf,28 index=0,29 expected=indent_steps,30 actual=leaf.indent)31 violation_list.append(v)32 violation_list.extend(33 IndentStepsChecker._check(leaf, indent_steps))34 return violation_list35class KeywordStyleChecker(Checker):36 """Checks reserved keywords style.37 Whether reserved keywords match one of following formats.38 - lower: e.g) select39 - upper-all: e.g) SELECT40 - upper-head: e.g) Select41 """42 @staticmethod43 def check(tree: SyntaxTree, config: Config) -> List[Violation]:44 # TODO: Enable users to ignore violation cases by config.45 keyword_style = config.keyword_style46 return KeywordStyleChecker._check(tree, keyword_style)47 @staticmethod48 def _check(tree: SyntaxTree, keyword_style: str) -> List[Violation]:49 violation_list: List[Violation] = list()50 for leaf in tree.leaves:51 for idx, token in enumerate(leaf.tokens):52 if token.kind not in [Token.KEYWORD, Token.FUNCTION]:53 continue54 word: str = token.word55 expected: str = format_keyword(word, keyword_style)56 if word != expected:57 params = {'style': keyword_style, 'actual': word, 'expected': expected}58 v = violation.KeywordStyleViolation(59 tree=leaf,60 index=idx,61 **params)62 violation_list.append(v)63 violation_list.extend(64 KeywordStyleChecker._check(leaf, keyword_style))65 return violation_list66class CommaChecker(Checker):67 """ Checks violations about comma.68 1. Whether comma is head or end of a line.(default: head)69 """70 @staticmethod71 def check(tree: SyntaxTree, config: Config) -> List[Violation]:72 # TODO: Enable users to ignore violation cases by config.73 comma_position = config.comma_position74 result: List[Violation] = []75 # 1. Whether comma is head or end of a line.(default: head)76 result.extend(CommaChecker._check_position(tree, comma_position))77 return result78 @staticmethod79 def _check_position(tree: SyntaxTree, comma_position: str) -> List[Violation]:80 violation_list: List[Violation] = list()81 lb = Token('(', Token.BRACKET_LEFT)82 rb = Token(')', Token.BRACKET_RIGHT)83 for leaf in tree.leaves:84 # removes whitespaces and comments at head and end of line.85 ltripped_node: Node = leaf.node.ltrip_kind(Token.WHITESPACE, Token.COMMENT)86 lindex = len(leaf.node) - len(ltripped_node)87 tokens = ltripped_node.rtrip_kind(Token.WHITESPACE, Token.COMMENT).tokens88 comma_indexes = [i for i, x in enumerate(tokens) if x == ',']89 if comma_position == 'head':90 comma_indexes = [i for i in comma_indexes if i != 0]91 elif comma_position == 'end':92 comma_indexes = [i for i in comma_indexes if i != len(tokens)-1]93 for idx in comma_indexes:94 # If a comma is in brackets, it is appropriate not to break a line at the comma.95 # Determines that by counting left- and right- brackets at left-right-side.96 is_open_bracket = 0 < (tokens[0:idx].count(lb) - tokens[0:idx].count(rb))97 is_close_bracket = 0 < (tokens[idx+1:].count(rb) - tokens[idx+1:].count(lb))98 if not is_open_bracket or not is_close_bracket:99 violation_list.append(100 violation.CommaPositionViolation(101 tree=leaf,102 index=lindex+idx,103 comma_position=comma_position))104 violation_list.extend(105 CommaChecker._check_position(leaf, comma_position))106 return violation_list107class WhitespaceChecker(Checker):108 """ Checks violations about whitespace.109 1. Whether multiple whitespaces exist.110 2. Whether a Whitespace is after a comma and not before it.111 3. Whether a Whitespace is after a bracket and not before it.112 4. Whether a Whitespace is after a operator and not before it.113 """114 @staticmethod115 def check(tree: SyntaxTree, config: Config) -> List[Violation]:116 # TODO: Enable users to ignore violation cases by config.117 result: List[Violation] = []118 # 1. Whether comma is head or end of a line.(default: head)119 result.extend(WhitespaceChecker._check_multiple(tree))120 # 2. Whether a Whitespace is after a comma and not before it.121 result.extend(WhitespaceChecker._check_comma(tree))122 # 3. Whether a Whitespace is after and before bracket.123 result.extend(WhitespaceChecker._check_bracket(tree))124 # 4. Whether a Whitespace is after and before operator.125 result.extend(WhitespaceChecker._check_operator(tree))126 return result127 @staticmethod128 def _check_multiple(tree: SyntaxTree) -> List[Violation]:129 violation_list: List[Violation] = list()130 for leaf in tree.leaves:131 # ignores token at head of a line132 tokens = leaf.tokens[1:]133 for idx, tk in enumerate(tokens):134 length = len(tk)135 # ignores except whitespaces136 if tk.kind != tk.WHITESPACE:137 continue138 # 2 spaces before comment is valid139 if length == 2 and (idx+1 < len(tokens) and tokens[idx+1].kind == Token.COMMENT):140 continue141 if length > 1:142 v = violation.MultiSpacesViolation(tree=leaf, index=idx)143 violation_list.append(v)144 violation_list.extend(WhitespaceChecker._check_multiple(leaf))145 return violation_list146 @staticmethod147 def _check_comma(tree: SyntaxTree) -> List[Violation]:148 violation_list: List[Violation] = list()149 for leaf in tree.leaves:150 # Comma at end of line dose not need to checked151 for idx, token in enumerate(leaf.tokens[:-1]):152 if token.kind != Token.COMMA:153 continue154 # Checks that a whitespace does not exist before comma.155 # However, when comma is at head of line, it is allowed that whitespace is before.156 if idx >= 2 and leaf.tokens[idx-1].kind == Token.WHITESPACE:157 params = {'token': Token.COMMA,158 'position': 'before'}159 violation_list.append(160 violation.WhitespaceViolation(161 tree=leaf,162 index=idx,163 **params))164 # checks whether a whitespace exists after comma.165 if leaf.tokens[idx+1].kind != Token.WHITESPACE:166 params = {'token': Token.COMMA,167 'position': 'after',168 'target': f'{token.word}{leaf.tokens[idx+1].word}'}169 violation_list.append(170 violation.WhitespaceViolation(171 tree=leaf,172 index=idx,173 **params))174 violation_list.extend(175 WhitespaceChecker._check_comma(leaf))176 return violation_list177 @staticmethod178 def _check_bracket(tree: SyntaxTree) -> List[Violation]:179 violation_list: List[Violation] = list()180 for leaf in tree.leaves:181 # Comma at end of line dose not need to checked182 for idx, token in enumerate(leaf.tokens[:-1]):183 # Checks whether a whitespace does not exist after left-bracket "( ".184 if token.kind == Token.BRACKET_LEFT \185 and leaf.tokens[idx+1].kind == Token.WHITESPACE:186 params = {'token': Token.BRACKET_LEFT,187 'position': 'after',188 'target': f'{token.word}{leaf.tokens[idx+1].word}'}189 violation_list.append(190 violation.WhitespaceViolation(tree=leaf, index=idx, **params))191 # Checks whether a whitespace does not exist before right-bracket " )".192 if token.kind == Token.BRACKET_RIGHT \193 and (idx >= 2 and leaf.tokens[idx-1].kind == Token.WHITESPACE):194 params = {195 'token': Token.BRACKET_RIGHT,196 'position': 'before',197 'target': f'{leaf.tokens[idx-1].word}{token.word}'}198 violation_list.append(199 violation.WhitespaceViolation(200 tree=leaf,201 index=idx,202 **params))203 violation_list.extend(204 WhitespaceChecker._check_bracket(leaf))205 return violation_list206 @staticmethod207 def _check_operator(tree: SyntaxTree) -> List[Violation]:208 violation_list: List[Violation] = list()209 for leaf in tree.leaves:210 # Comma at end of line dose not need to checked211 for idx, token in enumerate(leaf.tokens[:-1]):212 if token.kind != Token.OPERATOR:213 continue214 # Checks whether a whitespace exists before operator.215 if idx >= 2 and leaf.tokens[idx-1].kind != Token.WHITESPACE:216 params = {217 'token': Token.OPERATOR,218 'position': 'before',219 'target': f'{leaf.tokens[idx-1].word}{token.word}'}220 violation_list.append(221 violation.WhitespaceViolation(tree=leaf, index=idx, **params))222 # Checks whether a whitespace exists after operator.223 if leaf.tokens[idx + 1].kind != Token.WHITESPACE:224 params = {225 'token': Token.OPERATOR,226 'position': 'after',227 'target': f'{token.word}{leaf.tokens[idx + 1].word}'}228 violation_list.append(229 violation.WhitespaceViolation(tree=leaf, index=idx, **params))230 violation_list.extend(231 WhitespaceChecker._check_operator(leaf))232 return violation_list233class JoinChecker(Checker):234 """ Checks violations about join context.235 1. Whether join context and table name are same line.236 2. Whether join contexts are described fully, for example [inner join], [left outer join], [right outer join]237 """238 @staticmethod239 def check(tree: SyntaxTree, config: Config) -> List[Violation]:240 # TODO: Enable users to ignore violation cases by config.241 result: List[Violation] = []242 # 1. Whether join context and table name are same line.243 result.extend(JoinChecker._check_table_existance(tree))244 # 2. Whether join contexts are described fully, for example [inner join], [left outer join], [right outer join]245 expected_kvs = {246 'LEFT': ['LEFT', 'OUTER', 'JOIN'],247 'RIGHT': ['RIGHT', 'OUTER', 'JOIN'],248 'FULL': ['FULL', 'OUTER', 'JOIN'],249 'OUTER': ['[LEFT|RIGHT|FULL]', 'OUTER', 'JOIN'],250 'INNER': ['INNER', 'JOIN'],251 'CROSS': ['CROSS', 'JOIN'],252 }253 expected_list = {}254 for k, vs in expected_kvs.items():255 _key = JoinChecker._format_str(k)256 _value = ' '.join([JoinChecker._format_str(v) for v in vs])257 expected_list[_key] = _value258 result.extend(JoinChecker._check_context(tree, expected_list))259 return result260 @staticmethod261 def _format_str(value: str) -> str:262 return value.upper()263 @staticmethod264 def _check_table_existance(tree: SyntaxTree) -> List[Violation]:265 """Checks the token next to 'Join' is identifier(maybe table_name) or SubQuery """266 violation_list: List[Violation] = list()267 for leaf in tree.leaves:268 for idx, token in enumerate(leaf.tokens):269 # ignores token except join270 if token.word.upper() != 'JOIN':271 continue272 # ignores the token next to 'JOIN' is identifier which may be table.273 if idx <= len(leaf.tokens)-2 and leaf.tokens[idx+2].kind == Token.IDENTIFIER:274 continue275 # TODO: Checks below276 # TODO: SubQueries will become violation in the future.277 """278 Ignores the token next to 'Join' is 'Select' (maybe SubQuery)279 Examples:280 1) ------281 From282 x283 Join Select id From y284 ------285 2) ------286 From287 x288 Join (Select id From y)289 ------290 """291 v = violation.JoinTableNotExistViolation(tree=leaf, index=idx)292 violation_list.append(v)293 violation_list.extend(JoinChecker._check_table_existance(leaf))294 return violation_list295 @staticmethod296 def _check_context(tree: SyntaxTree, expected_list: Dict[str, str]) -> List[Violation]:297 """Checks whether join are described fully, for example [inner join], [left outer join], [right outer join] """298 violation_list: List[Violation] = list()299 # TODO: too deeply nest and complex code300 for leaf in tree.leaves:301 join_indexes = [i for i, x in enumerate(leaf.tokens) if x.word.upper() == 'JOIN']302 for idx in join_indexes:303 token = leaf.tokens[idx]304 # concat keyword concerned with join305 join_contexts = [token.word]306 # only 'JOIN' is expected INNER JOIN307 expected: str = expected_list[JoinChecker._format_str('INNER')]308 for tk in reversed(leaf.tokens[:idx]):309 if tk.kind in [Token.WHITESPACE, Token.COMMENT]:310 continue311 word = JoinChecker._format_str(tk.word)312 if word in expected_list.keys():313 join_contexts.insert(0, tk.word)314 expected = expected_list[word]315 else:316 break317 join_context_str = JoinChecker._format_str(' '.join(join_contexts))318 if join_context_str not in expected_list.values():319 params = {'actual': join_context_str, 'expected': expected}320 v = violation.JoinContextOmitViolation(tree=leaf, index=idx, **params)321 violation_list.append(v)322 violation_list.extend(JoinChecker._check_context(leaf, expected_list))323 return violation_list324class LineChecker(Checker):325 """Checks violations about lines management.326 1. Checks whether two or more blank lines exist.327 2. Checks whether breaking line after specified keywords.328 Examples:329 --- Good ---330 Select331 x332 From333 y334 ------------335 ---- NG ----336 Select x From y337 ------------338 """339 @staticmethod340 def check(tree: SyntaxTree, config: Config) -> List[Violation]:341 result: List[Violation] = []342 # 1. Checks whether two or more blank lines exist.343 v_list, blank_count, last_tree = LineChecker._check_blank_line(tree, blank_count=0)344 if blank_count >= 2:345 v_list.append(violation.MultiBlankLineViolation(last_tree, index=0))346 result.extend(v_list)347 # 2. Checks whether breaking line after specified keywords.348 # TODO: Implement349 return result350 @staticmethod351 def _check_blank_line(tree: SyntaxTree, blank_count: int) -> Tuple[List[Violation], int, SyntaxTree]:352 violation_list: List[Violation] = []353 last_tree = tree354 for leaf in tree.leaves:355 count = len(leaf.node)356 is_blank = (count == 0)357 if count == 1 and leaf.tokens[0].kind == Token.WHITESPACE:358 violation_list.append(violation.OnlyWhitespaceViolation(tree=leaf, index=0))359 # If this line is not blank and 2 or more previous lines are blank, stack violation.360 if is_blank:361 blank_count += 1362 else:363 if blank_count >= 2:364 violation_list.append(violation.MultiBlankLineViolation(tree=leaf, index=0))365 blank_count = 0366 v_list, blank_count, last_tree = LineChecker._check_blank_line(leaf, blank_count)367 violation_list.extend(v_list)...
lenin_search_engine.py
Source:lenin_search_engine.py
...225 for f, positions in input_dict.items():226 for position in positions:227 context = Context.from_file(f, position, context_size)228 contexts_dict.setdefault(f, []).append(context)229 joined_contexts_dict = self.join_contexts(contexts_dict)230 return joined_contexts_dict231 def join_contexts(self, input_dict):232 """233 This method joins intersecting windows in a dictionary of files and234 context windows.235 Args:236 input_dict (dict): a dictionary of files and context windows of the237 following structure {file: [contexts]}238 Returns a dictionary of files and joined contexts {file: [contexts]}239 """240 contexts_dict = {}241 null = Context([], "", 0, 0)242 for f, contexts in input_dict.items():243 previous_context = null244 for context in contexts:245 if previous_context.isintersected(context):246 previous_context.join(context)247 else:248 if previous_context is not null:249 contexts_dict.setdefault(f, []).append(previous_context)250 previous_context = context251 contexts_dict.setdefault(f, []).append(previous_context)252 return contexts_dict253 def search_to_context(self, query, context_size=3):254 """255 Performs a search of a multiword query against the database. Returns256 a dictionary of files, that contain all the words of the query. If any257 of the words of the query is not in the database, no files will be258 found.259 The values in the dictionary are contexts of the found words joined260 if intersecting each other.261 Args:262 query (str): search query263 context_size (int): size of the context window264 Returns:265 Dictionary of files and contexts of all the words of the query266 in a given file in the format {filename: [contexts]}267 """268 positions_dict = self.multiword_search(query)269 context_dict = self.get_context_windows(positions_dict, context_size)270 return context_dict271 def search_to_sentence(self, query, context_size=3):272 """273 Performs a search of a multiword query against the database. Returns274 a dictionary of files, that contain all the words of the query. If any275 of the words of the query is not in the database, no files will be276 found.277 The values in the dictionary are contexts of the found words extended to278 the sentence boundaries and joined if intersecting each other.279 Args:280 query (str): search query281 context_size (int): size of the initial context window built for282 search results283 Returns:284 Dictionary of files and contexts of all the words of the query285 in a given file in the format {filename: [contexts]}286 """287 context_dict = self.search_to_context(query, context_size)288 for contexts in context_dict.values():289 for context in contexts:290 context.to_sentence()291 sentence_dict = self.join_contexts(context_dict)292 return sentence_dict293 def search_to_quote(self, query, context_size=3):294 """295 Performs a search of a multiword query against the database. Returns296 a dictionary of files, that contain all the words of the query. If any297 of the words of the query is not in the database, no files will be298 found.299 The values in the dictionary are quotes with found words surrounded by300 <b></b> HTML tags.301 Args:302 query (str): search query303 context_size (int): size of the initial context window built for304 search results305 Returns:...
cli.py
Source:cli.py
...60 except:61 return []62 if current_dic:63 return list(current_dic)64def join_contexts(curcontext):65 """66 This function will join the global context with the current context.67 It will overwrite any commands in the global context with any commands68 that are defined in the current context. I.e., so if you have a69 command that generally functions one way, you can define it in the70 global context to always behave that way. Then, you can over-ride it71 in one or more specific contexts which will over-ride that default72 global behavior. It will also merge the first layer of sub-commands,73 so if you have "show" in global and "show" in a given context, it74 will merge whatever subcommands are part of both contexts.75 :param curcontext: the current context that is selected76 :return: combined list of current commands77 """78 ctx_dict = {}79 sub_dict = {}80 ctx_join = context["global"][:]81 for c in range(0, len(ctx_join)):82 sub_list = ctx_join[c].get("subcommands", {})83 for s in range(0, len(sub_list)):84 sub_dict[sub_list[s]["command"]] = {"num": c}85 ctx_dict[ctx_join[c]["command"]] = {"num": c, "sub": sub_dict}86 for c in context[curcontext]:87 if c["command"] in ctx_dict:88 if "subcommands" in c:89 for sc in c["subcommands"]:90 if sc["command"] in ctx_dict[c["command"]]["sub"]:91 pass92 else:93 ctx_join[ctx_dict[c["command"]]["num"]]["subcommands"] += [sc]94 else:95 ctx_join[ctx_dict[c["command"]]["num"]] = c96 else:97 ctx_join.append(c)98 return ctx_join99def parse_input(strinput, curcontext, gethelp=False):100 """101 This function is designed to parse the currently typed input to102 determine what has been typed. It is called when the user103 presses ? or when they press Enter.104 :param strinput: Currently typed text at prompt105 :param contextchain: Full context chain the user is in106 :param gethelp: True if the user enters ?, otherwise False107 :return: String that will be printed to screen108 """109 modifiers = ["begin", "include", "exclude"]110 cmd_list = strinput.split(" ")111 temp_cmd = join_contexts(curcontext)112 add_modifiers = False113 mod_text = []114 sel_modifier = ""115 command_chain = []116 cur_commands = []117 out_help = []118 out_command = {}119 last_func = None120 leftovers = None121 if cmd_list[len(cmd_list) - 1] == "":122 showhelp = True123 else:124 showhelp = False125 for c in cmd_list:126 cur_commands = []127 for a in temp_cmd:128 if a["command"].find(c) == 0 and c != "":129 command_chain.append(a["command"])130 cur_commands.append(a["command"])131 out_command = a132 temp_cmd = a.get("subcommands", {})133 if a.get("function", None) is not None:134 last_func = a.get("function", None)135 leftovers = "".join(strinput.split(c)[-1:]).strip()136 if out_command == {} and not strinput == "":137 return "% Invalid input detected" # at '^' marker."138 if sel_modifier != "":139 mod_text.append(c)140 if add_modifiers:141 for m in modifiers:142 if m.find(c) == 0 and c != "":143 sel_modifier = m144 add_modifiers = False145 if c == "|":146 add_modifiers = True147 curcmd = ""148 for cc in command_chain:149 curcmd += cc + " "150 if gethelp:151 msg = ""152 if showhelp:153 if temp_cmd == {}:154 if sel_modifier != "":155 out_help.append(["", "LINE", "", "Regular Expression"])156 elif add_modifiers:157 out_help.append(["", "begin", "", "Begin with the line that matches"])158 out_help.append(["", "exclude", "", "Exclude lines that match"])159 out_help.append(["", "include", "", "Include lines that match"])160 else:161 out_help.append(["", "|", "", "Output modifiers"])162 out_help.append(["", "<cr>", "", ""])163 else:164 for x in temp_cmd:165 out_help.append(["", x["command"], "", x.get("help", "no help available")])166 msg += "?\n" + cli_command_exec.format_data(out_help)167 else:168 if add_modifiers:169 out_help.append("|")170 msg += "?\n" + " ".join(out_help) + "\n"171 elif sel_modifier != "":172 out_help.append(["", "LINE", "", "Search Text"])173 msg += "?\n" + cli_command_exec.format_data(out_help)174 else:175 for cc in cur_commands:176 out_help.append(cc)177 msg += "?\n" + " ".join(out_help) + "\n"178 return msg179 else:180 if temp_cmd != {}:181 if curcmd == "":182 return ""183 else:184 return '% Type "' + curcmd + '?" for a list of subcommands'185 else:186 if len(cur_commands) > 1:187 return "% Ambiguous command: " + strinput188 else:189 return {"command": out_command, "function": last_func, "context": curcontext, "remains": leftovers}190def add_filters(input, output):191 """192 This function is designed to filter output when using include,193 exclude, etc.194 :param input: Raw output string195 :param output: Raw output from command196 :return: Filtered string197 """198 if "|" in input:199 newout = ""200 incmd = input.split("|")[1].strip()201 filterlist = incmd.split(" ")202 outlist = output.split("\n")203 newout = outlist[0] + "\n"204 if filterlist[0] in ["i", "in", "inc", "incl", "inclu", "includ", "include"]:205 for o in outlist[1:]:206 if " ".join(filterlist[1:]).lower() in o.lower():207 newout += o + "\n"208 elif filterlist[0] in ["e", "ex", "exc", "excl", "exclu", "exclud", "exclude"]:209 for o in outlist[1:]:210 if " ".join(filterlist[1:]).lower() not in o.lower():211 newout += o + "\n"212 elif filterlist[0] in ["b", "be", "beg", "begi", "begin"]:213 foundbeg = False214 for o in outlist[1:]:215 if " ".join(filterlist[1:]).lower() in o.lower():216 foundbeg = True217 if foundbeg:218 newout += o + "\n"219 if newout[-2:] == "\n\n":220 return newout[0:-1]221 else:222 return newout223 return output224def main():225 curcontextdesc = "#"226 curcontext = "root"227 contextchain = [{"prompt": curcontextdesc, "contextname": curcontext, "elements": None, "selected": None, "selected_data": None}]228 bindings = KeyBindings()229 @bindings.add('?')230 def _(event):231 i = parse_input(session.app.current_buffer.text, contextchain[len(contextchain)-1]["contextname"], gethelp=True)232 print(i, end="")233 print("\n" + contextchain[len(contextchain)-1]["prompt"] + " " + session.app.current_buffer.text, end="")234 print('Welcome to the Meraki shell. Type help or ? to list commands.\n')235 session = PromptSession()236 while True:237 try:238 n = NestedCompleter(words_dic=join_contexts(contextchain[len(contextchain)-1]["contextname"]))239 text = session.prompt(contextchain[len(contextchain)-1]["prompt"] + " ", key_bindings=bindings, completer=n, complete_style=CompleteStyle.READLINE_LIKE)240 except KeyboardInterrupt: # Ctrl-C241 continue242 except EOFError: # Ctrl-D243 break244 else:245 pi = parse_input(text, contextchain[len(contextchain)-1]["contextname"])246 if pi != "":247 if isinstance(pi, dict) and pi["command"]:248 execfx = getattr(cli_command_exec, pi["function"])249 result, contextchain = execfx(pi, text, contextchain)250 if result != "":251 print(add_filters(text, result))252 if contextchain == []:...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!