import type { Config, Dictionary, LocalOptions } from 'style-dictionary/types' import { describe, expect, it } from 'vitest' import { processGridTokens } from './grid-processor.js' describe('processGridTokens', () => { const createMockOptions = (prefix?: string): Config & LocalOptions => ({ prefix, platforms: {}, source: [], include: [], exclude: [], files: [], transform: {}, transformGroup: {}, format: {}, action: {}, fileHeader: '', log: {}, }) it('should return empty string when no grid tokens are provided', () => { const dictionary: Dictionary = { tokens: {}, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(`""`) }) it('should generate single grid utility with default breakpoint only', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, }, }, breakpoint: { md: { $value: '768px' }, lg: { $value: '1024px' }, }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--grid-layout-columns--default), 1fr); grid-gap: var(--grid-layout-gutter--default); margin: 0 var(--grid-layout-margin--default); } " `) }) it('should generate grid utility with responsive breakpoints', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, md: { columns: { $value: 12 }, gutter: { $value: '1.5rem' }, margin: { $value: '2rem' }, }, lg: { columns: { $value: 12 }, gutter: { $value: '2rem' }, margin: { $value: '3rem' }, }, }, }, breakpoint: { md: { $value: '768px' }, lg: { $value: '1024px' }, }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--grid-layout-columns--default), 1fr); grid-gap: var(--grid-layout-gutter--default); margin: 0 var(--grid-layout-margin--default); @media screen and (min-width: 768px) { grid-template-columns: repeat(var(--grid-layout-columns--md), 1fr); grid-gap: var(--grid-layout-gutter--md); margin: 0 var(--grid-layout-margin--md); } @media screen and (min-width: 1024px) { grid-template-columns: repeat(var(--grid-layout-columns--lg), 1fr); grid-gap: var(--grid-layout-gutter--lg); margin: 0 var(--grid-layout-margin--lg); } } " `) }) it('should generate multiple grid utilities', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, md: { columns: { $value: 12 }, gutter: { $value: '1.5rem' }, margin: { $value: '2rem' }, }, }, sidebar: { default: { columns: { $value: 4 }, gutter: { $value: '0.5rem' }, margin: { $value: '0.5rem' }, }, lg: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, }, }, breakpoint: { md: { $value: '768px' }, lg: { $value: '1024px' }, }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--grid-layout-columns--default), 1fr); grid-gap: var(--grid-layout-gutter--default); margin: 0 var(--grid-layout-margin--default); @media screen and (min-width: 768px) { grid-template-columns: repeat(var(--grid-layout-columns--md), 1fr); grid-gap: var(--grid-layout-gutter--md); margin: 0 var(--grid-layout-margin--md); } } @utility grid-sidebar { display: grid; grid-template-columns: repeat(var(--grid-sidebar-columns--default), 1fr); grid-gap: var(--grid-sidebar-gutter--default); margin: 0 var(--grid-sidebar-margin--default); @media screen and (min-width: 1024px) { grid-template-columns: repeat(var(--grid-sidebar-columns--lg), 1fr); grid-gap: var(--grid-sidebar-gutter--lg); margin: 0 var(--grid-sidebar-margin--lg); } } " `) }) it('should apply prefix to variable names when provided', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, md: { columns: { $value: 12 }, gutter: { $value: '1.5rem' }, margin: { $value: '2rem' }, }, }, }, breakpoint: { md: { $value: '768px' }, }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions('uy') const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--uy-grid-layout-columns--default), 1fr); grid-gap: var(--uy-grid-layout-gutter--default); margin: 0 var(--uy-grid-layout-margin--default); @media screen and (min-width: 768px) { grid-template-columns: repeat(var(--uy-grid-layout-columns--md), 1fr); grid-gap: var(--uy-grid-layout-gutter--md); margin: 0 var(--uy-grid-layout-margin--md); } } " `) }) it('should skip breakpoints not defined in breakpoint tokens', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, custom: { columns: { $value: 8 }, gutter: { $value: '1.2rem' }, margin: { $value: '1.5rem' }, }, }, }, breakpoint: { md: { $value: '768px' }, // Note: 'custom' breakpoint is not defined here }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--grid-layout-columns--default), 1fr); grid-gap: var(--grid-layout-gutter--default); margin: 0 var(--grid-layout-margin--default); } " `) }) it('should handle missing breakpoint token values', () => { const dictionary: Dictionary = { tokens: { grid: { layout: { default: { columns: { $value: 6 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, md: { columns: { $value: 12 }, gutter: { $value: '1.5rem' }, margin: { $value: '2rem' }, }, }, }, breakpoint: { md: {}, // Missing $value }, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-layout { display: grid; grid-template-columns: repeat(var(--grid-layout-columns--default), 1fr); grid-gap: var(--grid-layout-gutter--default); margin: 0 var(--grid-layout-margin--default); @media screen and (min-width: undefined) { grid-template-columns: repeat(var(--grid-layout-columns--md), 1fr); grid-gap: var(--grid-layout-gutter--md); margin: 0 var(--grid-layout-margin--md); } } " `) }) it('should handle complex identifier names', () => { const dictionary: Dictionary = { tokens: { grid: { 'main-content': { default: { columns: { $value: 8 }, gutter: { $value: '1rem' }, margin: { $value: '1rem' }, }, }, }, breakpoint: {}, }, allTokens: [], properties: {}, usesReference: () => false, getReferences: () => [], transformTokens: () => [], } as unknown as Dictionary const options = createMockOptions() const result = processGridTokens(dictionary, options) expect(result).toMatchInlineSnapshot(` "@utility grid-main-content { display: grid; grid-template-columns: repeat(var(--grid-main-content-columns--default), 1fr); grid-gap: var(--grid-main-content-gutter--default); margin: 0 var(--grid-main-content-margin--default); } " `) }) })