diff --git a/lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.test.ts b/lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.test.ts index f88960a29..6dd76c039 100644 --- a/lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.test.ts +++ b/lightly_studio_view/src/lib/components/DatasetDistributionPanel/DatasetDistributionPanel.test.ts @@ -46,6 +46,24 @@ if (typeof globalThis.ResizeObserver === 'undefined') { } const defaultProps = { data: balanced }; +const comparisonData = [ + { + sample_tag_id: 'tag-a', + sample_tag_name: 'Reviewed', + counts: [ + { label_name: 'car', count: 2 }, + { label_name: 'dog', count: 0 } + ] + }, + { + sample_tag_id: 'tag-b', + sample_tag_name: 'Priority', + counts: [ + { label_name: 'car', count: 1 }, + { label_name: 'dog', count: 5 } + ] + } +]; describe('DatasetDistributionPanel', () => { beforeAll(() => { @@ -195,6 +213,65 @@ describe('DatasetDistributionPanel', () => { expect(screen.queryByTestId('dataset-distribution-source-select')).not.toBeInTheDocument(); }); + it('ranks comparison classes by aggregate counts and keeps tag series independent', async () => { + render(DatasetDistributionPanel, { + props: { + sources: [ + { + id: 'classes', + label: 'Annotation classes', + data: [{ label: 'car', count: 10 }], + comparisonData + } + ] + } + }); + + const option = echartsMock.instance.setOption.mock.lastCall?.[0] as { + yAxis: { data: string[] }; + series: { name: string; data: number[] }[]; + }; + expect(option.yAxis.data).toEqual(['dog', 'car']); + expect(option.series).toMatchObject([ + { name: 'Reviewed', data: [0, 2] }, + { name: 'Priority', data: [5, 1] } + ]); + expect(screen.getByText(/2 sample tags/)).toBeInTheDocument(); + expect(screen.queryByText(/annotations/)).not.toBeInTheDocument(); + + await fireEvent.click(screen.getByTestId('dataset-distribution-expand')); + await waitFor(() => expect(screen.getAllByText(/2 sample tags/)).toHaveLength(2)); + }); + + it('renders comparison data from the selected annotation-type group', async () => { + const user = userEvent.setup(); + render(DatasetDistributionPanel, { + props: { + sources: [ + { + id: 'classes', + label: 'Annotation classes', + groupLabel: 'Annotation type', + groups: [ + { id: 'all', label: 'All types', data: balanced }, + { + id: 'classification', + label: 'Classification', + data: [{ label: 'car', count: 3 }], + comparisonData + } + ] + } + ] + } + }); + + await user.click(screen.getByTestId('dataset-distribution-group-select')); + await user.click(screen.getByText('Classification')); + + await waitFor(() => expect(screen.getByText(/2 sample tags/)).toBeInTheDocument()); + }); + it('defaults to the first source with content when a leading source is empty', () => { const sources: DistributionSource[] = [ { id: 'all', label: 'All types', data: [], valueNoun: 'annotations' }, diff --git a/lightly_studio_view/src/lib/components/DatasetDistributionPanel/TagComparisonSelect.test.ts b/lightly_studio_view/src/lib/components/DatasetDistributionPanel/TagComparisonSelect.test.ts new file mode 100644 index 000000000..099e21994 --- /dev/null +++ b/lightly_studio_view/src/lib/components/DatasetDistributionPanel/TagComparisonSelect.test.ts @@ -0,0 +1,45 @@ +import { render, screen } from '@testing-library/svelte'; +import userEvent from '@testing-library/user-event'; +import { beforeAll, describe, expect, it, vi } from 'vitest'; +import TagComparisonSelect from './TagComparisonSelect.svelte'; + +const items = [ + { value: 'tag-a', label: 'Reviewed' }, + { value: 'tag-b', label: 'Priority' } +]; + +describe('TagComparisonSelect', () => { + beforeAll(() => { + Element.prototype.scrollIntoView = vi.fn(); + }); + + it('selects a tag without mutating the controlled value', async () => { + const user = userEvent.setup(); + const onChange = vi.fn(); + render(TagComparisonSelect, { props: { items, selectedIds: [], onChange } }); + + await user.click(screen.getByTestId('dataset-distribution-tag-select')); + await user.click(screen.getByText('Reviewed')); + + expect(onChange).toHaveBeenCalledWith(['tag-a']); + expect(screen.getByTestId('dataset-distribution-tag-select')).toHaveTextContent( + 'Compare sample tags' + ); + }); + + it('deselects an already selected tag', async () => { + const user = userEvent.setup(); + const onChange = vi.fn(); + render(TagComparisonSelect, { + props: { items, selectedIds: ['tag-a'], onChange } + }); + + expect(screen.getByTestId('dataset-distribution-tag-select')).toHaveTextContent( + '1 tag selected' + ); + await user.click(screen.getByTestId('dataset-distribution-tag-select')); + await user.click(screen.getByText('Reviewed')); + + expect(onChange).toHaveBeenCalledWith([]); + }); +});