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