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>
62 lines
2.2 KiB
TypeScript
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')
|
|
})
|
|
})
|