test: PR30测试 — 子序列匹配、单位系统、volume优先级 + 拼音补字
Some checks failed
PR Preview / test (pull_request) Has been skipped
Deploy Production / test (push) Successful in 5s
Test / unit-test (push) Successful in 6s
PR Preview / teardown-preview (pull_request) Successful in 17s
PR Preview / deploy-preview (pull_request) Has been skipped
Test / build-check (push) Successful in 3s
Deploy Production / deploy (push) Successful in 8s
Test / e2e-test (push) Failing after 3m8s
Some checks failed
PR Preview / test (pull_request) Has been skipped
Deploy Production / test (push) Successful in 5s
Test / unit-test (push) Successful in 6s
PR Preview / teardown-preview (pull_request) Successful in 17s
PR Preview / deploy-preview (pull_request) Has been skipped
Test / build-check (push) Successful in 3s
Deploy Production / deploy (push) Successful in 8s
Test / e2e-test (push) Failing after 3m8s
新增12个测试: pinyinMatchScore、产品名拼音、单位映射、volume优先级 更新2个旧测试适配substring/subsequence匹配 补全拼音: 面、湿 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit was merged in pull request #30.
This commit is contained in:
@@ -58,15 +58,15 @@ describe('getPinyinInitials', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('matchesPinyinInitials', () => {
|
describe('matchesPinyinInitials', () => {
|
||||||
it('matches prefix only', () => {
|
it('matches prefix', () => {
|
||||||
expect(matchesPinyinInitials('生姜', 's')).toBe(true)
|
expect(matchesPinyinInitials('生姜', 's')).toBe(true)
|
||||||
expect(matchesPinyinInitials('生姜', 'sj')).toBe(true)
|
expect(matchesPinyinInitials('生姜', 'sj')).toBe(true)
|
||||||
expect(matchesPinyinInitials('茶树', 's')).toBe(false) // cs doesn't start with s
|
|
||||||
expect(matchesPinyinInitials('茶树', 'cs')).toBe(true)
|
expect(matchesPinyinInitials('茶树', 'cs')).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('does not match substring', () => {
|
it('matches substring and subsequence', () => {
|
||||||
expect(matchesPinyinInitials('茶树', 's')).toBe(false)
|
expect(matchesPinyinInitials('茶树', 's')).toBe(true) // substring
|
||||||
|
expect(matchesPinyinInitials('新瑞活力身体紧致霜', 'js')).toBe(true) // subsequence
|
||||||
})
|
})
|
||||||
|
|
||||||
it('matches 忍冬花 with r', () => {
|
it('matches 忍冬花 with r', () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { describe, it, expect } from 'vitest'
|
import { describe, it, expect } from 'vitest'
|
||||||
import { recipeNameEn, oilEn } from '../composables/useOilTranslation'
|
import { recipeNameEn, oilEn } from '../composables/useOilTranslation'
|
||||||
import { matchesPinyinInitials, getPinyinInitials } from '../composables/usePinyinMatch'
|
import { matchesPinyinInitials, getPinyinInitials, pinyinMatchScore } from '../composables/usePinyinMatch'
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// EDITOR_ONLY_TAGS includes '已下架'
|
// EDITOR_ONLY_TAGS includes '已下架'
|
||||||
@@ -376,3 +376,71 @@ describe('viewer tag visibility logic', () => {
|
|||||||
expect([...myTags]).toHaveLength(0)
|
expect([...myTags]).toHaveLength(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// PR30: Pinyin subsequence matching + pinyinMatchScore
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
describe('pinyin subsequence matching — PR30', () => {
|
||||||
|
it('js matches 紧致霜 via subsequence', () => {
|
||||||
|
expect(matchesPinyinInitials('新瑞活力身体紧致霜', 'js')).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('prefix match scores 0', () => {
|
||||||
|
expect(pinyinMatchScore('麦卢卡', 'mlk')).toBe(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('substring match scores 1', () => {
|
||||||
|
expect(pinyinMatchScore('椒样薄荷', 'ybh')).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('subsequence match scores 2', () => {
|
||||||
|
expect(pinyinMatchScore('新瑞活力身体紧致霜', 'js')).toBe(2)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('no match scores -1', () => {
|
||||||
|
expect(pinyinMatchScore('薰衣草', 'zz')).toBe(-1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('product names have pinyin', () => {
|
||||||
|
expect(getPinyinInitials('身体紧致霜')).toBe('stjzs')
|
||||||
|
expect(getPinyinInitials('深层净肤面膜')).toBe('scjfmm')
|
||||||
|
expect(getPinyinInitials('青春无龄保湿霜')).toBe('qcwlbss')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// PR30: Unit system (drop/ml/g/capsule)
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
describe('unit system — PR30', () => {
|
||||||
|
const UNIT_LABELS = {
|
||||||
|
drop: { zh: '滴' },
|
||||||
|
ml: { zh: 'ml' },
|
||||||
|
g: { zh: 'g' },
|
||||||
|
capsule: { zh: '颗' },
|
||||||
|
}
|
||||||
|
|
||||||
|
it('maps unit to correct label', () => {
|
||||||
|
expect(UNIT_LABELS['drop'].zh).toBe('滴')
|
||||||
|
expect(UNIT_LABELS['ml'].zh).toBe('ml')
|
||||||
|
expect(UNIT_LABELS['g'].zh).toBe('g')
|
||||||
|
expect(UNIT_LABELS['capsule'].zh).toBe('颗')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('volume display priority: stored > calculated > product sum', () => {
|
||||||
|
// Stored volume takes priority
|
||||||
|
const recipe1 = { volume: 'single', ingredients: [{ oil: '椰子油', drops: 96 }] }
|
||||||
|
const vol1 = recipe1.volume === 'single' ? '单次' : ''
|
||||||
|
expect(vol1).toBe('单次')
|
||||||
|
|
||||||
|
// No stored volume, has coconut oil → calculate
|
||||||
|
const recipe2 = { volume: '', ingredients: [{ oil: '薰衣草', drops: 3 }, { oil: '椰子油', drops: 90 }] }
|
||||||
|
const total = recipe2.ingredients.reduce((s, i) => s + i.drops, 0)
|
||||||
|
const ml = Math.round(total / 18.6)
|
||||||
|
expect(ml).toBe(5)
|
||||||
|
|
||||||
|
// No coconut oil, has product → show product volume
|
||||||
|
const recipe3 = { volume: '', ingredients: [{ oil: '薰衣草', drops: 3 }, { oil: '玫瑰护手霜', drops: 30 }] }
|
||||||
|
const hasProduct = recipe3.ingredients.some(i => i.oil === '玫瑰护手霜')
|
||||||
|
expect(hasProduct).toBe(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const PINYIN_MAP = {
|
|||||||
'膜': 'm', '乳': 'r', '液': 'y', '瓶': 'p', '盒': 'h',
|
'膜': 'm', '乳': 'r', '液': 'y', '瓶': 'p', '盒': 'h',
|
||||||
'深': 's', '层': 'c', '肤': 'f', '磨': 'm', '砂': 's',
|
'深': 's', '层': 'c', '肤': 'f', '磨': 'm', '砂': 's',
|
||||||
'龄': 'l', '无': 'w', '年': 'n', '华': 'h', '娇': 'j',
|
'龄': 'l', '无': 'w', '年': 'n', '华': 'h', '娇': 'j',
|
||||||
'颜': 'y', '喷': 'p', '雾': 'w',
|
'颜': 'y', '喷': 'p', '雾': 'w', '面': 'm', '湿': 's',
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user