diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-22 09:52:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-22 09:52:57 +0300 |
| commit | 6945a0ae9afb18313636c09f34959ee5b225f78d (patch) | |
| tree | e74aa7b861543f5407de863f9667b4ccc994bbbd /tests | |
| parent | 79d78a296d2919155fe4d4bb2fac73d2fa7adeec (diff) | |
Add dynamic subdivided thumbnail tiles
Make the album preview grid livelier: with a configurable probability
(THUMB_SUBDIVIDE_PERCENT, default 30%) a square thumbnail tile is
subdivided into several smaller thumbnails packed into the same square
footprint, chosen at random from:
- quad: 2x2 squares (4 photos)
- two-wide: two stacked full-width strips (2 photos)
- squares+wide: two squares plus one full-width strip, strip on the
top or the bottom (3 photos)
Each sub-thumbnail stays its own clickable photo with its own view page;
subdivision only groups consecutive photos visually, so preview
numbering and the view/details/redirect pages are unchanged. No new
images are generated (CSS object-fit crops the existing aspect-correct
thumbs into squares or wide strips). Sub-thumbnails get the same random
entry animation and the same dramatic hover (flip/scale/rotate/filter)
as full thumbs. The layout choice reuses the seeded random_index, so
builds stay reproducible under RANDOM_SEED. THUMB_SUBDIVIDE_PERCENT=0
reproduces the previous output byte-for-byte.
The new option is wired through the config defaults, validation
(0..100), --print-config, the --subdivide CLI flag, the usage text, and
the shuriken.json / --dry-run metadata, with docs and tests updated.
Generated HTML and CSS pass the W3C Nu HTML checker and CSS validator.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'tests')
| -rwxr-xr-x | tests/cli.sh | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/cli.sh b/tests/cli.sh index 436970a..3181746 100755 --- a/tests/cli.sh +++ b/tests/cli.sh @@ -139,6 +139,7 @@ assert metadata["settings"]["title"] == title assert metadata["settings"]["height"] == "120" assert metadata["settings"]["thumbheight"] == "30" assert metadata["settings"]["maxpreviews"] == maxpreviews +assert metadata["settings"]["subdivide_percent"] == "30" assert metadata["settings"]["image_jobs"] == "3" assert metadata["settings"]["shuffle"] is False assert isinstance(metadata["settings"]["splash_page"], bool) @@ -1412,6 +1413,7 @@ TITLE=A\\ simple\\ Shuriken HEIGHT=1200 THUMBHEIGHT=300 MAXPREVIEWS=40 +THUMB_SUBDIVIDE_PERCENT=30 IMAGE_JOBS=3 IMAGEMAGICK_TIMEOUT=60 RANDOM_SEED='' @@ -1461,6 +1463,7 @@ TITLE=Minimal\\ defaults HEIGHT='' THUMBHEIGHT=30 MAXPREVIEWS=40 +THUMB_SUBDIVIDE_PERCENT=30 IMAGE_JOBS=3 IMAGEMAGICK_TIMEOUT=60 RANDOM_SEED='' @@ -1603,6 +1606,7 @@ TITLE=Selected\\ config HEIGHT=120 THUMBHEIGHT=30 MAXPREVIEWS=7 +THUMB_SUBDIVIDE_PERCENT=30 IMAGE_JOBS=3 IMAGEMAGICK_TIMEOUT=60 RANDOM_SEED='' @@ -1647,6 +1651,7 @@ TITLE=Current\\ directory\\ config HEIGHT=120 THUMBHEIGHT=30 MAXPREVIEWS=8 +THUMB_SUBDIVIDE_PERCENT=30 IMAGE_JOBS=3 IMAGEMAGICK_TIMEOUT=60 RANDOM_SEED='' @@ -1699,6 +1704,7 @@ test_print_config_applies_cli_overrides_without_writes() { --height 456 \ --thumbheight 45 \ --maxpreviews 9 \ + --subdivide 55 \ --image-jobs 2 \ --random-seed cli-seed \ --shuffle \ @@ -1716,6 +1722,7 @@ TITLE=CLI\\ title HEIGHT=456 THUMBHEIGHT=45 MAXPREVIEWS=9 +THUMB_SUBDIVIDE_PERCENT=55 IMAGE_JOBS=2 IMAGEMAGICK_TIMEOUT=60 RANDOM_SEED=cli-seed @@ -1932,6 +1939,7 @@ test_dry_run_reports_cli_overrides_without_writes() { --height 456 \ --thumbheight 45 \ --maxpreviews 2 \ + --subdivide 25 \ --image-jobs 2 \ --random-seed dry-seed \ --shuffle \ @@ -1951,6 +1959,7 @@ test_dry_run_reports_cli_overrides_without_writes() { test::assert_contains 'Height: 456' "$output" test::assert_contains 'Thumb height: 45' "$output" test::assert_contains 'Max previews per page: 2' "$output" + test::assert_contains 'Subdivide percent: 25' "$output" test::assert_contains 'Image jobs: 2' "$output" test::assert_contains 'Random seed: dry-seed' "$output" test::assert_contains 'Shuffle: yes' "$output" @@ -2350,6 +2359,48 @@ test_generate_preflight_rejects_invalid_numbers() { test::teardown } +# THUMB_SUBDIVIDE_PERCENT is a 0..100 integer (0 disables tile subdivision, 100 +# always subdivides). Unlike the positive-integer vars, 0 is valid, so it has its +# own validator with its own range message. +test_config_validate_percentage_var_enforces_range() { + local output + local value + local -i status=0 + + # shellcheck source=src/lib/config.validate.source.sh + source "$TEST_REPO_ROOT/src/lib/config.validate.source.sh" + + # The inclusive bounds and a mid value are accepted. + for value in 0 30 100; do + export THUMB_SUBDIVIDE_PERCENT="$value" + set +e + validate_percentage_config_var THUMB_SUBDIVIDE_PERCENT 2>/dev/null + status=$? + set -e + if (( status != 0 )); then + printf 'FAIL: expected %s to be a valid percentage\n' "$value" >&2 + exit 1 + fi + done + + # Out-of-range, negative, and non-integer values are rejected with the + # range message. + for value in 101 150 -1 not-a-number 3.5; do + export THUMB_SUBDIVIDE_PERCENT="$value" + set +e + output=$(validate_percentage_config_var THUMB_SUBDIVIDE_PERCENT 2>&1) + status=$? + set -e + if (( status == 0 )); then + printf 'FAIL: expected %s to be rejected\n' "$value" >&2 + exit 1 + fi + test::assert_contains \ + 'ERROR: THUMB_SUBDIVIDE_PERCENT must be an integer between 0 and 100' \ + "$output" + done +} + test_config_validators_fail_fast_without_errexit() { local output local -i status=0 @@ -6493,6 +6544,9 @@ main() { '--generate preflight rejects invalid numbers' \ test_generate_preflight_rejects_invalid_numbers test::run_case \ + 'percentage config var enforces 0..100 range' \ + test_config_validate_percentage_var_enforces_range + test::run_case \ 'config validators fail fast without errexit' \ test_config_validators_fail_fast_without_errexit test::run_case \ |
