Add bats test suite for image processing scripts
Tests cover skip-already-processed logic, cleanup, idempotency, and the config.sh single-source-of-truth invariant. bats-core, bats-assert, and bats-support added as submodules under tests/libs/.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
[submodule "tests/libs/bats-core"]
|
||||
path = tests/libs/bats-core
|
||||
url = https://github.com/bats-core/bats-core.git
|
||||
[submodule "tests/libs/bats-assert"]
|
||||
path = tests/libs/bats-assert
|
||||
url = https://github.com/bats-core/bats-assert.git
|
||||
[submodule "tests/libs/bats-support"]
|
||||
path = tests/libs/bats-support
|
||||
url = https://github.com/bats-core/bats-support.git
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
load 'helpers/common'
|
||||
|
||||
@test "config.sh defines MAGICK_COMMENT" {
|
||||
run bash -c "source '$REPO_ROOT/config.sh' && echo \"\$MAGICK_COMMENT\""
|
||||
assert_success
|
||||
assert_output "magick:resize=8mp,quality=85,sampling=4:2:0"
|
||||
}
|
||||
|
||||
@test "config.sh defines MAX_PIXELS" {
|
||||
run bash -c "source '$REPO_ROOT/config.sh' && echo \"\$MAX_PIXELS\""
|
||||
assert_success
|
||||
assert_output "8000000"
|
||||
}
|
||||
|
||||
@test "MAGICK_COMMENT matches in images_resize.sh and zip_images_resize.sh" {
|
||||
local comment_from_config comment_in_resize comment_in_zip
|
||||
comment_from_config=$(bash -c "source '$REPO_ROOT/config.sh' && echo \"\$MAGICK_COMMENT\"")
|
||||
comment_in_resize=$(grep 'MAGICK_COMMENT=' "$REPO_ROOT/images_resize.sh" | grep -v source || true)
|
||||
comment_in_zip=$(grep 'MAGICK_COMMENT=' "$REPO_ROOT/zip_images_resize.sh" | grep -v source || true)
|
||||
# Neither script should define MAGICK_COMMENT itself — only config.sh should
|
||||
assert_equal "" "$comment_in_resize"
|
||||
assert_equal "" "$comment_in_zip"
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 804 B |
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 316 B |
@@ -0,0 +1,30 @@
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
FIXTURES="$REPO_ROOT/tests/fixtures"
|
||||
MOCKS="$REPO_ROOT/tests/mocks"
|
||||
|
||||
setup_mock_env() {
|
||||
# Redirect ~/Applications/magick to our mock by overriding HOME
|
||||
TEST_HOME="$(mktemp -d)"
|
||||
mkdir -p "$TEST_HOME/Applications"
|
||||
ln -s "$MOCKS/magick" "$TEST_HOME/Applications/magick"
|
||||
export HOME="$TEST_HOME"
|
||||
|
||||
# Working dir for each test
|
||||
TEST_WORKDIR="$(mktemp -d)"
|
||||
}
|
||||
|
||||
teardown_mock_env() {
|
||||
rm -rf "$TEST_HOME" "$TEST_WORKDIR"
|
||||
}
|
||||
|
||||
make_zip() {
|
||||
local zip_path="$1"; shift # destination zip path
|
||||
local -a jpegs=("$@") # JPEG files to include
|
||||
local tmpdir
|
||||
tmpdir="$(mktemp -d)"
|
||||
for jpg in "${jpegs[@]}"; do
|
||||
cp "$jpg" "$tmpdir/"
|
||||
done
|
||||
(cd "$tmpdir" && zip -q "$zip_path" ./*.jpg)
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
load 'helpers/common'
|
||||
|
||||
SCRIPT="$REPO_ROOT/images_resize.sh"
|
||||
|
||||
setup() {
|
||||
setup_mock_env
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_mock_env
|
||||
}
|
||||
|
||||
@test "skips JPEG that already has the processing comment" {
|
||||
cp "$FIXTURES/processed.jpg" "$TEST_WORKDIR/img.jpg"
|
||||
run bash -c "cd '$TEST_WORKDIR' && '$SCRIPT'"
|
||||
assert_success
|
||||
assert_output --partial "Skipping"
|
||||
assert_output --partial "already processed"
|
||||
}
|
||||
|
||||
@test "processes JPEG without the comment and embeds it" {
|
||||
cp "$FIXTURES/unprocessed.jpg" "$TEST_WORKDIR/img.jpg"
|
||||
run bash -c "cd '$TEST_WORKDIR' && '$SCRIPT'"
|
||||
assert_success
|
||||
assert_output --partial "Resized"
|
||||
local comment
|
||||
comment=$(identify -format "%c" "$TEST_WORKDIR/img.jpg")
|
||||
assert_equal "$comment" "magick:resize=8mp,quality=85,sampling=4:2:0"
|
||||
}
|
||||
|
||||
@test "re-running skips a JPEG that was just processed" {
|
||||
cp "$FIXTURES/unprocessed.jpg" "$TEST_WORKDIR/img.jpg"
|
||||
bash -c "cd '$TEST_WORKDIR' && '$SCRIPT'" >/dev/null 2>&1
|
||||
run bash -c "cd '$TEST_WORKDIR' && '$SCRIPT'"
|
||||
assert_success
|
||||
assert_output --partial "Skipping"
|
||||
}
|
||||
|
||||
@test "processes only JPEGs, ignores other file types" {
|
||||
cp "$FIXTURES/unprocessed.jpg" "$TEST_WORKDIR/img.jpg"
|
||||
echo "not an image" > "$TEST_WORKDIR/readme.txt"
|
||||
run bash -c "cd '$TEST_WORKDIR' && '$SCRIPT'"
|
||||
assert_success
|
||||
assert_output --partial "Resized"
|
||||
refute_output --partial "readme.txt"
|
||||
}
|
||||
Submodule
+1
Submodule tests/libs/bats-assert added at 697471b7a8
Submodule
+1
Submodule tests/libs/bats-core added at 5a7db7a989
Submodule
+1
Submodule tests/libs/bats-support added at 0954abb992
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
# Mock for ~/Applications/magick.
|
||||
# identify: delegate to real system identify.
|
||||
# convert (resize call): copy in-place and embed the comment so the file
|
||||
# looks processed on the next run.
|
||||
if [ "$1" = "identify" ]; then
|
||||
shift
|
||||
identify "$@"
|
||||
exit $?
|
||||
fi
|
||||
|
||||
# Parse -set comment <value> and the output file (last arg) from the argument list
|
||||
COMMENT=""
|
||||
OUTFILE="${@: -1}"
|
||||
args=("$@")
|
||||
for i in "${!args[@]}"; do
|
||||
if [ "${args[$i]}" = "-set" ] && [ "${args[$i+1]}" = "comment" ]; then
|
||||
COMMENT="${args[$i+2]}"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$COMMENT" ]; then
|
||||
convert "$OUTFILE" -set comment "$COMMENT" "$OUTFILE"
|
||||
fi
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env bats
|
||||
|
||||
load 'libs/bats-support/load'
|
||||
load 'libs/bats-assert/load'
|
||||
load 'helpers/common'
|
||||
|
||||
SCRIPT="$REPO_ROOT/zip_images_resize.sh"
|
||||
|
||||
setup() {
|
||||
setup_mock_env
|
||||
}
|
||||
|
||||
teardown() {
|
||||
teardown_mock_env
|
||||
}
|
||||
|
||||
@test "prints usage and exits 1 when no arguments given" {
|
||||
run "$SCRIPT"
|
||||
assert_failure
|
||||
assert_output --partial "Usage:"
|
||||
}
|
||||
|
||||
@test "skips ZIP whose first JPEG already has the processing comment" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/processed.jpg"
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
assert_success
|
||||
assert_output --partial "Skipping"
|
||||
assert_output --partial "already processed"
|
||||
}
|
||||
|
||||
@test "does not skip ZIP whose JPEG has no processing comment" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/unprocessed.jpg"
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
assert_success
|
||||
refute_output --partial "Skipping"
|
||||
assert_output --partial "Resized"
|
||||
}
|
||||
|
||||
@test "processed ZIP is unchanged on disk after skip" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/processed.jpg"
|
||||
local before_size after_size
|
||||
before_size=$(stat -c%s "$TEST_WORKDIR/archive.zip")
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
after_size=$(stat -c%s "$TEST_WORKDIR/archive.zip")
|
||||
assert_equal "$before_size" "$after_size"
|
||||
}
|
||||
|
||||
@test "after processing, re-running skips the same ZIP" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/unprocessed.jpg"
|
||||
"$SCRIPT" "$TEST_WORKDIR/archive.zip" >/dev/null 2>&1
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
assert_success
|
||||
assert_output --partial "Skipping"
|
||||
}
|
||||
|
||||
@test "ZIP with no JPEGs inside is processed without error" {
|
||||
echo "not an image" > "$TEST_WORKDIR/readme.txt"
|
||||
(cd "$TEST_WORKDIR" && zip -q archive.zip readme.txt)
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
assert_success
|
||||
refute_output --partial "Skipping"
|
||||
refute_output --partial "Error:"
|
||||
}
|
||||
|
||||
@test "no temp files left in /dev/shm after processing" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/unprocessed.jpg"
|
||||
local before after
|
||||
before=$(find /dev/shm -maxdepth 1 -name 'tmp.*' | sort)
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
after=$(find /dev/shm -maxdepth 1 -name 'tmp.*' | sort)
|
||||
assert_equal "$before" "$after"
|
||||
}
|
||||
|
||||
@test "no temp files left in /dev/shm after skipping" {
|
||||
make_zip "$TEST_WORKDIR/archive.zip" "$FIXTURES/processed.jpg"
|
||||
local before after
|
||||
before=$(find /dev/shm -maxdepth 1 -name 'tmp.*' | sort)
|
||||
run "$SCRIPT" "$TEST_WORKDIR/archive.zip"
|
||||
after=$(find /dev/shm -maxdepth 1 -name 'tmp.*' | sort)
|
||||
assert_equal "$before" "$after"
|
||||
}
|
||||
|
||||
@test "processes multiple ZIPs, skipping already-processed ones" {
|
||||
make_zip "$TEST_WORKDIR/done.zip" "$FIXTURES/processed.jpg"
|
||||
make_zip "$TEST_WORKDIR/todo.zip" "$FIXTURES/unprocessed.jpg"
|
||||
run "$SCRIPT" "$TEST_WORKDIR/done.zip" "$TEST_WORKDIR/todo.zip"
|
||||
assert_success
|
||||
assert_output --partial "Skipping"
|
||||
assert_output --partial "Resized"
|
||||
}
|
||||
Reference in New Issue
Block a user