Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
1a536f3
test: add proptest and insta dev-dependencies
Horuse Sep 17, 2026
b78ab07
test: DSP effects unit and property tests, fix waveform append seedin…
Horuse Sep 17, 2026
ecd226e
test: DAG graph end-to-end and validation tests for pipeline dag and …
Horuse Sep 17, 2026
a14360d
test: resampler and pipeline input/output worker tests
Horuse Sep 17, 2026
c0aa5fc
test: reconcile signature, cue decoder and xrun tick tests
Horuse Sep 17, 2026
5ee5ea9
test: encoder roundtrips for every format and command core helpers
Horuse Sep 17, 2026
432ec42
test: jitter buffer fan-out registry and playback tap tests
Horuse Sep 17, 2026
c739754
test: direct-IP channel encoder and decoder roundtrips
Horuse Sep 17, 2026
e2aaa2f
test: packet timeline gap and resync semantics
Horuse Sep 17, 2026
ae3019f
test: UDP net receiver datagram, gap concealment and registry lifecycle
Horuse Sep 17, 2026
0e2c2bf
test: audio file reader loop lifecycle via ProgressEmitter trait
Horuse Sep 18, 2026
ac6c3d9
test: health counter and high-water mark semantics
Horuse Sep 18, 2026
e1df8eb
test: widen UDP receiver wait budget under parallel load
Horuse Sep 18, 2026
608ee7e
test: capture broadcast bridge lifecycle
Horuse Sep 18, 2026
ad497cf
test: retry UDP receiver scenario across port races
Horuse Sep 18, 2026
07ffd62
test: clock pacing, pipeline orchestration state and file command rou…
Horuse Sep 19, 2026
3a13ff8
test: engine dispatcher idle arms and clean channel shutdown
Horuse Sep 19, 2026
5263c13
test: widen clock pacing band under parallel load
Horuse Sep 19, 2026
d5622df
test: sdp codec roundtrips, webrtc session registry and local two-pee…
Horuse Sep 19, 2026
37b3d1c
test: drop unused import
Horuse Sep 19, 2026
9c61bf6
test: webrtc decode task timeline, mute and outage semantics
Horuse Sep 19, 2026
a2d1359
test: peaks range clamping and opus buffering edge cases
Horuse Sep 19, 2026
6c28ac0
test: frontend unit tests for format helpers, markdown parser and pip…
Horuse Sep 19, 2026
5e558d3
fix(tests): replace vacuous coverage assertions
Horuse Sep 19, 2026
44bde50
fix(audio): contain non-finite effect samples
Horuse Sep 19, 2026
cbc6cbb
test(audio): strengthen decoder restart checks
Horuse Sep 19, 2026
26ede76
fix(audio): preserve encoded frame boundaries and duration
Horuse Sep 20, 2026
800297b
test(audio): replace weak assertions with behavioral contracts
Horuse Sep 20, 2026
5834a29
chore(tests): remove unused snapshot dependency
Horuse Sep 20, 2026
198bbc5
fix(pipeline): harden persisted schema migration
Horuse Sep 20, 2026
0631452
test(updater): cover update lifecycle
Horuse Sep 20, 2026
231acbd
fix(audio): harden recovery and destructive paths
Horuse Sep 20, 2026
ea63ee4
chore(test): unify frontend and Rust commands
Horuse Sep 20, 2026
8c81438
fix(pipeline): serialize persisted writes
Horuse Sep 20, 2026
fe451f8
ci: run frontend tests on every platform
Horuse Sep 20, 2026
4ad57d2
test(audio): remove scheduler-dependent assertions
Horuse Sep 20, 2026
2c7145b
fix(tests): cover AAC in cross-platform format matches
Horuse Sep 20, 2026
25b5eec
Merge branch 'main' into fix/audio-test-hardening
Horuse Sep 27, 2026
1675e61
test: harden flaky timing tests and cover untested RT paths
Horuse Sep 27, 2026
8df19ce
test(signaling): pin the signaling server wire format
Horuse Sep 27, 2026
769d264
Merge branch 'dev' into fix/audio-test-hardening
Horuse Sep 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
- Read docs/CONTRIBUTING.md and docs/RULES.md.
- Keep the diff to the change. No drive-by renames, reformatting, or
refactors of code the change does not touch.
- Run `bun run check`, `cargo check --manifest-path src-tauri/Cargo.toml`,
and `bun run format` — all must pass and leave the tree clean.
- Run `bun run test`, `bun run check`, and `bun run format` —
all must pass and leave the tree clean.
- If you changed a `#[derive(TS)]` type in Rust, run `bun run generate` and
commit the regenerated files in src/lib/modules/pipeline/generated/.
-->
Expand All @@ -21,8 +21,8 @@ _Explain the design choice. What alternatives were considered and rejected? If t
## Checklist

- [ ] Diff is limited to the change — no unrelated edits
- [ ] `bun run test` passes
- [ ] `bun run check` passes
- [ ] `cargo check --manifest-path src-tauri/Cargo.toml` passes
- [ ] `bun run format` leaves the tree clean
- [ ] Generated TS types are committed with the Rust change (if any)
- [ ] No new dependency without a reason in the PR description
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ jobs:
- name: Install JS deps
run: bun install --frozen-lockfile

- name: Frontend tests
run: bun run test:frontend

# Each OS backend needs its native headers to compile. Linux installs
# PipeWire and the GTK stack explicitly; macOS and Windows runners ship
# their SDKs (CoreAudio / WASAPI + MSVC) preinstalled.
Expand Down Expand Up @@ -93,8 +96,6 @@ jobs:
fi
if [ "$RUNNER_OS" = "Windows" ]; then
cargo test --no-run
elif [ "$RUNNER_OS" = "Linux" ]; then
cargo test -- --skip audio::playback::tests::playback_pulls_samples
else
cargo test
fi
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Without these, one chunk takes ~16 ms and the worker stalls.
## When in doubt

- Read the current code, not earlier explanations.
- RT path change → `cargo check`.
- RT path change → `bun run check`.
- Svelte change → `bun run check`.
- New node or shared UI component → reuse existing Storybook components first, add its stories under `src/stories/` in the same commit (see [docs/UI.md](docs/UI.md)).
- Rust `#[derive(TS)]` change → `bun run generate`, commit the generated files with the Rust change.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ If a platform genuinely cannot support what you are adding, return a real error
## Before you open the PR

```bash
bun run check # svelte-check + tsc
cargo check --manifest-path src-tauri/Cargo.toml
bun run test # frontend + Rust tests in parallel
bun run check # frontend + Rust checks in parallel
bun run format # Prettier + rustfmt
```

Both checks must pass, and `format` must leave the tree clean. A new node or shared component ships with its Storybook stories in the same PR; see [docs/UI.md](docs/UI.md). If you changed a `#[derive(TS)]` type in Rust, run `bun run generate` and commit the regenerated files in `src/lib/modules/pipeline/generated/` together with the Rust change — never by hand, and never on their own.
All checks must pass, and `format` must leave the tree clean. A new node or shared component ships with its Storybook stories in the same PR; see [docs/UI.md](docs/UI.md). If you changed a `#[derive(TS)]` type in Rust, run `bun run generate` and commit the regenerated files in `src/lib/modules/pipeline/generated/` together with the Rust change — never by hand, and never on their own.

Anything persisted to disk — pipeline JSON, `virtual-devices.json`, the macOS driver plist — has to keep loading for people upgrading. Add a `#[serde(default)]` or a versioned migration; do not silently change the meaning of an existing field.

Expand Down
4 changes: 2 additions & 2 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ bun run tauri dev
## Useful commands

```bash
bun run check # svelte-check + tsc
bun run test # frontend + Rust tests in parallel
bun run check # frontend + Rust checks in parallel
bun run generate # regenerate TypeScript types from Rust (ts-rs)
bun run storybook # Storybook on :6006, nodes and shared components with mocked engine
cargo check --manifest-path src-tauri/Cargo.toml
bun run tauri build --bundles app # local .app build (macOS)
bun run tauri build --bundles appimage # local AppImage build (Linux)
bun run tauri build --bundles nsis # local installer build (Windows)
Expand Down
2 changes: 1 addition & 1 deletion docs/RULES.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type(scope): subject
## When in doubt

- Read the current code, not earlier explanations.
- RT path change → `cargo check`.
- RT path change → `bun run check`.
- Svelte change → `bun run check`.
- New node or shared component → add its stories in the same commit, see [UI.md](UI.md).
- Rust `#[derive(TS)]` change → `bun run generate`, commit the generated files with the Rust change.
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"test": "bun scripts/test-all.ts",
"test:frontend": "bun test tests",
"check": "bun scripts/check-all.ts",
"check:frontend": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"tauri": "tauri",
"format": "prettier --write \"**/*.{ts,tsx,md,svelte,json}\" && cargo fmt --manifest-path src-tauri/Cargo.toml",
Expand Down
29 changes: 29 additions & 0 deletions scripts/check-all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const tasks = [
{
name: 'frontend',
command: ['bun', 'run', 'check:frontend']
},
{
name: 'backend',
command: ['cargo', 'check', '--manifest-path', 'src-tauri/Cargo.toml']
}
] as const;

const children = tasks.map((task) => ({
...task,
process: Bun.spawn(task.command, {
stdin: 'inherit',
stdout: 'inherit',
stderr: 'inherit'
})
}));

const results = await Promise.all(children.map(async ({ name, process }) => ({ name, exitCode: await process.exited })));
const failed = results.filter(({ exitCode }) => exitCode !== 0);

if (failed.length > 0) {
for (const { name, exitCode } of failed) {
console.error(`${name} check failed with exit code ${exitCode}`);
}
process.exit(1);
}
29 changes: 29 additions & 0 deletions scripts/test-all.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const tasks = [
{
name: 'frontend',
command: ['bun', 'run', 'test:frontend']
},
{
name: 'backend',
command: ['cargo', 'test', '--manifest-path', 'src-tauri/Cargo.toml']
}
] as const;

const children = tasks.map((task) => ({
...task,
process: Bun.spawn(task.command, {
stdin: 'inherit',
stdout: 'inherit',
stderr: 'inherit'
})
}));

const results = await Promise.all(children.map(async ({ name, process }) => ({ name, exitCode: await process.exited })));
const failed = results.filter(({ exitCode }) => exitCode !== 0);

if (failed.length > 0) {
for (const { name, exitCode } of failed) {
console.error(`${name} tests failed with exit code ${exitCode}`);
}
process.exit(1);
}
64 changes: 63 additions & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ opt-level = 3
[profile.dev.package.deep_filter]
opt-level = 3

[dev-dependencies]
proptest = "1"
tauri = { version = "2", features = ["test"] }

[dependencies]
tauri = { version = "2", features = ["unstable"] }
tauri-plugin-opener = "2"
Expand Down
7 changes: 7 additions & 0 deletions src-tauri/proptest-regressions/audio/effects/compressor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Seeds for failure cases proptest has generated in the past. It is
# automatically read and these particular cases re-run before any
# novel cases are generated.
#
# It is recommended to check this file in to source control so that
# everyone who runs the test benefits from these saved cases.
cc 23a029b70867959f62fcbeb4c4f6e04ea8fb2e8dbeaef82c1212fd1deaec5e00 # shrinks to input = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], poison_pos = 0, makeup = 0.0
Loading
Loading