test_help_navigation.sh
1 #!/bin/bash 2 # Validate help navigation behaviour when forcing a pager 3 4 set -euo pipefail 5 6 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 REPO_ROOT="$(dirname "$SCRIPT_DIR")" 8 BAR_CMD="$REPO_ROOT/bar" 9 10 first_line() { 11 local line fd 12 exec {fd}< <("$@") 13 if IFS= read -r line <&$fd; then 14 printf '%s\n' "$line" 15 exec {fd}<&- 16 return 0 17 fi 18 exec {fd}<&- 19 return 1 20 } 21 22 first_non_empty_line() { 23 local line fd 24 exec {fd}< <("$@") 25 while IFS= read -r line <&$fd; do 26 [[ -z "$line" ]] && continue 27 printf '%s\n' "$line" 28 exec {fd}<&- 29 return 0 30 done 31 exec {fd}<&- 32 return 1 33 } 34 35 # 1. Indexed match should jump directly to ABOUT 36 if ! about_line="$(BAR_FORCE_PAGER=less first_line "$BAR_CMD" --bare help about)"; then 37 echo "✗ help about command failed" 38 exit 1 39 fi 40 if [[ "$about_line" =~ ^[[:space:]]*ABOUT[[:space:]]*$ ]]; then 41 echo "✓ help about jumps to ABOUT" 42 else 43 echo "✗ help about should start at ABOUT (got: $about_line)" 44 exit 1 45 fi 46 47 # 2. Unknown query should fall back to full help without failing 48 if ! fallback_line="$(BAR_FORCE_PAGER=less first_non_empty_line "$BAR_CMD" --bare help __does_not_exist)"; then 49 echo "✗ help fallback command failed" 50 exit 1 51 fi 52 if [[ "$fallback_line" =~ ^[[:space:]]*bar[[:space:]]-- ]]; then 53 echo "✓ help fallback prints full help when query is missing" 54 else 55 echo "✗ help fallback should start with header (got: $fallback_line)" 56 exit 1 57 fi 58 59 # 2b. Example documentation should not be treated as real symbol 60 if ! foo_line="$(BAR_FORCE_PAGER=less first_non_empty_line "$BAR_CMD" --bare help foo)"; then 61 echo "✗ help foo command failed" 62 exit 1 63 fi 64 if [[ "$foo_line" =~ foo ]]; then 65 echo "✗ help foo should not jump to documentation example (got: $foo_line)" 66 exit 1 67 else 68 echo "✓ help foo does not treat documentation example as symbol" 69 fi 70 71 # 3. Partial function name should resolve to git_ls_files 72 if ! ls_line="$(BAR_FORCE_PAGER=less first_line "$BAR_CMD" --bare help ls_files)"; then 73 echo "✗ help ls_files command failed" 74 exit 1 75 fi 76 if [[ "$ls_line" =~ ls_files ]]; then 77 echo "✓ help ls_files jumps to git_ls_files" 78 else 79 echo "✗ help ls_files should show git_ls_files (got: $ls_line)" 80 exit 1 81 fi 82 83 # 4. No query should still succeed under BAR_FORCE_PAGER when piped 84 if ! header_line="$(BAR_FORCE_PAGER=less first_non_empty_line "$BAR_CMD" --bare help)"; then 85 echo "✗ help without query failed" 86 exit 1 87 fi 88 if [[ "$header_line" =~ ^[[:space:]]*bar[[:space:]]-- ]]; then 89 echo "✓ help without query works under BAR_FORCE_PAGER" 90 else 91 echo "✗ help without query should start with header (got: $header_line)" 92 exit 1 93 fi 94 95 # 5. --section should slice to the matching section 96 if ! section_line="$(BAR_FORCE_PAGER=less first_non_empty_line "$BAR_CMD" --bare help --section git)"; then 97 echo "✗ help --section git command failed" 98 exit 1 99 fi 100 if [[ "$section_line" =~ ^[[:space:]]*git[[:space:]]- ]]; then 101 echo "✓ help --section git limits output to git section" 102 else 103 echo "✗ help --section git should start at git section (got: $section_line)" 104 exit 1 105 fi