Files
trans-form-middleware/test/parseFilters.test.js
T
windychen ccd16bf956
Node.js Build / build (push) Has been skipped
chore: 初始化 trans-form 项目脚手架
- 基于 grill-me Q1-Q61 决策
- Vitest 测试与 CI workflow
- middleware: parseFilters 核心实现
- component: Vue3 TransForm 基础组件 + Storybook

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-07 00:47:58 +00:00

130 lines
3.3 KiB
JavaScript

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