mirror of
https://github.com/nvm-sh/nvm.git
synced 2025-05-10 14:21:50 +00:00
[Tests] use a better JSON parsing implementation
This commit is contained in:
parent
aa427ad396
commit
e597bb208e
236
test/common.sh
236
test/common.sh
@ -102,104 +102,146 @@ watch() {
|
|||||||
return $EXIT_CODE
|
return $EXIT_CODE
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_json() {
|
|
||||||
local json
|
|
||||||
json="$1"
|
|
||||||
local key
|
|
||||||
key=""
|
|
||||||
local value
|
|
||||||
value=""
|
|
||||||
local output
|
|
||||||
output=""
|
|
||||||
local in_key
|
|
||||||
in_key=0
|
|
||||||
local in_value
|
|
||||||
in_value=0
|
|
||||||
local in_string
|
|
||||||
in_string=0
|
|
||||||
local escaped
|
|
||||||
escaped=0
|
|
||||||
local buffer
|
|
||||||
buffer=""
|
|
||||||
local char
|
|
||||||
local len
|
|
||||||
len=${#json}
|
|
||||||
local arr_index
|
|
||||||
arr_index=0
|
|
||||||
local in_array
|
|
||||||
in_array=0
|
|
||||||
|
|
||||||
for ((i = 0; i < len; i++)); do
|
# JSON parsing from https://gist.github.com/assaf/ee377a186371e2e269a7
|
||||||
char="${json:i:1}"
|
nvm_json_throw() {
|
||||||
|
nvm_err "$*"
|
||||||
if [ "$in_string" -eq 1 ]; then
|
exit 1
|
||||||
if [ "$escaped" -eq 1 ]; then
|
|
||||||
buffer="$buffer$char"
|
|
||||||
escaped=0
|
|
||||||
elif [ "$char" = "\\" ]; then
|
|
||||||
escaped=1
|
|
||||||
elif [ "$char" = "\"" ]; then
|
|
||||||
in_string=0
|
|
||||||
if [ "$in_key" -eq 1 ]; then
|
|
||||||
key="$buffer"
|
|
||||||
buffer=""
|
|
||||||
in_key=0
|
|
||||||
elif [ "$in_value" -eq 1 ]; then
|
|
||||||
value="$buffer"
|
|
||||||
buffer=""
|
|
||||||
output="$output$key=\"$value\"\n"
|
|
||||||
in_value=0
|
|
||||||
elif [ "$in_array" -eq 1 ]; then
|
|
||||||
value="$buffer"
|
|
||||||
buffer=""
|
|
||||||
output="$output$arr_index=\"$value\"\n"
|
|
||||||
arr_index=$((arr_index + 1))
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
buffer="$buffer$char"
|
|
||||||
fi
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
case "$char" in
|
|
||||||
"\"")
|
|
||||||
in_string=1
|
|
||||||
buffer=""
|
|
||||||
if [ "$in_value" -eq 0 ] && [ "$in_array" -eq 0 ]; then
|
|
||||||
in_key=1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
":")
|
|
||||||
in_value=1
|
|
||||||
;;
|
|
||||||
",")
|
|
||||||
if [ "$in_value" -eq 1 ]; then
|
|
||||||
in_value=0
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"[")
|
|
||||||
in_array=1
|
|
||||||
;;
|
|
||||||
"]")
|
|
||||||
in_array=0
|
|
||||||
;;
|
|
||||||
"{" | "}")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if [ "$in_value" -eq 1 ] && [ "$char" != " " ] && [ "$char" != "\n" ] && [ "$char" != "\t" ]; then
|
|
||||||
buffer="$buffer$char"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
printf "%b" "$output"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_value() {
|
nvm_json_awk_egrep() {
|
||||||
local key
|
local pattern_string
|
||||||
key="$1"
|
pattern_string="${1}"
|
||||||
local parsed
|
|
||||||
parsed="$2"
|
awk '{
|
||||||
echo "$parsed" | grep "^$key=" | cut -d'=' -f2 | tr -d '"'
|
while ($0) {
|
||||||
|
start=match($0, pattern);
|
||||||
|
token=substr($0, start, RLENGTH);
|
||||||
|
print token;
|
||||||
|
$0=substr($0, start+RLENGTH);
|
||||||
|
}
|
||||||
|
}' "pattern=${pattern_string}"
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm_json_tokenize() {
|
||||||
|
local GREP
|
||||||
|
GREP='grep -Eao'
|
||||||
|
|
||||||
|
local ESCAPE
|
||||||
|
local CHAR
|
||||||
|
|
||||||
|
# if echo "test string" | grep -Eo "test" > /dev/null 2>&1; then
|
||||||
|
# ESCAPE='(\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
|
||||||
|
# CHAR='[^[:cntrl:]"\\]'
|
||||||
|
# else
|
||||||
|
GREP=nvm_json_awk_egrep
|
||||||
|
ESCAPE='(\\\\[^u[:cntrl:]]|\\u[0-9a-fA-F]{4})'
|
||||||
|
CHAR='[^[:cntrl:]"\\\\]'
|
||||||
|
# fi
|
||||||
|
|
||||||
|
local STRING
|
||||||
|
STRING="\"${CHAR}*(${ESCAPE}${CHAR}*)*\""
|
||||||
|
local NUMBER
|
||||||
|
NUMBER='-?(0|[1-9][0-9]*)([.][0-9]*)?([eE][+-]?[0-9]*)?'
|
||||||
|
local KEYWORD
|
||||||
|
KEYWORD='null|false|true'
|
||||||
|
local SPACE
|
||||||
|
SPACE='[[:space:]]+'
|
||||||
|
|
||||||
|
$GREP "${STRING}|${NUMBER}|${KEYWORD}|${SPACE}|." | TERM=dumb grep -Ev "^${SPACE}$"
|
||||||
|
}
|
||||||
|
|
||||||
|
_json_parse_array() {
|
||||||
|
local index=0
|
||||||
|
local ary=''
|
||||||
|
read -r token
|
||||||
|
case "$token" in
|
||||||
|
']') ;;
|
||||||
|
*)
|
||||||
|
while :; do
|
||||||
|
_json_parse_value "${1}" "${index}"
|
||||||
|
index=$((index+1))
|
||||||
|
ary="${ary}${value}"
|
||||||
|
read -r token
|
||||||
|
case "${token}" in
|
||||||
|
']') break ;;
|
||||||
|
',') ary="${ary}," ;;
|
||||||
|
*) nvm_json_throw "EXPECTED , or ] GOT ${token:-EOF}" ;;
|
||||||
|
esac
|
||||||
|
read -r token
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
_json_parse_object() {
|
||||||
|
local key
|
||||||
|
local obj=''
|
||||||
|
read -r token
|
||||||
|
case "$token" in
|
||||||
|
'}') ;;
|
||||||
|
*)
|
||||||
|
while :; do
|
||||||
|
case "${token}" in
|
||||||
|
'"'*'"') key="${token}" ;;
|
||||||
|
*) nvm_json_throw "EXPECTED string GOT ${token:-EOF}" ;;
|
||||||
|
esac
|
||||||
|
read -r token
|
||||||
|
case "${token}" in
|
||||||
|
':') ;;
|
||||||
|
*) nvm_json_throw "EXPECTED : GOT ${token:-EOF}" ;;
|
||||||
|
esac
|
||||||
|
read -r token
|
||||||
|
_json_parse_value "${1}" "${key}"
|
||||||
|
obj="${obj}${key}:${value}"
|
||||||
|
read -r token
|
||||||
|
case "${token}" in
|
||||||
|
'}') break ;;
|
||||||
|
',') obj="${obj}," ;;
|
||||||
|
*) nvm_json_throw "EXPECTED , or } GOT ${token:-EOF}" ;;
|
||||||
|
esac
|
||||||
|
read -r token
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
_json_parse_value() {
|
||||||
|
local jpath="${1:+$1,}$2"
|
||||||
|
local isleaf=0
|
||||||
|
local isempty=0
|
||||||
|
local print=0
|
||||||
|
|
||||||
|
case "$token" in
|
||||||
|
'{') _json_parse_object "${jpath}" ;;
|
||||||
|
'[') _json_parse_array "${jpath}" ;;
|
||||||
|
# At this point, the only valid single-character tokens are digits.
|
||||||
|
''|[!0-9]) nvm_json_throw "EXPECTED value GOT >${token:-EOF}<" ;;
|
||||||
|
*)
|
||||||
|
value=$token
|
||||||
|
isleaf=1
|
||||||
|
[ "${value}" = '""' ] && isempty=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ "${value}" = '' ] && return
|
||||||
|
[ "${isleaf}" -eq 1 ] && [ $isempty -eq 0 ] && print=1
|
||||||
|
[ "${print}" -eq 1 ] && printf "[%s]\t%s\n" "${jpath}" "${value}"
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
_json_parse() {
|
||||||
|
read -r token
|
||||||
|
_json_parse_value
|
||||||
|
read -r token
|
||||||
|
case "${token}" in
|
||||||
|
'') ;;
|
||||||
|
*) nvm_json_throw "EXPECTED EOF GOT >${token}<" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm_json_extract() {
|
||||||
|
nvm_json_tokenize | _json_parse | grep -e "${1}" | awk '{print $2 $3}'
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ for f in ../../../test/fixtures/nvmrc/test/fixtures/valid/*; do
|
|||||||
STDOUT="$(nvm_process_nvmrc $f/.nvmrc 2>/dev/null)"
|
STDOUT="$(nvm_process_nvmrc $f/.nvmrc 2>/dev/null)"
|
||||||
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
|
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
|
||||||
|
|
||||||
EXPECTED="$(extract_value node "$(parse_json "$(cat "$f/expected.json")")")"
|
EXPECTED="$(nvm_json_extract node < "${f}/expected.json" | tr -d '"')"
|
||||||
|
|
||||||
[ "${EXIT_CODE}" = "0" ] || die "$(basename "${f}"): expected exit code of 0 but got ${EXIT_CODE}"
|
[ "${EXIT_CODE}" = "0" ] || die "$(basename "${f}"): expected exit code of 0 but got ${EXIT_CODE}"
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ for f in ../../../test/fixtures/nvmrc/test/fixtures/invalid/*; do
|
|||||||
STDERR="$(nvm_process_nvmrc $f/.nvmrc 2>&1 >/dev/null | awk '{if(NR > 8) print $0}' | strip_colors)"
|
STDERR="$(nvm_process_nvmrc $f/.nvmrc 2>&1 >/dev/null | awk '{if(NR > 8) print $0}' | strip_colors)"
|
||||||
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
|
EXIT_CODE="$(nvm_process_nvmrc $f/.nvmrc >/dev/null 2>/dev/null; echo $?)"
|
||||||
|
|
||||||
EXPECTED="$(parse_json "$(cat "$f/expected.json")" | sed 's/^[0-9]*="//;s/"$//')"
|
EXPECTED="$(nvm_json_extract < "${f}/expected.json" | tr -d '"')"
|
||||||
|
|
||||||
[ "${EXIT_CODE}" != "0" ] || die "$(basename "${f}"): expected exit code of 'not 0' but got ${EXIT_CODE}"
|
[ "${EXIT_CODE}" != "0" ] || die "$(basename "${f}"): expected exit code of 'not 0' but got ${EXIT_CODE}"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user