mirror of
https://github.com/denisidoro/navi
synced 2024-11-24 20:43:06 +00:00
parent
2753e84ea6
commit
c4e9c7a90a
16 changed files with 338 additions and 75 deletions
|
@ -58,4 +58,7 @@ git clean -dxf
|
|||
# Sign all commits in a branch based on master
|
||||
git rebase master -S -f
|
||||
|
||||
# See all open pull requests of a user on Github
|
||||
url::open 'https://github.com/pulls?&q=author:<user>+is:open+is:pr'
|
||||
|
||||
$ branch: git branch | awk '{print $NF}'
|
||||
|
|
3
navi
3
navi
|
@ -36,6 +36,7 @@ source "${SCRIPT_DIR}/src/main.sh"
|
|||
##? Please refer to the README at https://github.com/denisidoro/navi
|
||||
|
||||
VERSION="0.8.1"
|
||||
opts::eval "$@"
|
||||
|
||||
OPTIONS="$(opts::eval "$@")"
|
||||
export NAVI_PATH="$(dict::get "$OPTIONS" path)"
|
||||
main "$@"
|
||||
|
|
|
@ -4,8 +4,8 @@ set -euo pipefail
|
|||
export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
script() {
|
||||
echo "#!/usr/bin/env bash"
|
||||
echo "${SCRIPT_DIR}/navi" '"$@"'
|
||||
echo "#!/usr/bin/env bash"
|
||||
echo "${SCRIPT_DIR}/navi" '"$@"'
|
||||
}
|
||||
|
||||
BIN="/usr/local/bin/navi"
|
||||
|
|
|
@ -3,6 +3,10 @@ set -euo pipefail
|
|||
|
||||
export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
|
||||
# please refer to https://github.com/denisidoro/dotfiles/blob/master/scripts/code/beautify
|
||||
|
||||
cd "${SCRIPT_DIR}"
|
||||
find . -iname '*.sh' | xargs -I% dot code beautify %
|
||||
find scripts/* | xargs -I% dot code beautify %
|
||||
dot code beautify "${SCRIPT_DIR}/test/run"
|
||||
dot code beautify "${SCRIPT_DIR}/navi"
|
||||
|
|
|
@ -5,21 +5,21 @@ export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|||
source "${SCRIPT_DIR}/src/main.sh"
|
||||
|
||||
sha256() {
|
||||
if command_exists sha256sum; then
|
||||
sha256sum
|
||||
elif command_exists shasum; then
|
||||
shasum -a 256
|
||||
elif command_exists openssl; then
|
||||
openssl dgst -sha256
|
||||
else
|
||||
echoerr "Unable to calculate sha256!"
|
||||
exit 43
|
||||
fi
|
||||
if command_exists sha256sum; then
|
||||
sha256sum
|
||||
elif command_exists shasum; then
|
||||
shasum -a 256
|
||||
elif command_exists openssl; then
|
||||
openssl dgst -sha256
|
||||
else
|
||||
echoerr "Unable to calculate sha256!"
|
||||
exit 43
|
||||
fi
|
||||
}
|
||||
|
||||
header() {
|
||||
echo "$*"
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
}
|
||||
|
||||
cd "$SCRIPT_DIR"
|
||||
|
|
30
src/arg.sh
30
src/arg.sh
|
@ -1,13 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
ARG_REGEX="<[0-9a-zA-Z_]+>"
|
||||
ARG_DELIMITER="£"
|
||||
|
||||
arg::fn() {
|
||||
awk -F'---' '{print $1}'
|
||||
}
|
||||
arg::dict() {
|
||||
local -r fn="$(awk -F'---' '{print $1}')"
|
||||
local -r opts="$(awk -F'---' '{print $2}')"
|
||||
|
||||
arg::opts() {
|
||||
awk -F'---' '{print $2}'
|
||||
dict::new fn "$fn" opts "$opts"
|
||||
}
|
||||
|
||||
arg::interpolate() {
|
||||
|
@ -19,21 +19,35 @@ arg::interpolate() {
|
|||
|
||||
arg::next() {
|
||||
grep -Eo "$ARG_REGEX" \
|
||||
| xargs \
|
||||
| head -n1 \
|
||||
| tr -d '<' \
|
||||
| tr -d '>'
|
||||
}
|
||||
|
||||
arg::deserialize() {
|
||||
local -r arg="$1"
|
||||
|
||||
if [ ${arg:0:1} = "'" ]; then
|
||||
local -r out="$(echo "${arg:1:${#arg}-2}")"
|
||||
else
|
||||
local -r out="$arg"
|
||||
fi
|
||||
|
||||
echo "$out" | sed "s/${ARG_DELIMITER}/ /g"
|
||||
}
|
||||
|
||||
# TODO: separation of concerns
|
||||
arg::pick() {
|
||||
local -r arg="$1"
|
||||
local -r cheat="$2"
|
||||
|
||||
local -r prefix="$ ${arg}:"
|
||||
local -r length="$(echo "$prefix" | str::length)"
|
||||
local -r arg_description="$(grep "$prefix" "$cheat" | str::sub $((length + 1)))"
|
||||
local -r arg_dict="$(grep "$prefix" "$cheat" | str::sub $((length + 1)) | arg::dict)"
|
||||
|
||||
local -r fn="$(echo "$arg_description" | arg::fn)"
|
||||
local -r args_str="$(echo "$arg_description" | arg::opts | tr ' ' '\n' || echo "")"
|
||||
local -r fn="$(dict::get "$arg_dict" fn)"
|
||||
local -r args_str="$(dict::get "$arg_dict" opts | tr ' ' '\n' || echo "")"
|
||||
local arg_name=""
|
||||
|
||||
for arg_str in $args_str; do
|
||||
|
|
|
@ -24,7 +24,7 @@ cheat::from_selection() {
|
|||
local -r cheats="$1"
|
||||
local -r selection="$2"
|
||||
|
||||
local -r tags="$(echo "$selection" | selection::tags)"
|
||||
local -r tags="$(dict::get "$selection" tags)"
|
||||
|
||||
for cheat in $cheats; do
|
||||
if grep -q "% $tags" "$cheat"; then
|
||||
|
|
110
src/dict.sh
Normal file
110
src/dict.sh
Normal file
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
DICT_DELIMITER='\f'
|
||||
|
||||
dict::_post() {
|
||||
sed -E 's/; /\\n/g' | awk 'NF > 0' | dict::_unescape_value | sort
|
||||
}
|
||||
|
||||
dict::new() {
|
||||
if [ $# = 0 ]; then
|
||||
echo ""
|
||||
else
|
||||
echo "" | dict::assoc "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
dict::dissoc() {
|
||||
local -r key="$1"
|
||||
|
||||
grep -Ev "^${key}[^:]*:" | dict::_post
|
||||
}
|
||||
|
||||
dict::_escape_value() {
|
||||
tr '\n' "$DICT_DELIMITER"
|
||||
}
|
||||
|
||||
dict::_unescape_value() {
|
||||
tr "$DICT_DELIMITER" '\n'
|
||||
}
|
||||
|
||||
dict::assoc() {
|
||||
local -r key="${1:-}"
|
||||
local -r value="$(echo "${2:-}" | dict::_escape_value)"
|
||||
local -r input="$(cat)"
|
||||
|
||||
if [ -z $key ]; then
|
||||
printf "$input" | dict::_post
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$input" ]; then
|
||||
local -r base="$(printf "$input" | dict::dissoc "$key"); "
|
||||
else
|
||||
local -r base=""
|
||||
fi
|
||||
|
||||
shift 2
|
||||
printf "${base}${key}: ${value}" | dict::_post | dict::assoc "$@" | dict::_post
|
||||
}
|
||||
|
||||
dict::get() {
|
||||
if [ $# = 1 ]; then
|
||||
local -r input="$(cat)"
|
||||
local -r key="$1"
|
||||
else
|
||||
local -r input="$1"
|
||||
local -r key="$2"
|
||||
fi
|
||||
|
||||
local -r prefix="${key}[^:]*: "
|
||||
local -r result="$(echo "$input" | grep -E "^${prefix}")"
|
||||
local -r matches="$(echo "$result" | wc -l || echo 0)"
|
||||
|
||||
if [ $matches -gt 1 ]; then
|
||||
echo "$result" | dict::_unescape_value
|
||||
else
|
||||
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value
|
||||
fi
|
||||
}
|
||||
|
||||
dict::keys() {
|
||||
grep -Eo '^[^:]+: ' | sed 's/: //g'
|
||||
}
|
||||
|
||||
dict::values() {
|
||||
awk -F':' '{$1=""; print $0}' | cut -c3-
|
||||
}
|
||||
|
||||
dict::zipmap() {
|
||||
IFS='\n'
|
||||
|
||||
local -r keys_str="$1"
|
||||
local -r values_str="$2"
|
||||
|
||||
keys=()
|
||||
values=()
|
||||
for key in $keys_str; do
|
||||
keys+=("$key")
|
||||
done
|
||||
for value in $values_str; do
|
||||
values+=("$value")
|
||||
done
|
||||
|
||||
for ((i=0; i<${#keys[@]}; ++i)); do
|
||||
if [ -n "${keys[i]}" ]; then
|
||||
echo "${keys[i]}: ${values[i]}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
dict::update() {
|
||||
local -r key="$1"
|
||||
local -r fn="$2"
|
||||
local -r input="$(cat)"
|
||||
|
||||
local -r value="$(echo "$input" | dict::get "$key")"
|
||||
local -r updated_value="$(eval "$fn" "$value")"
|
||||
|
||||
echo "$input" | dict::assoc "$key" "$updated_value"
|
||||
}
|
32
src/main.sh
32
src/main.sh
|
@ -2,6 +2,7 @@
|
|||
|
||||
source "${SCRIPT_DIR}/src/arg.sh"
|
||||
source "${SCRIPT_DIR}/src/cheat.sh"
|
||||
source "${SCRIPT_DIR}/src/dict.sh"
|
||||
source "${SCRIPT_DIR}/src/health.sh"
|
||||
source "${SCRIPT_DIR}/src/misc.sh"
|
||||
source "${SCRIPT_DIR}/src/opts.sh"
|
||||
|
@ -14,8 +15,11 @@ handler::main() {
|
|||
local -r cheats="$(cheat::find)"
|
||||
local -r selection="$(ui::select "$cheats")"
|
||||
local -r cheat="$(cheat::from_selection "$cheats" "$selection")"
|
||||
|
||||
[ -z "$cheat" ] && exit 67
|
||||
local cmd="$(selection::command "$selection" "$cheat")"
|
||||
|
||||
local -r interpolation="$(dict::get "$OPTIONS" interpolation)"
|
||||
local cmd="$(selection::cmd "$selection" "$cheat")"
|
||||
local arg value
|
||||
|
||||
while $interpolation; do
|
||||
|
@ -36,6 +40,7 @@ handler::main() {
|
|||
|
||||
local -r unresolved_arg="$(echo "$cmd" | arg::next || echo "")"
|
||||
|
||||
local -r print="$(dict::get "$OPTIONS" print)"
|
||||
if $print || [ -n "$unresolved_arg" ]; then
|
||||
echo "$cmd"
|
||||
else
|
||||
|
@ -44,26 +49,37 @@ handler::main() {
|
|||
}
|
||||
|
||||
handler::preview() {
|
||||
local -r selection="$(echo "$query" | selection::standardize)"
|
||||
local -r query="$1"
|
||||
local -r selection="$(echo "$query" | selection::dict)"
|
||||
local -r cheats="$(cheat::find)"
|
||||
local -r cheat="$(cheat::from_selection "$cheats" "$selection")"
|
||||
[ -n "$cheat" ] && selection::command "$selection" "$cheat"
|
||||
[ -n "$cheat" ] && selection::cmd "$selection" "$cheat"
|
||||
}
|
||||
|
||||
handler::text() {
|
||||
dict::get "$OPTIONS" text
|
||||
ui::clear_previous_line
|
||||
}
|
||||
|
||||
main() {
|
||||
case ${entry_point:-} in
|
||||
case "$(dict::get "$OPTIONS" entry_point)" in
|
||||
preview)
|
||||
handler::preview "$@" \
|
||||
|| echo "Unable to find command for '${query:-}'"
|
||||
local -r query="$(dict::get "$OPTIONS" query)"
|
||||
handler::preview "$query" \
|
||||
|| echo "Unable to find command for '$query'"
|
||||
;;
|
||||
search)
|
||||
health::fzf
|
||||
local -r query="$(dict::get "$OPTIONS" query)"
|
||||
search::save "$query" || true
|
||||
handler::main "$@"
|
||||
handler::main
|
||||
;;
|
||||
text)
|
||||
handler::text
|
||||
;;
|
||||
*)
|
||||
health::fzf
|
||||
handler::main "$@"
|
||||
handler::main
|
||||
;;
|
||||
esac
|
||||
}
|
12
src/misc.sh
12
src/misc.sh
|
@ -12,3 +12,15 @@ command_exists() {
|
|||
echoerr() {
|
||||
echo "$@" 1>&2
|
||||
}
|
||||
|
||||
url::open() {
|
||||
if command_exists xdg-open; then
|
||||
xdg-open "$@"
|
||||
elif command_exists open; then
|
||||
open "$@"
|
||||
elif command_exists google-chrome; then
|
||||
google-chrome "$@"
|
||||
elif command_exists firefox; then
|
||||
firefox "$@"
|
||||
fi
|
||||
}
|
36
src/opts.sh
36
src/opts.sh
|
@ -6,37 +6,27 @@ opts::extract_help() {
|
|||
grep "^##?" "$file" | cut -c 5-
|
||||
}
|
||||
|
||||
opts::preview_hack() {
|
||||
local -r arg="$1"
|
||||
|
||||
if [ ${arg:0:1} = "'" ]; then
|
||||
echo "${arg:1:${#arg}-2}"
|
||||
else
|
||||
echo "$arg"
|
||||
fi
|
||||
}
|
||||
|
||||
opts::eval() {
|
||||
local wait_for=""
|
||||
|
||||
entry_point="main"
|
||||
print=false
|
||||
interpolation=true
|
||||
preview=true
|
||||
local entry_point="main"
|
||||
local print=false
|
||||
local interpolation=true
|
||||
local preview=true
|
||||
local path="${NAVI_PATH:-${NAVI_DIR:-${SCRIPT_DIR}/cheats}}"
|
||||
|
||||
for arg in "$@"; do
|
||||
case $wait_for in
|
||||
path) NAVI_PATH="$arg"; wait_for="" ;;
|
||||
preview) query="$(opts::preview_hack "$arg" | tr "^" " ")"; wait_for=""; break ;;
|
||||
search) query="$arg"; wait_for=""; export NAVI_PATH="${NAVI_PATH}:$(search::full_path "$query")"; ;;
|
||||
path) path="$arg"; wait_for="" ;;
|
||||
preview) query="$(arg::deserialize "$arg")"; wait_for="" ;;
|
||||
search) query="$arg"; wait_for=""; path="${path}:$(search::full_path "$query")"; ;;
|
||||
query) query="$arg"; wait_for="" ;;
|
||||
esac
|
||||
|
||||
case $arg in
|
||||
--print) print=true ;;
|
||||
--no-interpolation) interpolation=false ;;
|
||||
--version) echo "${VERSION:-unknown}" && exit 0 ;;
|
||||
help|--help) opts::extract_help "$0" && exit 0 ;;
|
||||
--version) dict::new entry_point "text" text "${VERSION:-unknown}" && exit 0 ;;
|
||||
help|--help) dict::new entry_point "text" text "$(opts::extract_help "$0")" && exit 0 ;;
|
||||
--command-for) wait_for="command-for" ;;
|
||||
--no-preview) preview=false ;;
|
||||
--path) wait_for="path" ;;
|
||||
|
@ -45,10 +35,6 @@ opts::eval() {
|
|||
q|query) wait_for="query" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
opts::fallback_path() {
|
||||
echo "${NAVI_DIR:-${SCRIPT_DIR}/cheats}"
|
||||
dict::new entry_point "$entry_point" print "$print" interpolation "$interpolation" preview "$preview" query "${query:-}" path "$path"
|
||||
}
|
||||
|
||||
export NAVI_PATH="${NAVI_PATH:-$(opts::fallback_path)}"
|
|
@ -1,31 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
selection::standardize() {
|
||||
selection::dict() {
|
||||
local -r str="$(cat)"
|
||||
|
||||
local -r tags="$(echo "$str" | awk -F'[' '{print $NF}' | tr -d ']')"
|
||||
local -r core="$(echo "$str" | sed -e "s/ \[${tags}\]$//")"
|
||||
|
||||
echo "${core}^${tags}"
|
||||
}
|
||||
|
||||
selection::core() {
|
||||
cut -d'^' -f1
|
||||
}
|
||||
|
||||
selection::tags() {
|
||||
cut -d'^' -f2
|
||||
dict::new core "$core" tags "$tags"
|
||||
}
|
||||
|
||||
selection::core_is_comment() {
|
||||
grep -qE '^#'
|
||||
}
|
||||
|
||||
selection::command() {
|
||||
selection::cmd() {
|
||||
local -r selection="$1"
|
||||
local -r cheat="$2"
|
||||
|
||||
local -r core="$(echo $selection | selection::core)"
|
||||
local -r core="$(echo "$selection" | dict::get core)"
|
||||
|
||||
if echo "$core" | selection::core_is_comment; then
|
||||
grep "$core" "$cheat" -A999 \
|
||||
|
|
16
src/ui.sh
16
src/ui.sh
|
@ -4,10 +4,16 @@ ui::pick() {
|
|||
fzf --height '100%' --inline-info "$@"
|
||||
}
|
||||
|
||||
# TODO: separation of concerns
|
||||
ui::select() {
|
||||
local -r cheats="$1"
|
||||
local -r script_path="$(which navi | head -n1 || echo "${SCRIPT_DIR}/navi")"
|
||||
local -r preview_cmd="echo \"{}\" | tr ' ' '^' | xargs -I% \"${script_path}\" preview %"
|
||||
|
||||
local -r script_path="${SCRIPT_DIR}/navi"
|
||||
local -r preview_cmd="echo \"{}\" | tr ' ' '${ARG_DELIMITER}' | xargs -I% \"${script_path}\" preview %"
|
||||
|
||||
local -r query="$(dict::get "$OPTIONS" query)"
|
||||
local -r entry_point="$(dict::get "$OPTIONS" entry_point)"
|
||||
local -r preview="$(dict::get "$OPTIONS" preview)"
|
||||
|
||||
local args=()
|
||||
args+=("-i")
|
||||
|
@ -16,10 +22,10 @@ ui::select() {
|
|||
args+=("--preview"); args+=("$preview_cmd")
|
||||
args+=("--preview-window"); args+=("up:1")
|
||||
fi
|
||||
if [ -n "${query:-}" ]; then
|
||||
if [ -n "$query" ]; then
|
||||
args+=("--query=${query} ")
|
||||
fi
|
||||
if [ "${entry_point:-}" = "search" ]; then
|
||||
if [ "$entry_point" = "search" ]; then
|
||||
args+=("--header")
|
||||
args+=("Displaying online results. Please refer to 'navi --help' for details")
|
||||
fi
|
||||
|
@ -27,7 +33,7 @@ ui::select() {
|
|||
echo "$cheats" \
|
||||
| cheat::read_many \
|
||||
| ui::pick "${args[@]}" \
|
||||
| selection::standardize
|
||||
| selection::dict
|
||||
}
|
||||
|
||||
ui::clear_previous_line() {
|
||||
|
|
13
test/core.sh
13
test/core.sh
|
@ -2,6 +2,9 @@
|
|||
|
||||
source "${SCRIPT_DIR}/src/main.sh"
|
||||
|
||||
OPTIONS="$(opts::eval "$@")"
|
||||
export NAVI_PATH="$(dict::get "$OPTIONS" path)"
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
|
@ -23,6 +26,16 @@ test::run() {
|
|||
eval "$*" && test::success || test::fail
|
||||
}
|
||||
|
||||
test::equals() {
|
||||
local -r actual="$(cat | tr -d '\n')"
|
||||
local -r expected="$(echo "${1:-}" | tr -d '\n' | sed 's/\\n//g')"
|
||||
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
echo "Expected '${expected}' but got '${actual}'"
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
test::finish() {
|
||||
echo
|
||||
if [ $FAILED -gt 0 ]; then
|
||||
|
|
106
test/dict_test.sh
Normal file
106
test/dict_test.sh
Normal file
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
inc() {
|
||||
local -r x="$1"
|
||||
echo $((x+1))
|
||||
}
|
||||
|
||||
dict_assoc() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" \
|
||||
| test::equals "foo: 42"
|
||||
}
|
||||
|
||||
dict_assoc_multiple() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar" "5" \
|
||||
| test::equals "bar: 5\nfoo: 42"
|
||||
}
|
||||
|
||||
dict_dissoc() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar" "5" \
|
||||
| dict::dissoc "bar" \
|
||||
| test::equals "foo: 42"
|
||||
}
|
||||
|
||||
dict_assoc_again() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" \
|
||||
| dict::assoc "foo" "42" \
|
||||
| test::equals "foo: 42"
|
||||
}
|
||||
|
||||
dict_dissoc_nested() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::dissoc "bar" \
|
||||
| test::equals "baz: 63\nfoo: 42"
|
||||
}
|
||||
|
||||
dict_assoc_nested() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.c" 7 "baz" 63 \
|
||||
| dict::assoc "bar.b" 6 \
|
||||
| test::equals "bar.a: 5\nbar.b: 6\nbar.c: 7\nbaz: 63\nfoo: 42"
|
||||
}
|
||||
|
||||
dict_get() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" \
|
||||
| dict::get "foo" \
|
||||
| test::equals "42"
|
||||
}
|
||||
|
||||
dict_get_nested() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::get "bar.a" \
|
||||
| test::equals "5"
|
||||
}
|
||||
|
||||
dict_get_dict() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::get "bar" \
|
||||
| test::equals "bar.a: 5\nbar.b: 6"
|
||||
}
|
||||
|
||||
dict_get_keys() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::keys \
|
||||
| test::equals "bar.a\nbar.b\nbaz\nfoo"
|
||||
}
|
||||
|
||||
dict_get_values() {
|
||||
dict::new \
|
||||
| dict::assoc "foo" "42" "bar.a" 5 "bar.b" 6 "baz" 63 \
|
||||
| dict::values \
|
||||
| test::equals "5\n6\n63\n42"
|
||||
}
|
||||
|
||||
dict_zipmap() {
|
||||
dict::zipmap "key1\nkey2\nkey3" "value1\nvalue2\nvalue3" \
|
||||
| test::equals "$(dict::new "key1" "value1" "key2" "value2" "key3" "value3")"
|
||||
}
|
||||
|
||||
dict_update() {
|
||||
dict::new "foo" 42 "bar" 5 \
|
||||
| dict::update "bar" inc \
|
||||
| test::equals "$(dict::new "foo" 42 "bar" 6)"
|
||||
}
|
||||
|
||||
test::run "We can assoc a value" dict_assoc
|
||||
test::run "We can assoc multiple values" dict_assoc_multiple
|
||||
test::run "We can assoc a nested value" dict_assoc_nested
|
||||
test::run "We can dissoc a value" dict_dissoc
|
||||
test::run "Associng the same value is a no-op" dict_assoc_again
|
||||
test::run "Dissocing a key will replace all its subvalues" dict_dissoc_nested
|
||||
test::run "We can get a value" dict_get
|
||||
test::run "We can get a nested value" dict_get_nested
|
||||
test::run "We can get a dictionary" dict_get_dict
|
||||
test::run "We can get all keys" dict_get_keys
|
||||
test::run "We can get all values" dict_get_values
|
||||
test::run "We can get create a dict from a zipmap" dict_zipmap
|
||||
test::run "We can update a value" dict_update
|
2
test/run
2
test/run
|
@ -7,7 +7,7 @@ source "${SCRIPT_DIR}/test/core.sh"
|
|||
tests="$(find "$SCRIPT_DIR/test" -iname '*_test.sh')"
|
||||
|
||||
for test in $tests; do
|
||||
source "$test"
|
||||
source "$test"
|
||||
done
|
||||
|
||||
test::finish
|
||||
|
|
Loading…
Reference in a new issue