Files
lucide/packages/icons/tests/buildLucideIconNode.spec.ts
KarsaandEric Fennis 99d25bdee2 feat(packages): extract icon build logic into @lucide/shared (#4409)
* feat(packages): extract build logic to @lucide/shared, still wip

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(packages): extract build logic to @lucide/shared, still wip

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* feat(): unify icon build logic some more, add nonScalingStroke option, marking absoluteStrokeWidth as deprecated

* chore(icons): revert git hook changes made to icons

* fix(packages/astro,react-native,vue): fix iconNode type
fix(packages/vue): fix hasA11yProp

* fix(packages/solid): make component reactive & add unit tests for checking prop changes

* test(packages/vue): add reactivity tests to @lucide/vue

* fix(packages): replace cpy-cli, accidentally removed during main merge

* docs(packages): upgrade react documentation with nonScalingStroke

* fix(tests): update snapshots for lucide-react

* feat(docs): upgraded package guides with nonScalingStroke, dropping absoluteStrokeWidth

* fix(vue,react-native): fix linting issues

* fix(icons): add proper fallback for icon width in calculatedStrokeWidth

* fix(packages/svelte): add globalProps.class to icons

* fix(packages/shared): wrap width, height & size in isDefined

* Update types.ts

* fix(packages/svelte): do not pass propsClass to mergeClasses

---------

Co-authored-by: Eric Fennis <eric.fennis@gmail.com>
2026-09-04 16:38:01 +02:00

139 lines
4.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { House } from '../src/lucide-icons';
import buildLucideIconNode from '../src/buildLucideIconNode';
describe('buildLucideIconNode', () => {
it('should create icon node', () => {
const HouseSVG = buildLucideIconNode(House);
expect(HouseSVG.at(0)).toBe('svg');
});
it('should match the snapshot', () => {
const HouseSVG = buildLucideIconNode(House);
expect(JSON.stringify(HouseSVG.at(1))).toMatchSnapshot();
});
it('should override dimensions, but not viewBox', () => {
const HouseSVG = buildLucideIconNode(House, { size: 12 });
expect(HouseSVG[1]['width']).toBe(12);
expect(HouseSVG[1]['height']).toBe(12);
expect(HouseSVG[1]['viewBox']).toBe('0 0 24 24');
});
it('should override width, but not height', () => {
const HouseSVG = buildLucideIconNode(House, { width: 12 });
expect(HouseSVG[1]['width']).toBe(12);
expect(HouseSVG[1]['height']).toBe(24);
expect(HouseSVG[1]['viewBox']).toBe('0 0 24 24');
});
it('should override height, but not width', () => {
const HouseSVG = buildLucideIconNode(House, { height: 12 });
expect(HouseSVG[1]['width']).toBe(24);
expect(HouseSVG[1]['height']).toBe(12);
expect(HouseSVG[1]['viewBox']).toBe('0 0 24 24');
});
it('should override color', () => {
const HouseSVG = buildLucideIconNode(House, { color: 'pink' });
expect(HouseSVG[1]['stroke']).toBe('pink');
expect(HouseSVG[1]['fill']).toBe('none');
});
it('should override stroke width', () => {
const HouseSVG = buildLucideIconNode(House, { strokeWidth: 12 });
expect(HouseSVG[1]['stroke-width']).toBe(12);
});
it('should scale the stroke width', () => {
const HouseSVG = buildLucideIconNode(House, {
size: 12,
strokeWidth: 2,
absoluteStrokeWidth: true,
});
expect(HouseSVG[1]['stroke-width']).toBe(4);
});
it('should not scale the stroke width', () => {
const HouseSVG = buildLucideIconNode(House, {
size: 12,
strokeWidth: 2,
absoluteStrokeWidth: false,
});
expect(HouseSVG[1]['stroke-width']).toBe(2);
});
it('should set non-scaling-stroke to child nodes', () => {
const HouseSVG = buildLucideIconNode(House, { nonScalingStroke: true });
for (const node of HouseSVG[2]!) {
expect(node[1]['vector-effect']).toBe('non-scaling-stroke');
}
});
it('should not set non-scaling-stroke', () => {
const HouseSVG = buildLucideIconNode(House, { nonScalingStroke: false });
expect(HouseSVG[1]['vector-effect']).toBeUndefined();
});
it('should create icon node with attributes', () => {
const HouseSVG = buildLucideIconNode(House, { attributes: { fill: 'red' } });
expect(HouseSVG[1]['fill']).toBe('red');
});
it('should create icon node with class name', () => {
const HouseSVG = buildLucideIconNode(House, { attributes: { class: 'icon' } });
expect(HouseSVG[1]['class']).toBe('icon');
});
it('should add backwards-compatible classes', () => {
const HouseSVG = buildLucideIconNode(House);
expect(HouseSVG[1]['class']).toBe('lucide lucide-house lucide-home');
});
it('should merge classes', () => {
const HouseSVG = buildLucideIconNode(House, { className: 'icon' });
expect(HouseSVG[1]['class']).toBe('lucide lucide-house lucide-home icon');
});
it('should support className with multiple classes', () => {
const HouseSVG = buildLucideIconNode(House, {
className: ' icon custom lucide-house ',
});
expect(HouseSVG[1]['class']).toBe('lucide lucide-house lucide-home icon custom');
});
it('should not include default classes when includeDefaultClasses is false', () => {
const HouseSVG = buildLucideIconNode(House, { includeDefaultClasses: false });
expect(HouseSVG[1]['class']).toBeUndefined();
});
it('should add aria-hidden when hasA11yProp is false', () => {
const HouseSVG = buildLucideIconNode(House, { hasA11yProp: false });
expect(HouseSVG[1]['aria-hidden']).toBe('true');
});
it('should not add aria-hidden when hasA11yProp is true', () => {
const HouseSVG = buildLucideIconNode(House, { hasA11yProp: true });
expect(HouseSVG[1]['aria-hidden']).toBeUndefined();
});
});