<feed xmlns='http://www.w3.org/2005/Atom'>
<title>chime/tests, branch main</title>
<subtitle>Emacs chimes, notifications, and modeline reminders so you don't miss events
</subtitle>
<id>https://git.cjennings.net/chime/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/chime/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/'/>
<updated>2026-06-11T19:54:03+00:00</updated>
<entry>
<title>test: add failing tests for the async fetch watchdog</title>
<updated>2026-06-11T19:54:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-11T19:54:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=6b8918b4cc44dc39e70a5544e8286eb781a97ccc'/>
<id>urn:sha1:6b8918b4cc44dc39e70a5544e8286eb781a97ccc</id>
<content type='text'>
</content>
</entry>
<entry>
<title>test: cover per-event override through the agenda pipeline</title>
<updated>2026-05-11T12:21:08+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T12:21:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=a8db4796820190d725789456a579d11da75382e5'/>
<id>urn:sha1:a8db4796820190d725789456a579d11da75382e5</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat: add per-event :CHIME_NOTIFY_BEFORE: interval override</title>
<updated>2026-05-11T10:40:24+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T10:40:24+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=ee90de269e4f65a9b57b4fc9e260d3aa6948b6ca'/>
<id>urn:sha1:ee90de269e4f65a9b57b4fc9e260d3aa6948b6ca</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>test: add failing tests for per-event interval override</title>
<updated>2026-05-11T10:02:17+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T10:02:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=73faba8658ea783bca8392e4d4cc14cf7f94a48f'/>
<id>urn:sha1:73faba8658ea783bca8392e4d4cc14cf7f94a48f</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>test: close coverage gaps to 99.88% line coverage</title>
<updated>2026-05-11T09:50:45+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T09:50:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=21ec114def7df9aa61e43e8f2cee484ded772e72'/>
<id>urn:sha1:21ec114def7df9aa61e43e8f2cee484ded772e72</id>
<content type='text'>
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 &lt; 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.
</content>
</entry>
<entry>
<title>feat: make modeline status-message strings customizable</title>
<updated>2026-05-11T09:37:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-11T09:37:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=a11f554fd533f2139cf6b9e592388a5385d4462b'/>
<id>urn:sha1:a11f554fd533f2139cf6b9e592388a5385d4462b</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>feat: tighten chime runtime validation and tooltip behavior</title>
<updated>2026-05-10T21:36:47+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-10T21:36:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=3c64dac1b98049d475be838294349326c32248ae'/>
<id>urn:sha1:3c64dac1b98049d475be838294349326c32248ae</id>
<content type='text'>
</content>
</entry>
<entry>
<title>test: harden test dependency and temp-dir setup</title>
<updated>2026-05-10T21:36:17+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-10T21:36:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=93063d8a35060d5467e2d056bd4496e51f17ddc1'/>
<id>urn:sha1:93063d8a35060d5467e2d056bd4496e51f17ddc1</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor!: collapse six filter defcustoms into include/exclude alists</title>
<updated>2026-05-05T17:39:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-05T17:39:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=3019a33d391912120a78cad43a49eb34c4a1d044'/>
<id>urn:sha1:3019a33d391912120a78cad43a49eb34c4a1d044</id>
<content type='text'>
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"))
  ;; -&gt;
  (setq chime-include-filters '((keywords . ("TODO"))))

  (setq chime-predicate-blacklist '(my-pred))
  ;; -&gt;
  (setq chime-exclude-filters '((predicates . (my-pred))))

This brings the consolidation pass to 37 -&gt; 29 defcustoms, the target
from .ai/settings-consolidation.org.
</content>
</entry>
<entry>
<title>refactor!: collapse three time-left format defcustoms into one alist</title>
<updated>2026-05-05T17:30:42+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-05-05T17:30:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/chime/commit/?id=26fabb22edfea51e8a686c179ab91d00a2ff0bc3'/>
<id>urn:sha1:26fabb22edfea51e8a686c179ab91d00a2ff0bc3</id>
<content type='text'>
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.
</content>
</entry>
</feed>
