def test_duplicate_keyword(self, func, exception):
        menu = {'command': 'test', 'function': func}
        mn = MenuNode(**menu)
        kwargs = [Kwarg('e', 'prompt'), Kwarg('e', 'prompt')]

        with pytest.raises(exception):
            mn._validate_function_args(kwargs)
    def test_no_function_no_matching_child(self):
        child = {'command': 'child', 'function': dummy}
        node = {'command': 'test', 'children': [child]}
        menu_node = MenuNode(**node)

        with pytest.raises(InvalidArgError):
            menu_node.process_arg('prompt')
    def test_get_menu_children_none(self):
        expected = {'test': None}

        node_1 = {'command': 'test', 'function': dummy, 'children': None}
        node_2 = {'command': 'test', 'function': dummy, 'children': []}

        assert MenuNode(**node_1).get_menu() == expected
        assert MenuNode(**node_2).get_menu() == expected
    def test_init_missing_kwargs(self):
        no_command = {'function': None, 'children': [1]}
        no_child = {'command': 'test', 'function': dummy}
        no_func = {'command': 'test', 'children': [no_child]}

        with pytest.raises(TypeError):
            MenuNode(**no_command)
        MenuNode(**no_func)
        MenuNode(**no_child)
    def test_init_children_mismatch_type(self):
        mismatch_1 = ['string', {'k': 'v'}]
        mismatch_2 = [NestedDict, 'string']
        node_1 = {'command': 'test', 'function': None, 'children': mismatch_1}
        node_2 = {'command': 'test', 'function': None, 'children': mismatch_2}

        with pytest.raises(TypeError):
            MenuNode(**node_1)
        with pytest.raises(TypeError):
            MenuNode(**node_2)
 def test_init_children_list_string_with_function_successful(self):
     node = {
         'command': 'test',
         'function': dummy,
         'children': ['prompt', 'menu']
     }
     MenuNode(**node)
    def test_get_menu_children_nested_dict(self):
        expected = {'test': self._nest}

        nested_dict = NestedDict(self._nest)
        node = {'command': 'test', 'function': dummy, 'children': nested_dict}

        assert MenuNode(**node).get_menu() == expected
 def test_init_children_list_string_no_function_raises(self):
     node = {
         'command': 'test',
         'function': None,
         'children': ['prompt', 'menu']
     }
     with pytest.raises(TypeError):
         MenuNode(**node)
    def test_get_menu_children_list_strings(self):
        expected = {'test': {'prompt', 'menu'}}
        node = {
            'command': 'test',
            'function': dummy,
            'children': ['prompt', 'menu']
        }

        assert MenuNode(**node).get_menu() == expected
    def test_init_duplicate_child_commands(self):
        child_1 = {'command': 'bob', 'function': dummy, 'children': None}
        child_2 = child_1
        node = {
            'command': 'test',
            'function': None,
            'children': [child_1, child_2]
        }

        with pytest.raises(TypeError):
            MenuNode(**node)
    def template_test(self, func, letters, number_args):
        args_packed = pack_args(letters, number_args)
        args, kwarg_objects = MenuNode._split_kwargs(args_packed)

        kwargs = {kw.key(): kw.value() for kw in kwarg_objects}
        print(kwargs)

        menu = {'command': 'test', 'function': func}
        mn = MenuNode(**menu)

        try:
            mn._function(*args, **kwargs)
        except TypeError:
            with pytest.raises(InvalidArgError):
                mn._validate_function_args(args_packed)
        else:
            # assert anything here?
            mn._validate_function_args(args_packed)
    def test_get_menu_children_list_nodes(self):
        expected = {'test': {'prompt': {'toolkit', 'menu'}, 'exit': None}}
        children = [{
            'command': 'prompt',
            'function': dummy,
            'children': ['toolkit', 'menu']
        }, {
            'command': 'exit',
            'function': dummy,
            'children': None
        }]
        node = {'command': 'test', 'function': None, 'children': children}

        assert MenuNode(**node).get_menu() == expected
 def test_init_children_list_dict_no_function_successful(self):
     child = {'command': 'bob', 'function': dummy, 'children': None}
     node = {'command': 'test', 'function': None, 'children': [child]}
     MenuNode(**node)
    def test_calls_function(self):
        node = {'command': 'test', 'function': lambda: 42}
        menu_node = MenuNode(**node)

        assert menu_node.process_arg('') == 42
 def test_init_children_nested_dict_with_function_successful(self):
     nested_dict = NestedDict(self._nest)
     node = {'command': 'test', 'function': dummy, 'children': nested_dict}
     MenuNode(**node)
 def test_init_children_nested_dict_no_function_raises(self):
     nested_dict = NestedDict(self._nest)
     node = {'command': 'test', 'function': None, 'children': nested_dict}
     with pytest.raises(TypeError):
         MenuNode(**node)
 def test_init_children_empty_list_with_function_successful(self):
     node = {'command': 'test', 'function': dummy, 'children': []}
     MenuNode(**node)
 def test_args_first(self):
     args = [1, 'test']
     kwargs = [Kwarg('test', 1), Kwarg('test', 2)]
     expected = (args, kwargs)
     assert MenuNode._split_kwargs([*args, *kwargs]) == expected
 def test_init_children_none_with_function_successful(self):
     node = {'command': 'test', 'function': dummy, 'children': None}
     MenuNode(**node)
    def test_calls_child_function(self):
        child = {'command': 'child', 'function': lambda: 42}
        node = {'command': 'test', 'children': [child]}
        menu_node = MenuNode(**node)

        assert menu_node.process_arg('child') == 42
 def test_empty(self):
     expected = ([], [])
     assert MenuNode._split_kwargs([]) == expected
 def test_only_args(self):
     args = [1, 'test']
     expected = (args, [])
     assert MenuNode._split_kwargs(args) == expected
    def test_kwargs_first(self):
        args = [1, 'test']
        kwargs = [Kwarg('test', 1), Kwarg('test', 2)]

        with pytest.raises(SyntaxError):
            MenuNode._split_kwargs([*kwargs, *args])
 def test_init_children_list_dict_with_function_raises(self):
     child = {'command': 'bob', 'function': dummy, 'children': None}
     node = {'command': 'test', 'function': dummy, 'children': [child]}
     with pytest.raises(TypeError):
         MenuNode(**node)
 def test_init_children_empty_list_no_function_raises(self):
     node = {'command': 'test', 'function': None, 'children': []}
     with pytest.raises(TypeError):
         MenuNode(**node)
 def test_mixed(self):
     li = [1, Kwarg('test', 1), 'test']
     with pytest.raises(SyntaxError):
         MenuNode._split_kwargs(li)
 def test_only_kwargs(self):
     kwargs = [Kwarg('test', 1), Kwarg('test', 2)]
     expected = ([], kwargs)
     assert MenuNode._split_kwargs(kwargs) == expected