Add -l tests, update editmode tape, fix service schedule pattern
All checks were successful
CI / shellcheck (push) Successful in 20s

5 new tests for -l: service job presence, timer job presence, pipe
alignment, and mutual exclusivity checks. Fix | service | pattern in
edit mode test to handle alignment padding. Add -l demo step to
editmode.tape before opening the editor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthias Johnson 2026-02-28 01:45:44 -07:00
parent 8368f1dcf7
commit 0943a639cc
4 changed files with 60 additions and 32 deletions

View file

@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"label": "tests",
"message": "83 passed",
"message": "88 passed",
"color": "brightgreen"
}

View file

@ -25,6 +25,18 @@ Type "systab -t daily -c '/home/user/backup.sh' -i"
Enter
Sleep 2s
# List jobs in crontab format without opening editor
Hide
Type "./demo/note.sh 'Listing jobs in crontab format (-l)'"
Enter
Sleep 500ms
Show
Sleep 1s
Type "systab -l"
Sleep 500ms
Enter
Sleep 2s
# Open edit mode with EDITOR=nano for visibility
Hide
Type "./demo/note.sh 'Opening edit mode — add notifications, create and modify jobs'"

42
systab
View file

@ -614,35 +614,8 @@ createJobFromEdit() {
echo "$_created_id"
}
# Print crontab content (header + aligned job lines) to stdout
# Print aligned job lines to stdout (no header/footer)
printCrontabContent() {
cat <<'HEADER'
# systab jobs — edit schedule/command, enable/disable, add/remove lines
# Format: ID[:FLAGS] | SCHEDULE | COMMAND (pipe-separated)
# Remove a line to delete a job.
# Add a line with "new" as ID to create a job: new | daily | /path/to/cmd
# Comment out a line to disable, uncomment to re-enable.
#
# Flags (append to ID with ':'): s - service, i - notify desktop, e=addr - send email,
# o - include output (default 10 lines), o=N - include N lines of output,
# n=name = human-readable name (usable in place of hex ID)
# a1b2c3:n=backup,i | daily | cmd named job with desktop notification
# a1b2c3:i,e=user@host | daily | cmd email and desktop notificaton
# a1b2c3:s | service | cmd persistent service (no timer)
# new:s,n=name | service | cmd new persistent service
#
# Schedule formats (systemd OnCalendar):
# service persistent service (started on login, auto-restarted)
# hourly, daily, weekly, monthly, yearly
# *:0/15 every 15 minutes
# *-*-* 02:00:00 daily at 2am
# Mon *-*-* 09:00 every Monday at 9am
# *-*-01 00:00:00 first of every month
#########################
### add entries below ###
#########################
HEADER
local -a id_fields schedules commands disabled
local job
@ -713,8 +686,17 @@ editJobs() {
# shellcheck disable=SC2064
trap "rm -f '$temp_file' '$orig_file'" EXIT
# Build crontab content
printCrontabContent > "$temp_file"
# Build crontab content: jobs first, condensed hint at bottom
{
printCrontabContent
cat <<'HINT'
### ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #
### format: ID[:FLAGS] | SCHEDULE | COMMAND #
### add: new | daily | cmd #
### flags: n=name / i / e=addr / o[=N] / s #
### comment out = disable / delete = remove #
HINT
} > "$temp_file"
# Save original for diffing
cp "$temp_file" "$orig_file"

36
test.sh
View file

@ -404,12 +404,46 @@ assert_output "enable already enabled service" "Already enabled:" $SYSTAB -E "$i
# Edit mode shows service jobs with 'service' in schedule column
# (mirrors tape: EDITOR=nano systab -e shows "id:s | service | cmd")
edit_output=$(EDITOR=cat $SYSTAB -e 2>&1 || true)
if [[ "$edit_output" == *"| service |"* ]]; then
if [[ "$edit_output" == *"| service"* ]]; then
pass "edit mode shows service job with 'service' schedule"
else
fail "edit mode shows service job with 'service' schedule" "not found in: $edit_output"
fi
# -l prints crontab format to stdout
list_output=$($SYSTAB -l 2>&1)
if [[ "$list_output" == *"| service"* ]]; then
pass "-l prints service job with 'service' schedule"
else
fail "-l prints service job with 'service' schedule" "not found in: $list_output"
fi
if [[ "$list_output" == *"$id_recurring"* ]]; then
pass "-l includes timer job"
else
fail "-l includes timer job" "not found in: $list_output"
fi
# -l pipe separators are aligned (all first pipes at same column)
pipe_cols=()
while IFS= read -r line; do
[[ "$line" == *"|"* ]] || continue
# skip hint/separator lines (not job entries)
[[ "$line" =~ ^# ]] && [[ ! "$line" =~ ^#[[:space:]][0-9a-f]{6} ]] && continue
pipe_prefix="${line%%|*}"
pipe_cols+=("${#pipe_prefix}")
done <<< "$list_output"
if [[ ${#pipe_cols[@]} -gt 1 ]]; then
unique_cols=$(printf '%s\n' "${pipe_cols[@]}" | sort -u | wc -l)
if [[ "$unique_cols" -eq 1 ]]; then
pass "-l pipe separators are aligned"
else
fail "-l pipe separators are aligned" "first-pipe columns: ${pipe_cols[*]}"
fi
fi
assert_failure "-l and -e are mutually exclusive" $SYSTAB -l -e
assert_failure "-l cannot be used with job creation options" $SYSTAB -l -t daily -c "echo test"
# Mutually exclusive flags (mirrors tape design: -s conflicts with -t/-i/-m/-o)
assert_failure "-s and -t are mutually exclusive" $SYSTAB -s -t daily -c "echo test"
assert_failure "-s and -i are mutually exclusive" $SYSTAB -s -i -c "echo test"