diagrams-opus-electron/tests/properties.test.ts
Ilya Ashikhmin e70ec822c9 test: cover domain, engine and controller scenarios; add headless mode
Add Vitest suites for relations, properties, catalogue, symbols, edge
styles, flow solver, settings, JointJS shapes/serialization and the
controller lifecycle (add/connect/edit/delete, undo-redo, copy-paste,
flow, save-load). Introduce headless DiagramController (Paper-less) so the
controller is testable outside a browser, and fix the flow direction sign.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 23:31:12 +02:00

62 lines
2.2 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import { coerce, validate, defaultsFor, schemaIndex, type PropertyDef, type PropertySchema } from '@diagram/properties'
const intDef: PropertyDef = { key: 'n', label: 'N', type: 'int', group: 'g', min: 0, max: 10 }
const floatDef: PropertyDef = { key: 'f', label: 'F', type: 'float', group: 'g', min: 0 }
const enumDef: PropertyDef = { key: 'e', label: 'E', type: 'enum', group: 'g', options: [{ value: 'a', label: 'A' }, { value: 'b', label: 'B' }] }
const listDef: PropertyDef = { key: 'l', label: 'L', type: 'listOfValues', group: 'g', itemType: 'int' }
describe('property coercion', () => {
it('rounds and clamps integers', () => {
expect(coerce(intDef, '3.7')).toBe(4)
expect(coerce(intDef, 99)).toBe(10)
expect(coerce(intDef, -5)).toBe(0)
expect(coerce(intDef, 'nope')).toBe(0)
})
it('parses floats without rounding', () => {
expect(coerce(floatDef, '2.5')).toBe(2.5)
})
it('coerces list of values to the item type', () => {
expect(coerce(listDef, ['1', '2', 'x'])).toEqual([1, 2])
})
it('stringifies enum/string/color', () => {
expect(coerce(enumDef, 'a')).toBe('a')
expect(coerce({ key: 'c', label: 'C', type: 'color', group: 'g' }, '#fff')).toBe('#fff')
})
})
describe('property validation', () => {
const schema: PropertySchema = [
{ id: 'g', label: 'G', defs: [{ ...intDef, required: true }, enumDef] }
]
it('flags required empties and out-of-range', () => {
const r = validate(schema, { n: '' as unknown as number, e: 'a' })
expect(r.ok).toBe(false)
expect(r.errors.n).toBeTruthy()
})
it('accepts valid values', () => {
expect(validate(schema, { n: 5, e: 'a' }).ok).toBe(true)
})
it('rejects unknown enum option', () => {
expect(validate(schema, { n: 5, e: 'zzz' }).ok).toBe(false)
})
})
describe('schema helpers', () => {
const schema: PropertySchema = [
{ id: 'g', label: 'G', defs: [{ ...intDef, default: 3 }, { ...enumDef, default: 'b' }] }
]
it('produces defaults', () => {
expect(defaultsFor(schema)).toEqual({ n: 3, e: 'b' })
})
it('indexes by key', () => {
expect(schemaIndex(schema).get('n')?.type).toBe('int')
})
})