Skip to content

Commit

Permalink
Chart library: Improve overall test coverage (#41449)
Browse files Browse the repository at this point in the history
* add tooltip tests

* add legend testing

* changelog

* add additional legend tests
  • Loading branch information
annacmc authored Jan 31, 2025
1 parent bc44e59 commit 7063861
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Charts: add additional testing for library
12 changes: 10 additions & 2 deletions projects/js-packages/charts/src/components/legend/base-legend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const BaseLegend: FC< LegendProps > = ( {
<div
className={ clsx( styles.legend, styles[ `legend--${ orientation }` ], className ) }
role="list"
data-testid={ `legend-${ orientation }` }
>
<LegendOrdinal
scale={ legendScale }
Expand All @@ -44,13 +45,20 @@ export const BaseLegend: FC< LegendProps > = ( {
{ labels => (
<div className={ styles[ `legend--${ orientation }` ] }>
{ labels.map( label => (
<div key={ label.text } className={ styles[ 'legend-item' ] }>
<svg width={ 16 } height={ 16 }>
<div
key={ label.text }
className={ styles[ 'legend-item' ] }
role="listitem"
data-testid="legend-item"
>
<svg width={ 16 } height={ 16 } role="img">
<rect
width={ 16 }
height={ 16 }
fill={ label.value }
className={ styles[ 'legend-item-swatch' ] }
data-testid="legend-marker"
role="presentation"
/>
</svg>
<span className={ styles[ 'legend-item-label' ] }>
Expand Down
76 changes: 76 additions & 0 deletions projects/js-packages/charts/src/components/legend/legend.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { render, screen } from '@testing-library/react';
import { BaseLegend } from './base-legend';

describe( 'BaseLegend', () => {
const defaultItems = [
{ label: 'Item 1', value: '50%', color: '#ff0000' },
{ label: 'Item 2', value: '30%', color: '#00ff00' },
];

test( 'renders horizontal legend items', () => {
render( <BaseLegend items={ defaultItems } orientation="horizontal" /> );
expect( screen.getByText( 'Item 1' ) ).toBeInTheDocument();
expect( screen.getByText( 'Item 2' ) ).toBeInTheDocument();
expect( screen.getByText( '50%' ) ).toBeInTheDocument();
expect( screen.getByText( '30%' ) ).toBeInTheDocument();
} );

test( 'renders vertical legend items', () => {
render( <BaseLegend items={ defaultItems } orientation="vertical" /> );
const items = screen.getAllByText( /Item \d/ );
expect( items ).toHaveLength( 2 );
} );

test( 'applies color styles to legend markers', () => {
render( <BaseLegend items={ defaultItems } orientation="horizontal" /> );
const markers = screen.getAllByTestId( 'legend-marker' );
expect( markers[ 0 ] ).toHaveAttribute( 'fill', '#ff0000' );
expect( markers[ 1 ] ).toHaveAttribute( 'fill', '#00ff00' );
} );

test( 'handles empty items array', () => {
render( <BaseLegend items={ [] } orientation="horizontal" /> );
const legendItems = screen.queryAllByRole( 'listitem' );
expect( legendItems ).toHaveLength( 0 );
} );

test( 'handles missing values', () => {
const itemsWithoutValues = [
{ label: 'Item 1', color: '#ff0000', value: undefined },
{ label: 'Item 2', color: '#00ff00', value: undefined },
];
render( <BaseLegend items={ itemsWithoutValues } orientation="horizontal" /> );
expect( screen.getByText( 'Item 1' ) ).toBeInTheDocument();
expect( screen.getByText( 'Item 2' ) ).toBeInTheDocument();
} );

test( 'applies custom className', () => {
render(
<BaseLegend items={ defaultItems } className="custom-legend" orientation="horizontal" />
);
expect( screen.getByRole( 'list' ) ).toHaveClass( 'custom-legend' );
} );

test( 'renders with correct orientation styles', () => {
const { rerender } = render( <BaseLegend items={ defaultItems } orientation="horizontal" /> );
expect( screen.getByTestId( 'legend-horizontal' ) ).toBeInTheDocument();

rerender( <BaseLegend items={ defaultItems } orientation="vertical" /> );
expect( screen.getByTestId( 'legend-vertical' ) ).toBeInTheDocument();
} );

test( 'renders legend items with correct spacing', () => {
render( <BaseLegend items={ defaultItems } orientation="horizontal" /> );
const items = screen.getAllByTestId( 'legend-item' );
expect( items ).toHaveLength( 2 );
} );

test( 'handles items with long labels', () => {
const itemsWithLongLabels = [
{ label: 'Very Long Label That Should Still Display', value: '50%', color: '#ff0000' },
{ label: 'Another Long Label for Testing', value: '30%', color: '#00ff00' },
];
render( <BaseLegend items={ itemsWithLongLabels } orientation="horizontal" /> );
expect( screen.getByText( 'Very Long Label That Should Still Display' ) ).toBeInTheDocument();
} );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { render, screen } from '@testing-library/react';
import { BaseTooltip } from '../base-tooltip';

describe( 'BaseTooltip', () => {
const defaultProps = {
data: {
label: 'Test Label',
value: 100,
valueDisplay: '100%',
},
top: 100,
left: 200,
};

test( 'renders default tooltip content', () => {
render( <BaseTooltip { ...defaultProps } /> );
expect( screen.getByText( 'Test Label: 100%' ) ).toBeInTheDocument();
expect( screen.getByRole( 'tooltip' ) ).toBeInTheDocument();
} );

test( 'renders children instead of data when provided', () => {
render(
<BaseTooltip top={ 100 } left={ 200 }>
<div>Custom Child Content</div>
</BaseTooltip>
);
expect( screen.getByText( 'Custom Child Content' ) ).toBeInTheDocument();
} );

test( 'applies correct positioning styles', () => {
render( <BaseTooltip { ...defaultProps } /> );
const tooltip = screen.getByRole( 'tooltip' );
expect( tooltip ).toHaveStyle( {
top: '100px',
left: '200px',
} );
} );

test( 'handles missing valueDisplay', () => {
const propsWithoutDisplay = {
...defaultProps,
data: {
label: 'Test',
value: 50,
},
};
render( <BaseTooltip { ...propsWithoutDisplay } /> );
expect( screen.getByText( 'Test: 50' ) ).toBeInTheDocument();
} );
} );

0 comments on commit 7063861

Please sign in to comment.