import { describe, expect, it } from 'vitest'; import { DEFAULT_OPERATOR_MAP, mapOperators, parseFilters, splitMultiValue, toTree, } from '../src/index.js'; describe('mapOperators', () => { it('maps known query codes', () => { expect(mapOperators('EQ')).toBe('='); expect(mapOperators('NOT_IN')).toBe('NOT IN'); }); it('allows custom overrides', () => { expect(mapOperators('EQ', { EQ: 'equals' })).toBe('equals'); }); }); describe('splitMultiValue', () => { it('splits IN values', () => { expect(splitMultiValue('IN', 'a,b,c')).toEqual(['a', 'b', 'c']); }); it('splits BETWEEN values', () => { expect(splitMultiValue('BETWEEN', '2024-01-01,2024-12-31')).toEqual([ '2024-01-01', '2024-12-31', ]); }); }); describe('parseFilters', () => { const allowedFields = ['name', 'status', 'tags', 'created']; it('requires allowedFields', () => { expect(() => parseFilters([], {})).toThrow(/allowedFields/); }); it('parses basic conditions with logic pass-through', () => { const input = [ { field: 'name', value: 'xx', query: 'EQ' }, { field: 'tags', value: 'a,b', query: 'IN', logic: 'OR' }, ]; const out = parseFilters(input, { allowedFields }); expect(out).toEqual([ { field: 'name', query: 'EQ', op: '=', value: 'xx', }, { field: 'tags', query: 'IN', op: 'IN', value: 'a,b', values: ['a', 'b'], logic: 'OR', }, ]); }); it('preserves empty markers by default', () => { const out = parseFilters( [{ field: 'name', value: null, query: 'EQ', empty: true }], { allowedFields }, ); expect(out[0].empty).toBe(true); }); it('skips disabled and hidden by default', () => { const out = parseFilters( [ { field: 'name', value: 'a', query: 'EQ', disabled: true }, { field: 'status', value: 'b', query: 'EQ', hidden: true }, { field: 'tags', value: 'c', query: 'EQ' }, ], { allowedFields }, ); expect(out).toHaveLength(1); expect(out[0].field).toBe('tags'); }); it('can skip empty items when skipEmpty is true', () => { const out = parseFilters( [{ field: 'name', value: null, query: 'EQ', empty: true }], { allowedFields, skipEmpty: true }, ); expect(out).toEqual([]); }); it('throws on unknown field by default', () => { expect(() => parseFilters([{ field: 'unknown', value: 'x', query: 'EQ' }], { allowedFields, }), ).toThrow(/unknown field/); }); it('supports flat mode', () => { const out = parseFilters( [{ field: 'name', value: 'x', query: 'EQ', logic: 'AND' }], { allowedFields, mode: 'flat' }, ); expect(out[0].logic).toBeUndefined(); }); }); describe('toTree', () => { it('nests flat filters', () => { const flat = [ { field: 'a', query: 'EQ', op: '=', value: '1' }, { field: 'b', query: 'EQ', op: '=', value: '2', logic: 'OR' }, ]; const tree = toTree(flat); expect(tree[0]).toMatchObject({ logic: 'OR', children: expect.any(Array), }); }); }); describe('DEFAULT_OPERATOR_MAP', () => { it('includes IS_NULL operators', () => { expect(DEFAULT_OPERATOR_MAP.IS_NULL).toBe('IS NULL'); }); });