mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 19:27:03 +01:00
i3blocks: automation_tutor block (today's tutor credits, click runs plc-lab run.sh)
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c287f59621
commit
698fdd5c8e
@ -0,0 +1,31 @@
|
||||
{
|
||||
"intent": "The i3 bar shows today's Automation tutor progress (tutor n/4), hides at 4/4, and a click opens the tutor via plc-lab's run.sh.",
|
||||
"scope": [
|
||||
"linux_configuration/i3blocks/automation_tutor.sh, the [automation_tutor] stanza in linux_configuration/i3blocks/config, linux_configuration/tests/test_i3blocks_automation_tutor.sh",
|
||||
"Non-goal: no ledger HMAC check (earned_time owns that); display only"
|
||||
],
|
||||
"changes": [
|
||||
"New block counts kind==credit rows dated today in ~/.local/share/automation_tutor/ledger.json; hidden at 4/4; orange message when jq is missing or the ledger is unreadable",
|
||||
"Click runs ~/src/plc-lab/run.sh (override AUTOMATION_TUTOR_RUN); ledger override AUTOMATION_TUTOR_LEDGER",
|
||||
"Hermetic test with a stub run.sh and fixture ledgers: no ledger, 2 today + 1 yesterday, 4 today, unreadable, click"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "bash linux_configuration/tests/test_i3blocks_automation_tutor.sh",
|
||||
"result": "pass",
|
||||
"evidence": "automation_tutor block: all checks passed"
|
||||
},
|
||||
{
|
||||
"command": "pre-commit run --files <changed-files>",
|
||||
"result": "pass",
|
||||
"evidence": "shellcheck, codespell, file caps and shell hooks passed"
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"i3blocks config is deployed by the installer; the block only appears after the next deploy to ~/.config/i3blocks"
|
||||
],
|
||||
"rollback": [
|
||||
"git revert the commit",
|
||||
"Remove [automation_tutor] from ~/.config/i3blocks/config and reload i3blocks"
|
||||
]
|
||||
}
|
||||
55
linux_configuration/i3blocks/automation_tutor.sh
Executable file
55
linux_configuration/i3blocks/automation_tutor.sh
Executable file
@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ============================================================================
|
||||
# Automation tutor status for i3blocks: today's credited 15-minute blocks.
|
||||
#
|
||||
# A click runs plc-lab's run.sh, which starts the tutor if it is down and
|
||||
# opens it in the browser -- nobody has to remember the port. Hidden once all
|
||||
# four blocks are in: nothing left to earn, nothing to click.
|
||||
#
|
||||
# Counts the tutor ledger's credit rows dated today. It does not check their
|
||||
# HMAC (that needs the key and Python); earned_time does, so this is a
|
||||
# display, never the authority on what was paid.
|
||||
# ============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
readonly LEDGER="${AUTOMATION_TUTOR_LEDGER:-$HOME/.local/share/automation_tutor/ledger.json}"
|
||||
# i3blocks' PATH has no ~/src: absolute path.
|
||||
readonly RUN="${AUTOMATION_TUTOR_RUN:-$HOME/src/plc-lab/run.sh}"
|
||||
readonly TARGET=4
|
||||
|
||||
readonly YELLOW='#F1FA8C'
|
||||
readonly ORANGE='#FFB86C'
|
||||
|
||||
emit() {
|
||||
# full_text, short_text, color — the three lines i3blocks reads.
|
||||
printf '%s\n%s\n%s\n' "$1" "$2" "$3"
|
||||
}
|
||||
|
||||
if [[ ${BLOCK_BUTTON:-0} -ne 0 ]]; then
|
||||
setsid -f "$RUN" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
if ! command -v jq >/dev/null 2>&1; then
|
||||
emit '⚙ tutor: no jq' '⚙ ?' "$ORANGE"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
printf -v today '%(%Y-%m-%d)T' -1
|
||||
done_blocks=0
|
||||
# No ledger yet is a real zero: the tutor creates it on the first block.
|
||||
if [[ -e $LEDGER ]]; then
|
||||
if ! done_blocks=$(jq --arg d "$today" \
|
||||
'[.entries[] | select(.kind == "credit" and .day == $d)] | length' \
|
||||
"$LEDGER" 2>/dev/null); then
|
||||
emit '⚙ tutor: ledger unreadable' '⚙ ?' "$ORANGE"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if ((done_blocks >= TARGET)); then
|
||||
emit '' '' "$YELLOW"
|
||||
exit 0
|
||||
fi
|
||||
emit "⚙ tutor ${done_blocks}/${TARGET}" "⚙ ${done_blocks}/${TARGET}" "$YELLOW"
|
||||
@ -63,6 +63,10 @@ interval=30
|
||||
command=~/.config/i3blocks/book_guard.sh
|
||||
interval=30
|
||||
|
||||
[automation_tutor]
|
||||
command=~/.config/i3blocks/automation_tutor.sh
|
||||
interval=30
|
||||
|
||||
[issue_dashboard]
|
||||
command=~/.config/i3blocks/issue_dashboard.sh
|
||||
interval=30
|
||||
|
||||
106
linux_configuration/tests/test_i3blocks_automation_tutor.sh
Executable file
106
linux_configuration/tests/test_i3blocks_automation_tutor.sh
Executable file
@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# Behaviour tests for the i3blocks automation_tutor block: today's credit
|
||||
# count, the hidden 4/4 state, the unreadable-ledger warning and the click.
|
||||
# The ledger is a fixture and run.sh is a stub, so nothing reads the real
|
||||
# ledger and no tutor or browser is ever started.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||
REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd)
|
||||
BLOCK="$REPO_DIR/i3blocks/automation_tutor.sh"
|
||||
TMP_DIR=$(mktemp -d)
|
||||
|
||||
cleanup() {
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
fail() {
|
||||
printf 'FAIL: %s\n' "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_eq() {
|
||||
local expected=$1
|
||||
local actual=$2
|
||||
local context=$3
|
||||
if [[ "$expected" != "$actual" ]]; then
|
||||
fail "$context (expected '$expected', actual '$actual')"
|
||||
fi
|
||||
}
|
||||
|
||||
printf '{}' | jq -e . >/dev/null 2>&1 ||
|
||||
fail 'a working jq is required for the automation_tutor tests (pacman -S jq)'
|
||||
|
||||
BIN_DIR="$TMP_DIR/bin"
|
||||
mkdir -p "$BIN_DIR"
|
||||
cat >"$BIN_DIR/run.sh" <<STUB
|
||||
#!/bin/bash
|
||||
echo clicked >>"$TMP_DIR/clicks"
|
||||
STUB
|
||||
chmod +x "$BIN_DIR/run.sh"
|
||||
|
||||
LEDGER="$TMP_DIR/ledger.json"
|
||||
|
||||
TODAY=$(date +%Y-%m-%d)
|
||||
YESTERDAY=$(date -d yesterday +%Y-%m-%d)
|
||||
|
||||
# ledger <day:kind>... (writes {"entries":[...]})
|
||||
ledger() {
|
||||
local rows=()
|
||||
local spec
|
||||
for spec in "$@"; do
|
||||
rows+=("$(jq -n --arg day "${spec%%:*}" --arg kind "${spec##*:}" \
|
||||
'{day: $day, kind: $kind}')")
|
||||
done
|
||||
printf '%s\n' "${rows[@]}" | jq -s '{entries: .}' >"$LEDGER"
|
||||
}
|
||||
|
||||
run_block() {
|
||||
AUTOMATION_TUTOR_LEDGER="$LEDGER" AUTOMATION_TUTOR_RUN="$BIN_DIR/run.sh" \
|
||||
bash "$BLOCK"
|
||||
}
|
||||
|
||||
line() {
|
||||
sed -n "${1}p" <<<"$2"
|
||||
}
|
||||
|
||||
printf 'Checking automation_tutor block states...\n'
|
||||
|
||||
rm -f "$LEDGER"
|
||||
out=$(run_block)
|
||||
assert_eq '⚙ tutor 0/4' "$(line 1 "$out")" 'no ledger is 0/4'
|
||||
assert_eq '⚙ 0/4' "$(line 2 "$out")" 'no ledger short text'
|
||||
assert_eq '#F1FA8C' "$(line 3 "$out")" 'progress is yellow'
|
||||
|
||||
ledger "$TODAY:credit" "$TODAY:credit" "$YESTERDAY:credit"
|
||||
out=$(run_block)
|
||||
assert_eq '⚙ tutor 2/4' "$(line 1 "$out")" 'counts only today'
|
||||
assert_eq '⚙ 2/4' "$(line 2 "$out")" 'short text'
|
||||
|
||||
ledger "$TODAY:credit" "$TODAY:debit"
|
||||
assert_eq '⚙ tutor 1/4' "$(line 1 "$(run_block)")" 'only credit rows count'
|
||||
|
||||
ledger "$TODAY:credit" "$TODAY:credit" "$TODAY:credit" "$TODAY:credit"
|
||||
out=$(run_block)
|
||||
assert_eq '' "$(line 1 "$out")" '4/4 hides the block'
|
||||
assert_eq '' "$(line 2 "$out")" '4/4 short text hidden'
|
||||
|
||||
printf 'Checking failure states are never blank or green...\n'
|
||||
|
||||
printf '{' >"$LEDGER"
|
||||
out=$(run_block)
|
||||
assert_eq '⚙ tutor: ledger unreadable' "$(line 1 "$out")" 'unreadable text'
|
||||
assert_eq '#FFB86C' "$(line 3 "$out")" 'unreadable is orange'
|
||||
|
||||
printf 'Checking a click runs run.sh...\n'
|
||||
|
||||
ledger "$TODAY:credit"
|
||||
BLOCK_BUTTON=1 run_block >/dev/null
|
||||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||||
[[ -s "$TMP_DIR/clicks" ]] && break
|
||||
sleep 0.1
|
||||
done
|
||||
assert_eq 'clicked' "$(cat "$TMP_DIR/clicks" 2>/dev/null)" 'click runs run.sh'
|
||||
|
||||
printf 'automation_tutor block: all checks passed\n'
|
||||
Loading…
Reference in New Issue
Block a user