diff options
| author | Craig Jennings <c@cjennings.net> | 2025-11-03 15:26:11 -0600 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2025-11-03 15:26:11 -0600 |
| commit | 0a69c5854378afcafc567d965f206cf6a0a984be (patch) | |
| tree | 923425a2aaf106c51cf5a3100cdf42f98e534da8 /modules | |
| parent | 9f8aec55033d46ca4f1cd78fbd315444a0c00bc6 (diff) | |
test: Add comprehensive test suite for video-audio-recording module
Added 83 test cases across 9 test files with 100% pass rate, covering
device detection, parsing, grouping, and complete workflow integration.
## What Was Done
### Refactoring for Testability
- Extracted `cj/recording--parse-pactl-output` from `cj/recording-parse-sources`
- Separated parsing logic from shell command execution
- Enables testing with fixture data instead of live system calls
### Test Fixtures Created
- `pactl-output-normal.txt` - All device types (built-in, USB, Bluetooth)
- `pactl-output-empty.txt` - Empty output
- `pactl-output-single.txt` - Single device
- `pactl-output-monitors-only.txt` - Only monitor devices
- `pactl-output-inputs-only.txt` - Only input devices
- `pactl-output-malformed.txt` - Invalid/malformed output
### Unit Tests (8 files, 78 test cases)
1. **test-video-audio-recording-friendly-state.el** (10 tests)
- State name conversion: SUSPENDED→Ready, RUNNING→Active
2. **test-video-audio-recording-parse-pactl-output.el** (14 tests)
- Parse raw pactl output into structured data
- Handle empty, malformed, and mixed valid/invalid input
3. **test-video-audio-recording-parse-sources.el** (6 tests)
- Shell command wrapper testing with mocked output
4. **test-video-audio-recording-detect-mic-device.el** (13 tests)
- Documents bugs: Returns ID numbers instead of device names
- Doesn't filter monitors (legacy function, not actively used)
5. **test-video-audio-recording-detect-system-device.el** (13 tests)
- Works correctly: Returns full device names
- Tests monitor detection with various device types
6. **test-video-audio-recording-group-devices-by-hardware.el** (12 tests)
- CRITICAL: Bluetooth MAC address normalization (colons vs underscores)
- Device pairing logic (mic + monitor from same hardware)
- Friendly name assignment
- Filters incomplete devices
7. **test-video-audio-recording-check-ffmpeg.el** (3 tests)
- ffmpeg availability detection
8. **test-video-audio-recording-get-devices.el** (7 tests)
- Auto-detection fallback logic
- Error handling for incomplete detection
### Integration Tests (1 file, 5 test cases)
9. **test-integration-recording-device-workflow.el** (5 tests)
- Complete workflow: parse → group → friendly names
- Bluetooth MAC normalization end-to-end
- Incomplete device filtering across components
- Malformed data graceful handling
## Key Testing Insights
### Bugs Documented
- `cj/recording-detect-mic-device` has bugs (returns IDs, doesn't filter monitors)
- These functions appear to be legacy code not used by main workflow
- Tests document current behavior to catch regressions if fixed
### Critical Features Validated
- **Bluetooth MAC normalization**: Input uses colons (00:1B:66:C0:91:6D),
output uses underscores (00_1B_66_C0_91_6D), grouping normalizes correctly
- **Device pairing**: Only devices with BOTH mic and monitor are included
- **Friendly names**: USB/PCI/Bluetooth patterns correctly identified
### Test Coverage
- Normal cases: Valid inputs, typical workflows
- Boundary cases: Empty, single device, incomplete pairs
- Error cases: Malformed input, missing devices, partial detection
## Test Execution
All tests pass: 9/9 files, 83/83 test cases (100% pass rate)
```bash
make test-file FILE=test-video-audio-recording-*.el
# All pass individually
# Integration test also passes
make test-file FILE=test-integration-recording-device-workflow.el
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/video-audio-recording.el | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/modules/video-audio-recording.el b/modules/video-audio-recording.el index de770623..f8df2cb4 100644 --- a/modules/video-audio-recording.el +++ b/modules/video-audio-recording.el @@ -69,11 +69,11 @@ Returns device name or nil if not found." (when (string-match "\\([^\t\n]+\\.monitor\\)" output) (match-string 1 output)))) -(defun cj/recording-parse-sources () - "Parse pactl sources output into structured list. -Returns list of (device-name description state) tuples." - (let ((output (shell-command-to-string "pactl list sources short 2>/dev/null")) - (sources nil)) +(defun cj/recording--parse-pactl-output (output) + "Internal parser for pactl sources output. Takes OUTPUT string. +Returns list of (device-name driver state) tuples. +Extracted for testing without shell command execution." + (let ((sources nil)) (dolist (line (split-string output "\n" t)) (when (string-match "^[0-9]+\t\\([^\t]+\\)\t\\([^\t]+\\)\t\\([^\t]+\\)\t\\([^\t]+\\)" line) (let ((device (match-string 1 line)) @@ -82,6 +82,12 @@ Returns list of (device-name description state) tuples." (push (list device driver state) sources)))) (nreverse sources))) +(defun cj/recording-parse-sources () + "Parse pactl sources output into structured list. +Returns list of (device-name driver state) tuples." + (cj/recording--parse-pactl-output + (shell-command-to-string "pactl list sources short 2>/dev/null"))) + (defun cj/recording-friendly-state (state) "Convert technical state name to user-friendly label. STATE is the raw state from pactl (SUSPENDED, RUNNING, IDLE, etc.)." |
