From 6051f707cabec0a24f694d6fa5088a16d64fc628 Mon Sep 17 00:00:00 2001 From: felixlohmeier Date: Wed, 30 Nov 2022 22:49:54 +0000 Subject: [PATCH 1/5] first draft functional tests --- orcli | 185 +++++++++++++++++++++++++++++++++++- src/bashly.yml | 8 ++ src/lib/send_completions.sh | 6 +- src/test_command.sh | 72 ++++++++++++++ tests/fail.sh | 29 ++++++ tests/import-csv.sh | 29 ++++++ 6 files changed, 327 insertions(+), 2 deletions(-) create mode 100644 src/test_command.sh create mode 100644 tests/fail.sh create mode 100644 tests/import-csv.sh diff --git a/orcli b/orcli index 52d5779..2bdc2bd 100755 --- a/orcli +++ b/orcli @@ -38,6 +38,7 @@ orcli_usage() { echo " import commands to create OpenRefine projects from files or URLs" echo " list list projects on OpenRefine server" echo " info show OpenRefine project's metadata" + echo " test run functional tests on tmp OpenRefine workspace" echo " transform apply undo/redo JSON file(s) to an OpenRefine project" echo " export commands to export data from OpenRefine projects to files" echo " run run tmp OpenRefine workspace and execute shell script(s)" @@ -363,6 +364,44 @@ orcli_info_usage() { fi } +# :command.usage +orcli_test_usage() { + if [[ -n $long_usage ]]; then + printf "orcli test - run functional tests on tmp OpenRefine workspace\n" + echo + + else + printf "orcli test - run functional tests on tmp OpenRefine workspace\n" + echo + + fi + + printf "Usage:\n" + printf " orcli test [FILE...]\n" + printf " orcli test --help | -h\n" + echo + + # :command.long_usage + if [[ -n $long_usage ]]; then + printf "Options:\n" + + # :command.usage_fixed_flags + echo " --help, -h" + printf " Show this help\n" + echo + + # :command.usage_args + printf "Arguments:\n" + + # :argument.usage + echo " FILE..." + printf " Path to one or more files\n" + printf " Default: tests/*.sh\n" + echo + + fi +} + # :command.usage orcli_transform_usage() { if [[ -n $long_usage ]]; then @@ -880,12 +919,16 @@ send_completions() { echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help -h")" -- "$cur" )' echo $' ;;' echo $'' + echo $' \'test\'*)' + echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help -h")" -- "$cur" )' + echo $' ;;' + echo $'' echo $' \'run\'*)' echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --interactive --memory --port --quiet -h -q")" -- "$cur" )' echo $' ;;' echo $'' echo $' *)' - echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --version -h -v completions export import info list run transform")" -- "$cur" )' + echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --version -h -v completions export import info list run test transform")" -- "$cur" )' echo $' ;;' echo $'' echo $' esac' @@ -1004,6 +1047,84 @@ orcli_info_command() { echo "$projectid" } +# :command.function +orcli_test_command() { + # src/test_command.sh + # shellcheck shell=bash + + # catch args, convert the space delimited string to an array + files=() + eval "files=(${args[file]})" + + # check existence of files + for i in "${!files[@]}"; do + if ! [[ -f "${files[$i]}" ]]; then + error "cannot open ${files[$i]} (no such file)!" + fi + done + + # locate orcli and OpenRefine + scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") + if [[ -x "${scriptpath}/refine" ]]; then + openrefine="${scriptpath}/refine" + else + error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" + fi + + # create tmp directory + OPENREFINE_TMPDIR="$(mktemp -d)" + trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 + + # check if OpenRefine is already running + if curl -fs "${OPENREFINE_URL}" &>/dev/null; then + error "OpenRefine is already running." + fi + + # start OpenRefine with tmp workspace and autosave period 25 hours + REFINE_AUTOSAVE_PERIOD=1440 $openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & + OPENREFINE_PID="$!" + + # update trap to kill OpenRefine on error or exit + trap '{ rm -rf "$OPENREFINE_TMPDIR"; kill -9 "$OPENREFINE_PID"; }' 0 2 3 15 + + # wait until OpenRefine is running (timeout 20s) + if ! curl -fs --retry 20 --retry-connrefused --retry-delay 1 "${OPENREFINE_URL}/command/core/get-version" &>/dev/null; then + error "starting OpenRefine server failed!" + else + log "started OpenRefine with tmp workspace ${OPENREFINE_TMPDIR}" + fi + + # execute script(s) in subshell + export OPENREFINE_TMPDIR OPENREFINE_URL OPENREFINE_PID + results=() + for i in "${!files[@]}"; do + set +e + bash <( + if ! command -v orcli &>/dev/null; then + echo "shopt -s expand_aliases" + echo "alias orcli=${scriptpath}/orcli" + fi + awk 1 "${files[$i]}" + ) &>"$OPENREFINE_TMPDIR/test.log" + results+=(${?}) + set -e + if [[ "${results[$i]}" =~ [1-9] ]]; then + cat "$OPENREFINE_TMPDIR/test.log" + log "FAILED ${files[$i]} with exit code ${results[$i]}!" + else + log "PASSED ${files[$i]}" + fi + done + + # summary + if [[ "${results[*]}" =~ [1-9] ]]; then + error "failed tests!" + else + log "all tests passed!" + fi + +} + # :command.function orcli_transform_command() { # src/transform_command.sh @@ -1316,6 +1437,13 @@ parse_requirements() { shift $# ;; + test ) + action="test" + shift + orcli_test_parse_requirements "$@" + shift $# + ;; + transform ) action="transform" shift @@ -1768,6 +1896,53 @@ orcli_info_parse_requirements() { } +# :command.parse_requirements +orcli_test_parse_requirements() { + # :command.fixed_flags_filter + case "${1:-}" in + --help | -h ) + long_usage=yes + orcli_test_usage + exit + ;; + + esac + + # :command.command_filter + action="test" + + # :command.parse_requirements_while + while [[ $# -gt 0 ]]; do + key="$1" + case "$key" in + + -?* ) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; + + * ) + # :command.parse_requirements_case + # :command.parse_requirements_case_repeatable + if [[ -z ${args[file]+x} ]]; then + + args[file]="\"$1\"" + shift + else + args[file]="${args[file]} \"$1\"" + shift + fi + + ;; + + esac + done + + # :command.default_assignments + [[ -n ${args[file]:-} ]] || args[file]="tests/*.sh" + +} + # :command.parse_requirements orcli_transform_parse_requirements() { # :command.fixed_flags_filter @@ -2147,6 +2322,14 @@ run() { orcli_info_command fi + elif [[ $action == "test" ]]; then + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_test_usage + else + orcli_test_command + fi + elif [[ $action == "transform" ]]; then if [[ ${args[--help]:-} ]]; then long_usage=yes diff --git a/src/bashly.yml b/src/bashly.yml index dbe56ae..335e910 100644 --- a/src/bashly.yml +++ b/src/bashly.yml @@ -116,6 +116,14 @@ commands: - orcli info "duplicates" - orcli info 1234567890123 + - name: test + help: run functional tests on tmp OpenRefine workspace + args: + - name: file + help: Path to one or more files + default: "tests/*.sh" + repeatable: true + - name: transform help: apply undo/redo JSON file(s) to an OpenRefine project args: diff --git a/src/lib/send_completions.sh b/src/lib/send_completions.sh index dbee111..5cadb15 100644 --- a/src/lib/send_completions.sh +++ b/src/lib/send_completions.sh @@ -66,12 +66,16 @@ send_completions() { echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help -h")" -- "$cur" )' echo $' ;;' echo $'' + echo $' \'test\'*)' + echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help -h")" -- "$cur" )' + echo $' ;;' + echo $'' echo $' \'run\'*)' echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --interactive --memory --port --quiet -h -q")" -- "$cur" )' echo $' ;;' echo $'' echo $' *)' - echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --version -h -v completions export import info list run transform")" -- "$cur" )' + echo $' while read -r; do COMPREPLY+=( "$REPLY" ); done < <( compgen -W "$(_orcli_completions_filter "--help --version -h -v completions export import info list run test transform")" -- "$cur" )' echo $' ;;' echo $'' echo $' esac' diff --git a/src/test_command.sh b/src/test_command.sh new file mode 100644 index 0000000..813d9d3 --- /dev/null +++ b/src/test_command.sh @@ -0,0 +1,72 @@ +# shellcheck shell=bash + +# catch args, convert the space delimited string to an array +files=() +eval "files=(${args[file]})" + +# check existence of files +for i in "${!files[@]}"; do + if ! [[ -f "${files[$i]}" ]]; then + error "cannot open ${files[$i]} (no such file)!" + fi +done + +# locate orcli and OpenRefine +scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") +if [[ -x "${scriptpath}/refine" ]]; then + openrefine="${scriptpath}/refine" +else + error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" +fi + +# create tmp directory +OPENREFINE_TMPDIR="$(mktemp -d)" +trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 + +# check if OpenRefine is already running +if curl -fs "${OPENREFINE_URL}" &>/dev/null; then + error "OpenRefine is already running." +fi + +# start OpenRefine with tmp workspace and autosave period 25 hours +REFINE_AUTOSAVE_PERIOD=1440 $openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & +OPENREFINE_PID="$!" + +# update trap to kill OpenRefine on error or exit +trap '{ rm -rf "$OPENREFINE_TMPDIR"; kill -9 "$OPENREFINE_PID"; }' 0 2 3 15 + +# wait until OpenRefine is running (timeout 20s) +if ! curl -fs --retry 20 --retry-connrefused --retry-delay 1 "${OPENREFINE_URL}/command/core/get-version" &>/dev/null; then + error "starting OpenRefine server failed!" +else + log "started OpenRefine with tmp workspace ${OPENREFINE_TMPDIR}" +fi + +# execute script(s) in subshell +export OPENREFINE_TMPDIR OPENREFINE_URL OPENREFINE_PID +results=() +for i in "${!files[@]}"; do + set +e + bash <( + if ! command -v orcli &>/dev/null; then + echo "shopt -s expand_aliases" + echo "alias orcli=${scriptpath}/orcli" + fi + awk 1 "${files[$i]}" + ) &>"$OPENREFINE_TMPDIR/test.log" + results+=(${?}) + set -e + if [[ "${results[$i]}" =~ [1-9] ]]; then + cat "$OPENREFINE_TMPDIR/test.log" + log "FAILED ${files[$i]} with exit code ${results[$i]}!" + else + log "PASSED ${files[$i]}" + fi +done + +# summary +if [[ "${results[*]}" =~ [1-9] ]]; then + error "failed tests!" +else + log "all tests passed!" +fi diff --git a/tests/fail.sh b/tests/fail.sh new file mode 100644 index 0000000..50acc94 --- /dev/null +++ b/tests/fail.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# environment +t=import-csv +mkdir "${OPENREFINE_TMPDIR}/${t}" +cd "${OPENREFINE_TMPDIR}/${t}" || exit 1 + +# data +cat << "DATA" > "test.csv" +a,b,c +1,2,3 +0,0,0 +$,\,' +DATA + +# assertion +cat << "DATA" > "test.assert" +a b c +1 2 3 +0 1 0 +$ \ ' +DATA + +# action +orcli import csv "test.csv" +orcli export tsv "test csv" --output "test.output" + +# test +diff -u "test.assert" "test.output" \ No newline at end of file diff --git a/tests/import-csv.sh b/tests/import-csv.sh new file mode 100644 index 0000000..878a9e5 --- /dev/null +++ b/tests/import-csv.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# environment +t=import-csv +mkdir "${OPENREFINE_TMPDIR}/${t}" +cd "${OPENREFINE_TMPDIR}/${t}" || exit 1 + +# data +cat << "DATA" > "test.csv" +a,b,c +1,2,3 +0,0,0 +$,\,' +DATA + +# assertion +cat << "DATA" > "test.assert" +a b c +1 2 3 +0 0 0 +$ \ ' +DATA + +# action +orcli import csv "test.csv" +orcli export tsv "test csv" --output "test.output" + +# test +diff -u "test.assert" "test.output" \ No newline at end of file From aea762f22f9eba9c11c087d037412e1a25bfc24d Mon Sep 17 00:00:00 2001 From: felixlohmeier Date: Thu, 1 Dec 2022 22:43:52 +0000 Subject: [PATCH 2/5] move setup from test file to test command --- orcli | 9 +++++++-- src/test_command.sh | 9 +++++++-- tests/fail.sh | 29 ----------------------------- tests/import-csv.sh | 14 ++++++-------- 4 files changed, 20 insertions(+), 41 deletions(-) delete mode 100644 tests/fail.sh diff --git a/orcli b/orcli index 2bdc2bd..bdc89f9 100755 --- a/orcli +++ b/orcli @@ -1050,7 +1050,7 @@ orcli_info_command() { # :command.function orcli_test_command() { # src/test_command.sh - # shellcheck shell=bash + # shellcheck shell=bash disable=SC2154 # catch args, convert the space delimited string to an array files=() @@ -1099,11 +1099,16 @@ orcli_test_command() { results=() for i in "${!files[@]}"; do set +e - bash <( + bash -e <( + # support ./orcli if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" echo "alias orcli=${scriptpath}/orcli" fi + # separate subdirectory for each test + echo "mkdir -p ${OPENREFINE_TMPDIR}/${files[$i]}" + echo "cd ${OPENREFINE_TMPDIR}/${files[$i]} || exit 1" + # echo test file awk 1 "${files[$i]}" ) &>"$OPENREFINE_TMPDIR/test.log" results+=(${?}) diff --git a/src/test_command.sh b/src/test_command.sh index 813d9d3..20894b9 100644 --- a/src/test_command.sh +++ b/src/test_command.sh @@ -1,4 +1,4 @@ -# shellcheck shell=bash +# shellcheck shell=bash disable=SC2154 # catch args, convert the space delimited string to an array files=() @@ -47,11 +47,16 @@ export OPENREFINE_TMPDIR OPENREFINE_URL OPENREFINE_PID results=() for i in "${!files[@]}"; do set +e - bash <( + bash -e <( + # support ./orcli if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" echo "alias orcli=${scriptpath}/orcli" fi + # separate subdirectory for each test + echo "mkdir -p ${OPENREFINE_TMPDIR}/${files[$i]}" + echo "cd ${OPENREFINE_TMPDIR}/${files[$i]} || exit 1" + # echo test file awk 1 "${files[$i]}" ) &>"$OPENREFINE_TMPDIR/test.log" results+=(${?}) diff --git a/tests/fail.sh b/tests/fail.sh deleted file mode 100644 index 50acc94..0000000 --- a/tests/fail.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -# environment -t=import-csv -mkdir "${OPENREFINE_TMPDIR}/${t}" -cd "${OPENREFINE_TMPDIR}/${t}" || exit 1 - -# data -cat << "DATA" > "test.csv" -a,b,c -1,2,3 -0,0,0 -$,\,' -DATA - -# assertion -cat << "DATA" > "test.assert" -a b c -1 2 3 -0 1 0 -$ \ ' -DATA - -# action -orcli import csv "test.csv" -orcli export tsv "test csv" --output "test.output" - -# test -diff -u "test.assert" "test.output" \ No newline at end of file diff --git a/tests/import-csv.sh b/tests/import-csv.sh index 878a9e5..f9406d5 100644 --- a/tests/import-csv.sh +++ b/tests/import-csv.sh @@ -1,12 +1,10 @@ #!/bin/bash # environment -t=import-csv -mkdir "${OPENREFINE_TMPDIR}/${t}" -cd "${OPENREFINE_TMPDIR}/${t}" || exit 1 +t="$(basename "$(pwd)" .sh)" # data -cat << "DATA" > "test.csv" +cat << "DATA" > "${t}.csv" a,b,c 1,2,3 0,0,0 @@ -14,7 +12,7 @@ $,\,' DATA # assertion -cat << "DATA" > "test.assert" +cat << "DATA" > "${t}.assert" a b c 1 2 3 0 0 0 @@ -22,8 +20,8 @@ $ \ ' DATA # action -orcli import csv "test.csv" -orcli export tsv "test csv" --output "test.output" +orcli import csv "${t}.csv" +orcli export tsv "${t} csv" --output "${t}.output" # test -diff -u "test.assert" "test.output" \ No newline at end of file +diff -u "${t}.assert" "${t}.output" \ No newline at end of file From 8b2e35ced2cb2b70f9e6ff31085ddbb84c0c1253 Mon Sep 17 00:00:00 2001 From: felixlohmeier Date: Sat, 3 Dec 2022 00:30:01 +0000 Subject: [PATCH 3/5] make test scripts standalone --- orcli | 1340 +++++++++++++++++++++------------------- src/bashly.yml | 5 - src/test_command.sh | 19 +- tests/data/example.csv | 4 + tests/data/example.tsv | 4 + tests/help.sh | 19 + tests/import-csv.sh | 26 +- 7 files changed, 740 insertions(+), 677 deletions(-) create mode 100644 tests/data/example.csv create mode 100644 tests/data/example.tsv create mode 100644 tests/help.sh diff --git a/orcli b/orcli index bdc89f9..9fda828 100755 --- a/orcli +++ b/orcli @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# This script was generated by bashly 0.8.10 (https://bashly.dannyb.co) +# This script was generated by bashly 0.9.0 (https://bashly.dannyb.co) # Modifying it manually is not recommended # :wrapper.bash3_bouncer @@ -377,7 +377,7 @@ orcli_test_usage() { fi printf "Usage:\n" - printf " orcli test [FILE...]\n" + printf " orcli test\n" printf " orcli test --help | -h\n" echo @@ -390,15 +390,6 @@ orcli_test_usage() { printf " Show this help\n" echo - # :command.usage_args - printf "Arguments:\n" - - # :argument.usage - echo " FILE..." - printf " Path to one or more files\n" - printf " Default: tests/*.sh\n" - echo - fi } @@ -635,7 +626,7 @@ normalize_input() { input+=("${BASH_REMATCH[2]}") elif [[ $arg =~ ^-([a-zA-Z0-9][a-zA-Z0-9]+)$ ]]; then flags="${BASH_REMATCH[1]}" - for (( i=0 ; i < ${#flags} ; i++ )); do + for ((i = 0; i < ${#flags}; i++)); do input+=("-${flags:i:1}") done else @@ -648,14 +639,14 @@ normalize_input() { # :command.inspect_args inspect_args() { readarray -t sorted_keys < <(printf '%s\n' "${!args[@]}" | sort) - if (( ${#args[@]} )); then + if ((${#args[@]})); then echo args: for k in "${sorted_keys[@]}"; do echo "- \${args[$k]} = ${args[$k]}"; done else echo args: none fi - if (( ${#other_args[@]} )); then + if ((${#other_args[@]})); then echo echo other_args: echo "- \${other_args[*]} = ${other_args[*]}" @@ -1052,16 +1043,12 @@ orcli_test_command() { # src/test_command.sh # shellcheck shell=bash disable=SC2154 - # catch args, convert the space delimited string to an array - files=() - eval "files=(${args[file]})" - # check existence of files - for i in "${!files[@]}"; do - if ! [[ -f "${files[$i]}" ]]; then - error "cannot open ${files[$i]} (no such file)!" - fi - done + if ! [[ -f "tests/help.sh" ]]; then + error "Cannot open test files!" + fi + cd "tests" + files=(*.sh) # locate orcli and OpenRefine scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") @@ -1100,15 +1087,10 @@ orcli_test_command() { for i in "${!files[@]}"; do set +e bash -e <( - # support ./orcli if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" echo "alias orcli=${scriptpath}/orcli" fi - # separate subdirectory for each test - echo "mkdir -p ${OPENREFINE_TMPDIR}/${files[$i]}" - echo "cd ${OPENREFINE_TMPDIR}/${files[$i]} || exit 1" - # echo test file awk 1 "${files[$i]}" ) &>"$OPENREFINE_TMPDIR/test.log" results+=(${?}) @@ -1379,30 +1361,37 @@ orcli_run_command() { # :command.parse_requirements parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --version | -v ) - version_command - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --version | -v) + version_command + exit + ;; - --help | -h ) - long_usage=yes - orcli_usage - exit - ;; + --help | -h) + long_usage=yes + orcli_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.environment_variables_filter # :command.environment_variables_default export OPENREFINE_URL="${OPENREFINE_URL:-http://localhost:3333}" # :command.dependencies_filter - if ! [[ -x "$(command -v curl)" ]]; then + if ! command -v curl >/dev/null 2>&1; then printf "missing dependency: curl\n" >&2 exit 1 fi - if ! [[ -x "$(command -v jq)" ]]; then + + if ! command -v jq >/dev/null 2>&1; then printf "missing dependency: jq\n" >&2 exit 1 fi @@ -1411,75 +1400,75 @@ parse_requirements() { action=${1:-} case $action in - -* ) - ;; + -*) + ;; - completions ) - action="completions" - shift - orcli_completions_parse_requirements "$@" - shift $# - ;; + completions) + action="completions" + shift + orcli_completions_parse_requirements "$@" + shift $# + ;; - import ) - action="import" - shift - orcli_import_parse_requirements "$@" - shift $# - ;; + import) + action="import" + shift + orcli_import_parse_requirements "$@" + shift $# + ;; - list ) - action="list" - shift - orcli_list_parse_requirements "$@" - shift $# - ;; + list) + action="list" + shift + orcli_list_parse_requirements "$@" + shift $# + ;; - info ) - action="info" - shift - orcli_info_parse_requirements "$@" - shift $# - ;; + info) + action="info" + shift + orcli_info_parse_requirements "$@" + shift $# + ;; - test ) - action="test" - shift - orcli_test_parse_requirements "$@" - shift $# - ;; + test) + action="test" + shift + orcli_test_parse_requirements "$@" + shift $# + ;; - transform ) - action="transform" - shift - orcli_transform_parse_requirements "$@" - shift $# - ;; + transform) + action="transform" + shift + orcli_transform_parse_requirements "$@" + shift $# + ;; - export ) - action="export" - shift - orcli_export_parse_requirements "$@" - shift $# - ;; + export) + action="export" + shift + orcli_export_parse_requirements "$@" + shift $# + ;; - run ) - action="run" - shift - orcli_run_parse_requirements "$@" - shift $# - ;; + run) + action="run" + shift + orcli_run_parse_requirements "$@" + shift $# + ;; - # :command.command_fallback - "" ) - orcli_usage >&2 - exit 1 - ;; + # :command.command_fallback + "") + orcli_usage >&2 + exit 1 + ;; - * ) - printf "invalid command: %s\n" "$action" >&2 - exit 1 - ;; + *) + printf "invalid command: %s\n" "$action" >&2 + exit 1 + ;; esac @@ -1488,18 +1477,18 @@ parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - ;; + ;; esac done @@ -1509,14 +1498,20 @@ parse_requirements() { # :command.parse_requirements orcli_completions_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_completions_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_completions_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="completions" @@ -1526,18 +1521,18 @@ orcli_completions_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - ;; + ;; esac done @@ -1547,46 +1542,52 @@ orcli_completions_parse_requirements() { # :command.parse_requirements orcli_import_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_import_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_import_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action=${1:-} case $action in - -* ) - ;; + -*) + ;; - csv ) - action="csv" - shift - orcli_import_csv_parse_requirements "$@" - shift $# - ;; + csv) + action="csv" + shift + orcli_import_csv_parse_requirements "$@" + shift $# + ;; - tsv ) - action="tsv" - shift - orcli_import_tsv_parse_requirements "$@" - shift $# - ;; + tsv) + action="tsv" + shift + orcli_import_tsv_parse_requirements "$@" + shift $# + ;; - # :command.command_fallback - "" ) - orcli_import_usage >&2 - exit 1 - ;; + # :command.command_fallback + "") + orcli_import_usage >&2 + exit 1 + ;; - * ) - printf "invalid command: %s\n" "$action" >&2 - exit 1 - ;; + *) + printf "invalid command: %s\n" "$action" >&2 + exit 1 + ;; esac @@ -1595,18 +1596,18 @@ orcli_import_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - ;; + ;; esac done @@ -1616,14 +1617,20 @@ orcli_import_parse_requirements() { # :command.parse_requirements orcli_import_csv_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_import_csv_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_import_csv_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="import csv" @@ -1632,85 +1639,85 @@ orcli_import_csv_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in - # :flag.case - --separator ) + # :flag.case + --separator) - # :flag.case_arg - if [[ -n ${2+x} ]]; then + # :flag.case_arg + if [[ -n ${2+x} ]]; then - args[--separator]="$2" + args[--separator]="$2" + shift + shift + else + printf "%s\n" "--separator requires an argument: --separator SEPARATOR" >&2 + exit 1 + fi + ;; + + # :flag.case + --encoding) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + + args[--encoding]="$2" + shift + shift + else + printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 + exit 1 + fi + ;; + + # :flag.case + --trimStrings) + + # :flag.case_no_arg + args[--trimStrings]=1 shift + ;; + + # :flag.case + --projectName) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + + args[--projectName]="$2" + shift + shift + else + printf "%s\n" "--projectName requires an argument: --projectName PROJECTNAME" >&2 + exit 1 + fi + ;; + + # :flag.case + --quiet | -q) + + # :flag.case_no_arg + args[--quiet]=1 shift - else - printf "%s\n" "--separator requires an argument: --separator SEPARATOR" >&2 + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 exit 1 - fi - ;; + ;; - # :flag.case - --encoding ) + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_repeatable + if [[ -z ${args[file]+x} ]]; then - # :flag.case_arg - if [[ -n ${2+x} ]]; then + args[file]="\"$1\"" + shift + else + args[file]="${args[file]} \"$1\"" + shift + fi - args[--encoding]="$2" - shift - shift - else - printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 - exit 1 - fi - ;; - - # :flag.case - --trimStrings ) - - # :flag.case_no_arg - args[--trimStrings]=1 - shift - ;; - - # :flag.case - --projectName ) - - # :flag.case_arg - if [[ -n ${2+x} ]]; then - - args[--projectName]="$2" - shift - shift - else - printf "%s\n" "--projectName requires an argument: --projectName PROJECTNAME" >&2 - exit 1 - fi - ;; - - # :flag.case - --quiet | -q ) - - # :flag.case_no_arg - args[--quiet]=1 - shift - ;; - - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_repeatable - if [[ -z ${args[file]+x} ]]; then - - args[file]="\"$1\"" - shift - else - args[file]="${args[file]} \"$1\"" - shift - fi - - ;; + ;; esac done @@ -1724,14 +1731,20 @@ orcli_import_csv_parse_requirements() { # :command.parse_requirements orcli_import_tsv_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_import_tsv_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_import_tsv_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="import tsv" @@ -1740,70 +1753,70 @@ orcli_import_tsv_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in - # :flag.case - --encoding ) + # :flag.case + --encoding) - # :flag.case_arg - if [[ -n ${2+x} ]]; then + # :flag.case_arg + if [[ -n ${2+x} ]]; then - args[--encoding]="$2" + args[--encoding]="$2" + shift + shift + else + printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 + exit 1 + fi + ;; + + # :flag.case + --trimStrings) + + # :flag.case_no_arg + args[--trimStrings]=1 shift + ;; + + # :flag.case + --projectName) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + + args[--projectName]="$2" + shift + shift + else + printf "%s\n" "--projectName requires an argument: --projectName PROJECTNAME" >&2 + exit 1 + fi + ;; + + # :flag.case + --quiet | -q) + + # :flag.case_no_arg + args[--quiet]=1 shift - else - printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 exit 1 - fi - ;; + ;; - # :flag.case - --trimStrings ) + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_repeatable + if [[ -z ${args[file]+x} ]]; then - # :flag.case_no_arg - args[--trimStrings]=1 - shift - ;; + args[file]="\"$1\"" + shift + else + args[file]="${args[file]} \"$1\"" + shift + fi - # :flag.case - --projectName ) - - # :flag.case_arg - if [[ -n ${2+x} ]]; then - - args[--projectName]="$2" - shift - shift - else - printf "%s\n" "--projectName requires an argument: --projectName PROJECTNAME" >&2 - exit 1 - fi - ;; - - # :flag.case - --quiet | -q ) - - # :flag.case_no_arg - args[--quiet]=1 - shift - ;; - - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_repeatable - if [[ -z ${args[file]+x} ]]; then - - args[file]="\"$1\"" - shift - else - args[file]="${args[file]} \"$1\"" - shift - fi - - ;; + ;; esac done @@ -1816,14 +1829,20 @@ orcli_import_tsv_parse_requirements() { # :command.parse_requirements orcli_list_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_list_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_list_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="list" @@ -1833,18 +1852,18 @@ orcli_list_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - ;; + ;; esac done @@ -1854,14 +1873,20 @@ orcli_list_parse_requirements() { # :command.parse_requirements orcli_info_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_info_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_info_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="info" @@ -1871,24 +1896,24 @@ orcli_info_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - if [[ -z ${args[project]+x} ]]; then - - args[project]=$1 - shift - else - printf "invalid argument: %s\n" "$key" >&2 + -?*) + printf "invalid option: %s\n" "$key" >&2 exit 1 - fi + ;; - ;; + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + if [[ -z ${args[project]+x} ]]; then + + args[project]=$1 + shift + else + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + fi + + ;; esac done @@ -1904,14 +1929,20 @@ orcli_info_parse_requirements() { # :command.parse_requirements orcli_test_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_test_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_test_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="test" @@ -1921,44 +1952,41 @@ orcli_test_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_repeatable - if [[ -z ${args[file]+x} ]]; then + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - args[file]="\"$1\"" - shift - else - args[file]="${args[file]} \"$1\"" - shift - fi - - ;; + ;; esac done - # :command.default_assignments - [[ -n ${args[file]:-} ]] || args[file]="tests/*.sh" - } # :command.parse_requirements orcli_transform_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_transform_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_transform_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="transform" @@ -1967,36 +1995,36 @@ orcli_transform_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in - # :flag.case - --quiet | -q ) + # :flag.case + --quiet | -q) - # :flag.case_no_arg - args[--quiet]=1 - shift - ;; - - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_repeatable - if [[ -z ${args[project]+x} ]]; then - - args[project]=$1 + # :flag.case_no_arg + args[--quiet]=1 shift - elif [[ -z ${args[file]+x} ]]; then + ;; - args[file]="\"$1\"" - shift - else - args[file]="${args[file]} \"$1\"" - shift - fi + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - ;; + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_repeatable + if [[ -z ${args[project]+x} ]]; then + + args[project]=$1 + shift + elif [[ -z ${args[file]+x} ]]; then + + args[file]="\"$1\"" + shift + else + args[file]="${args[file]} \"$1\"" + shift + fi + + ;; esac done @@ -2015,39 +2043,45 @@ orcli_transform_parse_requirements() { # :command.parse_requirements orcli_export_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_export_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_export_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action=${1:-} case $action in - -* ) - ;; + -*) + ;; - tsv ) - action="tsv" - shift - orcli_export_tsv_parse_requirements "$@" - shift $# - ;; + tsv) + action="tsv" + shift + orcli_export_tsv_parse_requirements "$@" + shift $# + ;; - # :command.command_fallback - "" ) - orcli_export_usage >&2 - exit 1 - ;; + # :command.command_fallback + "") + orcli_export_usage >&2 + exit 1 + ;; - * ) - printf "invalid command: %s\n" "$action" >&2 - exit 1 - ;; + *) + printf "invalid command: %s\n" "$action" >&2 + exit 1 + ;; esac @@ -2056,18 +2090,18 @@ orcli_export_parse_requirements() { key="$1" case "$key" in - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; + -?*) + printf "invalid option: %s\n" "$key" >&2 + exit 1 + ;; - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - printf "invalid argument: %s\n" "$key" >&2 - exit 1 + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + printf "invalid argument: %s\n" "$key" >&2 + exit 1 - ;; + ;; esac done @@ -2077,14 +2111,20 @@ orcli_export_parse_requirements() { # :command.parse_requirements orcli_export_tsv_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_export_tsv_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_export_tsv_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="export tsv" @@ -2093,62 +2133,62 @@ orcli_export_tsv_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in - # :flag.case - --output ) + # :flag.case + --output) - # :flag.case_arg - if [[ -n ${2+x} ]]; then + # :flag.case_arg + if [[ -n ${2+x} ]]; then - args[--output]="$2" + args[--output]="$2" + shift + shift + else + printf "%s\n" "--output requires an argument: --output FILE" >&2 + exit 1 + fi + ;; + + # :flag.case + --encoding) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + + args[--encoding]="$2" + shift + shift + else + printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 + exit 1 + fi + ;; + + # :flag.case + --quiet | -q) + + # :flag.case_no_arg + args[--quiet]=1 shift - shift - else - printf "%s\n" "--output requires an argument: --output FILE" >&2 + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 exit 1 - fi - ;; + ;; - # :flag.case - --encoding ) + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_simple + if [[ -z ${args[project]+x} ]]; then - # :flag.case_arg - if [[ -n ${2+x} ]]; then + args[project]=$1 + shift + else + printf "invalid argument: %s\n" "$key" >&2 + exit 1 + fi - args[--encoding]="$2" - shift - shift - else - printf "%s\n" "--encoding requires an argument: --encoding ENCODING" >&2 - exit 1 - fi - ;; - - # :flag.case - --quiet | -q ) - - # :flag.case_no_arg - args[--quiet]=1 - shift - ;; - - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_simple - if [[ -z ${args[project]+x} ]]; then - - args[project]=$1 - shift - else - printf "invalid argument: %s\n" "$key" >&2 - exit 1 - fi - - ;; + ;; esac done @@ -2167,14 +2207,20 @@ orcli_export_tsv_parse_requirements() { # :command.parse_requirements orcli_run_parse_requirements() { # :command.fixed_flags_filter - case "${1:-}" in - --help | -h ) - long_usage=yes - orcli_run_usage - exit - ;; + while [[ $# -gt 0 ]]; do + case "${1:-}" in + --help | -h) + long_usage=yes + orcli_run_usage + exit + ;; - esac + *) + break + ;; + + esac + done # :command.command_filter action="run" @@ -2183,70 +2229,70 @@ orcli_run_parse_requirements() { while [[ $# -gt 0 ]]; do key="$1" case "$key" in - # :flag.case - --memory ) + # :flag.case + --memory) - # :flag.case_arg - if [[ -n ${2+x} ]]; then + # :flag.case_arg + if [[ -n ${2+x} ]]; then - args[--memory]="$2" + args[--memory]="$2" + shift + shift + else + printf "%s\n" "--memory requires an argument: --memory RAM" >&2 + exit 1 + fi + ;; + + # :flag.case + --port) + + # :flag.case_arg + if [[ -n ${2+x} ]]; then + + args[--port]="$2" + shift + shift + else + printf "%s\n" "--port requires an argument: --port PORT" >&2 + exit 1 + fi + ;; + + # :flag.case + --interactive) + + # :flag.case_no_arg + args[--interactive]=1 shift + ;; + + # :flag.case + --quiet | -q) + + # :flag.case_no_arg + args[--quiet]=1 shift - else - printf "%s\n" "--memory requires an argument: --memory RAM" >&2 + ;; + + -?*) + printf "invalid option: %s\n" "$key" >&2 exit 1 - fi - ;; + ;; - # :flag.case - --port ) + *) + # :command.parse_requirements_case + # :command.parse_requirements_case_repeatable + if [[ -z ${args[file]+x} ]]; then - # :flag.case_arg - if [[ -n ${2+x} ]]; then + args[file]="\"$1\"" + shift + else + args[file]="${args[file]} \"$1\"" + shift + fi - args[--port]="$2" - shift - shift - else - printf "%s\n" "--port requires an argument: --port PORT" >&2 - exit 1 - fi - ;; - - # :flag.case - --interactive ) - - # :flag.case_no_arg - args[--interactive]=1 - shift - ;; - - # :flag.case - --quiet | -q ) - - # :flag.case_no_arg - args[--quiet]=1 - shift - ;; - - -?* ) - printf "invalid option: %s\n" "$key" >&2 - exit 1 - ;; - - * ) - # :command.parse_requirements_case - # :command.parse_requirements_case_repeatable - if [[ -z ${args[file]+x} ]]; then - - args[file]="\"$1\"" - shift - else - args[file]="${args[file]} \"$1\"" - shift - fi - - ;; + ;; esac done @@ -2279,97 +2325,111 @@ run() { normalize_input "$@" parse_requirements "${input[@]}" - if [[ $action == "completions" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_completions_usage - else - orcli_completions_command - fi + case "$action" in + "completions") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_completions_usage + else + orcli_completions_command + fi + ;; - elif [[ $action == "import" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_import_usage - else - orcli_import_command - fi + "import") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_import_usage + else + orcli_import_command + fi + ;; - elif [[ $action == "import csv" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_import_csv_usage - else - orcli_import_csv_command - fi + "import csv") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_import_csv_usage + else + orcli_import_csv_command + fi + ;; - elif [[ $action == "import tsv" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_import_tsv_usage - else - orcli_import_tsv_command - fi + "import tsv") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_import_tsv_usage + else + orcli_import_tsv_command + fi + ;; - elif [[ $action == "list" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_list_usage - else - orcli_list_command - fi + "list") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_list_usage + else + orcli_list_command + fi + ;; - elif [[ $action == "info" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_info_usage - else - orcli_info_command - fi + "info") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_info_usage + else + orcli_info_command + fi + ;; - elif [[ $action == "test" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_test_usage - else - orcli_test_command - fi + "test") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_test_usage + else + orcli_test_command + fi + ;; - elif [[ $action == "transform" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_transform_usage - else - orcli_transform_command - fi + "transform") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_transform_usage + else + orcli_transform_command + fi + ;; - elif [[ $action == "export" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_export_usage - else - orcli_export_command - fi + "export") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_export_usage + else + orcli_export_command + fi + ;; - elif [[ $action == "export tsv" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_export_tsv_usage - else - orcli_export_tsv_command - fi + "export tsv") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_export_tsv_usage + else + orcli_export_tsv_command + fi + ;; - elif [[ $action == "run" ]]; then - if [[ ${args[--help]:-} ]]; then - long_usage=yes - orcli_run_usage - else - orcli_run_command - fi + "run") + if [[ ${args[--help]:-} ]]; then + long_usage=yes + orcli_run_usage + else + orcli_run_command + fi + ;; - elif [[ $action == "root" ]]; then - root_command - fi + "root") + root_command + ;; + + esac } initialize diff --git a/src/bashly.yml b/src/bashly.yml index 335e910..aaa23f9 100644 --- a/src/bashly.yml +++ b/src/bashly.yml @@ -118,11 +118,6 @@ commands: - name: test help: run functional tests on tmp OpenRefine workspace - args: - - name: file - help: Path to one or more files - default: "tests/*.sh" - repeatable: true - name: transform help: apply undo/redo JSON file(s) to an OpenRefine project diff --git a/src/test_command.sh b/src/test_command.sh index 20894b9..77a8b0e 100644 --- a/src/test_command.sh +++ b/src/test_command.sh @@ -1,15 +1,11 @@ # shellcheck shell=bash disable=SC2154 -# catch args, convert the space delimited string to an array -files=() -eval "files=(${args[file]})" - # check existence of files -for i in "${!files[@]}"; do - if ! [[ -f "${files[$i]}" ]]; then - error "cannot open ${files[$i]} (no such file)!" - fi -done +if ! [[ -f "tests/help.sh" ]]; then + error "Cannot open test files!" +fi +cd "tests" +files=(*.sh) # locate orcli and OpenRefine scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") @@ -48,15 +44,10 @@ results=() for i in "${!files[@]}"; do set +e bash -e <( - # support ./orcli if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" echo "alias orcli=${scriptpath}/orcli" fi - # separate subdirectory for each test - echo "mkdir -p ${OPENREFINE_TMPDIR}/${files[$i]}" - echo "cd ${OPENREFINE_TMPDIR}/${files[$i]} || exit 1" - # echo test file awk 1 "${files[$i]}" ) &>"$OPENREFINE_TMPDIR/test.log" results+=(${?}) diff --git a/tests/data/example.csv b/tests/data/example.csv new file mode 100644 index 0000000..8be467b --- /dev/null +++ b/tests/data/example.csv @@ -0,0 +1,4 @@ +a,b,c +1,2,3 +0,0,0 +$,\,' diff --git a/tests/data/example.tsv b/tests/data/example.tsv new file mode 100644 index 0000000..8c6d4cb --- /dev/null +++ b/tests/data/example.tsv @@ -0,0 +1,4 @@ +a b c +1 2 3 +0 0 0 +$ \ ' diff --git a/tests/help.sh b/tests/help.sh new file mode 100644 index 0000000..ee61e27 --- /dev/null +++ b/tests/help.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +t="help" + +# environment +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 +cd "${tmpdir}" || exit 1 + +# assertion +cat << "DATA" > "${t}.assert" +orcli - OpenRefine command-line interface written in Bash +DATA + +# action +orcli --help | head -n1 > "${t}.output" + +# test +diff -u "${t}.assert" "${t}.output" diff --git a/tests/import-csv.sh b/tests/import-csv.sh index f9406d5..9c93bf1 100644 --- a/tests/import-csv.sh +++ b/tests/import-csv.sh @@ -1,27 +1,17 @@ #!/bin/bash +t="import-csv" + # environment -t="$(basename "$(pwd)" .sh)" - -# data -cat << "DATA" > "${t}.csv" -a,b,c -1,2,3 -0,0,0 -$,\,' -DATA - -# assertion -cat << "DATA" > "${t}.assert" -a b c -1 2 3 -0 0 0 -$ \ ' -DATA +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 +cp data/example.csv "${tmpdir}"/${t}.csv +cp data/example.tsv "${tmpdir}"/${t}.assert +cd "${tmpdir}" || exit 1 # action orcli import csv "${t}.csv" orcli export tsv "${t} csv" --output "${t}.output" # test -diff -u "${t}.assert" "${t}.output" \ No newline at end of file +diff -u "${t}.assert" "${t}.output" From 56c9bbe21e6013f76f5f4058477af1240044a7d3 Mon Sep 17 00:00:00 2001 From: felixlohmeier Date: Sat, 3 Dec 2022 00:33:01 +0000 Subject: [PATCH 4/5] support ./orcli test --- README.md | 6 ++++++ orcli | 14 +++++++------- src/test_command.sh | 14 +++++++------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c6178a6..34af565 100644 --- a/README.md +++ b/README.md @@ -137,3 +137,9 @@ orcli uses [bashly](https://github.com/DannyBen/bashly/) for generating the one- ```sh bashly generate --upgrade ``` + +4. Run tests + + ```sh + ./orcli test + ``` \ No newline at end of file diff --git a/orcli b/orcli index 9fda828..9a6b339 100755 --- a/orcli +++ b/orcli @@ -1043,13 +1043,6 @@ orcli_test_command() { # src/test_command.sh # shellcheck shell=bash disable=SC2154 - # check existence of files - if ! [[ -f "tests/help.sh" ]]; then - error "Cannot open test files!" - fi - cd "tests" - files=(*.sh) - # locate orcli and OpenRefine scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") if [[ -x "${scriptpath}/refine" ]]; then @@ -1058,6 +1051,13 @@ orcli_test_command() { error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" fi + # check existence of files + if ! [[ -f "tests/help.sh" ]]; then + error "Cannot open test files!" + fi + cd "tests" + files=(*.sh) + # create tmp directory OPENREFINE_TMPDIR="$(mktemp -d)" trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 diff --git a/src/test_command.sh b/src/test_command.sh index 77a8b0e..65b9113 100644 --- a/src/test_command.sh +++ b/src/test_command.sh @@ -1,12 +1,5 @@ # shellcheck shell=bash disable=SC2154 -# check existence of files -if ! [[ -f "tests/help.sh" ]]; then - error "Cannot open test files!" -fi -cd "tests" -files=(*.sh) - # locate orcli and OpenRefine scriptpath=$(dirname "$(readlink -f "${BASH_SOURCE[0]}")") if [[ -x "${scriptpath}/refine" ]]; then @@ -15,6 +8,13 @@ else error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" fi +# check existence of files +if ! [[ -f "tests/help.sh" ]]; then + error "Cannot open test files!" +fi +cd "tests" +files=(*.sh) + # create tmp directory OPENREFINE_TMPDIR="$(mktemp -d)" trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 From 40de708115c7d39f88e25adf5d387ed2bbe1b56b Mon Sep 17 00:00:00 2001 From: felixlohmeier Date: Sat, 3 Dec 2022 23:39:53 +0000 Subject: [PATCH 5/5] additional tests --- orcli | 35 +++++++++++++++------------ src/test_command.sh | 35 +++++++++++++++------------ tests/completions.sh | 19 +++++++++++++++ tests/data/duplicates-transformed.tsv | 7 ++++++ tests/data/duplicates.csv | 11 +++++++++ tests/data/duplicates.tsv | 11 +++++++++ tests/export-tsv.sh | 21 ++++++++++++++++ tests/help.sh | 6 ++--- tests/import-csv.sh | 14 +++++++---- tests/info.sh | 18 ++++++++++++++ tests/list.sh | 18 ++++++++++++++ tests/run.sh | 21 ++++++++++++++++ tests/transform.sh | 19 +++++++++++++++ 13 files changed, 197 insertions(+), 38 deletions(-) create mode 100644 tests/completions.sh create mode 100644 tests/data/duplicates-transformed.tsv create mode 100644 tests/data/duplicates.csv create mode 100644 tests/data/duplicates.tsv create mode 100644 tests/export-tsv.sh create mode 100644 tests/info.sh create mode 100644 tests/list.sh create mode 100644 tests/run.sh create mode 100644 tests/transform.sh diff --git a/orcli b/orcli index 9a6b339..08e93bc 100755 --- a/orcli +++ b/orcli @@ -1051,24 +1051,27 @@ orcli_test_command() { error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" fi - # check existence of files - if ! [[ -f "tests/help.sh" ]]; then - error "Cannot open test files!" - fi - cd "tests" - files=(*.sh) - # create tmp directory OPENREFINE_TMPDIR="$(mktemp -d)" trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 - # check if OpenRefine is already running - if curl -fs "${OPENREFINE_URL}" &>/dev/null; then - error "OpenRefine is already running." + # download the test files if needed + if ! [[ -f "tests/help.sh" ]]; then + cd "$OPENREFINE_TMPDIR" + if ! curl -fs -L -o orcli.zip https://github.com/opencultureconsulting/orcli/archive/refs/heads/main.zip; then + error "downloading test files failed!" "Please download the tests dir manually from GitHub." + fi + unzip -q -j orcli.zip "*/tests/*.sh" -d "tests/" + unzip -q -j orcli.zip "*/tests/data/*" -d "tests/data/" fi - # start OpenRefine with tmp workspace and autosave period 25 hours - REFINE_AUTOSAVE_PERIOD=1440 $openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & + # check if OpenRefine is already running + if curl -fs "${OPENREFINE_URL}" &>/dev/null; then + error "OpenRefine is already running on port 3333." "Please stop the other process." + fi + + # start OpenRefine with tmp workspace + $openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & OPENREFINE_PID="$!" # update trap to kill OpenRefine on error or exit @@ -1081,11 +1084,13 @@ orcli_test_command() { log "started OpenRefine with tmp workspace ${OPENREFINE_TMPDIR}" fi - # execute script(s) in subshell + # execute tests in subshell export OPENREFINE_TMPDIR OPENREFINE_URL OPENREFINE_PID + cd "tests" + files=(*.sh) results=() for i in "${!files[@]}"; do - set +e + set +e # do not exit on failed tests bash -e <( if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" @@ -1103,7 +1108,7 @@ orcli_test_command() { fi done - # summary + # print overall result if [[ "${results[*]}" =~ [1-9] ]]; then error "failed tests!" else diff --git a/src/test_command.sh b/src/test_command.sh index 65b9113..82f7e48 100644 --- a/src/test_command.sh +++ b/src/test_command.sh @@ -8,24 +8,27 @@ else error "OpenRefine's startup script (refine) not found!" "Did you put orcli in your OpenRefine app dir?" fi -# check existence of files -if ! [[ -f "tests/help.sh" ]]; then - error "Cannot open test files!" -fi -cd "tests" -files=(*.sh) - # create tmp directory OPENREFINE_TMPDIR="$(mktemp -d)" trap '{ rm -rf "$OPENREFINE_TMPDIR"; }' 0 2 3 15 -# check if OpenRefine is already running -if curl -fs "${OPENREFINE_URL}" &>/dev/null; then - error "OpenRefine is already running." +# download the test files if needed +if ! [[ -f "tests/help.sh" ]]; then + cd "$OPENREFINE_TMPDIR" + if ! curl -fs -L -o orcli.zip https://github.com/opencultureconsulting/orcli/archive/refs/heads/main.zip; then + error "downloading test files failed!" "Please download the tests dir manually from GitHub." + fi + unzip -q -j orcli.zip "*/tests/*.sh" -d "tests/" + unzip -q -j orcli.zip "*/tests/data/*" -d "tests/data/" fi -# start OpenRefine with tmp workspace and autosave period 25 hours -REFINE_AUTOSAVE_PERIOD=1440 $openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & +# check if OpenRefine is already running +if curl -fs "${OPENREFINE_URL}" &>/dev/null; then + error "OpenRefine is already running on port 3333." "Please stop the other process." +fi + +# start OpenRefine with tmp workspace +$openrefine -d "$OPENREFINE_TMPDIR" -x refine.headless=true -v warn &>"$OPENREFINE_TMPDIR/openrefine.log" & OPENREFINE_PID="$!" # update trap to kill OpenRefine on error or exit @@ -38,11 +41,13 @@ else log "started OpenRefine with tmp workspace ${OPENREFINE_TMPDIR}" fi -# execute script(s) in subshell +# execute tests in subshell export OPENREFINE_TMPDIR OPENREFINE_URL OPENREFINE_PID +cd "tests" +files=(*.sh) results=() for i in "${!files[@]}"; do - set +e + set +e # do not exit on failed tests bash -e <( if ! command -v orcli &>/dev/null; then echo "shopt -s expand_aliases" @@ -60,7 +65,7 @@ for i in "${!files[@]}"; do fi done -# summary +# print overall result if [[ "${results[*]}" =~ [1-9] ]]; then error "failed tests!" else diff --git a/tests/completions.sh b/tests/completions.sh new file mode 100644 index 0000000..95010fd --- /dev/null +++ b/tests/completions.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +t="completions" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# assertion +cat << "DATA" > "${tmpdir}/${t}.assert" +# orcli completion -*- shell-script -*- +DATA + +# action +cd "${tmpdir}" || exit 1 +orcli completions | head -n1 > "${t}.output" + +# test +diff -u "${t}.assert" "${t}.output" diff --git a/tests/data/duplicates-transformed.tsv b/tests/data/duplicates-transformed.tsv new file mode 100644 index 0000000..88ae21b --- /dev/null +++ b/tests/data/duplicates-transformed.tsv @@ -0,0 +1,7 @@ +email count name state gender purchase +arthur.duff@example4.com 2 Arthur Duff OR M Dining table +ben.morisson@example6.org 1 Ben Morisson FL M Amplifier +ben.tyler@example3.org 1 Ben Tyler NV M Flashlight +danny.baron@example1.com 3 Danny Baron CA M TV +jean.griffith@example5.org 1 Jean Griffith WA F Power drill +melanie.white@example2.edu 2 Melanie White NC F iPhone diff --git a/tests/data/duplicates.csv b/tests/data/duplicates.csv new file mode 100644 index 0000000..8fcb581 --- /dev/null +++ b/tests/data/duplicates.csv @@ -0,0 +1,11 @@ +email,name,state,gender,purchase +danny.baron@example1.com,Danny Baron,CA,M,TV +melanie.white@example2.edu,Melanie White,NC,F,iPhone +danny.baron@example1.com,D. Baron,CA,M,Winter jacket +ben.tyler@example3.org,Ben Tyler,NV,M,Flashlight +arthur.duff@example4.com,Arthur Duff,OR,M,Dining table +danny.baron@example1.com,Daniel Baron,CA,M,Bike +jean.griffith@example5.org,Jean Griffith,WA,F,Power drill +melanie.white@example2.edu,Melanie White,NC,F,iPad +ben.morisson@example6.org,Ben Morisson,FL,M,Amplifier +arthur.duff@example4.com,Arthur Duff,OR,M,Night table \ No newline at end of file diff --git a/tests/data/duplicates.tsv b/tests/data/duplicates.tsv new file mode 100644 index 0000000..13ff40f --- /dev/null +++ b/tests/data/duplicates.tsv @@ -0,0 +1,11 @@ +email name state gender purchase +danny.baron@example1.com Danny Baron CA M TV +melanie.white@example2.edu Melanie White NC F iPhone +danny.baron@example1.com D. Baron CA M Winter jacket +ben.tyler@example3.org Ben Tyler NV M Flashlight +arthur.duff@example4.com Arthur Duff OR M Dining table +danny.baron@example1.com Daniel Baron CA M Bike +jean.griffith@example5.org Jean Griffith WA F Power drill +melanie.white@example2.edu Melanie White NC F iPad +ben.morisson@example6.org Ben Morisson FL M Amplifier +arthur.duff@example4.com Arthur Duff OR M Night table diff --git a/tests/export-tsv.sh b/tests/export-tsv.sh new file mode 100644 index 0000000..f831c4f --- /dev/null +++ b/tests/export-tsv.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +t="export-tsv" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# input +cp data/example.csv "${tmpdir}/${t}.csv" + +# assertion +cp data/example.tsv "${tmpdir}/${t}.assert" + +# action +cd "${tmpdir}" || exit 1 +orcli import csv "${t}.csv" +orcli export tsv "${t} csv" --output "${t}.output" + +# test +diff -u "${t}.assert" "${t}.output" diff --git a/tests/help.sh b/tests/help.sh index ee61e27..aa8ab87 100644 --- a/tests/help.sh +++ b/tests/help.sh @@ -2,17 +2,17 @@ t="help" -# environment +# create tmp directory tmpdir="$(mktemp -d)" trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 -cd "${tmpdir}" || exit 1 # assertion -cat << "DATA" > "${t}.assert" +cat << "DATA" > "${tmpdir}/${t}.assert" orcli - OpenRefine command-line interface written in Bash DATA # action +cd "${tmpdir}" || exit 1 orcli --help | head -n1 > "${t}.output" # test diff --git a/tests/import-csv.sh b/tests/import-csv.sh index 9c93bf1..4918d59 100644 --- a/tests/import-csv.sh +++ b/tests/import-csv.sh @@ -2,16 +2,20 @@ t="import-csv" -# environment +# create tmp directory tmpdir="$(mktemp -d)" trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 -cp data/example.csv "${tmpdir}"/${t}.csv -cp data/example.tsv "${tmpdir}"/${t}.assert -cd "${tmpdir}" || exit 1 + +# input +cp data/example.csv "${tmpdir}/${t}.csv" + +# assertion +cp data/example.tsv "${tmpdir}/${t}.assert" # action +cd "${tmpdir}" || exit 1 orcli import csv "${t}.csv" -orcli export tsv "${t} csv" --output "${t}.output" +orcli export tsv "${t} csv" > "${t}.output" # test diff -u "${t}.assert" "${t}.output" diff --git a/tests/info.sh b/tests/info.sh new file mode 100644 index 0000000..b6c89ae --- /dev/null +++ b/tests/info.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +t="info" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# input +cp data/example.csv "${tmpdir}/${t}.csv" + +# action +cd "${tmpdir}" || exit 1 +orcli import csv "${t}.csv" +orcli info "${t} csv" + +# test +# grep "${t}" "${t}.output" diff --git a/tests/list.sh b/tests/list.sh new file mode 100644 index 0000000..cb28e0d --- /dev/null +++ b/tests/list.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +t="list" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# input +cp data/example.csv "${tmpdir}/${t}.csv" + +# action +cd "${tmpdir}" || exit 1 +orcli import csv "${t}.csv" +orcli list > "${t}.output" + +# test +grep "${t}" "${t}.output" diff --git a/tests/run.sh b/tests/run.sh new file mode 100644 index 0000000..4420b8d --- /dev/null +++ b/tests/run.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +t="run" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# assertion +cp data/duplicates-transformed.tsv "${tmpdir}/${t}.assert" + +# action +cd "${tmpdir}" || exit 1 +orcli run --memory "2000M" --port "3334" << EOF +orcli import csv "https://git.io/fj5hF" --projectName "duplicates" +orcli transform "duplicates" "https://git.io/fj5ju" +orcli export tsv "duplicates" --output "${t}.output" +EOF + +# test +diff -u "${t}.assert" "${t}.output" \ No newline at end of file diff --git a/tests/transform.sh b/tests/transform.sh new file mode 100644 index 0000000..a6ee492 --- /dev/null +++ b/tests/transform.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +t="transform" + +# create tmp directory +tmpdir="$(mktemp -d)" +trap '{ rm -rf "${tmpdir}"; }' 0 2 3 15 + +# assertion +cp data/duplicates-transformed.tsv "${tmpdir}/${t}.assert" + +# action +cd "${tmpdir}" || exit 1 +orcli import csv "https://git.io/fj5hF" --projectName "duplicates" +orcli transform "duplicates" "https://git.io/fj5ju" +orcli export tsv "duplicates" --output "${t}.output" + +# test +diff -u "${t}.assert" "${t}.output" \ No newline at end of file