import { it, describe, expect } from 'vitest'; const itEffect = (name: string, fn: () => Effect.Effect) => it(name, () => Effect.runPromise(fn())); import { Effect, Schema } from 'effect'; import { EntityESchema } from '../index.js'; import { ESchemaError } from '../index.js'; describe('ESchema', () => { describe('Decoding', () => { describe('Decode', () => { itEffect('decodes v1 data without migration', () => Effect.gen(function* () { const schema = EntityESchema.make('Test', 'id', { name: Schema.String, count: Schema.Number, }).build(); const decoded = yield* schema.decode({ _v: 'v1', id: 't1', name: 'foo', count: 10, }); expect(decoded).toEqual({ id: 't1', name: 'foo', count: 10 }); }), ); itEffect('decodes and migrates v1 to v2', () => Effect.gen(function* () { const schema = EntityESchema.make('Test', 'id', { a: Schema.Number, }) .evolve('v2', { b: Schema.String }, (v) => ({ ...v, b: 'added' })) .build(); const decoded = yield* schema.decode({ _v: 'v1', id: 't1', a: 42 }); expect(decoded).toEqual({ id: 't1', a: 42, b: 'added' }); }), ); itEffect('decodes latest version without running migrations', () => Effect.gen(function* () { const schema = EntityESchema.make('Test', 'id', { a: Schema.String, }) .evolve('v2', { b: Schema.String }, (v) => ({ ...v, b: 'should not appear', })) .build(); const decoded = yield* schema.decode({ _v: 'v2', id: 't1', a: 'hello', b: 'world', }); expect(decoded).toEqual({ id: 't1', a: 'hello', b: 'world' }); }), ); itEffect('fails with ESchemaError on unknown version', () => Effect.gen(function* () { const schema = EntityESchema.make('Test', 'id', { a: Schema.String, }).build(); const error = yield* Effect.flip( schema.decode({ _v: 'v99', id: 't1', a: 'hello' }), ); expect(error).toBeInstanceOf(ESchemaError); expect(error.message).toBe('Unknown schema version: v99'); }), ); itEffect('treats missing _v as the earliest version (v1)', () => Effect.gen(function* () { const schema = EntityESchema.make('Test', 'id', { a: Schema.String, }).build(); const decoded = yield* schema.decode({ id: 't1', a: 'hello' }); expect(decoded).toEqual({ id: 't1', a: 'hello' }); }), ); }); }); });