import { describe, it, expect } from 'vitest' import * as fc from 'fast-check' import { searchMolds } from './moldSearch' import type { MoldInfo } from '../types/mold' const moldInfoArb: fc.Arbitrary = fc.record({ id: fc.integer({ min: 1, max: 100000 }), name: fc.string({ minLength: 1, maxLength: 20 }), styleNo: fc.option(fc.string({ minLength: 1, maxLength: 10 }), { nil: undefined }), barcodeNo: fc.option(fc.string({ minLength: 1, maxLength: 15 }), { nil: undefined }), style: fc.option(fc.string({ minLength: 1, maxLength: 10 }), { nil: undefined }), images: fc.array(fc.string(), { minLength: 0, maxLength: 3 }), createdAt: fc.constant('2025-01-01'), updatedAt: fc.constant('2025-01-01'), }) // Feature: jewelry-mall, Property 5: 版房搜索结果匹配 // **Validates: Requirements 5.3** describe('Property 5: 版房搜索结果匹配', () => { it('搜索结果中每条记录至少有一个字段包含关键词', () => { fc.assert( fc.property( fc.array(moldInfoArb, { minLength: 0, maxLength: 20 }), fc.string({ minLength: 1, maxLength: 10 }), (molds, keyword) => { const results = searchMolds(molds, keyword) const kw = keyword.trim().toLowerCase() if (!kw) return true // 空关键词返回全部,不需要验证匹配 for (const mold of results) { const fields = [ mold.name, mold.styleNo ?? '', mold.barcodeNo ?? '', mold.style ?? '', ] const matched = fields.some((f) => f.toLowerCase().includes(kw)) expect(matched).toBe(true) } }, ), { numRuns: 100 }, ) }) })