#!/bin/bash setUp() { rm test*.yml || true } ## Convenient bash shortcut to read records of NUL separated values ## from stdin the safe way. See example usage in the next tests. read-0() { local eof="" IFS='' while [ "$1" ]; do ## - The `-r` avoids bad surprise with '\n' and other interpreted ## sequences that can be read. ## - The `-d ''` is the (strange?) way to refer to NUL delimiter. ## - The `--` is how to avoid unpleasant surprises if your ## "$1" starts with "-" (minus) sign. This protection also ## will produce a readable error if you want to try to start ## your variable names with a "-". read -r -d '' -- "$1" || eof=1 shift done [ -z "$eof" ] ## fail on EOF } ## Convenient bash shortcut to be used with the next function `p-err` ## to read NUL separated values the safe way AND catch any errors from ## the process creating the stream of NUL separated data. See example ## usage in the tests. read-0-err() { local ret="$1" eof="" idx=0 last= read -r -- "${ret?}" <<<"0" shift while [ "$1" ]; do last=$idx read -r -d '' -- "$1" || { ## Put this last value in ${!ret} eof="$1" read -r -- "$ret" <<<"${!eof}" break } ((idx++)) shift done [ -z "$eof" ] || { if [ "$last" != 0 ]; then ## Uhoh, we have no idea if the errorlevel of the internal ## command was properly delimited with a NUL char, and ## anyway something went really wrong at least about the ## number of fields separated by NUL char and the one ## expected. echo "Error: read-0-err couldn't fill all value $ret = '${!ret}', '$eof', '${!eof}'" >&2 read -r -- "$ret" <<<"not-enough-values" else if ! [[ "${!ret}" =~ ^[0-9]+$ && "${!ret}" -ge 0 && "${!ret}" -le 127 ]]; then ## This could happen if you don't use `p-err` wrapper, ## or used stdout in unexpected ways in your inner ## command. echo "Error: last value is not a number, did you finish with an errorlevel ?" >&2 read -r -- "$ret" <<<"last-value-not-a-number" fi fi false } } ## Simply runs command given as argument and adds errorlevel in the ## standard output. Is expected to be used in tandem with ## `read-0-err`. p-err() { local exp="$1" "$@" printf "%s" "$?" } wyq-r() { local exp="$1" ./yq e -0 -r=false "$1" printf "%s" "$?" } testBasicUsageRaw() { cat >test.yml < expected.out ## We need to compare binary content here. We have to filter the compared ## content through a representation that gets rid of NUL chars but accurately ## transcribe the content. ## Also as it would be nice to have a pretty output in case the test fails, ## we use here 'hd': a widely available shortcut to 'hexdump' that will ## pretty-print any binary to it's hexadecimal representation. ## ## Note that the standard `assertEquals` compare its arguments ## value, but they can't hold NUL characters (this comes from the ## limitation of the C API of `exec*(..)` functions that requires ## `const char *arv[]`). And these are NUL terminated strings. As a ## consequence, the NUL characters gets removed in bash arguments. assertEquals "$(hd expected.out)" \ "$(./yq e -0 '.a, .b' test.yml | hd)" rm expected.out } testBasicUsage() { local a b cat >test.yml <test.yml <test.yml <test.yml <test.yml <test.yml <test.yml <