import {describe, it, expect} from 'vitest';
import {extractText} from '../../src/transformers/text.js';
describe('extractText', () => {
it('returns undefined for non-TEXT nodes', () => {
expect(extractText({type: 'FRAME', characters: 'test'})).toBeUndefined();
});
it('returns undefined for TEXT nodes without characters', () => {
expect(extractText({type: 'TEXT'})).toBeUndefined();
});
it('extracts content from TEXT node', () => {
const result = extractText({type: 'TEXT', characters: 'Hello'});
expect(result?.content).toBe('Hello');
});
it('extracts font family', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {fontFamily: 'Inter'},
});
expect(result?.fontFamily).toBe('Inter');
});
it('extracts font weight', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {fontWeight: 700},
});
expect(result?.fontWeight).toBe(700);
});
it('extracts font size as px', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {fontSize: 16},
});
expect(result?.fontSize).toBe('16px');
});
it('calculates line-height as em', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {fontSize: 16, lineHeightPx: 24},
});
expect(result?.lineHeight).toBe('1.5em');
});
it('maps text alignment', () => {
expect(
extractText({type: 'TEXT', characters: 'x', style: {textAlignHorizontal: 'LEFT'}})?.textAlign,
).toBe('left');
expect(
extractText({type: 'TEXT', characters: 'x', style: {textAlignHorizontal: 'CENTER'}})?.textAlign,
).toBe('center');
expect(
extractText({type: 'TEXT', characters: 'x', style: {textAlignHorizontal: 'RIGHT'}})?.textAlign,
).toBe('right');
expect(
extractText({type: 'TEXT', characters: 'x', style: {textAlignHorizontal: 'JUSTIFIED'}})?.textAlign,
).toBe('justify');
});
it('extracts letter spacing', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {letterSpacing: 0.5},
});
expect(result?.letterSpacing).toBe('0.5px');
});
it('omits letter spacing when 0', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
style: {letterSpacing: 0},
});
expect(result?.letterSpacing).toBeUndefined();
});
it('extracts color from first visible fill', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello',
fills: [
{type: 'SOLID', visible: false, color: {r: 1, g: 0, b: 0, a: 1}},
{type: 'SOLID', visible: true, color: {r: 0, g: 0, b: 0, a: 1}},
],
});
expect(result?.color).toBe('#000000');
});
it('extracts full typography properties', () => {
const result = extractText({
type: 'TEXT',
characters: 'Hello World',
style: {
fontFamily: 'Inter',
fontWeight: 600,
fontSize: 24,
lineHeightPx: 32,
textAlignHorizontal: 'LEFT',
letterSpacing: 0,
},
fills: [{type: 'SOLID', visible: true, color: {r: 0.1, g: 0.1, b: 0.1, a: 1}}],
});
expect(result).toEqual({
content: 'Hello World',
fontFamily: 'Inter',
fontWeight: 600,
fontSize: '24px',
lineHeight: '1.33em',
textAlign: 'left',
color: '#1a1a1a',
});
});
});