Skip to content

Commit 3de503f

Browse files
vanceingallsclaude
andcommitted
test(studio): cover carve visibility through the real element
The panel derives carve's source list from the selected element's document, so a selection with no element has no sources — which the new visibility rule correctly reads as 'nothing to carve against'. The suite mounted exactly that, so it was asserting on a hidden block. Selections now carry a real <audio> with a sibling track, and the two cases the rule exists for are pinned directly. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent ce511c1 commit 3de503f

1 file changed

Lines changed: 39 additions & 3 deletions

File tree

‎packages/studio/src/components/editor/propertyPanelAudioFxGroup.test.tsx‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @vitest-environment happy-dom
22
import { act } from "react";
3-
import { describe, expect, it, vi } from "vitest";
3+
import { afterEach, describe, expect, it, vi } from "vitest";
44
import { createRoot } from "react-dom/client";
55
import { AudioFxGroup } from "./propertyPanelAudioFxGroup.js";
66
import type { DomEditSelection } from "./domEditingTypes";
@@ -12,14 +12,37 @@ const CHAIN = JSON.stringify({
1212
nodes: [{ type: "lowpass", id: "n1", params: { frequency: 900, q: 1.2, poles: "2" } }],
1313
});
1414

15-
function mount(dataAttributes: Record<string, string>) {
15+
// Each mount appends its tracks to the document; without clearing, a later
16+
// "only one audio track" case would still find the previous test's sibling.
17+
afterEach(() => {
18+
document.body.innerHTML = "";
19+
});
20+
21+
/**
22+
* A selected `<audio>` with a sibling track, so carve — which needs another
23+
* track to listen to — is offered. Pass `alone` for a composition holding just
24+
* this one.
25+
*/
26+
function audioSelection(dataAttributes: Record<string, string>, alone = false): DomEditSelection {
27+
const bed = document.createElement("audio");
28+
bed.id = "bed";
29+
document.body.append(bed);
30+
if (!alone) {
31+
const voice = document.createElement("audio");
32+
voice.id = "vo";
33+
document.body.append(voice);
34+
}
35+
return { dataAttributes, id: "bed", element: bed } as unknown as DomEditSelection;
36+
}
37+
38+
function mount(dataAttributes: Record<string, string>, alone = false) {
1639
// Every write is quiet: persisted without the preview reload that would
1740
// restart every playing track, but with a selection resync so the panel sees
1841
// what it just wrote.
1942
const onSetAttributeQuiet = vi.fn();
2043
const host = document.createElement("div");
2144
document.body.append(host);
22-
const selection = { dataAttributes, element: null } as unknown as DomEditSelection;
45+
const selection = audioSelection(dataAttributes, alone);
2346
act(() => {
2447
createRoot(host).render(
2548
<AudioFxGroup element={selection} onSetAttributeQuiet={onSetAttributeQuiet} />,
@@ -239,3 +262,16 @@ describe("AudioFxGroup successive edits", () => {
239262
expect(onSetAttributeQuiet.mock.calls[0][0]).toBe("data-fx-chain");
240263
});
241264
});
265+
266+
describe("AudioFxGroup carve visibility", () => {
267+
it("offers carve when the composition holds another audio track", () => {
268+
const { host } = mount({ "fx-chain": CHAIN });
269+
expect(host.querySelector(".hf-fx-carve")).toBeTruthy();
270+
});
271+
272+
it("does not offer carve for the only audio track in the composition", () => {
273+
// Nothing to listen to, so the picker would be empty and Analyse inert.
274+
const { host } = mount({ "fx-chain": CHAIN }, true);
275+
expect(host.querySelector(".hf-fx-carve")).toBeNull();
276+
});
277+
});

0 commit comments

Comments
 (0)