This commit is contained in:
@@ -102,7 +102,7 @@ const filters = parseFilters(
|
||||
|
||||
| # | 决策 |
|
||||
|---|------|
|
||||
| 40 | 支持 **`setFilters()` / `loadFilters()`** 回填 |
|
||||
| 40 | 回填能力在 **component 侧**(`setFilters()` / `loadFilters()` / `reset()` ref API,见 component DESIGN 输出协议);middleware 只做单向解析 |
|
||||
| 41 | 多函数导出:`parseFilters` / `toTree` / `mapOperators` / `splitMultiValue` 等 |
|
||||
|
||||
### 导出函数
|
||||
|
||||
@@ -106,6 +106,80 @@ describe('parseFilters', () => {
|
||||
);
|
||||
expect(out[0].logic).toBeUndefined();
|
||||
});
|
||||
|
||||
it('supports tree mode', () => {
|
||||
const out = parseFilters(
|
||||
[
|
||||
{ field: 'name', value: 'a', query: 'EQ' },
|
||||
{ field: 'status', value: 'b', query: 'EQ', logic: 'OR' },
|
||||
],
|
||||
{ allowedFields, mode: 'tree' },
|
||||
);
|
||||
expect(out).toHaveLength(1);
|
||||
expect(out[0].logic).toBe('OR');
|
||||
expect(out[0].children).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('skips unknown fields when unknownField is skip', () => {
|
||||
const out = parseFilters(
|
||||
[
|
||||
{ field: 'unknown', value: 'x', query: 'EQ' },
|
||||
{ field: 'name', value: 'a', query: 'EQ' },
|
||||
],
|
||||
{ allowedFields, unknownField: 'skip' },
|
||||
);
|
||||
expect(out).toHaveLength(1);
|
||||
expect(out[0].field).toBe('name');
|
||||
});
|
||||
|
||||
it('throws aggregated errors in strict mode', () => {
|
||||
expect(() =>
|
||||
parseFilters(
|
||||
[
|
||||
{ value: 'x', query: 'EQ' }, // missing field
|
||||
'not-an-object',
|
||||
],
|
||||
{ allowedFields, strict: true },
|
||||
),
|
||||
).toThrow(/validation error/);
|
||||
});
|
||||
|
||||
it('merges custom operatorMap', () => {
|
||||
const out = parseFilters(
|
||||
[{ field: 'name', value: 'x', query: 'EQ' }],
|
||||
{ allowedFields, operatorMap: { EQ: 'equals' } },
|
||||
);
|
||||
expect(out[0].op).toBe('equals');
|
||||
});
|
||||
|
||||
it('respects custom skipFlags', () => {
|
||||
const out = parseFilters(
|
||||
[
|
||||
{ field: 'name', value: 'a', query: 'EQ', readOnly: true },
|
||||
{ field: 'status', value: 'b', query: 'EQ' },
|
||||
],
|
||||
{ allowedFields, skipFlags: ['readOnly'] },
|
||||
);
|
||||
expect(out).toHaveLength(1);
|
||||
expect(out[0].field).toBe('status');
|
||||
});
|
||||
|
||||
it('does not emit values for scalar queries', () => {
|
||||
const out = parseFilters(
|
||||
[{ field: 'name', value: 'xx', query: 'EQ' }],
|
||||
{ allowedFields },
|
||||
);
|
||||
expect(out[0].values).toBeUndefined();
|
||||
});
|
||||
|
||||
it('parses IS_NULL with null value without values', () => {
|
||||
const out = parseFilters(
|
||||
[{ field: 'status', value: null, query: 'IS_NULL' }],
|
||||
{ allowedFields },
|
||||
);
|
||||
expect(out[0]).toMatchObject({ field: 'status', query: 'IS_NULL', op: 'IS NULL', value: null });
|
||||
expect(out[0].values).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('toTree', () => {
|
||||
|
||||
Reference in New Issue
Block a user