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') }) })