diff --git a/package.json b/package.json index b487000..9293d44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "javdict", - "version": "1.2.5", + "version": "1.2.6", "description": "AV番号命令行查询工具", "main": "./index.js", "type": "module", diff --git a/test/display.test.js b/test/display.test.js index f83c0ab..f83dae4 100644 --- a/test/display.test.js +++ b/test/display.test.js @@ -1,7 +1,6 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; +import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { display } from '../lib/display.js'; -// 完整的 mock 数据 const MOCK_INFO = { id: 'SSIS-001', title: '测试标题', @@ -20,7 +19,6 @@ const MOCK_INFO = { describe('display.js', () => { beforeEach(() => { - // 拦截 console.log,不真正打印,但可以断言调用内容 vi.spyOn(console, 'log').mockImplementation(() => {}); }); @@ -47,7 +45,6 @@ describe('display.js', () => { it('display:raw 模式输出 JSON 字符串', () => { display(MOCK_INFO, true); const allOutput = console.log.mock.calls.flat().join(' '); - // raw 模式应该输出可解析的 JSON expect(() => JSON.parse(allOutput)).not.toThrow(); }); diff --git a/test/fetcher.test.js b/test/fetcher.test.js index 23501fe..cbffc8d 100644 --- a/test/fetcher.test.js +++ b/test/fetcher.test.js @@ -1,49 +1,55 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -// mock axios,避免真实网络请求 -vi.mock('axios', () => ({ - default: { - get: vi.fn(), - }, +// mock execSync,避免真实的 curl 网络请求 +vi.mock('child_process', () => ({ + execSync: vi.fn(), + spawnSync: vi.fn(), })); -import axios from 'axios'; +// mock cache,避免缓存干扰测试结果 +vi.mock('../lib/cache.js', () => ({ + getCache: vi.fn().mockReturnValue(null), + setCache: vi.fn(), + getConfig: vi.fn().mockReturnValue({ session: 'mock_session' }), +})); + +import { execSync } from 'child_process'; import { search } from '../lib/fetcher.js'; -// 模拟搜索结果页的 HTML -const MOCK_SEARCH_HTML = ` -
-
- -
SSIS-001
-
+// 模拟 JAVBUS 详情页 HTML +const MOCK_JAVBUS_HTML = ` + + SSIS-001 + +
+
+

SSIS-001 测试标题

+
+ +
+
+

發行日期: 2021-01-01

+

長度: 150分鐘

+

導演: 导演A

+

製作商: SOD Create

+

發行商: SOD

+

系列: 系列A

+
+ 独占 + 美少女 + +
-
+ + `; -// 模拟详情页的 HTML -const MOCK_DETAIL_HTML = ` -

测试标题

-
-
4.5分
-
-
- 日期: - 2021-01-01 -
-
- 演員: - 天使もえ -
-
- 片商: - SOD Create -
-
- 時長: - 120分钟 -
-
+// 模拟 404 页面 +const MOCK_404_HTML = ` + + 404 + + `; describe('fetcher.js', () => { @@ -52,41 +58,36 @@ describe('fetcher.js', () => { }); it('search:正常番号能返回结构完整的对象', async () => { - // 第一次调用返回搜索页,第二次返回详情页 - axios.get - .mockResolvedValueOnce({ data: MOCK_SEARCH_HTML }) - .mockResolvedValueOnce({ data: MOCK_DETAIL_HTML }); + execSync.mockReturnValue(Buffer.from(MOCK_JAVBUS_HTML)); const result = await search('SSIS-001'); expect(result).not.toBeNull(); expect(result.id).toBe('SSIS-001'); - expect(result.title).toBe('测试标题'); + expect(result.source).toBe('JAVBUS'); expect(result.actresses).toContain('天使もえ'); expect(result.releaseDate).toBe('2021-01-01'); expect(result.studio).toBe('SOD Create'); - expect(result.duration).toBe('120分钟'); - expect(result.coverUrl).toBe('https://example.com/cover.jpg'); }); it('search:搜索结果为空时返回 null', async () => { - // 返回一个没有结果的搜索页 - axios.get.mockResolvedValueOnce({ data: '
' }); + execSync.mockReturnValue(Buffer.from(MOCK_404_HTML)); const result = await search('INVALID-999'); expect(result).toBeNull(); }); - it('search:网络请求失败时抛出错误', async () => { - axios.get.mockRejectedValueOnce(new Error('Network Error')); + it('search:网络请求失败时返回 null', async () => { + execSync.mockImplementation(() => { + throw new Error('Network Error'); + }); - await expect(search('SSIS-001')).rejects.toThrow('Network Error'); + const result = await search('SSIS-001'); + expect(result).toBeNull(); }); it('search:返回对象包含所有预期字段', async () => { - axios.get - .mockResolvedValueOnce({ data: MOCK_SEARCH_HTML }) - .mockResolvedValueOnce({ data: MOCK_DETAIL_HTML }); + execSync.mockReturnValue(Buffer.from(MOCK_JAVBUS_HTML)); const result = await search('SSIS-001'); const expectedFields = [