Files
trans-form-component/test/useFilters.test.js
T
2026-08-07 16:42:01 +08:00

162 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { afterEach, describe, expect, it } from 'vitest';
import { getDefaultQueryOption, resetConfig, setConfig } from '../src/config.js';
import {
applyFilters,
buildFilters,
createFieldState,
groupRows,
resolveQueryOption,
} from '../src/composables/useFilters.js';
// 每个用例后恢复全局配置,避免 setConfig 污染其它用例
afterEach(() => {
resetConfig();
});
const schema = [
{
row: 6,
field: 'name',
'field-name': '名称',
'query-option': [{ value: 'EQ', label: '=' }],
},
{
row: 6,
logic: 'OR',
field: 'status',
'query-option': [{ value: 'NE', label: '≠' }],
},
];
describe('createFieldState', () => {
it('initializes default query from first option', () => {
const state = createFieldState(schema);
expect(state.name.query).toBe('EQ');
expect(state.status.logic).toBe('OR');
});
});
describe('buildFilters', () => {
it('emits logic from second item onward', () => {
const state = createFieldState(schema);
state.name.value = 'alice';
state.status.value = 'active';
const filters = buildFilters(schema, state);
expect(filters[0].logic).toBeUndefined();
expect(filters[1].logic).toBe('OR');
});
it('marks empty values', () => {
const state = createFieldState(schema);
const filters = buildFilters(schema, state);
expect(filters[0].empty).toBe(true);
expect(filters[0].value).toBeNull();
});
});
describe('applyFilters', () => {
it('loads filters back into state', () => {
const loaded = applyFilters(schema, [
{ field: 'name', value: 'bob', query: 'EQ' },
]);
expect(loaded.name.value).toBe('bob');
});
});
describe('groupRows', () => {
it('wraps when row spans exceed 12', () => {
const groups = groupRows([
{ row: 2, field: 'a' },
{ row: 9, field: 'b' },
{ row: 4, field: 'c' },
]);
expect(groups).toHaveLength(2);
expect(groups[0]).toHaveLength(2);
expect(groups[1]).toHaveLength(1);
});
});
describe('resolveQueryOption(默认 query-option 解析)', () => {
it('无 query-option 且无 query-component 时返回默认操作符列表', () => {
const opts = resolveQueryOption({ field: 'name' });
expect(opts).toHaveLength(12);
expect(opts[0]).toEqual({ value: 'EQ', label: '=' });
expect(opts.map((o) => o.value)).toEqual([
'EQ', 'NE', 'GT', 'GTE', 'LT', 'LTE',
'LIKE', 'IN', 'NOT_IN', 'BETWEEN', 'IS_NULL', 'IS_NOT_NULL',
]);
});
it('有 query-option 的字段仍用 schema 自己的(不被默认覆盖)', () => {
const fieldDef = { field: 'name', 'query-option': [{ value: 'NE', label: '≠' }] };
expect(resolveQueryOption(fieldDef)).toEqual([{ value: 'NE', label: '≠' }]);
});
it('有 query-component 但无 query-option 时返回空数组(组件自己管理)', () => {
const fieldDef = { field: 'name', 'query-component': 'CustomQuery' };
expect(resolveQueryOption(fieldDef)).toEqual([]);
});
it('getDefaultQueryOption() 返回深拷贝:修改返回值不影响后续调用', () => {
const first = getDefaultQueryOption();
first.push({ value: 'X', label: 'x' });
first[0].label = '被改坏了';
first.splice(1, 1);
const second = getDefaultQueryOption();
expect(second).toHaveLength(12);
expect(second[0]).toEqual({ value: 'EQ', label: '=' });
expect(second[1]).toEqual({ value: 'NE', label: '≠' });
});
it('setConfig({ queryOption }) 后 getDefaultQueryOption() 返回新列表', () => {
setConfig({
queryOption: [
{ value: 'EQ', label: '=' },
{ value: 'GT', label: '>' },
],
});
expect(getDefaultQueryOption()).toEqual([
{ value: 'EQ', label: '=' },
{ value: 'GT', label: '>' },
]);
});
it('resetConfig() 恢复默认操作符列表', () => {
setConfig({ queryOption: [{ value: 'ONLY_EQ', label: '=' }] });
resetConfig();
expect(getDefaultQueryOption()).toHaveLength(12);
expect(getDefaultQueryOption()[0]).toEqual({ value: 'EQ', label: '=' });
});
});
describe('默认 query fallback(无 query-option 时取默认列表第一项)', () => {
it('createFieldState:无 query-option 且无 query-component 默认取默认列表第一项(EQ)', () => {
const state = createFieldState([{ field: 'name' }]);
expect(state.name.query).toBe('EQ');
});
it('buildFilters:无 query-option 且无 query-component 默认取默认列表第一项(EQ)', () => {
const state = createFieldState([{ field: 'name' }]);
const filters = buildFilters([{ field: 'name' }], state);
expect(filters[0].query).toBe('EQ');
});
it('setConfig 自定义 queryOption 后,默认 query 取新列表第一项', () => {
setConfig({ queryOption: [{ value: 'GT', label: '>' }] });
const state = createFieldState([{ field: 'age' }]);
expect(state.age.query).toBe('GT');
expect(buildFilters([{ field: 'age' }], state)[0].query).toBe('GT');
});
it('有 query-component 但无 query-option 时,默认 query 仍为 EQ', () => {
const state = createFieldState([{ field: 'custom', 'query-component': 'CustomQuery' }]);
expect(state.custom.query).toBe('EQ');
});
it('显式 default-query 优先级最高,覆盖默认列表第一项', () => {
const state = createFieldState([{ field: 'name', 'default-query': 'LIKE' }]);
expect(state.name.query).toBe('LIKE');
});
});