chore(tests): remove targeted non-null assertions
- Replace low-count E2E non-null assertions with store guards and optional expectations - Use expectDefined for tool adapter and XPath node lookups - Validate affected engine and E2E tests
This commit is contained in:
parent
39675b2969
commit
6ec18f1dfb
|
|
@ -63,9 +63,11 @@ test('autosave triggers after scene changes with a file handle', async () => {
|
|||
await canvas.drawRect(400, 400, 60, 60)
|
||||
|
||||
// Check that the scene version changed
|
||||
const versionAfterDraw = await page.evaluate(
|
||||
() => window.__OPEN_PENCIL_STORE__!.state.sceneVersion
|
||||
)
|
||||
const versionAfterDraw = await page.evaluate(() => {
|
||||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
return store.state.sceneVersion
|
||||
})
|
||||
expect(versionAfterDraw).toBeGreaterThan(0)
|
||||
|
||||
// Wait for autosave debounce (3s) + buffer
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ function getPageChildCount() {
|
|||
}
|
||||
|
||||
function getSelectedCount() {
|
||||
return page.evaluate(() => window.__OPEN_PENCIL_STORE__!.state.selectedIds.size)
|
||||
return page.evaluate(() => {
|
||||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
return store.state.selectedIds.size
|
||||
})
|
||||
}
|
||||
|
||||
function getSelectedNodes() {
|
||||
|
|
@ -35,7 +39,8 @@ function getSelectedNodes() {
|
|||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
return [...store.state.selectedIds].map((id) => {
|
||||
const n = store.graph.getNode(id)!
|
||||
const n = store.graph.getNode(id)
|
||||
if (!n) throw new Error(`Selected node ${id} not found`)
|
||||
return {
|
||||
id: n.id,
|
||||
name: n.name,
|
||||
|
|
|
|||
|
|
@ -61,7 +61,9 @@ async function getSceneTree(): Promise<SceneTreeNode> {
|
|||
|
||||
async function getSelectedCount(): Promise<number> {
|
||||
return page.evaluate(() => {
|
||||
return window.__OPEN_PENCIL_STORE__!.state.selectedIds.size
|
||||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
return store.state.selectedIds.size
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@ function getPages() {
|
|||
}
|
||||
|
||||
function getCurrentPageId() {
|
||||
return page.evaluate(() => window.__OPEN_PENCIL_STORE__!.state.currentPageId)
|
||||
return page.evaluate(() => {
|
||||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
return store.state.currentPageId
|
||||
})
|
||||
}
|
||||
|
||||
function getPageChildCount() {
|
||||
|
|
@ -141,7 +145,9 @@ test('rename page via store', async () => {
|
|||
|
||||
await page.evaluate(
|
||||
([id, name]) => {
|
||||
window.__OPEN_PENCIL_STORE__!.renamePage(id, name)
|
||||
const store = window.__OPEN_PENCIL_STORE__
|
||||
if (!store) throw new Error('OpenPencil store not initialized')
|
||||
store.renamePage(id, name)
|
||||
},
|
||||
[currentId, 'Renamed Page'] as [string, string]
|
||||
)
|
||||
|
|
@ -149,7 +155,7 @@ test('rename page via store', async () => {
|
|||
|
||||
const updated = await getPages()
|
||||
const renamed = updated.find((p) => p.id === currentId)
|
||||
expect(renamed!.name).toBe('Renamed Page')
|
||||
expect(renamed?.name).toBe('Renamed Page')
|
||||
|
||||
canvas.assertNoErrors()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ test('independent corners toggle shows per-corner inputs', async () => {
|
|||
await canvas.waitForRender()
|
||||
|
||||
const flags = await getSelectedNodeFlags()
|
||||
expect(flags!.type).toBe('FRAME')
|
||||
expect(flags!.independentCorners).toBe(false)
|
||||
expect(flags?.type).toBe('FRAME')
|
||||
expect(flags?.independentCorners).toBe(false)
|
||||
|
||||
const toggle = page.locator('[data-test-id="independent-corners-toggle"]')
|
||||
await expect(toggle).toBeVisible()
|
||||
|
|
@ -54,7 +54,7 @@ test('independent corners toggle shows per-corner inputs', async () => {
|
|||
await toggle.click()
|
||||
await canvas.waitForRender()
|
||||
|
||||
expect((await getSelectedNodeFlags())!.independentCorners).toBe(true)
|
||||
expect((await getSelectedNodeFlags())?.independentCorners).toBe(true)
|
||||
const grid = page.locator('[data-test-id="independent-corners-grid"]')
|
||||
await expect(grid).toBeVisible()
|
||||
const cornerInputs = grid.locator('[data-test-id="scrub-input"]')
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import * as v from 'valibot'
|
|||
|
||||
import { ALL_TOOLS, FigmaAPI, SceneGraph, toolsToAI } from '@open-pencil/core'
|
||||
|
||||
import { expectDefined } from '#tests/helpers/assert'
|
||||
|
||||
type AdapterTool = { execute(args: Record<string, unknown>): Promise<unknown>; description: string }
|
||||
|
||||
function adapterTool(tools: Record<string, unknown>, name: string): AdapterTool {
|
||||
|
|
@ -62,7 +64,7 @@ describe('AI adapter', () => {
|
|||
expect(result.type).toBe('RECTANGLE')
|
||||
expect(result.name).toBe('Test Rect')
|
||||
|
||||
const node = figma.getNodeById(result.id)!
|
||||
const node = expectDefined(figma.getNodeById(result.id), 'created node')
|
||||
expect(node.x).toBe(10)
|
||||
expect(node.y).toBe(20)
|
||||
expect(node.width).toBe(100)
|
||||
|
|
@ -76,7 +78,7 @@ describe('AI adapter', () => {
|
|||
const setFill = adapterTool(tools, 'set_fill')
|
||||
await setFill.execute({ id: rect.id, color: '#00ff00' })
|
||||
|
||||
const fills = figma.getNodeById(rect.id)!.fills
|
||||
const fills = expectDefined(figma.getNodeById(rect.id), 'filled rectangle').fills
|
||||
expect(fills.length).toBe(1)
|
||||
expect(fills[0].color.g).toBeCloseTo(1)
|
||||
})
|
||||
|
|
@ -167,7 +169,7 @@ describe('AI adapter', () => {
|
|||
padding: 16
|
||||
})
|
||||
|
||||
const node = figma.getNodeById(frame.id)!
|
||||
const node = expectDefined(figma.getNodeById(frame.id), 'layout frame')
|
||||
expect(node.layoutMode).toBe('HORIZONTAL')
|
||||
expect(node.itemSpacing).toBe(8)
|
||||
expect(node.paddingLeft).toBe(16)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { expectDefined } from '#tests/helpers/assert'
|
||||
import { getTool, setupToolTest, type ToolResult } from '#tests/helpers/tools'
|
||||
|
||||
describe('delete_node', () => {
|
||||
|
|
@ -37,7 +38,7 @@ describe('rename_node', () => {
|
|||
const tool = getTool('rename_node')
|
||||
tool.execute(figma, { id: rect.id, name: 'My Rectangle' })
|
||||
|
||||
expect(figma.getNodeById(rect.id)!.name).toBe('My Rectangle')
|
||||
expect(expectDefined(figma.getNodeById(rect.id), 'renamed rectangle').name).toBe('My Rectangle')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -52,7 +53,11 @@ describe('reparent_node', () => {
|
|||
const tool = getTool('reparent_node')
|
||||
tool.execute(figma, { id: rect.id, parent_id: frame.id })
|
||||
|
||||
expect(figma.getNodeById(frame.id)!.children.some((c) => c.id === rect.id)).toBe(true)
|
||||
expect(
|
||||
expectDefined(figma.getNodeById(frame.id), 'target frame').children.some(
|
||||
(c) => c.id === rect.id
|
||||
)
|
||||
).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -68,7 +73,10 @@ describe('group_nodes', () => {
|
|||
const result = tool.execute(figma, { ids: [r1.id, r2.id] }) as ToolResult
|
||||
|
||||
expect(result.type).toBe('GROUP')
|
||||
const group = figma.getNodeById(result.id)!
|
||||
const group = expectDefined(
|
||||
figma.getNodeById(expectDefined(result.id, 'group id')),
|
||||
'created group'
|
||||
)
|
||||
expect(group.children.length).toBe(2)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import { describe, expect, test } from 'bun:test'
|
|||
|
||||
import { FigmaAPI, SceneGraph, matchByXPath, nodeToXPath, queryByXPath } from '@open-pencil/core'
|
||||
|
||||
import { expectDefined } from '#tests/helpers/assert'
|
||||
|
||||
function setup() {
|
||||
const graph = new SceneGraph()
|
||||
const figma = new FigmaAPI(graph)
|
||||
|
|
@ -164,7 +166,7 @@ describe('nodeToXPath', () => {
|
|||
btn.name = 'Button'
|
||||
frame.appendChild(btn)
|
||||
|
||||
const xpath = nodeToXPath(graph, btn.id)!
|
||||
const xpath = expectDefined(nodeToXPath(graph, btn.id), 'button XPath')
|
||||
const results = await queryByXPath(graph, xpath)
|
||||
expect(results.length).toBe(1)
|
||||
expect(results[0].id).toBe(btn.id)
|
||||
|
|
@ -187,7 +189,7 @@ describe('matchByXPath', () => {
|
|||
rect.resize(100, 100)
|
||||
rect.name = 'TestRect'
|
||||
|
||||
const sceneNode = graph.getNode(rect.id)!
|
||||
const sceneNode = expectDefined(graph.getNode(rect.id), 'matching rectangle')
|
||||
const result = await matchByXPath(graph, '@name = "TestRect"', sceneNode)
|
||||
expect(result).toBe(true)
|
||||
})
|
||||
|
|
@ -198,7 +200,7 @@ describe('matchByXPath', () => {
|
|||
rect.resize(100, 100)
|
||||
rect.name = 'Other'
|
||||
|
||||
const sceneNode = graph.getNode(rect.id)!
|
||||
const sceneNode = expectDefined(graph.getNode(rect.id), 'non-matching rectangle')
|
||||
const result = await matchByXPath(graph, '@name = "TestRect"', sceneNode)
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue