wfxr.forgit/tests/fzf.test.sh
Wenxuan 17110bfc61
fix: preserve add paths across special filenames (#506)
Keep `forgit add` on the porcelain `git status --porcelain -zs` path so
filenames containing backslashes continue to work, while restoring the
behaviors that regressed when we moved away from Git's cwd-relative output.

This change makes the status picker emit a display label and a hidden
absolute-path payload separately. That lets the UI keep showing intuitive
cwd-relative paths, while preview, edit, and add actions operate on the real
path instead of reparsing the rendered status line. As a result, untracked
files, subdirectory workflows, and special filenames now share one consistent
path flow.

It also restores the old-Git fallback for plain `?? path` output before status
filtering, raises the required fzf version for `--accept-nth`, and adds
regression coverage for backslashes, spaces, tabs, subdirectory entries,
sibling directories, and logical symlink paths.

We explored a few alternatives before landing here. Keeping a single
human-readable line and reparsing it downstream remained too fragile for
quoted paths and backslashes. Shell-only display-path rewriting worked for
some cases but stayed brittle across logical vs physical paths and still
failed in macOS CI. A per-path `realpath` approach would have been easier to
read, but GNU-style relative-path support is not portable across the
platforms we test and would add one external process per file in a hot path.

The final tradeoff keeps the pipeline batch-oriented and portable by doing
the path normalization once in a single helper step, even though that is less
lightweight than the earlier shell-only versions. That complexity is
justified here because it fixes the old-Git untracked regression, preserves
correct preview/add behavior from subdirectories, and avoids reintroducing
long-standing filename parsing bugs.
2026-04-08 10:40:03 +08:00

50 lines
1.1 KiB
Bash

#!/usr/bin/env bash
function set_up_before_script() {
source bin/git-forgit
}
function test_exit_when_fzf_is_not_installed() {
# Error code 127 = "command not found"
bashunit::mock fzf "return 127"
output=$(bin/git-forgit)
assert_general_error
assert_contains "fzf is not installed" "$output"
}
# @data_provider fzf_versions_below_required_version
function test_exit_when_fzf_version_is_below_required_version() {
bashunit::mock "fzf" "echo '$1'"
output=$(bin/git-forgit)
assert_general_error
assert_contains "fzf version $REQUIRED_FZF_VERSION or higher is required" "$output"
}
function fzf_versions_below_required_version() {
echo "0.0.2"
echo "0.5.0"
echo "0.30.0"
echo "0.48.9"
}
# @data_provider fzf_versions_satisfying_required_version
function test_pass_when_fzf_version_satisfies_required_version() {
bashunit::mock "fzf" "echo '$1'"
output=$(bin/git-forgit)
assert_general_error
assert_contains "missing command" "$output"
}
function fzf_versions_satisfying_required_version() {
echo "0.60.0"
echo "0.60.1"
echo "0.80.0"
echo "1.1.0"
}