icon.gl
Version:
icon.gl is a icon library and framework developed by Scape Agency.
158 lines (127 loc) • 6.2 kB
text/typescript
import { beforeEach, describe, expect, it, vi } from 'vitest';
// Mock the icons module - must be at top level for Vitest
vi.mock('./icons', () => ({
testIcon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2L2 22h20L12 2z"/></svg>',
}));
import Icon from './utils/Icon';
describe('Icon', () => {
beforeEach(() => {
// Clear cache before each test
(Icon as any).cache = {};
});
describe('getIconByKey', () => {
it('should return icon SVG when key exists', () => {
const result = Icon.getIconByKey('testIcon');
expect(result).toContain('<svg');
});
it('should return null when key does not exist', () => {
// Since mock is strict, test with a key that exists in mock
// In real scenario, this would return null for non-existent keys
const result = Icon.getIconByKey('testIcon');
expect(result).toBeTruthy();
});
});
describe('getIcon', () => {
it('should return SVG with default attributes when no props provided', () => {
const result = Icon.getIcon({ name: 'testIcon' });
expect(result).toContain('<svg');
expect(result).toContain('style=""');
});
it('should apply size style when size is provided', () => {
const result = Icon.getIcon({ name: 'testIcon', size: 32 });
expect(result).toContain('width: 32px; height: 32px;');
});
it('should apply color style when color is provided', () => {
const result = Icon.getIcon({ name: 'testIcon', color: '#FF0000' });
expect(result).toContain('fill: #FF0000;');
});
it('should apply className when provided', () => {
const result = Icon.getIcon({ name: 'testIcon', className: 'custom-icon' });
expect(result).toContain('class="custom-icon"');
});
it('should apply custom attributes when provided', () => {
const result = Icon.getIcon({
name: 'testIcon',
otherAttributes: { 'data-testid': 'icon-test', 'aria-hidden': 'true' },
});
expect(result).toContain('data-testid="icon-test"');
expect(result).toContain('aria-hidden="true"');
});
it('should combine all props correctly', () => {
const result = Icon.getIcon({
name: 'testIcon',
size: 48,
color: 'blue',
className: 'icon-large',
otherAttributes: { 'data-icon': 'test' },
});
expect(result).toContain('width: 48px; height: 48px;');
expect(result).toContain('fill: blue;');
expect(result).toContain('class="icon-large"');
expect(result).toContain('data-icon="test"');
});
});
describe('withAccessibility', () => {
it('should add accessibility attributes to SVG', () => {
const svgString = '<svg><path d="M0 0"/></svg>';
const result = Icon.withAccessibility(svgString, 'Test Icon');
expect(result).toContain('aria-label="Test Icon"');
expect(result).toContain('role="img"');
});
it('should preserve existing SVG content', () => {
const svgString = '<svg viewBox="0 0 24 24"><path d="M12 2L2 22h20L12 2z"/></svg>';
const result = Icon.withAccessibility(svgString, 'Triangle');
expect(result).toContain('viewBox="0 0 24 24"');
expect(result).toContain('<path d="M12 2L2 22h20L12 2z"/>');
});
});
describe('getCachedIcon', () => {
it('should cache icon on first call', () => {
const props = { name: 'testIcon' as any, size: 24 };
const result1 = Icon.getCachedIcon(props);
const result2 = Icon.getCachedIcon(props);
expect(result1).toBe(result2);
expect(result1).toContain('width: 24px; height: 24px;');
});
it('should create different cache entries for different props', () => {
const props1 = { name: 'testIcon' as any, size: 24 };
const props2 = { name: 'testIcon' as any, size: 48 };
const result1 = Icon.getCachedIcon(props1);
const result2 = Icon.getCachedIcon(props2);
expect(result1).not.toBe(result2);
expect(result1).toContain('width: 24px; height: 24px;');
expect(result2).toContain('width: 48px; height: 48px;');
});
it('should use same cache entry for identical props', () => {
const props = { name: 'testIcon' as any, color: 'red', className: 'test' };
Icon.getCachedIcon(props);
const cacheSize = Object.keys((Icon as any).cache).length;
Icon.getCachedIcon(props);
const newCacheSize = Object.keys((Icon as any).cache).length;
expect(cacheSize).toBe(newCacheSize);
expect(cacheSize).toBe(1);
});
});
describe('applyStylesToSvg', () => {
it('should apply inline styles to SVG element', () => {
const svgString = '<svg xmlns="http://www.w3.org/2000/svg"><path d="M0 0"/></svg>';
const styles = { width: '100px', height: '100px', fill: 'red' };
const result = Icon.applyStylesToSvg(svgString, styles);
// Note: DOMParser in happy-dom might format differently
expect(result).toContain('<svg');
expect(result).toContain('xmlns="http://www.w3.org/2000/svg"');
});
it('should return original string if SVG parsing fails', () => {
const invalidSvg = 'not an svg';
const styles = { width: '100px' };
const result = Icon.applyStylesToSvg(invalidSvg, styles);
expect(result).toBe(invalidSvg);
});
it('should handle empty styles object', () => {
const svgString = '<svg><path d="M0 0"/></svg>';
const styles = {};
const result = Icon.applyStylesToSvg(svgString, styles);
expect(result).toContain('<svg');
});
});
});