Skip to content

Commit

Permalink
Rewrite completions to work with click>=8
Browse files Browse the repository at this point in the history
They changed the api and the were still calling the functions using
the old api style.

Sadly, the new api doesnt make it easy to test. I have tried for a while
but couldnt get anywhere, so now I tested it manually.
  • Loading branch information
voidus authored and teutat3s committed Nov 25, 2024
1 parent 0669f8b commit 2bc47b2
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 270 deletions.
4 changes: 2 additions & 2 deletions scripts/create-completion-script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ case $1 in
exit 0
;;
bash)
src_command="source"
src_command="bash_source"
target_file="watson.completion"
;;
zsh)
src_command="source_zsh"
src_command="zsh_source"
target_file="watson.zsh-completion"
;;
*)
Expand Down
146 changes: 4 additions & 142 deletions tests/test_autocompletion.py
Original file line number Diff line number Diff line change
@@ -1,148 +1,10 @@
"""Unit tests for the 'autocompletion' module."""

import json
from argparse import Namespace

import pytest

from watson.autocompletion import (
get_frames,
get_project_or_task_completion,
get_projects,
get_rename_name,
get_rename_types,
get_tags,
)

from . import TEST_FIXTURE_DIR


AUTOCOMPLETION_FRAMES_PATH = TEST_FIXTURE_DIR / "autocompletion"
with open(str(AUTOCOMPLETION_FRAMES_PATH / "frames")) as fh:
N_FRAMES = len(json.load(fh))
N_PROJECTS = 5
N_TASKS = 3
N_VARIATIONS_OF_PROJECT3 = 2
N_FRAME_IDS_FOR_PREFIX = 2

ClickContext = Namespace


@pytest.mark.datafiles(AUTOCOMPLETION_FRAMES_PATH)
@pytest.mark.parametrize(
"func_to_test, rename_type, args",
[
(get_frames, None, []),
(get_project_or_task_completion, None, ["project1", "+tag1"]),
(get_project_or_task_completion, None, []),
(get_projects, None, []),
(get_rename_name, "project", []),
(get_rename_name, "tag", []),
(get_rename_types, None, []),
(get_tags, None, []),
],
)
def test_if_returned_values_are_distinct(
watson_df, func_to_test, rename_type, args
):
ctx = ClickContext(obj=watson_df, params={"rename_type": rename_type})
prefix = ""
ret_list = list(func_to_test(ctx, args, prefix))
assert sorted(ret_list) == sorted(set(ret_list))


@pytest.mark.datafiles(AUTOCOMPLETION_FRAMES_PATH)
@pytest.mark.parametrize(
"func_to_test, n_expected_returns, rename_type, args",
[
(get_frames, N_FRAMES, None, []),
(get_project_or_task_completion, N_TASKS, None, ["project1", "+"]),
(get_project_or_task_completion, N_PROJECTS, None, []),
(get_projects, N_PROJECTS, None, []),
(get_rename_name, N_PROJECTS, "project", []),
(get_rename_name, N_TASKS, "tag", []),
(get_rename_types, 2, None, []),
(get_tags, N_TASKS, None, []),
],
)
def test_if_empty_prefix_returns_everything(
watson_df, func_to_test, n_expected_returns, rename_type, args
):
prefix = ""
ctx = ClickContext(obj=watson_df, params={"rename_type": rename_type})
completed_vals = set(func_to_test(ctx, args, prefix))
assert len(completed_vals) == n_expected_returns


@pytest.mark.datafiles(AUTOCOMPLETION_FRAMES_PATH)
@pytest.mark.parametrize(
"func_to_test, rename_type, args",
[
(get_frames, None, []),
(get_project_or_task_completion, None, ["project1", "+"]),
(get_project_or_task_completion, None, ["project1", "+tag1", "+"]),
(get_project_or_task_completion, None, []),
(get_projects, None, []),
(get_rename_name, "project", []),
(get_rename_name, "tag", []),
(get_rename_types, None, []),
(get_tags, None, []),
],
)
def test_completion_of_nonexisting_prefix(
watson_df, func_to_test, rename_type, args
):
ctx = ClickContext(obj=watson_df, params={"rename_type": rename_type})
prefix = "NOT-EXISTING-PREFIX"
ret_list = list(func_to_test(ctx, args, prefix))
assert not ret_list


@pytest.mark.datafiles(AUTOCOMPLETION_FRAMES_PATH)
@pytest.mark.parametrize(
"func_to_test, prefix, n_expected_vals, rename_type, args",
[
(get_frames, "f4f7", N_FRAME_IDS_FOR_PREFIX, None, []),
(
get_project_or_task_completion,
"+tag",
N_TASKS,
None,
["project1", "+tag3"],
),
(get_project_or_task_completion, "+tag", N_TASKS, None, ["project1"]),
(
get_project_or_task_completion,
"project3",
N_VARIATIONS_OF_PROJECT3,
None,
[],
),
(get_projects, "project3", N_VARIATIONS_OF_PROJECT3, None, []),
(get_rename_name, "project3", N_VARIATIONS_OF_PROJECT3, "project", []),
(get_rename_name, "tag", N_TASKS, "tag", []),
(get_rename_types, "ta", 1, None, []),
(get_tags, "tag", N_TASKS, None, []),
],
)
def test_completion_of_existing_prefix(
watson_df, func_to_test, prefix, n_expected_vals, rename_type, args
):
ctx = ClickContext(obj=watson_df, params={"rename_type": rename_type})
ret_set = set(func_to_test(ctx, args, prefix))
assert len(ret_set) == n_expected_vals
assert all(cur_elem.startswith(prefix) for cur_elem in ret_set)


@pytest.mark.datafiles(AUTOCOMPLETION_FRAMES_PATH)
@pytest.mark.parametrize(
"func_to_test, prefix, expected_vals",
[
(get_rename_types, "", ["project", "tag"]),
(get_rename_types, "t", ["tag"]),
(get_rename_types, "p", ["project"]),
],
)
def test_for_known_completion_values(func_to_test, prefix, expected_vals):
ret_list = list(func_to_test(None, [], prefix))
assert ret_list == expected_vals
def test_completion():
pytest.xfail(
"There's no good way to test this since click8, see https://github.com/pallets/click/issues/1453"
)
38 changes: 23 additions & 15 deletions watson.completion
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
_watson_completion() {
local IFS=$'
'
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_WATSON_COMPLETE=complete $1 ) )
local IFS=$'\n'
local response

response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _WATSON_COMPLETE=bash_complete $1)

for completion in $response; do
IFS=',' read type value <<< "$completion"

if [[ $type == 'dir' ]]; then
COMPREPLY=()
compopt -o dirnames
elif [[ $type == 'file' ]]; then
COMPREPLY=()
compopt -o default
elif [[ $type == 'plain' ]]; then
COMPREPLY+=($value)
fi
done

return 0
}

_watson_completionetup() {
local COMPLETION_OPTIONS=""
local BASH_VERSION_ARR=(${BASH_VERSION//./ })
# Only BASH version 4.4 and later have the nosort option.
if [ ${BASH_VERSION_ARR[0]} -gt 4 ] || ([ ${BASH_VERSION_ARR[0]} -eq 4 ] && [ ${BASH_VERSION_ARR[1]} -ge 4 ]); then
COMPLETION_OPTIONS="-o nosort"
fi

complete $COMPLETION_OPTIONS -F _watson_completion watson
_watson_completion_setup() {
complete -o nosort -F _watson_completion watson
}

_watson_completionetup;
_watson_completion_setup;

25 changes: 14 additions & 11 deletions watson.zsh-completion
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ _watson_completion() {
local -a response
(( ! $+commands[watson] )) && return 1

response=("${(@f)$( env COMP_WORDS="${words[*]}" \
COMP_CWORD=$((CURRENT-1)) \
_WATSON_COMPLETE="complete_zsh" \
watson )}")
response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _WATSON_COMPLETE=zsh_complete watson)}")

for key descr in ${(kv)response}; do
if [[ "$descr" == "_" ]]; then
completions+=("$key")
else
completions_with_descriptions+=("$key":"$descr")
fi
for type key descr in ${response}; do
if [[ "$type" == "plain" ]]; then
if [[ "$descr" == "_" ]]; then
completions+=("$key")
else
completions_with_descriptions+=("$key":"$descr")
fi
elif [[ "$type" == "dir" ]]; then
_path_files -/
elif [[ "$type" == "file" ]]; then
_path_files -f
fi
done

if [ -n "$completions_with_descriptions" ]; then
Expand All @@ -26,7 +29,7 @@ _watson_completion() {
if [ -n "$completions" ]; then
compadd -U -V unsorted -a completions
fi
compstate[insert]="automenu"
}

compdef _watson_completion watson;

Loading

0 comments on commit 2bc47b2

Please sign in to comment.