UNPKG

agnostic-query

Version:

Type-safe fluent builder for portable query schemas. Runtime-agnostic, database-agnostic — the same QuerySchema drives Drizzle, Kysely, db0, or raw SQL.

108 lines (92 loc) 3.17 kB
import { describe, expect, it } from 'bun:test'; import { createWhereSchema } from './zod.ts'; type UserShape = { id: string; name: string; age: number; tags: string[]; }; describe('createWhereSchema', () => { const fullSchema = createWhereSchema<UserShape>(); it('should parse valid UnaryComparisonWhere', () => { const result = fullSchema.safeParse({ field: ['name'], op: '=', value: 'Alice' }); expect(result.success).toBe(true); if (result.success) expect((result.data as any)?.value).toBe('Alice'); }); it('should parse valid MultiLogicalWhere (and)', () => { const data = { op: 'and' as const, conditions: [ { field: ['name'], op: '=', value: 'Alice' }, { field: ['age'], op: '>', value: 18 }, ], }; const result = fullSchema.safeParse(data); expect(result.success).toBe(true); }); it('should parse valid MultiLogicalWhere (or)', () => { const data = { op: 'or' as const, conditions: [{ field: ['id'], op: 'in', values: ['1', '2'] }], }; const result = fullSchema.safeParse(data); expect(result.success).toBe(true); }); it('should parse valid UnaryLogicalWhere (not)', () => { const data = { op: 'not' as const, condition: { field: ['age'], op: '<', value: 18 }, }; const result = fullSchema.safeParse(data); expect(result.success).toBe(true); }); it('should parse nested conditions', () => { const data = { op: 'and' as const, conditions: [ { op: 'or' as const, conditions: [ { field: ['name'], op: 'like', value: '%test%' }, { op: 'not', condition: { field: ['age'], op: '=', value: 0 } }, ], }, { field: ['id'], op: 'in', values: ['a', 'b'] }, ], }; const result = fullSchema.safeParse(data); expect(result.success).toBe(true); }); it('should accept string field (auto-convert to tuple)', () => { const result = fullSchema.safeParse({ field: 'name', op: '=', value: 'test' }); expect(result.success).toBe(true); }); it('should parse is null', () => { const result = fullSchema.safeParse({ field: ['name'], op: 'is null' }); expect(result.success).toBe(true); }); it('should parse @> (contains)', () => { const result = fullSchema.safeParse({ field: ['tags'], op: '@>', value: ['admin'] }); expect(result.success).toBe(true); }); it('should parse <@ (contained by)', () => { const result = fullSchema.safeParse({ field: ['tags'], op: '<@', value: ['admin', 'user'] }); expect(result.success).toBe(true); }); it('should parse && (overlaps)', () => { const result = fullSchema.safeParse({ field: ['tags'], op: '&&', value: ['admin'] }); expect(result.success).toBe(true); }); it('should reject invalid operator', () => { const result = fullSchema.safeParse({ field: ['name'], op: 'ne', value: 'x' }); expect(result.success).toBe(false); }); it('should reject non-array conditions for MultiWhere', () => { const result = fullSchema.safeParse({ op: 'and', conditions: {} }); expect(result.success).toBe(false); }); it('should reject missing condition for UnaryWhere', () => { const result = fullSchema.safeParse({ op: 'not' }); expect(result.success).toBe(false); }); });