Skip to content

feat(assert): symlink assertions - #995

Merged
Chemaclass merged 1 commit into
mainfrom
feat/981-symlink-assertions
Aug 8, 2026
Merged

feat(assert): symlink assertions#995
Chemaclass merged 1 commit into
mainfrom
feat/981-symlink-assertions

Conversation

@Chemaclass

Copy link
Copy Markdown
Member

🤔 Background

Related #981

Nothing in the catalogue could assert anything about a symlink. Every filesystem assertion follows the link (-f, -e report on the target), so a link and the file it points at were indistinguishable — and a dangling link answered "does not exist", the same as a path that was never created:

ln -s "$dir/target" "$dir/link"
assert_is_file "$dir/link"           # passes — describing the target

ln -s "$dir/missing" "$dir/broken"
assert_file_not_exists "$dir/broken" # passes — describing nothing

That matters for what people actually write bash for: install scripts, dotfile managers, a release layout with a current -> releases/N pointer. For those, "the link exists and points where it should" is the assertion.

💡 Changes

Assertion Passes when
assert_is_symlink "$path" $path is a symbolic link, resolved or not
assert_is_not_symlink "$path" $path is not a symbolic link
assert_symlink_to "$target" "$path" $path is a link and points at $target

🧭 Two decisions the issue asked to be made, not guessed

A dangling link is still a link. assert_is_symlink passes for one — separating "is a link" from "the target resolves" is exactly the distinction that was missing, and the two existing assertions already answer the second question.

assert_symlink_to compares the target as written, through readlink, not the resolved path. It's what the test author wrote, so a failure names something they recognise; and readlink -f is GNU-only, so resolving would need a second implementation for BSD/macOS. A relative link compares as the relative string it is — documented.

✅ Verification

8 new tests, all RED first. They skip on Windows, where Git Bash turns symlink creation into a copy — matching the existing guard on the permission tests.

docs/assertions.md, both completion scripts and the doc snapshot updated. The completions parity test caught assert_symlink_to missing from the lists, which is the job it exists for.

make sa · make lint · bash build.sh bin -v✅ Build verified ✅ · 1705 sequential / 1664 parallel-simple-strict.

Closes #981.

Nothing in the catalogue could assert anything about a symlink. Every
filesystem assertion follows the link -- `-f` and `-e` report on the target --
so a link and the file it points at were indistinguishable, and a dangling link
answered "does not exist", the same as a path that was never created:

    ln -s "$dir/target" "$dir/link"
    assert_is_file "$dir/link"          # passes, describing the target
    ln -s "$dir/missing" "$dir/broken"
    assert_file_not_exists "$dir/broken" # passes, describing nothing

That matters for the things people actually write bash for: install scripts,
dotfile managers, a release layout with a `current -> releases/N` pointer. For
those, "the link exists and points where it should" is the assertion.

Three added: assert_is_symlink, assert_is_not_symlink, assert_symlink_to.

Two decisions the issue asked to be made rather than guessed.

A dangling link is still a link. assert_is_symlink passes for one, because
separating "is a link" from "the target resolves" is exactly the distinction
that was missing -- and the two existing assertions already answer the second
question.

assert_symlink_to compares the target **as written**, through `readlink`, not
the resolved path. It is what the test author wrote, so a failure names
something they recognise, and `readlink -f` is GNU-only, so resolving would
need a second implementation for BSD/macOS. A relative link compares as the
relative string it is; documented as such.

Tests skip on Windows, where Git Bash turns symlink creation into a copy --
matching the existing guard on the permission tests.

docs/assertions.md, both completion scripts and the doc snapshot updated. The
completions parity test caught assert_symlink_to missing from the lists, which
is the job it exists for.

1705 sequential / 1664 parallel; baseline + 8, all RED first.
@Chemaclass Chemaclass added the enhancement New feature or request label Aug 8, 2026
@Chemaclass Chemaclass self-assigned this Aug 8, 2026
@Chemaclass
Chemaclass merged commit a2029e1 into main Aug 8, 2026
37 checks passed
@Chemaclass
Chemaclass deleted the feat/981-symlink-assertions branch August 8, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant