-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathResponsiveCodegen.test.ts
More file actions
145 lines (125 loc) · 4.79 KB
/
ResponsiveCodegen.test.ts
File metadata and controls
145 lines (125 loc) · 4.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test'
import { BREAKPOINT_ORDER, type BreakpointKey } from '../index'
const getPropsMock = mock(async (node: SceneNode) => ({ id: node.name }))
const renderNodeMock = mock(
(
component: string,
props: Record<string, unknown>,
depth: number,
children: string[],
) =>
`render:${component}:depth=${depth}:${JSON.stringify(props)}|${children.join(';')}`,
)
const getDevupComponentByNodeMock = mock(() => 'Box')
describe('ResponsiveCodegen', () => {
let ResponsiveCodegen: typeof import('../ResponsiveCodegen').ResponsiveCodegen
beforeEach(async () => {
mock.module('../../props', () => ({ getProps: getPropsMock }))
mock.module('../../render', () => ({ renderNode: renderNodeMock }))
mock.module('../../utils/get-devup-component', () => ({
getDevupComponentByNode: getDevupComponentByNodeMock,
}))
;({ ResponsiveCodegen } = await import('../ResponsiveCodegen'))
getPropsMock.mockClear()
renderNodeMock.mockClear()
getDevupComponentByNodeMock.mockClear()
})
afterEach(() => {
mock.restore()
})
const makeNode = (
name: string,
width?: number,
children: SceneNode[] = [],
type: SceneNode['type'] = 'FRAME',
) => {
const node: Record<string, unknown> = { name, children, type }
if (typeof width === 'number') {
node.width = width
}
return node as unknown as SceneNode
}
it('returns message when no responsive variants exist', async () => {
const section = {
type: 'SECTION',
children: [makeNode('no-width', undefined, [])],
} as unknown as SectionNode
const generator = new ResponsiveCodegen(section)
const result = await generator.generateResponsiveCode()
expect(result).toBe('// No responsive variants found in section')
})
it('falls back to single breakpoint generation', async () => {
const child = makeNode('mobile', 320, [makeNode('leaf', undefined, [])])
const section = {
type: 'SECTION',
children: [child],
} as unknown as SectionNode
const generator = new ResponsiveCodegen(section)
const nodeCode = await (
generator as unknown as {
generateNodeCode: (node: SceneNode, depth: number) => Promise<string>
}
).generateNodeCode(child, 0)
expect(renderNodeMock).toHaveBeenCalled()
const result = await generator.generateResponsiveCode()
expect(result.startsWith('render:Box')).toBeTrue()
expect(nodeCode.startsWith('render:Box')).toBeTrue()
})
it('merges breakpoints and adds display for missing child variants', async () => {
const onlyMobile = makeNode('OnlyMobile')
const sharedMobile = makeNode('Shared')
const sharedTablet = makeNode('Shared')
const mobileRoot = makeNode('RootMobile', 320, [onlyMobile, sharedMobile])
const tabletRoot = makeNode('RootTablet', 1000, [sharedTablet])
const section = {
type: 'SECTION',
children: [mobileRoot, tabletRoot],
} as unknown as SectionNode
const generator = new ResponsiveCodegen(section)
const result = await generator.generateResponsiveCode()
expect(getPropsMock).toHaveBeenCalled()
expect(renderNodeMock.mock.calls.length).toBeGreaterThan(0)
expect(result.startsWith('render:Box')).toBeTrue()
})
it('returns empty display when all breakpoints present', async () => {
const section = {
type: 'SECTION',
children: [makeNode('RootMobile', 320)],
} as unknown as SectionNode
const generator = new ResponsiveCodegen(section)
const displayProps = (
generator as unknown as {
getDisplayProps: (
present: Set<BreakpointKey>,
all: Set<BreakpointKey>,
) => Record<string, unknown>
}
).getDisplayProps(
new Set<BreakpointKey>(BREAKPOINT_ORDER),
new Set<BreakpointKey>(BREAKPOINT_ORDER),
)
expect(displayProps).toEqual({})
})
it('recursively generates node code', async () => {
const child = makeNode('child')
const parent = makeNode('parent', undefined, [child])
const section = {
type: 'SECTION',
children: [parent],
} as unknown as SectionNode
const generator = new ResponsiveCodegen(section)
const nodeCode = await (
generator as unknown as {
generateNodeCode: (node: SceneNode, depth: number) => Promise<string>
}
).generateNodeCode(parent, 0)
expect(nodeCode.startsWith('render:Box')).toBeTrue()
expect(renderNodeMock).toHaveBeenCalled()
})
it('static helpers detect section and parent section', () => {
const section = { type: 'SECTION' } as unknown as SectionNode
const frame = { type: 'FRAME', parent: section } as unknown as SceneNode
expect(ResponsiveCodegen.canGenerateResponsive(section)).toBeTrue()
expect(ResponsiveCodegen.hasParentSection(frame)).toEqual(section)
})
})