| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
The startup language-bundle sync repaired drift in these rulesets-owned files. Committing them at canonical so future syncs stay no-ops.
|
| |
|
|
| |
MELPA and list-packages index the summary line, and the old backronym carried no words anyone would search. I reworded it to plain terms and led the Keywords header with a standard finder keyword so package-lint stays clean. I synced the Eask file to match.
|
| |
|
|
| |
GitHub's org renderer drops #+begin_verse blocks, so the Fitzgerald lines vanished on the rendered page. Blank-line separation stacks them on both GitHub and Emacs export. Also reword the opening sentence, which had leaned on the removed Douglas Adams "whoosh" line.
|
| |
|
|
| |
Swap the Douglas Adams deadlines quote for Edward Fitzgerald's sundial verse, which names the chime directly.
|
| | |
|
| | |
|
| |
|
|
| |
A child that never returns produces no error sexp, so no failure path ever sees it. The failure counter stays at zero and the overlap guard blocks every subsequent check. The watchdog interrupts a fetch older than chime-async-timeout (default 120s, nil disables), records it through chime--record-async-failure, and lets the same check spawn a fresh child.
|
| |
|
|
| |
A vanished org-agenda-files entry hit org's interactive "[R]emove from list or [A]bort?" recovery prompt inside the -batch child, which blocked forever. The overlap guard then turned every subsequent check into a silent no-op and the modeline froze on a stale countdown. org-agenda-skip-unavailable-files makes org skip the missing file with a message instead.
|
| | |
|
| |
|
|
| |
The file was added to Eask's (files ...) list in 675fb68 but kept its standalone Version, Package-Requires, and Keywords headers. package-lint flags those as "Package-Requires outside the main file have no effect" and the lint step fails CI. Match the sibling auxiliary-file pattern (chime-debug.el, chime-org-contacts.el): keep Author + URL, add the convention note, drop the redundant metadata.
|
| |
|
|
| |
The PostToolUse hook tried to byte-compile every .el file edited, including ones outside the chime project. Out-of-project files typically require packages that aren't on the hook's -L paths, so validation failed for unrelated reasons. Exit 0 when the edited file isn't under $PROJECT_ROOT.
|
| |
|
|
| |
The unit tests call chime--gather-info on a marker built in the test. I added a :slow test that goes one layer up. It puts a SCHEDULED heading with :CHIME_NOTIFY_BEFORE: 30 in a temp .org file, runs org-agenda-list, and gathers events the way chime--retrieve-events does in the async child (split the agenda buffer into lines, pull the org-marker from each, drop nils, map chime--gather-info). The resulting event carries ((30 . medium)). That confirms the override survives a marker that came out of org-agenda-list, not just one built in the test.
|
| |
|
|
| |
The README's migration note said the per-event reminder property had been removed. That's stale now that the property is back. I rewrote the line to point at :CHIME_NOTIFY_BEFORE: and the deprecated :WILD_NOTIFIER_NOTIFY_BEFORE: alias. I also added a "Per-Event Override" section to docs/CONFIGURATION.org covering the syntax, the no-inheritance behavior, malformed-value handling, and the alias's deprecation path.
|
| |
|
|
|
|
|
|
|
|
| |
Chime's migration from org-wild-notifier dropped the per-event notify-before property, so a heading could no longer override the global chime-alert-intervals. I brought it back.
A heading's :CHIME_NOTIFY_BEFORE: N (a non-negative integer) means "notify once, N minutes before, severity medium" and replaces chime-alert-intervals for that event. The org-wild-notifier name :WILD_NOTIFIER_NOTIFY_BEFORE: still works, as a deprecated alias. When it supplies the value, chime emits one per-session warning pointing at the new name. :CHIME_NOTIFY_BEFORE: wins when both are set. A malformed value logs a message naming the heading and falls back to the global.
chime--gather-info reads the property in the async child. The deprecation flag rides on the event alist so the parent emits the warning without changing the async return contract.
I also touched two test files. test-chime-async-helpers.el's fixtures fed bare symbols where chime--handle-async-success now expects event alists, so they build real events via chime--make-event. And the new test file's message-capture macro had a lexical-scoping bug (the captured list was invisible after the macro returned), so the two affected tests inline the capture and the macro is gone.
|
| |
|
|
|
|
| |
I added fifteen tests ahead of the implementation, covering the per-event :CHIME_NOTIFY_BEFORE: property and the deprecated :WILD_NOTIFIER_NOTIFY_BEFORE: alias: value-string parsing (chime--parse-notify-before-value), property lookup with global fallback (chime--intervals-for-marker), the gather path (chime--gather-info honoring the property and flagging the alias on the event), and the once-per-session deprecation warning (chime--maybe-warn-deprecated-properties).
They all fail with void-function for the not-yet-defined helpers, plus a length mismatch on the gather-info tests since chime--gather-info still uses the global chime-alert-intervals.
|
| |
|
|
|
|
| |
TESTING.org carried a frozen "645 tests as of 2026-04-04" inventory plus a top-files table that goes stale every time a test file is added. I replaced it with a one-line pointer to `make count`, which is the live source.
README's History section said Artem Khramov "deprecated org-wild-notifier in favor of org-alert." He didn't. He archived the repo and stopped responding to issues. The README's "Alternatives" section listed org-alert and org-notify neutrally, never as recommended successors. And the project has since been picked back up under the Emacs Orphanage. I rewrote the paragraph to describe what happened and added a line about the orphanage fork.
|
| |
|
|
|
|
| |
Five new test files cover branches the per-function suites missed: the day-wide notification pipeline, the jump-to-event navigation path (including the org-show-entry fallback for Org < 9.6), chime--stop's process-interrupt branch, chime--start's debug log, and the two async error branches in chime--fetch-and-process. The edge-coverage file mops up scattered one-line fallbacks: the day-wide-notification "today" path, the tooltip placeholder pass-through, timestamp-parse's no-context error message, log-silently's mid-line newline insert, the validation :error count, and record-async-failure's chime-debug hook.
Line coverage on chime.el goes from 97.1% to 99.88%, 823 of 824 coverable lines. The one remaining line is a pcase _ fallback the preceding regex can't reach.
|
| |
|
|
|
|
| |
The validation banner, retry-attempt message, async-failure tooltip, and the initial loading tooltip were hardcoded English literals. I added defcustoms for them so the wording can be localized or adjusted. The format-string ones keep their %d/%s directives, with the order spelled out in each docstring.
I also dropped the dead :info severity from chime-validate-configuration's docstring. The function only ever emitted :ok, :warning, and :error.
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
The .claude/rules/ files (commits.md, testing.md, verification.md) were local copies that drifted from the canonical at ~/code/rulesets. I replaced them with absolute symlinks pointing at the canonical files. This repo now picks up rule updates automatically.
The symlinks are absolute. Cloning this repo on a new machine needs ~/code/rulesets at the same path. Otherwise the symlinks dangle.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Six per-axis filter variables (keyword/tags/predicate × whitelist/blacklist)
were carrying parallel structure for what's really one decision: include
events that look like X, exclude events that look like Y. I merged them
into two alists, `chime-include-filters' and `chime-exclude-filters', each
keyed by axis (`keywords', `tags', `predicates').
Default for `chime-exclude-filters' keeps the same out-of-the-box
behavior — done items and declined Google Calendar invites stay
filtered:
((predicates . (chime-done-keywords-predicate
chime-declined-events-predicate)))
Implementation: one shared `chime--filter-predicates' helper that walks
the alist and emits a marker-taking predicate per non-empty axis. The
public callers — now `chime--apply-include-filters' and
`chime--apply-exclude-filters' — wrap that helper with
`-orfn'-then-`-filter' and `-orfn'-then-`-remove' respectively. The
async-environment regex injection list shrank from six names to two,
and the debug config dump in chime-debug.el follows.
The terminology shift (whitelist/blacklist → include/exclude) drops
loaded language for descriptive intent. The internal helpers and the
public function names all moved together.
Tests: 700-ish lines across five test files (test-chime-apply-whitelist,
test-chime-apply-blacklist, test-chime-whitelist-blacklist-conflicts,
test-chime-environment-regex, test-chime-declined-events-predicate)
were rewritten to bind the new alists. The dedup-conflict tests still
exercise the same precedence rule (exclude wins on overlap). README's
filtering section was rewritten end-to-end with new examples.
Migration:
(setq chime-keyword-whitelist '("TODO"))
;; ->
(setq chime-include-filters '((keywords . ("TODO"))))
(setq chime-predicate-blacklist '(my-pred))
;; ->
(setq chime-exclude-filters '((predicates . (my-pred))))
This brings the consolidation pass to 37 -> 29 defcustoms, the target
from .ai/settings-consolidation.org.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I merged `chime-time-left-format-at-event', `chime-time-left-format-short',
and `chime-time-left-format-long' into a single alist `chime-time-left-formats'
keyed by `at-event' / `short' / `long'. Three knobs for one feature
(countdown display) was unnecessary surface area; one alist is the same
flexibility with a third the namespace.
`chime--time-left' switched from a pcase-on-variable to a pcase-on-regime
that picks an alist key, then `alist-get's the format string. Behavior
is identical for default settings.
Test setup in the four affected files now builds the alist with `(list
(cons 'KEY VAL) ...)' instead of `'(...)'. The literal-quote form
returns the SAME cons-cell structure on every evaluation, so a previous
test mutating it via `setf' on `alist-get' poisoned later tests. `list'
+ `cons' produces fresh structure per call, which is what the tests
actually need.
Migration: `(setq chime-time-left-format-short "in %mm")' becomes
`(setf (alist-get 'short chime-time-left-formats) "in %mm")', or a
full `(setq chime-time-left-formats '((at-event . ...) (short . ...)
(long . ...)))' replacement.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is an internal startup-timing parameter, not a knob real users have
reason to tune through `M-x customize'. I demoted it from defcustom to
defvar and renamed it to `chime--validation-max-retries' to make the
private status explicit. Anyone who was overriding it can keep doing so
with `setq' (the variable still exists, just under the new name).
The three customize-time validation tests went away with the defcustom —
nothing left to validate at customize-time once it stops being a
customize-target. The setter helper still applies to the other five
numeric defcustoms.
Test files that referenced the variable (`test-chime-validation-retry.el',
`test-integration-chime-mode.el') were renamed mechanically along with
the source.
Breaking change: `(setq chime-validation-max-retries N)' becomes
`(setq chime--validation-max-retries N)' if you actually had it. Most
users won't have touched it.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`chime-play-sound' was redundant with `chime-sound-file' — both had to be
truthy for sound to play, and `chime-sound-file' already documented "set
to nil to disable sound completely". Two knobs for one decision is a
trap.
I removed the defcustom and the `(when chime-play-sound ...)' guard in
`chime--notify' (it now just checks `chime-sound-file'). Tests, README
quick-start, and the troubleshooting checklist all reference the new
single-knob form. One redundant test (sound-disabled-via-the-toggle)
got dropped because it now duplicates the sound-file-nil case.
Breaking change: users with `(setq chime-play-sound nil)' in their
config will get a void-variable warning at customize time and lose
their disable. Migration: `(setq chime-sound-file nil)'.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Six numeric settings are declared as integers but were read straight into
arithmetic and timer math. A bad value (string, negative number, nil where
nil isn't supported) used to slip past the defcustom and surface as a
timer error or `arith-error' deep in a callback, instead of as a
configuration problem at the moment the user set it.
I added `chime--validate-integer-setting' as a small shared helper and
wired a `:set' on each of the affected defcustoms:
- `chime-modeline-lookahead-minutes' — integer >= 0 (0 disables)
- `chime-tooltip-lookahead-hours' — integer >= 1
- `chime-modeline-tooltip-max-events' — integer >= 1 or nil (show all)
- `chime-day-wide-advance-notice' — integer >= 0 or nil (same-day only)
- `chime-max-consecutive-failures' — integer >= 0 (0 disables warnings)
- `chime-validation-max-retries' — integer >= 0 (0 = fail immediately)
The constraints follow each docstring's stated intent. The helper signals
`user-error', so `customize-set-variable' surfaces it as a config problem
rather than a generic error trace.
Tests: 22 cases in `tests/test-chime-numeric-defcustom-setters.el' —
five direct on the helper plus each defcustom's accept/reject paths
through `customize-set-variable'.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`chime--deduplicate-events-by-title' was keying off the user-facing
title alone, so two real "1:1" entries on different days collapsed to
one and the second one disappeared from the tooltip.
I changed the key to `(marker-file . marker-pos)' — the source heading
identity — so distinct headings keep both copies and recurring expansions
of one heading still fold to the soonest. When marker info is missing
(synthesized test events, edge cases) the key falls back to title, which
preserves the older fixtures the function was originally tested against.
Three new tests cover the regression paths: two distinct headings sharing
a title both survive, one heading expanded into multiple instances still
collapses to the soonest, and a mix of sourced and unsourced events
behaves correctly under both code paths.
|
| |
|
|
|
|
|
| |
The lint backlog is now zero — all three checks (package-lint, checkdoc,
elisp-lint) are clean. Drop `continue-on-error: true' from each step so a
regression actually fails the build instead of quietly turning the job
green.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Took the package-lint commit's foundation and finished the job. Three
groups of changes:
1. **checkdoc** is now clean across all three package files. I worked
through every warning: 13 missing-double-space-after-period fixes, 4
message-capitalization fixes, 1 trailing-period-on-error fix, 6
Lisp-symbol-should-be-quoted fixes, and one rephrase from "starts" to
the imperative "Log the start of an async check". One `chime-debug.el'
docstring also exceeded 80 columns and got split into two lines.
2. **`make lint'** ran elisp-lint but had been silently broken. The shell
glob `test-*.el' wasn't expanding (CWD ended up at project root, not
tests/), and the noisy validators flagged everything. I rewrote the
target to lint package files explicitly via absolute paths, preload
chime.el so the byte-compiler sees cross-file symbols when checking
chime-debug.el, and disable the validators that conflict with project
style or duplicate other lint steps:
- `--no-checkdoc' (covered by `eask lint checkdoc')
- `--no-package-lint' (covered by `eask lint package'; running it on
auxiliary files re-flags them as standalone packages)
- `--no-indent-character' (project uses spaces per
`.claude/rules/elisp.md'; the validator defaults to tabs)
- `--no-fill-column' (project allows up to 80; validator defaults to 70)
- `--no-indent' (false-positives on dash threading macros `->'/`->>')
The validators-disabled list is documented in the recipe header.
3. **Generated autoload files** (`chime-autoloads.el',
`tests/tests-autoloads.el') are now gitignored. `tests/tests-autoloads.el'
was tracked from an earlier commit; I removed it from the index.
Eask regenerates these on every `eask compile' / `eask install-deps'
run, so they don't belong in the tree.
Verified: `make compile' clean (with byte-compile-error-on-warn t),
`make test-all' green at 677 tests, `eask lint package' clean,
`eask lint checkdoc' clean, `make lint' clean. Full lint backlog is now
zero across all three checks.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I worked through the package-lint backlog and got it to zero. Five changes:
1. Renamed six interactive debug commands from the private `chime--debug-*'
prefix to the public `chime-debug-*' form. They were always M-x targets,
so the private prefix was just wrong. The autoload cookies stay because
public commands SHOULD be autoloaded. README, docstring references in
chime.el, and the matching tests follow the rename.
2. Dropped `Version', `Package-Requires', and `Keywords' headers from
chime-org-contacts.el. Auxiliary files in a multi-file package shouldn't
carry their own metadata — package-lint flags it as an error because the
headers have no effect outside the main file. The main file (chime.el)
already declares the chime package's metadata.
3. Dropped `Keywords' from chime-debug.el for the same reason.
4. Dropped the auto-loader for the optional chime-org-contacts integration
from chime.el. The old code used `with-eval-after-load 'org-capture' to
pull the file in, which package-lint flags as a configuration pattern
that doesn't belong in a package. Users who want the integration now
require it themselves; the README shows both the plain `with-eval-after-load'
pattern and the `use-package :after' form. chime-org-contacts.el's
internal `with-eval-after-load' went away too — by the time the user has
required the file, they've already gated it on org-capture being loaded,
so the inner check is redundant.
5. Dropped the redundant `with-eval-after-load' from chime-org-contacts.el's
activation block. The setup function still guards on
`(boundp 'org-capture-templates)' so it's safe to require either order.
Behavioral note: this is a small breaking change for anyone whose config
relied on the auto-load. The README change spells out the migration path.
|
| |
|
|
|
|
|
|
| |
`string-search' was added in Emacs 28.1. Since chime's package floor is
27.1, the convert-org-contacts-birthdays test file failed on that version
in CI. I swapped each `string-search NEEDLE HAYSTACK' for the equivalent
`string-match-p (regexp-quote NEEDLE) HAYSTACK', which works on 27.1+ and
returns a truthy value the same way.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I added `.github/workflows/ci.yml` with three jobs:
1. test — Emacs 27.1 / 28.2 / 29.4 / 30.1, runs `make compile` (strict
warnings) and `make test-all`. fail-fast off so one version's failure
doesn't hide others.
2. lint (advisory) — `eask lint package`, `eask lint checkdoc`, and `make
lint` (elisp-lint). All three are `continue-on-error: true` because there's
an existing MELPA-prep backlog (1 package-lint error in chime-org-contacts.el,
~17 cosmetic checkdoc/package-lint warnings) that's worth surfacing without
blocking CI. Tighten to required once the backlog is cleared.
3. coverage — runs the full suite with undercover and uploads to Coveralls
via the official action. No secret needed because the repo is public —
GITHUB_TOKEN is enough.
Two supporting changes:
- `tests/run-coverage-file.el` now switches between simplecov (local) and
coveralls (CI, detected via the `CI` env var GitHub Actions sets
automatically) report formats. The Coveralls action expects coveralls JSON.
- `Makefile`'s `coverage' target now runs ALL_TESTS with selector `t', not
UNIT_TESTS with `(not (tag :slow))'. Without this the integration tests
contributed nothing to the reported coverage number.
|
| |
|
|
|
| |
Header version in chime.el and the Eask manifest both move from 0.6.0 to
0.7.0 for the v0.7.0 release.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
org-gcal writes `:STATUS: declined' on calendar entries the user has declined,
and chime was happily showing them in the tooltip, modeline, and notification
stream — which defeats the whole point of declining a meeting.
I added `chime-declined-events-predicate', mirroring the shape of
`chime-done-keywords-predicate', and put it on the default
`chime-predicate-blacklist'. The match is on the literal lowercase value
because that's what real org-gcal exports use; uppercase or other values pass
through. Users who want declined events back can pop the predicate off the
blacklist.
Tests cover all four STATUS values seen in real org-gcal data (accepted,
declined, needs-action, tentative), plus the no-property, empty-property,
todo-keyword-still-attached, gibberish-value, case-sensitivity, and
default-blacklist-membership cases.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I tagged the 15 end-to-end tests across `test-integration-chime-mode.el`,
`test-integration-recurring-events-tooltip.el`, and
`test-integration-startup.el` with `:tags '(:slow)`. The default `make test`
now runs only the 652 fast unit tests; `make test-all` runs the full 667.
While verifying, I hit a pre-existing bug in `tests/Makefile` where
`test-all`'s `--eval '(ert-run-tests-batch-and-exit)'` came back from eask's
argv passthrough with its quotes stripped, which broke shell parsing. Passing
the explicit `t` selector dodges whatever eask does to no-arg single-quoted
forms. The bug only mattered once integration tests were `:slow` — before
that, `test-all` overlapped fully with `test-unit` plus `test-integration`,
so nothing actually depended on it working.
|
| |
|
|
|
|
| |
I set `byte-compile-error-on-warn` to t in the root `compile' target. The
warning backlog is clear, so any new warning should break the build instead
of slipping by silently.
|
| |
|
|
|
|
| |
Eask flagged `agenda`, `chime`, and `sound` as unknown finder keywords. The
Eask manifest already lists the canonical set (notification, alert, org,
org-agenda, calendar), so I trimmed the in-file header to match.
|
| |
|
|
|
|
|
| |
`make compile' flagged it. The variable was bound but never referenced
in the bundled-notification branch, so I dropped the `let' binding.
Whether the bundled notification should actually carry that title is
a separate concern, not this fix.
|
| |
|
|
|
|
| |
`make compile' flagged the summary line at 86 chars. I split it across
two lines, with the lookahead clause and the return-value sentence on
the lines after.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I switched the test runner from `~/.emacs.d/elpa`-grep to eask. With
this, `make setup` installs every dep into a project-local `.eask/`,
so test runs don't depend on whatever's in my global elpa. It also
lets us catch missing Package-Requires entries before MELPA submission.
New targets:
- `make setup` — runs `eask install-deps --dev`
- `make compile` — byte-compiles chime.el and surfaces warnings that
checkdoc and elisp-lint don't catch
- `make coverage` — runs the unit suite under undercover and writes a
simplecov JSON to `.coverage/simplecov.json`
- `make test-all` — runs every test, including `:slow` tagged
- `-include makefile-local` in both Makefiles, for per-machine knobs
I added `ERT_FAST_SELECTOR` so `make test`, `test-unit`,
`test-integration`, and `test-file` exclude tests tagged `:slow`. When
we tag end-to-end integration tests as `:slow`, they'll stay out of
the fast feedback loop until someone explicitly asks for them via
`make test-all`.
Eask treats CWD as its workspace. So all eask invocations now run
from project root, with `(cd "tests/")' as the first `--eval' to
restore Emacs's default-directory. That preserves the relative loads
the existing test files and test-bootstrap.el rely on, without
touching either.
I updated `.gitignore` for `.eask/`, `.coverage/`, and the optional
`makefile-local` files.
|
| |
|
|
|
|
|
|
| |
Edebug's defun parser rejects the `(-> seconds (pcase ...) ...)' form,
so undercover can't instrument chime.el and `make coverage' produces
nothing. The let-bound rewrite is equivalent and parses cleanly.
I left an inline note so the form doesn't get folded back later.
|
| | |
|
| |
|
|
|
|
|
|
|
|
| |
Before MELPA submission, tighten the public API surface. Single-dash chime-foo is the convention for user-facing commands and predicates that external code can bind. Anything that is not meant to be bound externally should use the double-dash chime--foo prefix so byte-compile warnings, docstrings, and MELPA package inspection all point in the same direction.
Twelve helpers in chime.el had single-dash names but no user-facing role. They are not mentioned in README, they carry no interactive declaration, and their docstrings do not promise a behavior contract. Rename them: chime-get-minutes-into-day, chime-get-hours-minutes-from-time, chime-set-hours-minutes-for-time, chime-current-time-matches-time-of-day-string, chime-current-time-is-day-wide-time, chime-day-wide-notifications, chime-display-as-day-wide-event, chime-event-has-any-day-wide-timestamp, chime-event-within-advance-notice-window, chime-event-has-any-passed-time, chime-event-is-today, chime-environment-regex.
The public API surface is now intentional. It covers chime-mode, chime-validate-configuration, chime-refresh-modeline, chime-done-keywords-predicate, and the chime-debug-* interactive commands in chime-debug.el.
Breaking change. No alias shims because there are no downstream users yet.
|
| |
|
|
|
|
|
|
|
|
| |
Seven pure-function tests appended to the group-events-by-day file, covering Normal and Boundary cases.
Normal: event on the same calendar day as NOW returns "Today, ...". Event on the same calendar day as TOMORROW returns "Tomorrow, ...". Event three days out returns a weekday label and is neither Today nor Tomorrow.
Boundary: event at 00:00 on the NOW calendar day is Today. Event at 00:00 on the TOMORROW calendar day is Tomorrow. Event two calendar days out is not Tomorrow, gets a weekday label. Event on the previous calendar day is neither Today nor Tomorrow.
Since NOW and TOMORROW are function arguments, the tests use encode-time to build stable calendar values and skip the clock-mocking dance.
|
| |
|
|
|
|
|
|
| |
chime--group-events-by-day
The date-string computation mixed the today/tomorrow/weekday label selection in with the grouping loop and carried its own pre-decoded copies of NOW and TOMORROW through five let-bindings before it could decide which branch to take. Lift the selection into chime--day-label-for-event-time (event-time now tomorrow). The outer function becomes pure grouping, the label logic gets its own test target, and future label tweaks (localized strings, a "Yesterday" branch for overdue items) edit one helper.
The outer function drops from 36 to 15 lines. The redundant (when event-decoded) guard is replaced by (when event-time) because decode-time always returns a struct for valid time values.
|
| |
|
|
|
|
|
|
|
|
| |
The Normal and Boundary tests built events as fixed-minute offsets from real current-time. On late-night runs the +60 minute event in single-day crossed midnight and the test failed because events 1-2 landed "Today" while event 3 landed "Tomorrow". The intent of these Normal tests is routine grouping, not midnight behavior, so they should be deterministic.
Pin the clock with with-test-time using the established let-bind pattern. with-test-time re-evaluates BASE-TIME inside the mocked current-time lambda, so passing test-time-today-at directly would recurse, because the helper itself calls current-time.
Add two new Boundary tests that explicitly exercise the day-crossing logic at 23:50. One event at +5 minutes stays in Today and one at +20 minutes crosses into Tomorrow. These are the first tests in the file that actually target midnight behavior.
Drop stale "REFACTORED: Uses dynamic timestamps" annotations from docstrings since the behavior is documented at the file level.
|
| |
|
|
|
|
|
|
| |
Eight tests in a new file covering Normal and Boundary cases for both new helpers.
chime--record-async-failure increments the consecutive-failure counter, sets chime-modeline-string to the standard error tooltip, triggers the threshold warning when the counter hits chime-max-consecutive-failures, and leaves chime-modeline-string alone when chime-modeline-no-events-text is nil.
chime--handle-async-success resets the counter from non-zero to zero, invokes the callback with the events list, works with an empty events list, and is a no-op on the counter when it already starts at zero.
|
| |
|
|
|
|
| |
chime--fetch-and-process inlined two near-identical 7-line failure-handling blocks inside the async callback. They differed only in the log prefix ("Async error" for errors surfaced by the async process, "Error processing events" for errors thrown by the callback). Lift the shared body into chime--record-async-failure (err prefix) so the sequence lives in one place, and lift the success path into chime--handle-async-success (callback events) so the callback lambda becomes pure dispatch.
The outer function drops from 44 lines to 22.
|