0
0
Fork 0
mirror of https://github.com/ohmyzsh/ohmyzsh.git synced 2024-09-12 04:01:14 +02:00

fix(cli): fix edge cases in omz plugin disable command (#12401)

Also introduces tests, which will be refactored into the proper
place when a test system is finally designed.

Fixes #12400
This commit is contained in:
Marc Cornellà 2024-05-08 22:20:42 +02:00 committed by GitHub
parent 8c5f64cc2f
commit b0561d28b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 180 additions and 3 deletions

View file

@ -241,10 +241,18 @@ function _omz::plugin::disable {
# Remove plugins substitution awk script
local awk_subst_plugins="\
gsub(/[ \t]+(${(j:|:)dis_plugins})/, \"\") # with spaces before
gsub(/(${(j:|:)dis_plugins})[ \t]+/, \"\") # with spaces after
gsub(/\((${(j:|:)dis_plugins})\)/, \"\") # without spaces (only plugin)
gsub(/[ \t]+(${(j:|:)dis_plugins})[ \t]+/, \" \") # with spaces before or after
gsub(/[ \t]+(${(j:|:)dis_plugins})$/, \"\") # with spaces before and EOL
gsub(/^(${(j:|:)dis_plugins})[ \t]+/, \"\") # with BOL and spaces after
gsub(/\((${(j:|:)dis_plugins})[ \t]+/, \"(\") # with parenthesis before and spaces after
gsub(/[ \t]+(${(j:|:)dis_plugins})\)/, \")\") # with spaces before or parenthesis after
gsub(/\((${(j:|:)dis_plugins})\)/, \"()\") # with only parentheses
gsub(/^(${(j:|:)dis_plugins})\)/, \")\") # with BOL and closing parenthesis
gsub(/\((${(j:|:)dis_plugins})$/, \"(\") # with opening parenthesis and EOL
"
# Disable plugins awk script
local awk_script="
# if plugins=() is in oneline form, substitute disabled plugins and go to next line

169
lib/tests/cli.test.zsh Normal file
View file

@ -0,0 +1,169 @@
#!/usr/bin/zsh -df
run_awk() {
local -a dis_plugins=(${=1})
local input_text="$2"
(( ! DEBUG )) || set -xv
local awk_subst_plugins="\
gsub(/[ \t]+(${(j:|:)dis_plugins})[ \t]+/, \" \") # with spaces before or after
gsub(/[ \t]+(${(j:|:)dis_plugins})$/, \"\") # with spaces before and EOL
gsub(/^(${(j:|:)dis_plugins})[ \t]+/, \"\") # with BOL and spaces after
gsub(/\((${(j:|:)dis_plugins})[ \t]+/, \"(\") # with parenthesis before and spaces after
gsub(/[ \t]+(${(j:|:)dis_plugins})\)/, \")\") # with spaces before or parenthesis after
gsub(/\((${(j:|:)dis_plugins})\)/, \"()\") # with only parentheses
gsub(/^(${(j:|:)dis_plugins})\)/, \")\") # with BOL and closing parenthesis
gsub(/\((${(j:|:)dis_plugins})$/, \"(\") # with opening parenthesis and EOL
"
# Disable plugins awk script
local awk_script="
# if plugins=() is in oneline form, substitute disabled plugins and go to next line
/^[ \t]*plugins=\([^#]+\).*\$/ {
$awk_subst_plugins
print \$0
next
}
# if plugins=() is in multiline form, enable multi flag and disable plugins if they're there
/^[ \t]*plugins=\(/ {
multi=1
$awk_subst_plugins
print \$0
next
}
# if multi flag is enabled and we find a valid closing parenthesis, remove plugins and disable multi flag
multi == 1 && /^[^#]*\)/ {
multi=0
$awk_subst_plugins
print \$0
next
}
multi == 1 && length(\$0) > 0 {
$awk_subst_plugins
if (length(\$0) > 0) print \$0
next
}
{ print \$0 }
"
command awk "$awk_script" <<< "$input_text"
(( ! DEBUG )) || set +xv
}
# runs awk against stdin, checks if the resulting file is not empty and then checks if the file has valid zsh syntax
run_awk_and_test() {
local description="$1"
local plugins_to_disable="$2"
local input_text="$3"
local expected_output="$4"
local tmpfile==(:)
{
print -u2 "Test: $description"
DEBUG=0 run_awk "$plugins_to_disable" "$input_text" >| $tmpfile
if [[ ! -s "$tmpfile" ]]; then
print -u2 "\e[31mError\e[0m: output file empty"
return 1
fi
if ! zsh -n $tmpfile; then
print -u2 "\e[31mError\e[0m: zsh syntax error"
diff -u $tmpfile <(echo "$expected_output")
return 1
fi
if ! diff -u --color=always $tmpfile <(echo "$expected_output"); then
if (( DEBUG )); then
print -u2 ""
DEBUG=1 run_awk "$plugins_to_disable" "$input_text"
print -u2 ""
fi
print -u2 "\e[31mError\e[0m: output file does not match expected output"
return 1
fi
print -u2 "\e[32mSuccess\e[0m"
} always {
print -u2 ""
command rm -f "$tmpfile"
}
}
# These tests are for the `omz plugin disable` command
run_awk_and_test \
"it should delete a single plugin in oneline format" \
"git" \
"plugins=(git)" \
"plugins=()"
run_awk_and_test \
"it should delete a single plugin in multiline format" \
"github" \
"plugins=(
github
)" \
"plugins=(
)"
run_awk_and_test \
"it should delete multiple plugins in oneline format" \
"github git z" \
"plugins=(github git z)" \
"plugins=()"
run_awk_and_test \
"it should delete multiple plugins in multiline format" \
"github git z" \
"plugins=(
github
git
z
)" \
"plugins=(
)"
run_awk_and_test \
"it should delete a single plugin among multiple in oneline format" \
"git" \
"plugins=(github git z)" \
"plugins=(github z)"
run_awk_and_test \
"it should delete a single plugin among multiple in multiline format" \
"git" \
"plugins=(
github
git
z
)" \
"plugins=(
github
z
)"
run_awk_and_test \
"it should delete multiple plugins in mixed format" \
"git z" \
"plugins=(github
git z)" \
"plugins=(github
)"
run_awk_and_test \
"it should delete multiple plugins in mixed format 2" \
"github z" \
"plugins=(github
git
z)" \
"plugins=(
git
)"