Skip to content

test: add 91 tests for 5 piano roll components#1624

Open
ChuxiJ wants to merge 2 commits intomainfrom
feat/pianoroll-test-coverage-sprint
Open

test: add 91 tests for 5 piano roll components#1624
ChuxiJ wants to merge 2 commits intomainfrom
feat/pianoroll-test-coverage-sprint

Conversation

@ChuxiJ
Copy link
Copy Markdown

@ChuxiJ ChuxiJ commented Apr 8, 2026

Summary

  • Adds test coverage for 5 previously untested piano roll components: PianoRollConstants (47 tests), PianoRollEmptyState, TransformMenu, GeneratePatternDialog, QuantizeDialog
  • Piano roll test total goes from 58 → 149 tests across 11 files
  • All 7111 tests pass, zero TypeScript errors

Test plan

  • npm test — all 7111 tests pass
  • npx tsc --noEmit — 0 errors
  • No existing test regressions

Closes #1621

https://claude.ai/code/session_01AAbmUU34sN8t5XRPsvuyzh

Adds comprehensive test coverage for previously untested piano roll
components:

- PianoRollConstants: 47 tests (isBlackKey, midiNoteToName, gridSizeToBeats,
  normalizeMidiVelocity, velocityToColor, visual styles, tool shortcuts)
- PianoRollEmptyState: 4 tests (rendering, empty state messaging)
- TransformMenu: 13 tests (dropdown, transform types, parameter panels)
- GeneratePatternDialog: 10 tests (role/genre/key/scale selectors, density)
- QuantizeDialog: 13 tests (grid size, strength, swing, scope, apply/cancel)

Piano roll test total: 149 tests across 11 files (was 58 across 6).
All 7111 tests pass. Zero TypeScript errors.

https://claude.ai/code/session_01AAbmUU34sN8t5XRPsvuyzh
Copilot AI review requested due to automatic review settings April 8, 2026 20:00
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Vitest/@testing-library coverage for several previously untested Piano Roll utilities and UI components to increase confidence in note transforms, dialogs, and empty-state rendering (closing #1621).

Changes:

  • Introduces new unit tests for PianoRollConstants utility functions and visual-style helpers.
  • Adds basic render/interaction tests for TransformMenu, QuantizeDialog, and GeneratePatternDialog.
  • Adds a small render/layout test suite for PianoRollEmptyState.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/components/pianoroll/tests/PianoRollConstants.test.ts Adds unit tests for constants, note name/key helpers, velocity helpers, and visual-style functions.
src/components/pianoroll/tests/PianoRollEmptyState.test.tsx Verifies empty-state text, icon presence, and centering layout classes.
src/components/pianoroll/tests/TransformMenu.test.tsx Covers disabled/enabled state and basic navigation between transform list and parameter panels.
src/components/pianoroll/tests/GeneratePatternDialog.test.tsx Adds smoke tests for dialog rendering and key UI controls (role/genre/density/regenerate/cancel).
src/components/pianoroll/tests/QuantizeDialog.test.tsx Adds smoke tests for dialog rendering, labels/controls, and cancel behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@@ -0,0 +1,112 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vi is imported but never used in this test file. Remove it to keep the test dependencies minimal and avoid confusing readers about mocked timers/mocks.

Suggested change
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { describe, it, expect, beforeEach } from 'vitest';

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +16
function setupDialog() {
useProjectStore.getState().createProject();
useProjectStore.getState().addTrack('midi');
useUIStore.setState({
showQuantizeDialog: true,
quantizeTarget: {
clipId: 'clip-1',
noteIds: ['note-1', 'note-2', 'note-3'],
},
});
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupDialog() creates a project and adds a track, but it never creates a MIDI clip with id clip-1 or notes with ids note-1..note-3. As a result, QuantizeDialog's preview logic (targetNotes lookup + setQuantizePreviewPositions) never runs in these tests, and the test data doesn't reflect real usage where the target clip/notes exist. Create a pianoRoll track and a real MIDI clip (e.g. via ensureMidiClip / addClip with midiData) and seed it with notes matching quantizeTarget.noteIds.

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +21
const tracks = useProjectStore.getState().project!.tracks;
const track = tracks[tracks.length - 1];
const clip = track.clips[0];
useUIStore.setState({
showGeneratePatternDialog: true,
generatePatternClipId: clip?.id ?? 'clip-1',
});
return { clipId: clip?.id ?? 'clip-1' };
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupDialog() adds a track and then reads track.clips[0], but addTrack(...) creates a track with clips: [] (no default clip). This means generatePatternClipId will always fall back to 'clip-1', which likely doesn't exist in the project, so the tests aren't exercising behavior against a real MIDI clip. Consider creating a pianoRoll track and a MIDI clip explicitly (e.g. ensureMidiClip(track.id) or addClip(..., { midiData: { notes: [], grid: '1/16' } })) and using that returned clip id.

Suggested change
const tracks = useProjectStore.getState().project!.tracks;
const track = tracks[tracks.length - 1];
const clip = track.clips[0];
useUIStore.setState({
showGeneratePatternDialog: true,
generatePatternClipId: clip?.id ?? 'clip-1',
});
return { clipId: clip?.id ?? 'clip-1' };
const initialTracks = useProjectStore.getState().project!.tracks;
const initialTrack = initialTracks[initialTracks.length - 1];
const createdClip =
initialTrack.clips[0] ??
({
id: 'clip-1',
startBeat: 0,
durationBeats: 16,
midiData: {
notes: [],
grid: '1/16',
},
} as any);
if (!initialTrack.clips[0]) {
useProjectStore.setState((state) => ({
project: state.project
? {
...state.project,
tracks: state.project.tracks.map((track) =>
track.id === initialTrack.id
? { ...track, clips: [...track.clips, createdClip] }
: track
),
}
: state.project,
}));
}
const tracks = useProjectStore.getState().project!.tracks;
const track = tracks[tracks.length - 1];
const clip = track.clips[0] ?? createdClip;
useUIStore.setState({
showGeneratePatternDialog: true,
generatePatternClipId: clip.id,
});
return { clipId: clip.id };

Copilot uses AI. Check for mistakes.
Comment on lines +14 to +26
function setupProject() {
useProjectStore.getState().createProject();
useProjectStore.getState().addTrack('midi');
const tracks = useProjectStore.getState().project!.tracks;
const track = tracks[tracks.length - 1];
const clip = track.clips[0];
return { trackId: track.id, clipId: clip?.id ?? 'clip-1' };
}

describe('TransformMenu', () => {
beforeEach(() => {
setupProject();
});
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setupProject() adds a track and attempts to return clipId, but tracks are created with clips: [] by default and the returned ids are not used anywhere in the tests. Since these tests currently only validate menu UI state (and never invoke transformMidiNotes), consider removing the store setup entirely, or (if you plan to add apply/side-effect assertions) create a real MIDI clip via ensureMidiClip and pass the real clipId into TransformMenu so the tests reflect real usage.

Copilot uses AI. Check for mistakes.
- QuantizeDialog: remove unused vi import, use real MIDI clip with
  ensureMidiClip() and seeded notes instead of fake clip-1 id
- GeneratePatternDialog: use ensureMidiClip() for real clip id
- TransformMenu: remove unnecessary store setup (tests only validate
  menu UI state, not transform side effects)

https://claude.ai/code/session_01AAbmUU34sN8t5XRPsvuyzh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: Piano Roll test coverage sprint — 5 components, 91 new tests

2 participants