aboutsummaryrefslogtreecommitdiff
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
...
* refactor(transcription): extract four sentinel side-effect helpersCraig Jennings2026-04-191-0/+136
| | | | | | | | | | | | | | | | Break cj/--transcription-sentinel's seven inline side-effects into named helpers: - cj/--write-transcript-on-success: writes process output to .txt on success - cj/--append-to-log: appends event marker + process output to log - cj/--update-transcription-status: marks tracking-list entry complete/error - cj/--notify-completion: sends success or critical notification Also: switch the tautological (cj/--should-keep-log t) to use the local success-p (equivalent but matches the function signature), and rename the unused audio-file sentinel arg to _audio-file. Sentinel shrinks from 48 lines with 7 inline blocks to 14 lines of straight-line helper calls. 10 tests cover the extracted helpers.
* refactor(transcription): extract init-log-file and track-transcriptionCraig Jennings2026-04-191-0/+116
| | | | | | | | | | | Pull two more helpers out of cj/--start-transcription-process: - cj/--init-log-file: writes the initial log header with timestamp, backend, audio file, script path - cj/--track-transcription: pushes a running-status entry and refreshes the modeline Start-process shrinks from 58 lines with 4 levels of nesting to ~25 lines mostly at depth 1-2. 10 tests cover the extracted helpers.
* refactor(transcription): extract cj/--build-process-environmentCraig Jennings2026-04-191-0/+94
| | | | | | Pull the per-backend env-var assembly out of cj/--start-transcription-process into a standalone pure function. 9 tests cover: the three backends, parent-env preservation, non-mutation, missing-key user-error, unknown-backend error.
* refactor(transcription): consolidate backends into descriptor alistCraig Jennings2026-04-191-51/+64
| | | | | | | | | | | | | | Introduce cj/--transcription-backends alist mapping each backend to (:script :auth-host :env-var). Replace: - two near-identical cj/--get-{openai,assemblyai}-api-key functions with a single parameterized cj/--auth-source-password helper - the pcase in cj/--transcription-script-path with an alist lookup - the pcase block in cj/--start-transcription-process that assembled the API-key env var with an alist-driven assembly Adding a new backend is now a single line in the alist. The existing tests plus retargeted API-key tests (now 10, covering the parameterized helper and the descriptor data) verify no behavior change.
* test(transcription): add characterization tests for API-key retrievalCraig Jennings2026-04-191-0/+90
| | | | | | | 8 tests pinning down current behavior of cj/--get-openai-api-key and cj/--get-assemblyai-api-key (host query, string vs function secret, missing-entry → nil). Baseline for upcoming consolidation into a single parameterized helper.
* fix(reconcile): restore repo iteration under projects-dir and code-dirCraig Jennings2026-04-191-0/+181
| | | | | | | | | | | The outer dolist in cj/check-for-open-work guarded its body with (boundp 'base-dir), which always returns nil under lexical-binding because base-dir is a lexical loop variable. Every repo under projects-dir and code-dir was silently skipped; only org-dir and user-emacs-directory (both top-level defvars) still got reconciled. Remove the bogus boundp check. Add regression tests covering the entry point itself — the existing suite only exercised the helpers.
* refactor(reconcile): extract helpers, add recursive repo discovery and 28 testsCraig Jennings2026-04-196-0/+501
| | | | | Extract should-skip-p, pull-clean, pull-dirty from 6-level nested reconcile-git-directory. Make find-git-repos recurse into sub-repos.
* test(recording): add direct tests for device-sort-key, device-status-label, ↵Craig Jennings2026-04-053-0/+198
| | | | | | get-sink-index Previously tested only indirectly via label-devices and sink-has-active-audio-p.
* test(calendar-sync): add 32 tests for recurrence exceptions, helpers, unfoldingCraig Jennings2026-04-056-0/+313
| | | | | Cover occurrence-matches-exception-p (6), apply-single-exception (6), exdate-matches-p (6), extract-cn (5), extract-email (4), unfold-continuation (5).
* refactor(calendar-sync): remove dead function calendar-sync--timezone-nameCraig Jennings2026-04-051-7/+1
| | | | Function was defined but never called anywhere in the codebase.
* test(calendar-sync): add 68 tests across 13 files for untested pure functionsCraig Jennings2026-04-0513-0/+647
| | | | | | | Covers core parsing (parse-ics-datetime, parse-timestamp, format-timestamp, split-events, parse-event), date utilities (add-months, add-days, weekday-to-number, date-weekday, event-start-time), and timezone (format-timezone-offset, convert-utc-to-local, localize-parsed-datetime).
* test(recording): add direct tests for extracted refactoring helpersCraig Jennings2026-04-053-0/+243
| | | | | | Cover build-video-command (9 tests), select-from-labeled (5 tests), and test-device (4 tests). All three were previously tested only indirectly through their callers.
* refactor(recording): unify parse-pactl-sources/sinks-verbose into single ↵Craig Jennings2026-04-052-16/+16
| | | | | | | function Identical 31-line parser logic differed only in "Source #" vs "Sink #" header. Replaced with cj/recording--parse-pactl-verbose taking a record-type parameter.
* feat(music): add random-aware next/previous; refactor music + calendar-syncCraig Jennings2026-04-034-0/+914
| | | | | | | | | | Music: random mode now respected by next/previous keys. Previous navigates a 50-track play history ring buffer. Fixed playlist replacement bug. 24 new tests. Calendar-sync: consolidated duplicate parse functions, extracted timezone localization helper, unified expand-daily/monthly/yearly into parameterized function, removed dead code. 33 new characterization tests. -90 lines.
* feat(music): add test coverage for 7 functions, refactor with extracted helpersCraig Jennings2026-04-017-0/+930
| | | | | | | | | | | | Add 47 new unit tests across 7 test files covering playlist-modified-p, assert-valid-playlist-file, playlist-tracks, create-radio-station, ensure-playlist-buffer, after-playlist-clear, and header-text. Extract three helpers to reduce duplication: assert-m3u-files-exist (dedupes 2 identical guards), sync-playlist-file (dedupes 3 state-sync patterns), and select-m3u-file (reusable M3U selection with cancel). Simplify append-track-to-playlist nesting from 6 to 4 levels. Delete unused cj/music-keymap-prefix variable.
* fix(calendar-sync): handle variable-length date lists in RRULE UNTILCraig Jennings2026-03-091-0/+121
| | | | | | | date-to-time used (reverse date) which broke when RRULE UNTIL values were parsed as 5-element lists (year month day hour minute) from UTC timestamps. This caused recurring events with UTC UNTIL dates to expand to 0 occurrences, producing stale calendar entries.
* refactor(gptel): extract model-list and selection logic for testabilityCraig Jennings2026-03-062-0/+175
| | | | | | | - Extract cj/gptel--build-model-list from cj/gptel-change-model - Extract cj/gptel--current-model-selection from cj/gptel-change-model - Add test-ai-config-build-model-list.el (9 tests) - Add test-ai-config-current-model-selection.el (8 tests)
* refactor(gptel): lazy-load gptel-magit, rebind rewrite/context keysCraig Jennings2026-03-062-3/+131
| | | | | | | | | | - Replace use-package gptel-magit hook with autoloads via with-eval-after-load 'magit (loads gptel only on key press) - Move org header defuns above use-package to fix load order - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Add test-ai-config-gptel-magit-lazy-loading.el (8 tests) - Mark all ai-config cleanup items DONE in todo.org
* test(gptel): add unit tests for ai-config, remove dead cj/gptel-backendsCraig Jennings2026-03-064-0/+277
| | | | | | | | - Add testutil-ai-config.el with gptel stubs for batch testing - Add tests for cj/gptel--model-to-string (9 tests) - Add tests for cj/gptel--fresh-org-prefix (8 tests) - Add tests for cj/gptel-backend-and-model (8 tests) - Remove dead cj/gptel-backends defvar (duplicates cj/gptel--available-backends)
* feat(json,yaml): add tree-sitter modes, formatting, and jq integrationCraig Jennings2026-03-022-0/+185
| | | | | | | New prog-json module: json-ts-mode with jq formatting (C-; f) and jq-interactively (C-c C-q). Upgraded prog-yaml to yaml-ts-mode with prettier formatting. Both use treesit-auto for grammar management. Includes 18 new tests (10 JSON, 8 YAML), 185/185 passing.
* test(recording): add tests for label-devices, label-sinks, get-sink-appsCraig Jennings2026-02-265-0/+372
| | | | | Fill test gaps from quality-engineer review: 3 new test files (28 tests) and error cases for get-available-mics and get-available-sinks (+4 tests).
* feat(recording): intuitive labels, show muted devices, add app namesCraig Jennings2026-02-263-84/+151
| | | | | | | | | | | | | Rework quick-setup device picker: - Labels: [in use], [ready], [available], [muted] instead of PulseAudio jargon (RUNNING/IDLE/SUSPENDED) - Muted devices now shown (previously hidden) so users can see all connected hardware and understand why a device is unsuitable - Sink step shows which apps are playing through each output: "JDS Labs Element IV [in use] (Firefox, Spotify)" - Prompt changed from "audio output to monitor" to "audio output to capture" to avoid PulseAudio monitor terminology confusion - Sort order: in use → ready → available → muted
* feat(recording): replace icons with text state labels in quick-setupCraig Jennings2026-02-263-122/+86
| | | | | | | | | | | | Replace hard-to-distinguish nerd font icons with clear text labels: Jabra SPEAK 510 Mono [active - running] Shure MV7+ Analog Stereo [active - idle] Ryzen HD Audio Controller [inactive - suspended] Both mic and sink steps use the same labeling. Devices sorted running → idle → suspended. Removed mic-active-p and sink-active-p helpers — state now comes directly from the verbose pactl parsers via get-available-mics/sinks which return (name description state).
* feat(recording): add mic indicators and fix misleading sink iconCraig Jennings2026-02-261-21/+100
| | | | | | | | | Mic step now shows 󰍬 with green/dim coloring to indicate which mics are actively in use (RUNNING state), with active mics sorted to top. Changed sink inactive icon from 󰖁 (slashed speaker, reads as "broken/muted") to 󰖀 (plain speaker, reads as "no streams right now"). Active sinks still show 󰕾.
* fix(recording): remove drift detection that overrides explicit sink choiceCraig Jennings2026-02-261-14/+12
| | | | | | | | | | | | Validation Check 2 (default sink drifted) would silently replace the user's explicit sink selection from quick-setup with the default sink's monitor on every recording start. Removed it — if the device still exists, trust the user's choice. The no-audio warning (Check 3) already catches wrong-sink scenarios. Also fix commentary: device selection does not persist across sessions (both vars are plain defvar), and update validation section to match the two remaining checks.
* feat(recording): show sinks with active audio indicators in quick-setupCraig Jennings2026-02-266-51/+367
| | | | | | | | | | Quick-setup (C-; r s) is now a two-step flow: pick a mic, then pick an audio output sink. Sinks display 󰕾/󰖁 icons with green/dim coloring to indicate which have active audio streams, with active sinks sorted to the top. The chosen sink's .monitor is set as the system audio device. This replaces the old auto-default-sink approach, letting users see where audio is actually going and pick the right sink in one command.
* fix(recording): replace blocking y-or-n-p with non-blocking warningCraig Jennings2026-02-261-13/+21
| | | | | | | | The no-audio warning was a y-or-n-p prompt that blocked recording start. This fires too often in legitimate scenarios (starting before a meeting connects, during silence). Replace with a message in the echo area and diagnostic steps logged silently to *Messages*. Also add pre-recording validation to the Commentary section.
* feat(recording): validate system audio device before recordingCraig Jennings2026-02-2610-51/+479
| | | | | | | | | | Add pre-recording validation that catches stale or drifted system audio devices before they cause silent recordings. When the default audio output changes (Bluetooth reconnect, device switch) between setup and recording, the monitor device is auto-updated. Warns if no audio is currently playing through the monitored sink. Co-Authored-By: Craig Jennings <c@cjennings.net>
* fix(mousetrap): use buffer-local keymaps via emulation-mode-map-alistsCraig Jennings2026-02-201-7/+7
| | | | | | | | minor-mode-map-alist is global, so the last buffer to set its keymap won for all buffers. Dashboard's scroll+primary profile was immediately overwritten by other buffers' disabled profile. Switch to emulation-mode-map-alists with a buffer-local variable so each buffer gets its own independent keymap. Fixes dashboard click navigation.
* feat(restclient): add REST API client for interactive API explorationCraig Jennings2026-02-183-0/+247
| | | | | restclient.el + restclient-jq integration with SkyFi API templates, tutorial file, auto key injection from authinfo, 17 ERT tests.
* fix(tests): add missing requires for org-noter test dependenciesCraig Jennings2026-02-162-0/+4
| | | | | Tests failed after org-noter-config started using roam-dir and cj/custom-keymap. Added requires for user-constants and keybindings.
* test: add 38 tests for org-agenda-config and org-refile-configCraig Jennings2026-02-154-0/+504
| | | | | | | - testutil-org.el: shared dynamic timestamp helpers (days-ago, days-ahead, today) - org-agenda-config: 31 tests across 2 files (skip functions + add-files) - org-refile-config: 7 tests for ensure-org-mode validation - Remove prog-shell from checklist (fully covered by existing 9 tests)
* test: add 86 new tests, fix 3 production bugs, fix 8 stale testsCraig Jennings2026-02-1512-206/+765
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | New test coverage (86 tests across 7 files): - custom-case: 43 tests (title-case-region, upcase-dwim, downcase-dwim) - custom-datetime: 10 tests (all insert methods with mocked time) - config-utilities: 11 tests (format-build-time type branching) - org-capture-config: 22 tests (date-prefix + event-content) Production bugs found and fixed: - custom-case: title-case-region crashes on whitespace/punctuation-only input (char-after returns nil when no word chars found) - org-capture-config: browser branch missing empty-string guard on :initial plist value, producing stray newline in capture output - mousetrap-mode: keymap never registered in minor-mode-map-alist, so mode was silently not blocking any mouse events. Now pushes/removes on toggle. Additional fixes: - local-repository: fix cons cell syntax bug in localrepo-initialize (was calling vars as functions instead of using cons) - dupre-theme tests: update rainbow-delimiter color expectations - mousetrap tests: update dashboard profile (primary-click → scroll+primary) - music completion test: bind completion-ignore-case to prevent pollution - Delete redundant interactive recording test (duplicate of ERT version) Refactoring: - org-capture-config: extract cj/org-capture--date-prefix pure function from cj/org-capture-format-event-headline for testability Test checklist: todo.org updated to [11/25], removed untestable modules
* fix(reveal): suppress date/caps on title slide, move transition to init optionsCraig Jennings2026-02-151-5/+9
| | | | | | | | - Add date:nil, timestamp:nil, author:t to template OPTIONS - Set global CSS override (text-transform:none) via org-reveal-head-preamble - Move transition from obsolete REVEAL_TRANS to REVEAL_INIT_OPTIONS - Default transition changed to "none" - Global init options now reference cj/reveal-default-transition constant
* feat(music): add playlist UI with header overlay, track styling, and testsCraig Jennings2026-02-152-0/+272
| | | | | | | | | | | Replace raw file paths with clean track descriptions (Artist - Title [M:SS]), add multi-line header overlay showing playlist info, now-playing, mode indicators with gold/muted toggle states, and keybinding hints. Style non-playing tracks in Dupre steel, playing track in Dupre gold. Playlist window now opens from the bottom at 50% height with subtle background highlight on focus. Unit tests for format-duration (13 tests) and track-description (16 tests).
* feat(music): align EMMS keybindings with ncmpcpp, add consume modeCraig Jennings2026-02-151-0/+262
| | | | | | | | | | Reconcile playlist-mode bindings with ncmpcpp defaults: add ncmpcpp- compatible aliases (>/<, +, S-up/S-down, c), new toggles (r repeat, t repeat-track, z random, x consume), info keys (i, o), and relocate radio (r→R), reload (R→g), shuffle (x→Z). Add consume mode that removes tracks from playlist after playback via emms-player-finished- hook. Fix buffer-local bug where emms-playlist-selected-marker was checked outside with-current-buffer. 13 ERT tests.
* feat(reveal): add org-reveal presentation workflow with ERT testsCraig Jennings2026-02-142-0/+253
| | | | | | | Replaced pandoc-based reveal.js export with native ox-reveal integration. New org-reveal-config.el module provides offline, self-contained HTML export with keybindings under C-; p. Includes setup script for reveal.js 5.1.0 and 34 ERT tests covering header template and title-to-filename helpers.
* test: add ERT coverage for modeline-config and hugo-configCraig Jennings2026-02-146-0/+762
| | | | | | | Add 67 tests across 6 new test files for modeline and hugo modules. Refactor hugo-config: extract post-file-path and post-template helpers from interactive new-post function for testability. Update todo.org with test audit (31 modules), priority adjustments, and task cleanup.
* fix(agenda): scope file scan to immediate subdirs of ~/projectsCraig Jennings2026-02-131-27/+35
| | | | | | Replace recursive directory-files-recursively with shallow scan that only checks ~/projects/*/todo.org. Excludes nested archive todo.org files and keeps ~/code and ~/.emacs.d out of agenda.
* fix(test): add missing testutil require for sanitize-org-body testsCraig Jennings2026-02-064-24/+25
|
* feat(recording): rewrite device setup, fix video stop, update modeline iconsCraig Jennings2026-02-0616-346/+764
| | | | | | | | | | | | | | | Video stop fix: kill wf-recorder (producer) first on Wayland so ffmpeg gets clean EOF, then signal process group. Replaces sit-for with poll-based wait-for-exit. Fixes zero-byte output files. Device selection: rewrite quick setup to show all available mics with PulseAudio descriptions, auto-detect default sink monitor for system audio. Skip confirmation dialog, add Cancel option to mic list. Modeline: replace red dot emoji with nerd font icons (mic/camcorder). Rename quick-setup-for-calls to quick-setup, rebind C-; r s / C-; r S. 173 recording tests pass (was 165).
* fix(calendar-sync): sanitize description text to prevent org heading corruptionCraig Jennings2026-02-062-3/+81
| | | | | | Event descriptions containing lines starting with * were being interpreted as org headings, breaking file structure. Replace leading asterisks with dashes before writing descriptions.
* fix(calendar-sync): fix heading order, continuation lines, and exception ↵Craig Jennings2026-02-052-1/+25
| | | | | | | | | | | | | | | | | | text cleaning Three bugs found during manual verification of calendar sync output: 1. Heading/timestamp order reversed in event-to-org — nreverse pattern put timestamp before the org heading. Swap initial list order. 2. get-property continuation line regex broken — the ^ anchor in "^\n[ \t]" prevented matching at the correct position, truncating long DESCRIPTION values at the first ICS line fold. Remove anchor, add explicit position check (matching get-all-property-lines pattern). 3. collect-recurrence-exceptions didn't clean text — exception instances got raw ICS text (literal \n, HTML tags) replacing the cleaned base event text. Wrap summary/description/location in clean-text.
* feat(calendar-sync): add event details — attendees, organizer, status, URLCraig Jennings2026-02-0520-7/+903
| | | | | | | | Add ICS text unescaping (RFC 5545), HTML stripping, and new fields (attendees/status, organizer, meeting URL) to calendar-sync.el. event-to-org now outputs org property drawers. 88 new tests across 10 test files, 146/146 pass. Also fix pre-existing test require order and keymap guard issues.
* fix(email): improve MIME handle parsing for email viewerCraig Jennings2026-02-041-0/+237
| | | | | | | | - Add helper functions for robust MIME structure navigation - cj/--email-handle-is-type-p: check handle content type - cj/--email-find-displayable-part: recursively find HTML/plain text - Handle both leaf handles and nested multipart structures - Add 9 unit tests covering normal, boundary, and error cases
* test(video-recording): add process cleanup testsCraig Jennings2026-02-031-0/+229
| | | | | | | | | | | | Unit tests verify pkill wf-recorder is called: - On Wayland video stop (to kill orphan wf-recorder) - On Wayland video start (to clean previous orphans) - NOT called on X11 (only relevant for Wayland pipeline) Integration tests (tagged :integration :wayland) verify actual cleanup: - No orphan processes after stop - Start cleans up existing orphans - Multiple start/stop cycles don't accumulate orphans
* fix(video-recording): use generic 'Built-in Audio' labelCraig Jennings2026-02-033-10/+10
| | | | | Renamed 'Built-in Laptop Audio' to 'Built-in Audio' since PCI audio devices are used on both laptops and desktops.
* test(video-recording): add command structure validation testsCraig Jennings2026-02-031-0/+311
| | | | | | | | | | | These tests verify the syntax and flags of shell commands generated for video/audio recording. They catch issues like: - Invalid wf-recorder flags (e.g., --no-audio doesn't exist) - Wrong encoder names (h264 vs libx264) - Incorrect stdout output syntax (-o - vs -f /dev/stdout) - Missing required flags (-y for auto-confirm) 18 new tests covering Wayland, X11, and audio recording command structure.
* fix(tests): correct flaky test assertionsCraig Jennings2026-02-032-6/+10
| | | | | | | - calendar-sync: fix GTFO count bounds to match 15-month window (was incorrectly assuming 12-month/52-week window) - video-recording: add process-status mock to prevent race condition where process hadn't exited yet when sentinel was manually called
* feat(calendar-sync): add EXDATE support for excluded recurring event datesCraig Jennings2026-02-035-0/+676
| | | | | | | | | | | | | | | | | | | | | When someone deletes a single instance of a recurring meeting in Google Calendar, the calendar exports an EXDATE property marking that date as excluded. Previously, calendar-sync expanded the RRULE without filtering out these excluded dates, causing deleted instances to appear in org output. New functions: - calendar-sync--get-exdates: Extract all EXDATE values from event - calendar-sync--get-exdate-line: Get full EXDATE line with parameters - calendar-sync--parse-exdate: Parse EXDATE into datetime list - calendar-sync--collect-exdates: Collect excluded dates with TZ conversion - calendar-sync--exdate-matches-p: Check if occurrence matches an EXDATE - calendar-sync--filter-exdates: Filter out excluded dates from occurrences Modified calendar-sync--expand-recurring-event to collect and filter EXDATEs after RRULE expansion. Includes 47 new tests covering extraction, parsing, collection, filtering, and integration with RECURRENCE-ID exceptions.