def test_get_partial_action_raises_ValueError_if_extracted_completable_is_not_Action(
        completer: ActionCompleter, group: types.ActionGroup,
        fragments: List[str]):
    with patch("action_completer.completer.extract_context"
               ) as mocked_extract_context:
        mocked_extract_context.return_value = (None, None, group, fragments)

        with pytest.raises(ValueError):
            completer.get_partial_action("")
def test_run_action(completer: ActionCompleter, args: List[Any],
                    kwargs: Dict[str, Any]):
    with patch.object(completer,
                      "get_partial_action") as mocked_get_partial_action:
        mocked_get_partial_action.return_value = MagicMock()

        completer.run_action("", *args, **kwargs)
        mocked_get_partial_action.return_value.assert_called_with(
            *args, **kwargs)
def test_iter_group_completions(
    completer: ActionCompleter,
    group: types.ActionGroup,
    fragments: List[str],
    complete_event: CompleteEvent,
    start_position: int,
):
    with patch.object(
            completer, "_build_completion",
            wraps=completer._build_completion) as mock_build_completion:
        for completion in list(
                completer._iter_group_completions(
                    group,
                    fragments,
                    complete_event,
                    start_position=start_position)):
            assert isinstance(completion, Completion)
            assert completion.start_position == start_position

            for child in group.children.values():
                mock_build_completion.assert_called_with(
                    completable=child,
                    text="test",
                    start_position=start_position,
                )
def test_get_completion_style_returns_override_when_provided(
    completer: ActionCompleter,
    completable: types.ActionCompletable_T,
    text: str,
    default: str,
):
    assert completer._get_completion_style(completable, text,
                                           default) == default
def test_get_completion_display_meta_returns_override_when_provided(
    completer: ActionCompleter,
    completable: types.ActionCompletable_T,
    text: str,
    override: str,
):
    assert completer._get_completion_display_meta(completable, text,
                                                  override) == "test"
def test_iter_partial_action_parameters_applies_cast_if_present(
        completer: ActionCompleter, action: types.Action):
    assert all(
        isinstance(value, int)
        for value in completer._iter_partial_action_parameters(
            action,
            [param.source for param in action.params]  # type: ignore
        ))
def test_get_completion_display_meta_failed_override_falls_back_to_empty_string(
    completer: ActionCompleter,
    completable: types.ActionCompletable_T,
    text: str,
    override: types.LazyText_T,
):
    assert completer._get_completion_display_meta(completable, text,
                                                  override) == ""
def test_get_completions_does_not_yield_if_no_fragments_extracted(
        completer: ActionCompleter, complete_event: CompleteEvent):
    with patch("action_completer.completer.get_fragments"
               ) as mocked_get_fragments:
        mocked_get_fragments.return_value = []

        completions = completer.get_completions(Document(), complete_event)
        assert len(list(completions)) == 0
def test_iter_partial_action_parameters(completer: ActionCompleter,
                                        action: types.Action):
    targets = [param.source for param in action.params]  # type: ignore
    for source, target in zip(
            completer._iter_partial_action_parameters(action,
                                                      targets),  # type: ignore
            targets,
    ):
        assert source == target
def test_get_partial_action(completer: ActionCompleter, action: types.Action):
    with patch("action_completer.completer.extract_context"
               ) as mocked_extract_context:
        targets = [param.source for param in action.params]  # type: ignore
        mocked_extract_context.return_value = (None, None, action, targets)

        partial_action = completer.get_partial_action("")
        assert partial_action.func == utils.noop  # type: ignore
        assert partial_action.args == tuple(targets)  # type: ignore
def test_get_partial_action_defaults_to_noop_if_Action_missing_callable(
        completer: ActionCompleter, action: types.Action,
        fragments: List[str]):
    with patch("action_completer.completer.extract_context"
               ) as mocked_extract_context:
        mocked_extract_context.return_value = (None, None, action, fragments)

        partial_action = completer.get_partial_action("")
        assert partial_action.func == utils.noop  # type: ignore
def test_ActionCompleter_warns_if_root_contains_display_properties(
        lazy_string: types.LazyString_T, lazy_text: types.LazyText_T):
    for test_value, properties in zip(
        (lazy_string, lazy_text),
        (("style", "selected_style"), ("display", "display_meta")),
    ):
        for property_name in properties:
            with pytest.warns(UserWarning):
                ActionCompleter(
                    root=types.ActionGroup({}, **{property_name: test_value}))
def test_iter_action_completions_does_not_yield_if_no_completable_parameters_provided(
    completer: ActionCompleter,
    action: types.Action,
    fragments: List[str],
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = completer._iter_action_completions(
        action, fragments, complete_event, start_position=start_position)
    assert len(list(completions)) == 0
def test_get_completions_does_not_yield_if_no_completable_completion_iterator(
        completer: ActionCompleter, complete_event: CompleteEvent):
    with patch("action_completer.completer.extract_context"
               ) as mocked_extract_context:
        # fragments here must be a list of some string in order to skip the first early
        # return from the get_completions generator
        mocked_extract_context.return_value = (None, None, None, [""])

        completions = completer.get_completions(Document(), complete_event)
        assert len(list(completions)) == 0
def test_iter_action_completions(
    completer: ActionCompleter,
    action: types.Action,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = completer._iter_action_completions(
        action, [""], complete_event, start_position=start_position)
    assert len(list(completions)) > 0
    assert all(completion.start_position == start_position
               for completion in completions)
def test_iter_action_completions_does_not_yield_if_no_source_completion_iterator(
    completer: ActionCompleter,
    action: types.Action,
    fragments: List[str],
    complete_event: CompleteEvent,
    start_position: int,
):

    # XXX: this test is dependent that we don't ever attempt to complete for integers as
    # a parameter source in the future
    completions = completer._iter_action_completions(
        action, fragments, complete_event, start_position=start_position)
    assert len(list(completions)) == 0
def test_iter_group_completions_skips_inactive_sources(
    completer: ActionCompleter,
    group: types.ActionGroup,
    fragments: List[str],
    complete_event: CompleteEvent,
    start_position: int,
):
    assert (len(
        list(
            completer._iter_group_completions(
                group,
                fragments,
                complete_event,
                start_position=start_position))) == 0)
def test_iter_none_param_completions(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
    start_position: int,
):
    assert (len(
        list(
            completer._iter_none_param_completions(
                action,
                action_param,
                "test",
                complete_event,
                start_position=start_position,
            ))) == 0)
def test_iter_completer_param_completions(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
):

    completions = list(
        completer._iter_completer_param_completions(action, action_param,
                                                    "test", complete_event))
    assert len(completions) == 1

    first_completion, *_ = completions
    assert first_completion.text == "test"
    assert (isinstance(first_completion.start_position, int)
            and first_completion.start_position <= 0)
def test_iter_basic_param_completions_invalid_value(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    param_value: str,
    complete_event: CompleteEvent,
    start_position: int,
):
    assert (len(
        list(
            completer._iter_basic_param_completions(
                action,
                action_param,
                param_value,
                complete_event,
                start_position=start_position,
            ))) == 0)
def test_iter_none_param_completions_yields_if_display_or_display_meta_provided(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = list(
        completer._iter_none_param_completions(action,
                                               action_param,
                                               "test",
                                               complete_event,
                                               start_position=start_position))

    assert len(completions) == 1

    first_completion, *_ = completions
    assert first_completion.text == "test"
def test_iter_callable_param_completions(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = list(
        completer._iter_callable_param_completions(
            action,
            action_param,
            "fo",
            complete_event,
            start_position=start_position))
    assert len(completions) == 1

    first_completion, *_ = completions
    assert first_completion.text == "foo"
    assert first_completion.start_position == start_position
def test_iter_basic_param_completions(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = list(
        completer._iter_basic_param_completions(
            action,
            action_param,
            action_param.source,  # type: ignore
            complete_event,
            start_position=start_position,
        ))
    assert len(completions) == 1

    first_completion, *_ = completions
    assert first_completion.text == action_param.source
    assert first_completion.start_position == start_position
def test_get_completion(
    completer: ActionCompleter,
    completable: types.ActionCompletable_T,
    text: str,
    start_position: int,
):
    completion = completer._build_completion(completable,
                                             text,
                                             start_position=start_position)

    assert completion.text == text
    assert completion.start_position == start_position
    assert completion.style == "test style"
    assert completion.selected_style == "test selected_style"

    # XXX: Due to how prompt_toolkit's FormattedText has no clean method of extracting
    # the raw text from a FormattedText instance, we are JUST checking types here, not
    # content as I would like to
    assert isinstance(completion.display, (str, FormattedText))
    assert isinstance(completion.display_meta, (str, FormattedText))
def test_iter_iterable_param_completions(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = list(
        completer._iter_iterable_param_completions(
            action,
            action_param,
            "",
            complete_event,
            start_position=start_position))
    assert len(completions) == len(action_param.source)  # type: ignore

    for completion, source in zip(completions,
                                  action_param.source):  # type: ignore
        assert completion.text == source
        assert completion.start_position == start_position
def test_iter_iterable_param_completions_partial_text(
    completer: ActionCompleter,
    action: types.Action,
    action_param: types.ActionParam,
    param_value: str,
    complete_event: CompleteEvent,
    start_position: int,
):
    completions = list(
        completer._iter_iterable_param_completions(
            action,
            action_param,
            param_value,
            complete_event,
            start_position=start_position,
        ))
    assert len(completions) == 1

    first_completion, *_ = completions
    assert first_completion.text == "foo"
    assert first_completion.start_position == start_position
def test_get_validator(completer: ActionCompleter):
    validator = completer.get_validator()
    assert isinstance(validator, ActionValidator)
    assert validator.root == completer.root
def test_get_completion_style(completer: ActionCompleter,
                              completable: types.ActionCompletable_T,
                              text: str):
    assert completer._get_completion_style(completable, text) == "test"
def test_iter_partial_action_parameters_captures_trailing_fragments_if_capture_all(
        completer: ActionCompleter, action: types.Action,
        fragments: List[str]):
    action_parameters = completer._iter_partial_action_parameters(
        action, fragments)
    assert list(action_parameters) == fragments
def test_iter_partial_action_parameters_does_not_yield_for_empty_fragments(
        completer: ActionCompleter, action: types.Action,
        fragments: List[str]):
    action_parameters = completer._iter_partial_action_parameters(
        action, fragments)
    assert len(list(action_parameters)) == 0