Skip to content

Commit a7a5bc4

Browse files
authored
Merge pull request #25 from dev-five-git/support-boolean
Support boolean
2 parents 29ce680 + f97a743 commit a7a5bc4

36 files changed

+2362
-1269
lines changed

src/__tests__/utils.test.ts

Lines changed: 126 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
import { describe, expect, it, test } from 'bun:test'
2-
import { getComponentName, space } from '../utils'
1+
import { afterEach, describe, expect, it, test } from 'bun:test'
2+
import {
3+
getComponentName,
4+
propsToPropsWithTypography,
5+
resetTextStyleCache,
6+
space,
7+
} from '../utils'
8+
9+
// Minimal figma global for propsToPropsWithTypography tests
10+
if (!(globalThis as { figma?: unknown }).figma) {
11+
;(globalThis as { figma?: unknown }).figma = {
12+
getLocalTextStylesAsync: () => Promise.resolve([]),
13+
getStyleByIdAsync: () => Promise.resolve(null),
14+
} as unknown as typeof figma
15+
}
316

417
describe('space', () => {
518
it('should create space', () => {
@@ -9,6 +22,117 @@ describe('space', () => {
922
})
1023
})
1124

25+
describe('propsToPropsWithTypography', () => {
26+
afterEach(() => {
27+
resetTextStyleCache()
28+
})
29+
30+
it('should apply typography from resolved cache (sync fast path)', async () => {
31+
const origGetLocal = figma.getLocalTextStylesAsync
32+
const origGetStyle = figma.getStyleByIdAsync
33+
figma.getLocalTextStylesAsync = () =>
34+
Promise.resolve([{ id: 'ts-1' } as unknown as TextStyle]) as ReturnType<
35+
typeof figma.getLocalTextStylesAsync
36+
>
37+
figma.getStyleByIdAsync = (id: string) =>
38+
Promise.resolve(
39+
id === 'ts-1'
40+
? ({ id: 'ts-1', name: 'Typography/Body' } as unknown as BaseStyle)
41+
: null,
42+
) as ReturnType<typeof figma.getStyleByIdAsync>
43+
44+
// First call: populates async caches + resolved caches via .then()
45+
const r1 = await propsToPropsWithTypography(
46+
{ fontFamily: 'Arial', fontSize: 16, w: 100, h: 50 },
47+
'ts-1',
48+
)
49+
expect(r1.typography).toBe('body')
50+
expect(r1.fontFamily).toBeUndefined()
51+
expect(r1.w).toBeUndefined()
52+
53+
// Second call: hits sync resolved-value cache (lines 71-72)
54+
const r2 = await propsToPropsWithTypography(
55+
{ fontFamily: 'Inter', fontSize: 14, w: 200, h: 60 },
56+
'ts-1',
57+
)
58+
expect(r2.typography).toBe('body')
59+
expect(r2.fontFamily).toBeUndefined()
60+
expect(r2.w).toBeUndefined()
61+
62+
figma.getLocalTextStylesAsync = origGetLocal
63+
figma.getStyleByIdAsync = origGetStyle
64+
})
65+
66+
it('should return early from sync path when textStyleId not in resolved set', async () => {
67+
const origGetLocal = figma.getLocalTextStylesAsync
68+
const origGetStyle = figma.getStyleByIdAsync
69+
figma.getLocalTextStylesAsync = () =>
70+
Promise.resolve([{ id: 'ts-1' } as unknown as TextStyle]) as ReturnType<
71+
typeof figma.getLocalTextStylesAsync
72+
>
73+
figma.getStyleByIdAsync = () =>
74+
Promise.resolve(null) as ReturnType<typeof figma.getStyleByIdAsync>
75+
76+
// First call: populates resolved cache
77+
await propsToPropsWithTypography(
78+
{ fontFamily: 'Arial', w: 100, h: 50 },
79+
'ts-1',
80+
)
81+
82+
// Second call with unknown textStyleId — hits else branch (lines 75-76)
83+
const r = await propsToPropsWithTypography(
84+
{ fontFamily: 'Inter', w: 200, h: 60 },
85+
'ts-unknown',
86+
)
87+
expect(r.fontFamily).toBe('Inter')
88+
expect(r.typography).toBeUndefined()
89+
expect(r.w).toBeUndefined()
90+
91+
// Third call with empty textStyleId — also hits else branch
92+
const r2 = await propsToPropsWithTypography(
93+
{ fontFamily: 'Mono', w: 300, h: 70 },
94+
'',
95+
)
96+
expect(r2.fontFamily).toBe('Mono')
97+
expect(r2.typography).toBeUndefined()
98+
99+
figma.getLocalTextStylesAsync = origGetLocal
100+
figma.getStyleByIdAsync = origGetStyle
101+
})
102+
103+
it('should return props without typography when style resolves to null', async () => {
104+
const origGetLocal = figma.getLocalTextStylesAsync
105+
const origGetStyle = figma.getStyleByIdAsync
106+
figma.getLocalTextStylesAsync = () =>
107+
Promise.resolve([
108+
{ id: 'ts-null' } as unknown as TextStyle,
109+
]) as ReturnType<typeof figma.getLocalTextStylesAsync>
110+
figma.getStyleByIdAsync = () =>
111+
Promise.resolve(null) as ReturnType<typeof figma.getStyleByIdAsync>
112+
113+
// First call: populates caches, style is null
114+
const r1 = await propsToPropsWithTypography(
115+
{ fontFamily: 'Arial', fontSize: 16, w: 100, h: 50 },
116+
'ts-null',
117+
)
118+
expect(r1.typography).toBeUndefined()
119+
expect(r1.fontFamily).toBe('Arial')
120+
expect(r1.w).toBeUndefined()
121+
122+
// Second call: sync path, styleByIdResolved has null → style is falsy, skip applyTypography
123+
const r2 = await propsToPropsWithTypography(
124+
{ fontFamily: 'Inter', fontSize: 14, w: 200, h: 60 },
125+
'ts-null',
126+
)
127+
expect(r2.typography).toBeUndefined()
128+
expect(r2.fontFamily).toBe('Inter')
129+
expect(r2.w).toBeUndefined()
130+
131+
figma.getLocalTextStylesAsync = origGetLocal
132+
figma.getStyleByIdAsync = origGetStyle
133+
})
134+
})
135+
12136
describe('getComponentName', () => {
13137
test.each([
14138
{

src/code-impl.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
resetMainComponentCache,
55
} from './codegen/Codegen'
66
import { resetGetPropsCache } from './codegen/props'
7+
import { resetChildAnimationCache } from './codegen/props/reaction'
78
import { resetSelectorPropsCache } from './codegen/props/selector'
89
import { ResponsiveCodegen } from './codegen/responsive/ResponsiveCodegen'
910
import { nodeProxyTracker } from './codegen/utils/node-proxy'
@@ -139,6 +140,7 @@ export function registerCodegen(ctx: typeof figma) {
139140
perfReset()
140141
resetGetPropsCache()
141142
resetSelectorPropsCache()
143+
resetChildAnimationCache()
142144
resetVariableCache()
143145
resetTextStyleCache()
144146
resetMainComponentCache()

0 commit comments

Comments
 (0)