import { describe, it, expect } from 'vitest' import { parseMultiRecipes } from '../composables/useSmartPaste' import { getPinyinInitials, matchesPinyinInitials } from '../composables/usePinyinMatch' const oilNames = ['薰衣草','茶树','柠檬','芳香调理','永久花','椒样薄荷','乳香','檀香','天竺葵','佛手柑','生姜'] // --------------------------------------------------------------------------- // parseMultiRecipes // --------------------------------------------------------------------------- describe('parseMultiRecipes', () => { it('parses single recipe with name', () => { const results = parseMultiRecipes('舒缓放松,薰衣草3,茶树2', oilNames) expect(results).toHaveLength(1) expect(results[0].name).toBe('舒缓放松') expect(results[0].ingredients).toHaveLength(2) }) it('parses recipe with space-separated parts', () => { const results = parseMultiRecipes('长高 芳香调理8 永久花10', oilNames) expect(results).toHaveLength(1) expect(results[0].name).toBe('长高') expect(results[0].ingredients.length).toBeGreaterThanOrEqual(2) }) it('parses recipe with concatenated name+oil', () => { const results = parseMultiRecipes('长高芳香调理8永久花10', oilNames) expect(results).toHaveLength(1) expect(results[0].name).toBe('长高') }) it('parses multiple recipes', () => { const results = parseMultiRecipes('舒缓放松,薰衣草3,茶树2,提神醒脑,柠檬5', oilNames) expect(results).toHaveLength(2) expect(results[0].name).toBe('舒缓放松') expect(results[1].name).toBe('提神醒脑') }) it('handles recipe with no name', () => { const results = parseMultiRecipes('薰衣草3,茶树2', oilNames) expect(results).toHaveLength(1) expect(results[0].ingredients).toHaveLength(2) }) }) // --------------------------------------------------------------------------- // Pinyin matching // --------------------------------------------------------------------------- describe('getPinyinInitials', () => { it('returns correct initials for common oils', () => { expect(getPinyinInitials('薰衣草')).toBe('xyc') expect(getPinyinInitials('茶树')).toBe('cs') expect(getPinyinInitials('生姜')).toBe('sj') }) it('handles 忍冬花', () => { expect(getPinyinInitials('忍冬花呵护')).toBe('rdhhh') }) }) describe('matchesPinyinInitials', () => { it('matches prefix only', () => { expect(matchesPinyinInitials('生姜', 's')).toBe(true) expect(matchesPinyinInitials('生姜', 'sj')).toBe(true) expect(matchesPinyinInitials('茶树', 's')).toBe(false) // cs doesn't start with s expect(matchesPinyinInitials('茶树', 'cs')).toBe(true) }) it('does not match substring', () => { expect(matchesPinyinInitials('茶树', 's')).toBe(false) }) it('matches 忍冬花 with r', () => { expect(matchesPinyinInitials('忍冬花呵护', 'r')).toBe(true) expect(matchesPinyinInitials('忍冬花呵护', 'rdh')).toBe(true) expect(matchesPinyinInitials('忍冬花呵护', 'l')).toBe(false) }) }) // --------------------------------------------------------------------------- // EDITOR_ONLY_TAGS // --------------------------------------------------------------------------- describe('EDITOR_ONLY_TAGS', () => { it('exports EDITOR_ONLY_TAGS from recipes store', async () => { const { EDITOR_ONLY_TAGS } = await import('../stores/recipes') expect(EDITOR_ONLY_TAGS).toContain('已审核') }) }) // --------------------------------------------------------------------------- // English search // --------------------------------------------------------------------------- describe('English search matching', () => { const { oilEn } = require('../composables/useOilTranslation') it('oilEn returns English name for known oils', () => { expect(oilEn('薰衣草')).toBe('Lavender') expect(oilEn('茶树')).toBe('Tea Tree') expect(oilEn('乳香')).toBe('Frankincense') }) it('oilEn returns empty for unknown oils', () => { expect(oilEn('不存在的油')).toBeFalsy() }) it('English query detection', () => { const isEn = (q) => /^[a-zA-Z\s]+$/.test(q) expect(isEn('lavender')).toBe(true) expect(isEn('Tea Tree')).toBe(true) expect(isEn('薰衣草')).toBe(false) expect(isEn('lav3')).toBe(false) }) it('English matches oil name in recipe', () => { const recipe = { name: '助眠配方', en_name: 'Sleep Aid Blend', ingredients: [{ oil: '薰衣草', drops: 3 }], tags: [] } const q = 'lavender' const isEn = /^[a-zA-Z\s]+$/.test(q) const enNameMatch = isEn && (recipe.en_name || '').toLowerCase().includes(q) const oilEnMatch = isEn && recipe.ingredients.some(ing => (oilEn(ing.oil) || '').toLowerCase().includes(q)) expect(oilEnMatch).toBe(true) expect(enNameMatch).toBe(false) }) it('English matches recipe en_name', () => { const recipe = { name: '助眠', en_name: 'Sleep Aid Blend', ingredients: [], tags: [] } const q = 'sleep' const isEn = /^[a-zA-Z\s]+$/.test(q) const enNameMatch = isEn && (recipe.en_name || '').toLowerCase().includes(q) expect(enNameMatch).toBe(true) }) })