From 73e920cd8d52b749ed979d41ef38bb6f0c6edebc Mon Sep 17 00:00:00 2001 From: R2m1liA <15258427350@163.com> Date: Mon, 27 Oct 2025 14:12:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/mappers/productMapper.test.ts | 49 --------------- app/models/utils/object.test.ts | 66 ++++++++++++++++++++ app/models/utils/search-converter.test.ts | 75 +++++++++++++++++++++++ app/utils/file.test.ts | 5 -- 4 files changed, 141 insertions(+), 54 deletions(-) delete mode 100644 app/models/mappers/productMapper.test.ts create mode 100644 app/models/utils/object.test.ts create mode 100644 app/models/utils/search-converter.test.ts diff --git a/app/models/mappers/productMapper.test.ts b/app/models/mappers/productMapper.test.ts deleted file mode 100644 index ce5b498..0000000 --- a/app/models/mappers/productMapper.test.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { describe, it, expect } from 'vitest'; - -describe('toProductSpecView', () => { - it('should map translations.key an value corrently', () => { - const raw: ProductSpec = { - id: 1, - value: '100W', - translations: [ - { - id: 1, - key: 'Power', - }, - ], - }; - - const expected: ProductSpecView = { - id: 1, - key: 'Power', - value: '100W', - }; - - expect(toProductSpecView(raw)).toEqual(expected); - }); - - it('should handle missing translations gracefully', () => { - const raw: ProductSpec = { id: 2, value: '220V', translations: [] }; - const view = toProductSpecView(raw); - expect(view.key).toBe(''); - }); -}); - -describe('toProductSpecGroupView', () => { - it('should map translations.name and specs correctly', () => { - const raw: ProductSpecGroup = { - id: 1, - translations: [{ id: 1, name: 'Electrical' }], - specs: [ - { id: 1, value: '100W', translations: [{ id: 1, key: 'Power' }] }, - { id: 2, value: '220V', translations: [{ id: 2, key: 'Voltage' }] }, - ], - }; - const view: ProductSpecGroupView = toProductSpecGroupView(raw); - - expect(view.name).toBe('Electrical'); - expect(view.specs).toHaveLength(2); - expect(view.specs[0].key).toBe('Power'); - expect(view.specs[1].value).toBe('220V'); - }); -}); diff --git a/app/models/utils/object.test.ts b/app/models/utils/object.test.ts new file mode 100644 index 0000000..b217543 --- /dev/null +++ b/app/models/utils/object.test.ts @@ -0,0 +1,66 @@ +import { expect, test, describe } from 'vitest'; + +/** + * 单元测试: isObject + */ +describe('isObject', () => { + test('identify plain object', () => { + expect(isObject({})).toBe(true); + expect(isObject({ key: 'value' })).toBe(true); + }); + test('identify null as non objevt', () => { + expect(isObject(null)).toBe(false); + }); + test('identify non-object types', () => { + expect(isObject(undefined)).toBe(false); + expect(isObject(42)).toBe(false); + expect(isObject('string')).toBe(false); + expect(isObject(Symbol('sym'))).toBe(false); + expect(isObject(true)).toBe(false); + expect(isObject(() => {})).toBe(false); + }); + test('identify arrays as objects', () => { + expect(isObject([])).toBe(true); + }); + test('identify narrowed object type', () => { + const value: unknown = { id: 1 }; + if (isObject<{ id: number }>(value)) { + expect(value.id).toBe(1); + } else { + throw new Error('Type narrowing failed'); + } + }); +}); + +/** + * 单元测试: isArrayOfObject + */ +describe('isArrayOfObject', () => { + test('identify array of plain objects', () => { + const arr = [{ id: 1 }, { name: 'Alice' }]; + expect(isArrayOfObject<{ id?: number; name?: string }>(arr)).toBe(true); + }); + test('identify array containing non-objects', () => { + expect(isArrayOfObject([1, 2, 3])).toBe(false); + expect(isArrayOfObject([{ id: 1 }, null])).toBe(false); + expect(isArrayOfObject([{ id: 1 }, 'string'])).toBe(false); + }); + test('identify non-array types', () => { + expect(isArrayOfObject(null)).toBe(false); + expect(isArrayOfObject({})).toBe(false); + expect(isArrayOfObject(42)).toBe(false); + }); + test('identify empty array as array of objects', () => { + expect(isArrayOfObject([])).toBe(true); + }); + test('identify narrowed array of object type', () => { + const data: unknown = [{ id: 1 }, { id: 2 }]; + if (isArrayOfObject<{ id: number }>(data)) { + // TS 能识别为 { id: number }[] + expect(data[0].id).toBe(1); + expect(data[1].id).toBe(2); + } else { + throw new Error('Type guard failed'); + } + }); +}); diff --git a/app/models/utils/search-converter.test.ts b/app/models/utils/search-converter.test.ts new file mode 100644 index 0000000..e9d9947 --- /dev/null +++ b/app/models/utils/search-converter.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, test } from 'vitest'; + +/** + * 单元测试: converters + */ +describe('converters', () => { + test('convert product item', () => { + const item = { + id: 1, + name: 'Hydraulic Pump', + summary: 'High efficiency', + description: 'Detailed description', + type: 'pump', + }; + const result = converters.products(item); + expect(result).toEqual({ + id: 1, + type: 'product', + title: 'Hydraulic Pump', + summary: 'High efficiency', + }); + }); + + test('convert solution item', () => { + const item = { + id: 1, + title: 'Solution A', + summary: 'Effective solution', + content: 'Detailed content', + type: 'Type A', + }; + const result = converters.solutions(item); + expect(result).toEqual({ + id: 1, + type: 'solution', + title: 'Solution A', + summary: 'Effective solution', + }); + }); + + test('convert question item', () => { + const item = { + id: 1, + title: 'How to use product?', + content: + 'This is a detailed explanation of how to use the product effectively.', + products: ['Product A'], + product_types: ['Type A'], + }; + const result = converters.questions(item); + expect(result).toEqual({ + id: 1, + title: 'How to use product?', + summary: + 'This is a detailed explanation of how to use the product effectively....', + type: 'question', + }); + }); + + test('convert product document item', () => { + const item = { + id: 1, + title: 'User Manual', + products: ['Product A'], + product_types: ['Type A'], + }; + const result = converters.product_documents(item); + expect(result).toEqual({ + id: 1, + title: 'User Manual', + summary: undefined, + type: 'document', + }); + }); +}); diff --git a/app/utils/file.test.ts b/app/utils/file.test.ts index 5325b72..e95541a 100644 --- a/app/utils/file.test.ts +++ b/app/utils/file.test.ts @@ -1,8 +1,3 @@ -import { - formatFileSize, - getFileExtension, - formatFileExtension, -} from '@/utils/file'; import { expect, test, describe } from 'vitest'; /**