#!/bin/bash # shellcheck disable=SC2048,SC2086 # Unquoted $* is intentional — the jw-pkg command line export LC_ALL="C" set -euo pipefail jw_pkg_py="$*" # Print a header and run a command whose output is part of the expected # result. Under `set -e` a non-zero exit aborts the test. run() { local log_cmd # shellcheck disable=SC2001 log_cmd=$(echo "$*" | sed 's|.*python3[0-9.]*\s\+\(\.\.\/\)*scripts/||') printf '============= Running: %s\n' "$log_cmd" "$@" } # Run a command that must exit non-zero and report the given message. Prints # the command, the resulting error message, and the observed exit status. # Fails the test if the command unexpectedly succeeds or the message is # missing. Only the last output line is shown: for the app-level errors it is # the error itself, and for argparse rejections it is the error line, which # keeps the expected file free of the volatile usage text. expect_fail() { local expected out rc log_cmd expected=$1 shift # shellcheck disable=SC2001 log_cmd=$(echo "$*" | sed 's|.*python3[0-9.]*\s\+\(\.\.\/\)*scripts/||') printf '============= Running (expect failure): %s\n' "$log_cmd" set +e out=$("$@" 2>&1) rc=$? set -e printf '%s\n' "$(tail -n 1 <<<"$out")" printf '============= Exit status: %s\n' "$rc" if [ "$rc" -eq 0 ]; then echo "ERROR: expected failure, but the command succeeded" >&2 return 1 fi if ! grep -qF -- "$expected" <<<"$out"; then echo "ERROR: expected message not found: $expected" >&2 return 1 fi } cmd_test() { # -- tmpl: substitute a field; a marker without a value stays literal run $jw_pkg_py projects create-file --format tmpl \ --template-name basic.tmpl --search-path templates \ --field name=foo jw-pkg # -- tmpl: multi-value field, default separator (comma, newline) run $jw_pkg_py projects create-file --format tmpl \ --template-name list.tmpl --search-path templates \ --field items=a --field items=b jw-pkg # -- tmpl: multi-value field, custom separator run $jw_pkg_py projects create-file --format tmpl \ --template-name list.tmpl --search-path templates \ --field items=a --field items=b --field-separator '|' jw-pkg # -- tmpl: multi-value field, "%n" separator run $jw_pkg_py projects create-file --format tmpl \ --template-name list.tmpl --search-path templates \ --field items=a --field items=b --field-separator '%n' jw-pkg # -- tmpl: multi-value field, quoted values run $jw_pkg_py projects create-file --format tmpl \ --template-name list.tmpl --search-path templates \ --field items=a --field items=b --quote --field-separator '|' jw-pkg # -- tmpl: --field-keys adds keys that were not passed as empty fields run $jw_pkg_py projects create-file --format tmpl \ --template-name basic.tmpl --search-path templates \ --field-keys name,path --field name=foo jw-pkg # -- pyright: built-in template, extra paths from project metadata run $jw_pkg_py projects create-file --format pyright \ --field base=./conf/project/pyrightconfig-base.json \ --field include=src/python jw-pkg # -- errors expect_fail "Can't render template without name" \ $jw_pkg_py projects create-file --format tmpl jw-pkg expect_fail 'Failed to find template "nosuch.tmpl"' \ $jw_pkg_py projects create-file --format tmpl \ --template-name nosuch.tmpl --search-path templates jw-pkg expect_fail "not in --field-keys: path" \ $jw_pkg_py projects create-file --format tmpl \ --template-name basic.tmpl --search-path templates \ --field-keys name --field path=x jw-pkg expect_fail 'Unsupported separator for pyright config: "|"' \ $jw_pkg_py projects create-file --format pyright \ --field base=x --field include=y --field-separator '|' jw-pkg expect_fail "invalid choice: 'bogus'" \ $jw_pkg_py projects create-file --format bogus jw-pkg expect_fail "Expected KEY=VALUE" \ $jw_pkg_py projects create-file --format tmpl \ --template-name basic.tmpl --search-path templates --field noval jw-pkg } cmd_test