From 0943a639cc1e19d08c1ac1fcfc80d1e9a87b0620 Mon Sep 17 00:00:00 2001 From: Matthias Johnson Date: Sat, 28 Feb 2026 01:45:44 -0700 Subject: [PATCH] Add -l tests, update editmode tape, fix service schedule pattern 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 --- badges/tests.json | 2 +- demo/editmode.tape | 12 ++++++++++++ systab | 42 ++++++++++++------------------------------ test.sh | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 32 deletions(-) diff --git a/badges/tests.json b/badges/tests.json index bd09d8e..3e4522a 100644 --- a/badges/tests.json +++ b/badges/tests.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, "label": "tests", - "message": "83 passed", + "message": "88 passed", "color": "brightgreen" } diff --git a/demo/editmode.tape b/demo/editmode.tape index fdb6f66..8ddf4e9 100644 --- a/demo/editmode.tape +++ b/demo/editmode.tape @@ -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'" diff --git a/systab b/systab index 362c948..e21273f 100755 --- a/systab +++ b/systab @@ -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" diff --git a/test.sh b/test.sh index 1cdb824..972d94e 100755 --- a/test.sh +++ b/test.sh @@ -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"