def test_resolve_sequence_all_one_one(): # root = one_of('root', 'choice1', 'choice2') # path = ResolutionPath(root) # path = root.resolve(['root','invalid']) # # assert path.status == api.STATUS_UNSATISFIED # assert path.match_result.completions == [] root = node.CmdNode('ans').all_of([ node.CmdNode('play').one_of(['website.yml', 'appserver.yml']), node.CmdNode('list').one_of(['groups', 'hosts', 'playbooks']) ]) path = root.resolve(['ans', 'pl']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['play'] path = root.resolve(['ans', 'play']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['website.yml', 'appserver.yml'] path = root.resolve(['ans', 'play', 'website.yml']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['list'] path = root.resolve(['ans', 'play', 'website.yml', 'li']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['list'] path = root.resolve(['ans', 'play', 'website.yml', 'list']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['groups', 'hosts', 'playbooks'] path = root.resolve(['ans', 'play', 'website.yml', 'list', 'g']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == ['groups'] path = root.resolve(['ans', 'play', 'website.yml', 'list', 'groups']) assert path.status == api.STATUS_COMPLETED assert path.match_result.status == api.MATCH_FULL assert path.match_result.completions == []
def test_root_doesnt_resolve_if_children_cant_resolve(): root = node.CmdNode('root').one_of(['choice1', 'choice2']) path = root.resolve(['root', 'invalid']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == []
def test_full_and_fragment_siblings_same_prefix(): root = node.CmdNode('root').one_of(['prefix', 'prefix_and_suffix']) path = root.resolve(['root', 'prefix']) # The root is satisfied since child 'prefix' is completed by the input assert path.status == api.STATUS_SATISFIED # Even though root is satisfied completions from 'prefix_and_suffix' child should be offered assert path.match_result.completions == ['prefix_and_suffix']
def test_children_as_dir_listing(): root = node.CmdNode( 'filecmd', child_get_func=node.get_children_method_dir_listing('dsh/data')) path = root.resolve(['filecmd', 'schema.yml']) assert path.status == api.STATUS_COMPLETED path = root.resolve(['filecmd', 'schema']) assert path.status == api.STATUS_UNSATISFIED assert 'schema.yml' in path.match_result.completions
def test_resolve_sequence_hosts_duplicated(): # root = one_of('root', 'choice1', 'choice2') # path = ResolutionPath(root) # path = root.resolve(['root','invalid']) # # assert path.status == api.STATUS_UNSATISFIED # assert path.match_result.completions == [] root = node.CmdNode('ans') # root.one_of(child='arg1',choices='val1,val1') # root.all_of('val1,val1') # root.require('env') # root.option('--H') root.all_of([ node.CmdNode('play').one_of(['website.yml', 'appserver.yml']), node.CmdNode('list').all_of(['groups', 'hosts', 'playbooks']) ]) path = root.resolve(['ans', 'list', 'groups', 'playbooks']) assert path.match_result.completions == ['hosts']
def test_nested_containers(): root = node.node_container() root.all_of(['cmd_one', node.CmdNode('cmd_two').one_of(['opt1', 'opt2'])]) path = root.resolve(['cmd_one', 'cmd_two', 'opt1']) assert path.status == api.STATUS_COMPLETED assert path.match_result.completions == [] path = root.resolve(['cmd_one', 'cmd_two', 'op']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == ['opt1', 'opt2'] path = root.resolve(['cmd_two', 'op']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == ['opt1', 'opt2'] path = root.resolve(['cmd_two', 'opt1']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == ['cmd_one']
def test_node_options(): root = node.CmdNode( 'root', method_evaluate=evaluators.require_all_children).options( ['opt1', 'opt2']).add_child('cmd') path = root.resolve(['root']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == ['opt1', 'opt2', 'cmd'] path = root.resolve(['root', 'cmd']) assert path.status == api.STATUS_SATISFIED assert path.match_result.completions == ['opt1', 'opt2'] path = root.resolve(['root', 'opt1']) assert path.status == api.STATUS_UNSATISFIED assert path.match_result.completions == ['opt2', 'cmd'] # After the first option is supplied and then followed by a non-option # the second option should be presented as a completion path = root.resolve(['root', 'cmd', 'opt1']) assert path.status == api.STATUS_SATISFIED assert path.match_result.completions == ['opt2']
def node_factory_shell(name, ctx=None): def run_as_shell(snode, match_result, child_results): # If no child node results are available, then this node is assumed to be # at the end of the input and will execute as a interactive subcontext/shell matched_input = match_result.matched_input() if len(matched_input) == 1 and matched_input[ 0] == snode.name and not match_result.input_remainder(): # clone this node as a root node and run it cnode = node.node_root(snode.name, snode.context) for child in snode.get_children(): cnode.add_child(child) cnode.flange = snode.flange return shell.DevShell(cnode).run() # If there are children that returned a result, then just pass those on. # In this case this node is acting as a container if child_results: return child_results snode = node.CmdNode(name, context=ctx) snode.execute = lambda match_result, child_results: run_as_shell( snode, match_result, child_results) return snode
def test_match_string(): n = node.CmdNode('testcmd') assert_match_function_result_common( matchers.get_matcher_exact_string(n.name), n, n.name, get_standard_completions(n.name))
def node_factory_command(key, val, ctx={}, usage=None): """ handles "#/definitions/type_command" :param key: :param val: :param ctx: :return: """ # command can be specified by a simple string if isinstance(val, str): root = node.CmdNode(key, context=ctx, usage=usage, method_evaluate=evaluators.require_all_children) n = node.node_shell_command(key + "_cmdstr", val, ctx=ctx, return_output=False) n.match = matchers.match_always_consume_no_input root.add_child(n) return root # command can be a list of commands (nesting allowed) elif isinstance(val, list): root = node.CmdNode(key, context=ctx, usage=usage, method_evaluate=evaluators.require_all_children) # add child cmds for i, c in enumerate(val): cn = node_factory_command(key + '_' + str(i + 1), c, ctx=ctx) root.add_child(cn) # swallow completions cn.match = matchers.match_always_consume_no_input return root # command can be a dict with keys {do,help,env} elif isinstance(val, dict): root = node.CmdNode(key, context=ctx, method_evaluate=evaluators.require_all_children) newctx = ctx.copy() if 'vars' in val: newctx.update(val['vars']) try: cn = node_factory_command(key + '_do_dict', val['do'], ctx=newctx) root.add_child(cn) # swallow completions cn.match = matchers.match_always_consume_no_input # cn.evaluate = evaluators.require_all_children except Exception as e: # replace the root node with an error message echo root = node.node_display_message(key, str(e)) if 'on_failure' in val: print('adding failure node exe wrapper. cmd = {}'.format( val['on_failure'])) root.on_failure( node_factory_command(key + '_on_failure', val['on_failure'], ctx=newctx)) return root else: raise ValueError( "value of command {} must be a string, list, or dict. type is {}". format(key, type(val)))