openpencil/tools/dev/unit-tests/tests/shards.test.ts
Danila Poyarkov 8404cee664
refactor(design-jsx): extract design JSX into its own package (#793)
* refactor(design-jsx): extract design JSX into its own package

Design JSX elements, helpers, schema, reference, and JSX export only need
the scene graph, yet lived in Core, so every consumer of the authoring API
pulled in the renderer, layout, and file formats.

@open-pencil/design-jsx now owns them and depends only on scene-graph. The
renderer takes icon lookup, SVG conversion, vector creation, and layout as
DesignJSXServices; Core binds its own and exports the bound renderJSX and
renderTree from @open-pencil/core/design-jsx.

* feat(design-jsx): export the JSX runtime for TSX authoring

The package already had a JSX runtime, but nothing exported it, so design
trees could only be written as function calls or JSX strings. Export
`./jsx-runtime` and `./jsx-dev-runtime` so `jsxImportSource` works, and make
`Fragment` produce the same empty-type node as `<>` in `renderJSX` strings.

* fix(design-jsx): render fragments nested in other elements

A fragment builds a node with an empty type, which only renderJSX expanded, and only at the root. Nested fragments and fragments passed to renderTree failed with 'Unknown element: <>'. Inline fragment children when trees are built, and share root expansion between renderTree and renderJSX.
2026-09-30 20:55:27 +04:00

92 lines
3.3 KiB
TypeScript

import { expect, test } from 'bun:test'
import { resolveWorkspaceRoot } from '@open-pencil/package-artifacts-tools'
import {
isHeavyUnitTest,
listHeavyUnitTests,
listUnitTests,
pathsForUnitTestGroup,
unitTestGroupNames
} from '../src/shards'
const REPO_ROOT = await resolveWorkspaceRoot(import.meta.dir)
async function discover(pattern: string): Promise<string[]> {
return Array.fromAsync(new Bun.Glob(pattern).scan({ cwd: REPO_ROOT }))
}
test('every app, engine and package-local test belongs to exactly one shard', async () => {
const discovered = [
...(await discover('tests/app/**/*.test.ts')),
...(await discover('tests/integration/**/*.test.ts')),
...(await discover('tests/engine/**/*.test.ts')),
...(await discover('packages/*/tests/**/*.test.ts'))
].filter((file) => !file.startsWith('packages/harness/'))
const paths = pathsForUnitTestGroup('all')
const invalidAssignments = discovered.flatMap((file) => {
const owners = paths.filter((path) => file.startsWith(`${path}/`))
return owners.length === 1 ? [] : [{ file, owners }]
})
expect(discovered.length).toBeGreaterThan(0)
expect(invalidAssignments).toEqual([])
expect((await listUnitTests('all', { includeHeavy: true })).sort()).toEqual(discovered.sort())
})
test('canonical destinations are registered before they hold files', async () => {
const paths = pathsForUnitTestGroup('all')
expect(paths).toContain('tests/app')
expect(paths).toContain('tests/integration')
for (const owner of [
'core',
'scene-graph',
'vue',
'fig',
'kiwi',
'dom-css',
'design-jsx',
'pen',
'cli',
'mcp'
]) {
expect(paths).toContain(`packages/${owner}/tests`)
}
await expect(listUnitTests('all')).resolves.toBeArray()
})
test('quick and explicit heavy tests partition the full engine suite', async () => {
const quick = await listUnitTests('all')
const heavy = await listHeavyUnitTests()
const all = await listUnitTests('all', { includeHeavy: true })
expect(quick.filter((file) => heavy.includes(file))).toEqual([])
expect([...quick, ...heavy].sort()).toEqual(all)
})
test('unit test groups cover all declared shards', () => {
expect(unitTestGroupNames()).toContain('all')
expect(pathsForUnitTestGroup('dom')).toContain('tests/engine/dom-css')
expect(pathsForUnitTestGroup('fig')).toContain('packages/fig/tests')
expect(pathsForUnitTestGroup('all')).toContain('tests/engine/io')
})
test('heavy unit test matcher excludes fixture-heavy tests', () => {
expect(isHeavyUnitTest('tests/engine/io/fig/heavy/fixtures.test.ts')).toBe(true)
expect(isHeavyUnitTest('tests/engine/io/fig/roundtrip/glyph-blob.test.ts')).toBe(true)
expect(isHeavyUnitTest('tests/engine/dom-css/runtime.test.ts')).toBe(false)
})
test('quick unit test listing excludes heavy tests', async () => {
const quickFiles = await listUnitTests('all')
expect(quickFiles).toContain('tests/engine/dom-css/runtime.test.ts')
expect(quickFiles).not.toContain('tests/engine/io/fig/heavy/fixtures.test.ts')
expect(quickFiles).not.toContain('tests/engine/io/fig/roundtrip/glyph-blob.test.ts')
})
test('heavy unit test listing contains only heavy tests', async () => {
const heavyFiles = await listHeavyUnitTests()
expect(heavyFiles).toContain('tests/engine/io/fig/heavy/fixtures.test.ts')
expect(heavyFiles.every(isHeavyUnitTest)).toBe(true)
})