install.sh and pkg-inventory.sh carried byte-identical copies of read_manifest. That is the duplicated-code half of the problem; the worse half is untested — neither script had any test for the grammar that decides what gets installed. - scripts/lib/manifest.sh is the parser; both scripts source it - tests/manifest-parser.bats writes the contract first (comments, CRLF, first field only, unreadable file fails loudly instead of yielding "nothing desired") - an unreadable manifest now fails inside the helper rather than depending on whichever `set` options the caller happens to run under - install.sh check mode verified end to end against a stubbed pacman: a CRLF manifest with trailing comments resolves to bare names, installed names drop Refs #60
52 lines
2.1 KiB
Bash
Executable File
52 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bats
|
|
# tests/manifest-parser.bats — the one manifest parser, shared by install.sh and pkg-inventory.sh
|
|
#
|
|
# `packages/*.pkgs` is hand-written, so the parser's whole job is to forgive the ways a hand-edited
|
|
# list is wrong. The same function decides what install.sh tries to install and what pkg-inventory
|
|
# calls drift, so a manifest line must mean the same thing to both — which is why it lives in one
|
|
# file instead of being pasted into each caller (Refs #60: it was pasted twice).
|
|
#
|
|
# Observed through the function's exit status and stdout only:
|
|
# names first field of a line, one bare token; `#` and everything after it is a comment
|
|
# CRLF tolerated (the manifests get edited on more than one box)
|
|
# blank lines vanish
|
|
# unreadable non-zero with no names — an empty desired list must never be a silent success,
|
|
# because "nothing desired" is exactly what a rebuild would install
|
|
|
|
setup() {
|
|
TEST_TMP="$(mktemp -d)"
|
|
LIB="$BATS_TEST_DIRNAME/../scripts/lib/manifest.sh"
|
|
}
|
|
|
|
teardown() { rm -rf "$TEST_TMP"; }
|
|
|
|
parse() { # $1 = manifest contents, verbatim
|
|
printf '%s' "$1" > "$TEST_TMP/m.pkgs"
|
|
run bash -c 'source "$1"; read_manifest "$2"' _ "$LIB" "$TEST_TMP/m.pkgs"
|
|
}
|
|
|
|
@test "inline notes, full-line comments, blank rows and CRLF come out as bare names" {
|
|
parse $'# desired state\r\nghostty # terminal\r\n\r\n \r\nzoxide\r\n'
|
|
[ "$status" -eq 0 ]
|
|
[ "$(printf '%s\n' "$output" | tr '\n' ' ')" = "ghostty zoxide " ]
|
|
}
|
|
|
|
@test "only the first field of a line is a package" {
|
|
# install.sh hands every emitted token straight to pacman, so a stray second token on a line
|
|
# must never become an install target; whatever it is, the manifest did not declare it.
|
|
parse $'neovim extra tokens here\n'
|
|
[ "$output" = "neovim" ]
|
|
}
|
|
|
|
@test "a comment that names a package is not a package" {
|
|
parse $'# vlc\n#typora\nbun\n'
|
|
[ "$output" = "bun" ]
|
|
}
|
|
|
|
@test "an unreadable manifest fails loudly instead of yielding an empty desired list" {
|
|
run --separate-stderr bash -c 'source "$1"; read_manifest "$2"' _ "$LIB" "$TEST_TMP/nope.pkgs"
|
|
[ "$status" -ne 0 ]
|
|
[ -z "$output" ]
|
|
[[ "$stderr" == *nope.pkgs* ]]
|
|
}
|