uttrflow / uttrflow/uttrflow-swift

Test the dictation controller's withdrawn press while hands-free, and a long hold released during hands-free

Open Beginner friendly
#733 0 comments 0 reactions 0 assignees View on GitHub
area:dictation enhancement good first issue P2
Dominant language
Swift
Stars
4
Forks
17
Avg merge
3h 32m
Merged PRs (30d)
277

Description

## What happens

In `Sources/UttrflowPipeline/DictationController.swift`, three `else { return }` bodies have never run:

- line 264: `withdrawPress()` (a `.cancelled` event: the held modifiers began another shortcut) when the press did not open the microphone. That includes every press during hands-free, because `press(at:)` clears `pressOpenedTheMicrophone` there (line 197). This is what stops a chord from cancelling a hands-free dictation;
- line 266: `withdrawPress()` when the press opened the microphone but the pipeline is no longer listening, or has become hands-free, by the time the withdrawal is handled;
- line 367: `endHold()` when a real (long) hold is released while hands-free, which must not finish the dictation.

Line 352's `?? false` (a release with no recorded press) is also unexercised.

Measured on origin/main `26d7bc1` with `swift test --enable-code-coverage` (5,384 tests, all passing) and `xcrun llvm-cov export` over the test binary. The regions named below have an execution count of 0: no test runs them, so a change that breaks them passes `make verify`.

## Why it matters

A hands-free dictation can run for minutes. These guards are the only thing stopping it being cancelled when the user presses a shortcut that begins with the same modifier, or finished early when they lean on the key. Losing any of them discards or truncates the user's speech without asking.

## How to reproduce

Run `swift test --enable-code-coverage`, then `xcrun llvm-cov show -instr-profile .build/debug/codecov/default.profdata .build/debug/UttrflowPackageTests.xctest/Contents/MacOS/UttrflowPackageTests Sources/UttrflowPipeline/DictationController.swift` and look for the `0` counts on the lines named above.

## Acceptance criteria

- A test starts hands-free (double tap), then sends a press followed by `.cancelled` (a withdrawn press). It expects the pipeline still to be listening, with no `cancel` call.
- A test where the press opened the microphone but the dictation already ended (for example, the capture engine failed to start) before `.cancelled` arrives expects no `cancel` call.
- A test starts hands-free, then holds the key longer than `minimumHold` and releases it. It expects the dictation still to be listening.
- Each new test fails when the branch it covers is broken. Check this by hand before opening the PR: temporarily change the branch (flip the condition or return the other value), see the test fail, then restore it.

## Where to start

- `Tests/UttrflowPipelineTests/DictationControllerTests.swift`, suite "Dictation controller: turning key presses into dictations". Use `makeHarness`, `tap(_:)`, `FakeHotkeyMonitor` and the harness's manual clock. The existing test "a single tap while hands-free changes nothing" is the closest template.
- `Docs/pipeline-gestures.md` describes the gestures.

Read `CONTRIBUTING.md` first. Iterate with `swift test --filter `, then run `make verify` before pushing. Only tests change; no product code needs to.

**Size:** S to M.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md, then open Tests/UttrflowPipelineTests/DictationControllerTests.swift and the suite “Dictation controller: turning key presses into dictations”; use makeHarness, tap(_:) and FakeHotkeyMonitor with the manual clock. Use the existing hands-free test as a template, run the focused swift test filter, and verify that the new tests cover withdrawn presses and long holds without cancelling or ending dictation before running make verify.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
desktop, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
90/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.