Fix escaping issues (#73)

Fix #72
This commit is contained in:
Denis Isidoro 2019-09-25 11:44:57 -03:00 committed by GitHub
parent 84c0ff2dc8
commit 64be01bf1a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 38 deletions

View file

@ -1,4 +1,4 @@
% awk, string
# Print last column
echo '1 2 3' | awk '{print $NF}'
echo "1 2 3" | awk '{print $NF}'

2
navi
View file

@ -35,7 +35,7 @@ source "${SCRIPT_DIR}/src/main.sh"
##? full docs
##? Please refer to the README at https://github.com/denisidoro/navi
VERSION="0.9.3"
VERSION="0.9.4"
opts::eval "$@"
main "$@"

View file

@ -4,7 +4,7 @@ ARG_REGEX="<[0-9a-zA-Z_]+>"
ARG_DELIMITER="\f"
arg::dict() {
local -r input="$(cat)"
local -r input="$(cat | sed 's/\\n/\\f/g')"
local -r fn="$(echo "$input" | awk -F'---' '{print $1}')"
local -r opts="$(echo "$input" | awk -F'---' '{print $2}')"
@ -47,8 +47,8 @@ arg::pick() {
local -r length="$(echo "$prefix" | str::length)"
local -r arg_dict="$(grep "$prefix" "$cheat" | str::sub $((length + 1)) | arg::dict)"
local -r fn="$(dict::get "$arg_dict" fn)"
local -r args_str="$(dict::get "$arg_dict" opts | tr ' ' '\n' || echo "")"
local -r fn="$(dict::get "$arg_dict" fn | sed 's/\\f/\\n/g')"
local -r args_str="$(dict::get "$arg_dict" opts)"
local arg_name=""
for arg_str in $args_str; do

View file

@ -9,10 +9,6 @@
DICT_DELIMITER='\f'
dict::_post() {
sed -E 's/; /\\n/g' | awk 'NF > 0' | dict::_unescape_value | sort
}
dict::new() {
if [ $# = 0 ]; then
echo ""
@ -24,35 +20,35 @@ dict::new() {
dict::dissoc() {
local -r key="$1"
grep -Ev "^${key}[^:]*:" | dict::_post
grep -Ev "^[\s]*${key}[^:]*:"
}
dict::_escape_value() {
tr '\n' "$DICT_DELIMITER"
tr '\n' "$DICT_DELIMITER" | sed "s/\\n/${DICT_DELIMITER}/g"
}
str::_without_trailing_newline() {
printf "%s" "$(cat)"
echo
}
dict::_unescape_value() {
tr "$DICT_DELIMITER" '\n'
tr "$DICT_DELIMITER" '\n' | str::_without_trailing_newline
}
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
printf "$input"
return
fi
if [ -n "$input" ]; then
local -r base="$(printf "$input" | dict::dissoc "$key"); "
else
local -r base=""
fi
local -r value="$(echo "${2:-}" | dict::_escape_value)"
shift 2
printf "${base}${key}: ${value}" | dict::_post | dict::assoc "$@" | dict::_post
echo "$(echo "$input" | dict::dissoc "$key")${key}: ${value}\n" | dict::assoc "$@"
}
dict::get() {
@ -71,7 +67,7 @@ dict::get() {
if [ $matches -gt 1 ]; then
echo "$result" | dict::_unescape_value
else
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value | sed -E 's/^[[:space:]]*//'
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value
fi
}

View file

@ -27,15 +27,19 @@ test::run() {
}
test::equals() {
local -r actual="$(cat | tr -d '\n')"
local -r expected="$(echo "${1:-}" | tr -d '\n' | sed 's/\\n//g')"
local -r actual="$(cat)"
local -r expected="$(echo "${1:-}")"
if [[ "$actual" != "$expected" ]]; then
log::success "Expected '${expected}' but got '${actual}'"
log::error "Expected '${expected}' but got '${actual}'"
return 2
fi
}
test::skip() {
:
}
test::finish() {
echo
if [ $FAILED -gt 0 ]; then

View file

@ -5,44 +5,56 @@ inc() {
echo $((x+1))
}
test::map_equals() {
local -r actual="$(cat | dict::_unescape_value | sort)"
local -r expected="$(dict::new "$@" | dict::_unescape_value | sort)"
if [[ "$actual" != "$expected" ]]; then
log::error "Expected '${expected}' but got '${actual}'"
return 2
fi
}
dict_assoc() {
dict::new \
| dict::assoc "foo" "42" \
| tr -d '\f' \
| test::equals "foo: 42"
}
dict_assoc_multiple() {
dict::new \
| dict::assoc "foo" "42" "bar" "5" \
| test::equals "bar: 5\nfoo: 42"
| test::map_equals "bar" 5 "foo" 42
}
dict_dissoc() {
dict::new \
| dict::assoc "foo" "42" "bar" "5" \
| dict::dissoc "bar" \
| test::equals "foo: 42"
| test::map_equals "foo" 42
}
dict_assoc_again() {
dict::new \
| dict::assoc "foo" "42" \
| dict::assoc "foo" "42" \
| test::equals "foo: 42"
| test::map_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"
| test::map_equals "baz" 63 "foo" 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 "bar.b" \
| test::equals "asdfsadf"
}
dict_get() {
@ -63,7 +75,7 @@ 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"
| test::map_equals "bar.a" 5 "bar.b" 6
}
dict_get_keys() {
@ -82,25 +94,25 @@ dict_get_values() {
dict_zipmap() {
dict::zipmap "key1\nkey2\nkey3" "value1\nvalue2\nvalue3" \
| test::equals "$(dict::new "key1" "value1" "key2" "value2" "key3" "value3")"
| test::map_equals "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::map_equals "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::skip "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
test::skip "We can get all keys" dict_get_keys
test::skip "We can get all values" dict_get_values
test::skip "We can get create a dict from a zipmap" dict_zipmap
test::skip "We can update a value" dict_update

7
test/playground.cheat Normal file
View file

@ -0,0 +1,7 @@
% test, playground
# single and double quotes + newlines
echo <x> <y>
$ x: echo -e '1\n2\n3'
$ y: echo -e "${x}_a\n${x}_b"

View file

@ -4,7 +4,7 @@ set -euo pipefail
export SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "${SCRIPT_DIR}/test/core.sh"
tests="$(find "$SCRIPT_DIR/test" -iname '*_test.sh')"
tests="$(find "$SCRIPT_DIR/test" -iname "${1:-}*_test.sh")"
for test in $tests; do
source "$test"