openpencil/tests/engine/io/fig/import/group-reclassify.test.ts

72 lines
2.2 KiB
TypeScript
Raw Normal View History

fix(kiwi): import Figma groups as groups * fix(kiwi): import Figma groups as GROUP nodes instead of FRAME - Map FRAME nodes with `resizeToFit === true` to `GROUP` type on import - Write `resizeToFit = true` when exporting `GROUP` nodes back to Kiwi format - Document findings and diagnosis in packages/docs/development/group-to-frame-import-issue.md - Extract resolveNodeType helper to satisfy cyclomatic complexity limits * test(kiwi): harden Figma group import + add coverage Follow-up hardening on the group import/export fix: - convert.ts: reorder so the COMPONENT_SET check runs before the FRAME→GROUP reclassification, and guard the group check on the absence of auto-layout (`stackMode` unset/NONE). Figma auto-layout "hug" frames use stackPrimarySizing/stackCounterSizing, not `resizeToFit`, so this prevents a component-set or auto-layout frame that happens to carry `resizeToFit` from being misclassified as a group. - Add tests/engine/io/fig/import/group-reclassify.test.ts: unit coverage for the reclassification (FRAME+resizeToFit → GROUP, plain frame stays FRAME, auto-layout hug frame stays FRAME), plus a real-file assertion that gold-preview.fig imports its groups as GROUP. - Add tests/engine/io/fig/roundtrip/group.test.ts: a created GROUP survives export → re-import as a GROUP (validates the export-side resizeToFit write). - Update exhaustive.test.ts gold-preview golden: 519 nodes that were misimported as FRAME are now correctly GROUP (FRAME 4525→4006, GROUP 519), and export size shifts 594758→594770 because exported groups now carry resizeToFit. Note: the pre-existing material3 variables roundtrip failure ("Invalid value EXCLUDE for enum BooleanOperation") is unrelated to groups and also fails on master — out of scope here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(kiwi): remove temporary group-to-frame analysis doc It was a scratch diagnostic artifact (and contained a hardcoded local path); the rationale now lives in the fix's commit messages, code comments, and tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-06-06 10:49:19 +00:00
import { describe, expect, test } from 'bun:test'
import type { NodeChange } from '#core/kiwi/fig/codec'
import { nodeChangeToProps } from '#core/kiwi/fig/node-change/convert'
import { parseFixture } from '#tests/helpers/fig-fixtures'
import { collectAllNodes } from '#tests/helpers/fig-traversal'
import { HEAVY_TEST_TIMEOUT_MS } from '#tests/helpers/test-utils'
fix(kiwi): import Figma groups as groups * fix(kiwi): import Figma groups as GROUP nodes instead of FRAME - Map FRAME nodes with `resizeToFit === true` to `GROUP` type on import - Write `resizeToFit = true` when exporting `GROUP` nodes back to Kiwi format - Document findings and diagnosis in packages/docs/development/group-to-frame-import-issue.md - Extract resolveNodeType helper to satisfy cyclomatic complexity limits * test(kiwi): harden Figma group import + add coverage Follow-up hardening on the group import/export fix: - convert.ts: reorder so the COMPONENT_SET check runs before the FRAME→GROUP reclassification, and guard the group check on the absence of auto-layout (`stackMode` unset/NONE). Figma auto-layout "hug" frames use stackPrimarySizing/stackCounterSizing, not `resizeToFit`, so this prevents a component-set or auto-layout frame that happens to carry `resizeToFit` from being misclassified as a group. - Add tests/engine/io/fig/import/group-reclassify.test.ts: unit coverage for the reclassification (FRAME+resizeToFit → GROUP, plain frame stays FRAME, auto-layout hug frame stays FRAME), plus a real-file assertion that gold-preview.fig imports its groups as GROUP. - Add tests/engine/io/fig/roundtrip/group.test.ts: a created GROUP survives export → re-import as a GROUP (validates the export-side resizeToFit write). - Update exhaustive.test.ts gold-preview golden: 519 nodes that were misimported as FRAME are now correctly GROUP (FRAME 4525→4006, GROUP 519), and export size shifts 594758→594770 because exported groups now carry resizeToFit. Note: the pre-existing material3 variables roundtrip failure ("Invalid value EXCLUDE for enum BooleanOperation") is unrelated to groups and also fails on master — out of scope here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(kiwi): remove temporary group-to-frame analysis doc It was a scratch diagnostic artifact (and contained a hardcoded local path); the rationale now lives in the fix's commit messages, code comments, and tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-06-06 10:49:19 +00:00
describe('Figma group reclassification on import', () => {
test('FRAME with resizeToFit imports as GROUP', () => {
const props = nodeChangeToProps(
{ type: 'FRAME', name: 'Group 1', resizeToFit: true } as NodeChange,
[]
)
expect(props.nodeType).toBe('GROUP')
// groups never clip their children
expect(props.clipsContent).toBe(false)
})
test('plain FRAME stays FRAME', () => {
const props = nodeChangeToProps(
{ type: 'FRAME', name: 'Frame', resizeToFit: false } as NodeChange,
[]
)
expect(props.nodeType).toBe('FRAME')
})
test('FRAME with no resizeToFit flag stays FRAME', () => {
const props = nodeChangeToProps({ type: 'FRAME', name: 'Frame' } as NodeChange, [])
expect(props.nodeType).toBe('FRAME')
})
test('auto-layout hug frame stays FRAME (not GROUP)', () => {
const props = nodeChangeToProps(
{
type: 'FRAME',
name: 'AutoLayout',
stackMode: 'VERTICAL',
stackPrimarySizing: 'RESIZE_TO_FIT'
} as NodeChange,
[]
)
expect(props.nodeType).toBe('FRAME')
})
test('auto-layout frame that also carries resizeToFit stays FRAME', () => {
const props = nodeChangeToProps(
{
type: 'FRAME',
name: 'AutoLayout2',
stackMode: 'HORIZONTAL',
resizeToFit: true
} as NodeChange,
[]
)
expect(props.nodeType).toBe('FRAME')
})
test(
'gold-preview.fig fixture imports its groups as GROUP nodes',
{ timeout: HEAVY_TEST_TIMEOUT_MS },
async () => {
const graph = await parseFixture('gold-preview.fig')
const groups = collectAllNodes(graph).filter((n) => n.type === 'GROUP')
// gold-preview.fig contains real Figma groups (FRAME + resizeToFit) that must
// import as GROUP, not FRAME.
expect(groups.length).toBeGreaterThan(0)
}
)
fix(kiwi): import Figma groups as groups * fix(kiwi): import Figma groups as GROUP nodes instead of FRAME - Map FRAME nodes with `resizeToFit === true` to `GROUP` type on import - Write `resizeToFit = true` when exporting `GROUP` nodes back to Kiwi format - Document findings and diagnosis in packages/docs/development/group-to-frame-import-issue.md - Extract resolveNodeType helper to satisfy cyclomatic complexity limits * test(kiwi): harden Figma group import + add coverage Follow-up hardening on the group import/export fix: - convert.ts: reorder so the COMPONENT_SET check runs before the FRAME→GROUP reclassification, and guard the group check on the absence of auto-layout (`stackMode` unset/NONE). Figma auto-layout "hug" frames use stackPrimarySizing/stackCounterSizing, not `resizeToFit`, so this prevents a component-set or auto-layout frame that happens to carry `resizeToFit` from being misclassified as a group. - Add tests/engine/io/fig/import/group-reclassify.test.ts: unit coverage for the reclassification (FRAME+resizeToFit → GROUP, plain frame stays FRAME, auto-layout hug frame stays FRAME), plus a real-file assertion that gold-preview.fig imports its groups as GROUP. - Add tests/engine/io/fig/roundtrip/group.test.ts: a created GROUP survives export → re-import as a GROUP (validates the export-side resizeToFit write). - Update exhaustive.test.ts gold-preview golden: 519 nodes that were misimported as FRAME are now correctly GROUP (FRAME 4525→4006, GROUP 519), and export size shifts 594758→594770 because exported groups now carry resizeToFit. Note: the pre-existing material3 variables roundtrip failure ("Invalid value EXCLUDE for enum BooleanOperation") is unrelated to groups and also fails on master — out of scope here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(kiwi): remove temporary group-to-frame analysis doc It was a scratch diagnostic artifact (and contained a hardcoded local path); the rationale now lives in the fix's commit messages, code comments, and tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Danila Poyarkov <dev@dannote.net>
2026-06-06 10:49:19 +00:00
})