import { describe, expect, it } from 'vitest'; import { isSiumAsyncSchemaError, isSiumValidationError, SiumAsyncSchemaError, SiumValidationError, type Issue } from '../index.ts'; import { SIUM_ERR, SIUM_ERR_ASYNC_SCHEMA, SIUM_ERR_VALIDATION } from '../errors.ts'; import { CodeError, isCodeError, matches } from '$libs/errs'; const ISSUE: Issue = { path: ['name'], message: 'required', code: 'invalid_type' } as Issue; describe('SiumValidationError', () => { it('extends CodeError with the validation code', () => { const err = new SiumValidationError([ISSUE]); expect(err).toBeInstanceOf(CodeError); expect(err.code).toBe(SIUM_ERR_VALIDATION); expect(err.name).toBe(SIUM_ERR_VALIDATION); }); it('carries issues alongside the code', () => { const err = new SiumValidationError([ISSUE]); expect(err.issues).toEqual([ISSUE]); }); it('is detected by isSiumValidationError and isCodeError', () => { const err = new SiumValidationError([ISSUE]); expect(isSiumValidationError(err)).toBe(true); expect(isCodeError(err)).toBe(true); }); it('is matched by the SIUM_ERR module seed', () => { const err = new SiumValidationError([ISSUE]); expect(matches(err, SIUM_ERR)).toBe(true); }); }); describe('SiumAsyncSchemaError', () => { it('extends CodeError with the async-schema code', () => { const err = new SiumAsyncSchemaError('object'); expect(err).toBeInstanceOf(CodeError); expect(err.code).toBe(SIUM_ERR_ASYNC_SCHEMA); expect(err.name).toBe(SIUM_ERR_ASYNC_SCHEMA); }); it('carries the schema kind', () => { const err = new SiumAsyncSchemaError('union'); expect(err.schemaKind).toBe('union'); }); it('is detected by isSiumAsyncSchemaError and isCodeError', () => { const err = new SiumAsyncSchemaError(); expect(isSiumAsyncSchemaError(err)).toBe(true); expect(isCodeError(err)).toBe(true); }); it('does not match the validation code', () => { const err = new SiumAsyncSchemaError(); expect(matches(err, SIUM_ERR_VALIDATION)).toBe(false); expect(matches(err, SIUM_ERR_ASYNC_SCHEMA)).toBe(true); }); it('is matched by the SIUM_ERR module seed', () => { const err = new SiumAsyncSchemaError(); expect(matches(err, SIUM_ERR)).toBe(true); }); }); describe('CodeError fluent decorators on sium errors', () => { it('preserves the subclass-specific fields after withMessage', () => { const err = new SiumValidationError([ISSUE]); const decorated = err.withMessage('User-facing failure'); expect(decorated.userMessage).toBe('User-facing failure'); // Decoration returns plain CodeError; subclass fields stay on the // original instance only. expect(matches(decorated, SIUM_ERR_VALIDATION)).toBe(true); }); });