-
Notifications
You must be signed in to change notification settings - Fork 614
test: add vitest #509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: add vitest #509
Conversation
WalkthroughThe changes introduce a comprehensive testing infrastructure using Vitest, add related dependencies and scripts, and provide extensive documentation and setup files. The build configuration is updated to exclude the Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant Vitest as Vitest CLI
participant Setup as Test Setup Files
participant App as Application Modules
participant Mocks as Mocked Dependencies
Dev->>Vitest: Run test script (e.g., npm test)
Vitest->>Setup: Load setup.ts/setup.renderer.ts
Setup->>Mocks: Mock Node.js/Electron/Vue modules
Vitest->>App: Import modules under test
App->>Mocks: Use mocked dependencies
Vitest->>App: Execute test cases
App-->>Vitest: Return test results
Vitest-->>Dev: Output results and coverage
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (13)
.oxlintrc.json (1)
15-15: Consider keeping the legacytestsignore pattern as well
Previous configs ignoredtests/*; the new single entrytestis fine, but if any historical folder or developer still places specs undertests/they will suddenly be lint-checked.
Add both patterns for a painless transition."docs", - "test" + "test", + "tests"electron-builder-macx64.yml (1)
8-9: Duplicate!test/*entries – drop one for cleanliness
The same exclusion appears twice (lines 8 and 19). Builder tolerates duplicates but it is noisy and increases merge-conflict surface.- - '!test/*' # line 8 ... - - '!test/*' # line 19Also applies to: 19-20
electron-builder.yml (1)
8-9: Same!test/*duplication as the mac config
Two identical exclusion lines (8 and 19) – safe but untidy. Remove the second.Also applies to: 19-20
vitest.config.renderer.ts (1)
43-45: Timeouts: consider lowering for renderer unit tests
10 s per test/hook is generous and may hide hung tests. Typical unit tests complete in < 2 s. If E2E coverage is required, move those to Playwright/Cypress suites.test/setup.ts (1)
63-71: Usevi.resetModules()to ensure module isolation between tests
vi.clearAllMocks()resets call counts, andvi.restoreAllMocks()restores spied-on methods, but neither unloads mocked modules. Stateful singletons (e.g. Electron mocks) will therefore persist across tests.afterEach(() => { // Clean up after each test vi.restoreAllMocks() + vi.resetModules() })This guarantees each test receives a fresh module instance.
test/README.md (1)
5-17: Specify a language for the directory-tree code blockMarkdown-lint (MD040) flags fenced blocks without a language. Add
text(orbash) to improve syntax highlighting and keep the linter quiet.-``` +```text test/ ├── main/ ...<details> <summary>🧰 Tools</summary> <details> <summary>🪛 markdownlint-cli2 (0.17.2)</summary> 5-5: Fenced code blocks should have a language specified null (MD040, fenced-code-language) </details> </details> </blockquote></details> <details> <summary>vitest.config.ts (1)</summary><blockquote> `7-9`: **Minor style nit – stray indentation** Extra two-space indent before `'@shared'` is inconsistent with the rest of the file. Not blocking, just keeping the config tidy. ```diff - '@': resolve('src/main/'), - '@shared': resolve('src/shared') + '@': resolve('src/main/'), + '@shared': resolve('src/shared')test/setup.renderer.ts (2)
70-88: Globalwindow.apistub looks good but consider freezing structureDown-stream code may rely on
Object.freeze(window.api)behaviour from preload. To mimic production more closely and avoid accidental mutation inside tests:-Object.defineProperty(window, 'api', { - value: { +Object.defineProperty(window, 'api', { + value: Object.freeze({ devicePresenter: { getDeviceInfo: vi.fn(() => Promise.resolve({ /* … */ })) }, windowPresenter: { minimize: vi.fn(), maximize: vi.fn(), close: vi.fn(), isMaximized: vi.fn(() => Promise.resolve(false)) } - }, + }), writable: true })Optional, but reduces flakiness in larger suites.
103-106: Same isolation concern as main setup – reset mocked modulesMirror the change suggested for
test/setup.tsso renderer tests also start with clean modules.afterEach(() => { vi.restoreAllMocks() + vi.resetModules() })test/main/eventbus/eventbus.test.ts (2)
205-209: Prefer a deterministic promise-flush oversetTimeout(0)Using
await new Promise(r => setTimeout(r, 0))makes tests a tiny bit slower and can still race.
Consider a helper such as:const flushPromises = () => new Promise(queueMicrotask); await flushPromises();or
await vi.runAllTicks()if fake timers are active.Also applies to: 221-223, 235-237
5-26: Add a global mock reset inafterEachMocks are re-created per
beforeEach, but any strayvi.spyOnthat forgets tomockRestoremay leak across suites. Safer pattern:afterEach(() => { vi.restoreAllMocks(); });test/renderer/shell/main.test.ts (2)
8-17: Smoke test may be redundant & heavyImporting full ESM bundles of
vue,pinia, andvue-i18nonly to assert that factory functions exist costs ~100 ms per run and adds no behavioural coverage.
Consider stubbing those imports or removing the test entirely.
62-73: Spy-only assertion adds little value
addCollectionis a plainvi.fn()and you verify it was called – this does not test your icon system. Either use the real@iconify/vueAPI or drop the case to keep the suite meaningful.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
.github/workflows/prcheck.yml(1 hunks).oxlintrc.json(1 hunks)electron-builder-macx64.yml(1 hunks)electron-builder.yml(1 hunks)package.json(4 hunks)test/README.md(1 hunks)test/main/eventbus/eventbus.test.ts(1 hunks)test/main/presenter/llmProviderPresenter.test.ts(1 hunks)test/renderer/shell/main.test.ts(1 hunks)test/setup.renderer.ts(1 hunks)test/setup.ts(1 hunks)vitest.config.renderer.ts(1 hunks)vitest.config.ts(1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.37.1)
.github/workflows/prcheck.yml
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
🪛 markdownlint-cli2 (0.17.2)
test/README.md
5-5: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build-check (x64)
🔇 Additional comments (4)
vitest.config.renderer.ts (2)
9-12: Verify@alias points where you expect
'@': resolve('src/renderer/src')is unusual – many IDE/Vite presets map@to the top-levelsrc. Double-check imports like@/components/...still resolve after this change.
37-38:⚠️ Potential issueGlob pattern will not match any tests
'test/renderer/**/*.{test,spec}.{js,ts}'expands to*.{test,spec}.{js,ts}, which is invalid.
Use separate brace sections:- include: ['test/renderer/**/*.{test,spec}.{js,ts}'], + include: ['test/renderer/**/*.test.{js,ts}', 'test/renderer/**/*.spec.{js,ts}'],Otherwise Vitest silently skips your renderer tests.
Likely an incorrect or invalid review comment.
test/README.md (1)
35-40: Doc/implementation drift –npm testnot wired inpackage.jsonThe quick-start section recommends
npm test, but that script is absent (see previous comment). Update either the docs orpackage.jsonto stay in sync.Likely an incorrect or invalid review comment.
test/main/presenter/llmProviderPresenter.test.ts (1)
6-16: Ensure Vitest alias resolution matches'@/'pathsThe mocks reference
'@/eventbus','@/presenter', …
Ifvitest.config.tsdoes not provideresolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }the tests will fail at runtime.
|
Caution No docstrings were generated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (4)
.github/workflows/prcheck.yml (1)
35-35: Add trailing newline to satisfy YAML lint.The file is missing a newline at EOF, causing YAML-lint to error.
- run: npm run build + run: npm run build +🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
test/setup.ts (1)
60-66: 🛠️ Refactor suggestion
path.join/resolvemock still hides platform-specific bugs- join: vi.fn((...args) => args.join('/')), - resolve: vi.fn((...args) => args.join('/')) + join: vi.spyOn(actual as any, 'join'), + resolve: vi.spyOn(actual as any, 'resolve')Spying preserves real semantics while keeping call-count assertions intact.
test/main/presenter/llmProviderPresenter.test.ts (2)
132-150: Still performs real HTTP calls — please stub themThe test hits
https://mockllm.anya2a.com/v1, making the suite slow and non-deterministic. Mock the request layer (vi.mock/msw/nock) and assert against the stubbed payload instead.
435-451: Possible infinite loop in concurrency sectionThe
for awaitloop waits for events but a rejected stream may never yield, hanging until Vitest times out. Add a timeout guard (e.g.Promise.racewithsetTimeout) or abort signal.
🧹 Nitpick comments (11)
electron-builder.yml (1)
8-19: Remove duplicate exclusion and refine test directory pattern.The
!test/*exclusion appears twice (lines 8 and 19) and only excludes top-level files, not nested directories. Consolidate to a single glob that covers all test files:- - '!test/*' + - '!test/**'electron-builder-macx64.yml (1)
8-19: Remove duplicate exclusion and refine test directory pattern.The exclusion
!test/*is duplicated (lines 8 and 19) and doesn't match nested files. Replace with a single recursive pattern:- - '!test/*' + - '!test/**'.oxlintrc.json (1)
15-15: Ensure ignore pattern excludes nested test files.The pattern
"test"may not ignore subdirectories. Use a glob to match all files undertest/:- "test" + "test/**"test/setup.ts (1)
44-56:fs.promises.statstill un-stubbed – async callers will failSeveral production files call
fs.promises.stat. Add it to the promises mock.promises: { access: vi.fn(), readFile: vi.fn(), writeFile: vi.fn(), mkdir: vi.fn(), - readdir: vi.fn() + readdir: vi.fn(), + stat: vi.fn() }vitest.config.ts (1)
6-9: Alias indentation & trailing slash inconsistencyThe
@sharedalias is indented one level deeper than@, andsrc/main/includes a trailing slash whilesrc/shareddoes not. Although harmless at runtime, this inconsistency sparks avoidable merge noise across commits.- alias: { - '@': resolve('src/main/'), - '@shared': resolve('src/shared') - } + alias: { + '@': resolve('src/main'), + '@shared': resolve('src/shared') + }test/renderer/shell/main.test.ts (1)
58-73:addCollectionassertion weakThe expectation only checks the first argument shape. To guarantee both icon sets are registered, assert on the actual payload or call order.
-expect(addCollection).toHaveBeenCalledTimes(2) -expect(addCollection).toHaveBeenCalledWith( - expect.objectContaining({ icons: expect.any(Object) }) -) +expect(addCollection).toHaveBeenNthCalledWith(1, lucideIcons) +expect(addCollection).toHaveBeenNthCalledWith(2, vscodeIcons)test/setup.renderer.ts (2)
15-24: Router mock is missingisReady&afterEachMany Vue-Router consumers await
router.isReady()or registerafterEachhooks. Omitting them will crash tests that exercise navigation guards.createRouter: vi.fn(() => ({ + isReady: vi.fn(() => Promise.resolve()), + afterEach: vi.fn(), push: vi.fn(),
61-68: Icon component should be a valid Vue componentReturning a plain object may trigger “runtime missing template compiler” warnings. Wrap the stub with
defineComponent.-import '@iconify/vue' +import { defineComponent } from 'vue' ... - Icon: { - name: 'Icon', - template: '<span></span>' - } + Icon: defineComponent({ + name: 'IconStub', + template: '<span></span>' + })test/README.md (1)
5-17: Add language tag to fenced block (MD040)Markdown-lint complains because the directory tree block lacks a language. Mark it as
textto silence CI.-``` +```text🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
5-5: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
test/main/eventbus/eventbus.test.ts (2)
206-212: Flushing async work withsetTimeoutis brittleInstead of an empty
setTimeout, rely on Vitest helpers to flush micro-tasks. This avoids test flakiness on slower runners.-await new Promise(resolve => setTimeout(resolve, 0)) +await vi.runAllTicks()
334-349: Duplicate error-logging expectation patternThe three error-handling tests share near-identical setup/teardown. Extract a helper or use
describe.eachto shrink the suite and reduce maintenance.No diff provided – structural refactor suggested.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (16)
.github/workflows/prcheck.yml(1 hunks).oxlintrc.json(1 hunks)electron-builder-macx64.yml(1 hunks)electron-builder.yml(1 hunks)package.json(4 hunks)src/main/eventbus.ts(1 hunks)src/main/presenter/windowPresenter/index.ts(1 hunks)src/shared/presenter.d.ts(1 hunks)test/README.md(1 hunks)test/main/eventbus/eventbus.test.ts(1 hunks)test/main/presenter/llmProviderPresenter.test.ts(1 hunks)test/renderer/shell/main.test.ts(1 hunks)test/setup.renderer.ts(1 hunks)test/setup.ts(1 hunks)vitest.config.renderer.ts(1 hunks)vitest.config.ts(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
test/main/presenter/llmProviderPresenter.test.ts (3)
src/main/presenter/llmProviderPresenter/index.ts (1)
LLMProviderPresenter(50-1051)src/main/presenter/configPresenter/index.ts (1)
ConfigPresenter(73-954)src/shared/presenter.d.ts (3)
LLM_PROVIDER(439-453)ChatMessage(1048-1060)LLMAgentEvent(1096-1099)
test/main/eventbus/eventbus.test.ts (2)
src/main/eventbus.ts (1)
EventBus(9-148)src/shared/presenter.d.ts (2)
IWindowPresenter(143-168)ITabPresenter(170-204)
🪛 YAMLlint (1.37.1)
.github/workflows/prcheck.yml
[error] 35-35: no new line character at the end of file
(new-line-at-end-of-file)
🪛 markdownlint-cli2 (0.17.2)
test/README.md
5-5: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🔇 Additional comments (4)
src/main/eventbus.ts (1)
51-51: Corrected method invocation for default tab.The typo is fixed from
sendTodefaultTabtosendToDefaultTab, aligning with the presenter API.src/shared/presenter.d.ts (1)
165-167:Details
✅ Verification successful
Ensure callers have been migrated to the new method name
sendToDefaultTabis now the canonical spelling. double-check all invocations (main + renderer) to avoid a silent runtimeundefined is not a function.Run
to confirm no lingering references.
🏁 Script executed:
#!/bin/bash rg -n "sendTodefaultTab"Length of output: 24
🏁 Script executed:
#!/bin/bash # Check for any lingering references to the new canonical method name with correct casing rg -n "sendToDefaultTab"Length of output: 508
sendToDefaultTab migration complete
The method signature insrc/shared/presenter.d.ts(line 166) and all call sites have been updated to the new canonical name; no occurrences ofsendTodefaultTabremain.
• src/main/eventbus.ts:51
• src/main/presenter/windowPresenter/index.ts:916
• test/main/eventbus/eventbus.test.ts:17, 128src/main/presenter/windowPresenter/index.ts (1)
916-991: Implementation reads well – no functional concerns spottedLogic gracefully handles “no focused window / no tabs” cases, respects
switchToTarget, and returns the correct boolean.vitest.config.renderer.ts (1)
5-47: Renderer Vitest config looks goodjsdom environment, alias map and coverage filters are sensible.
| BrowserWindow: vi.fn(() => ({ | ||
| loadURL: vi.fn(), | ||
| loadFile: vi.fn(), | ||
| on: vi.fn(), | ||
| webContents: { | ||
| send: vi.fn(), | ||
| on: vi.fn(), | ||
| isDestroyed: vi.fn(() => false) | ||
| }, | ||
| isDestroyed: vi.fn(() => false), | ||
| close: vi.fn(), | ||
| show: vi.fn(), | ||
| hide: vi.fn() | ||
| })), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Missing static helpers & instance data on BrowserWindow mock
WindowPresenter relies on
• BrowserWindow.getFocusedWindow()
• BrowserWindow.fromWebContents()
• window.id
These are absent and tests that exercise focus / IPC logic will explode.
- BrowserWindow: vi.fn(() => ({
+ const createWindow = () => ({
+ id: Math.floor(Math.random() * 1000),
...
}))
- ,
+ const BrowserWindowMock: any = Object.assign(createWindow, {
+ fromWebContents: vi.fn(() => createWindow()),
+ getFocusedWindow: vi.fn(() => undefined) // customise in tests
+ })
+ BrowserWindow: BrowserWindowMock,Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In test/setup.ts between lines 13 and 26, the BrowserWindow mock is missing
static methods getFocusedWindow and fromWebContents, as well as the instance
property id. Add these static methods to the BrowserWindow mock returning
appropriate mock instances, and include an id property on the mock window object
to ensure tests involving focus and IPC logic work correctly without errors.
| "scripts": { | ||
| "test": "vitest", | ||
| "test:main": "vitest --config vitest.config.ts test/main", | ||
| "test:renderer": "vitest --config vitest.config.renderer.ts test/renderer", | ||
| "test:coverage": "vitest --coverage", | ||
| "test:watch": "vitest --watch", | ||
| "test:ui": "vitest --ui", | ||
| "format": "prettier --write .", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Top-level test script runs only main tests
Running plain vitest picks up vitest.config.ts but ignores the renderer config, so npm test gives partial coverage.
- "test": "vitest",
+ "test": "npm run test:main && npm run test:renderer",This keeps CI/local workflows aligned with the documented intent.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "scripts": { | |
| "test": "vitest", | |
| "test:main": "vitest --config vitest.config.ts test/main", | |
| "test:renderer": "vitest --config vitest.config.renderer.ts test/renderer", | |
| "test:coverage": "vitest --coverage", | |
| "test:watch": "vitest --watch", | |
| "test:ui": "vitest --ui", | |
| "format": "prettier --write .", | |
| "scripts": { | |
| - "test": "vitest", | |
| + "test": "npm run test:main && npm run test:renderer", | |
| "test:main": "vitest --config vitest.config.ts test/main", | |
| "test:renderer": "vitest --config vitest.config.renderer.ts test/renderer", | |
| "test:coverage": "vitest --coverage", | |
| "test:watch": "vitest --watch", | |
| "test:ui": "vitest --ui", | |
| "format": "prettier --write .", |
🤖 Prompt for AI Agents
In package.json lines 8 to 15, the top-level "test" script runs only the main
tests using vitest with vitest.config.ts, ignoring the renderer tests and their
config. To fix this, modify the "test" script to run both main and renderer
tests by combining or chaining the commands so that both configurations are
used, ensuring full test coverage when running npm test.
| }, | ||
| include: ['test/**/*.{test,spec}.{js,ts}'], | ||
| exclude: [ | ||
| 'node_modules/**', | ||
| 'dist/**', | ||
| 'out/**' | ||
| ], | ||
| testTimeout: 10000, | ||
| hookTimeout: 10000, | ||
| setupFiles: ['./test/setup.ts'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Glob pattern loses TSX / JSX and risks false-negatives
include: ['test/**/*.{test,spec}.{js,ts}'] does not match *.tsx/ *.jsx, and fast-glob expands this brace twice, which can occasionally mis-interpret nested braces. Prefer the explicit array recommended by Vitest docs.
- include: ['test/**/*.{test,spec}.{js,ts}'],
+ include: [
+ 'test/**/*.test.{js,ts,jsx,tsx}',
+ 'test/**/*.spec.{js,ts,jsx,tsx}'
+ ],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| }, | |
| include: ['test/**/*.{test,spec}.{js,ts}'], | |
| exclude: [ | |
| 'node_modules/**', | |
| 'dist/**', | |
| 'out/**' | |
| ], | |
| testTimeout: 10000, | |
| hookTimeout: 10000, | |
| setupFiles: ['./test/setup.ts'] | |
| }, | |
| include: [ | |
| 'test/**/*.test.{js,ts,jsx,tsx}', | |
| 'test/**/*.spec.{js,ts,jsx,tsx}' | |
| ], | |
| exclude: [ | |
| 'node_modules/**', | |
| 'dist/**', | |
| 'out/**' | |
| ], | |
| testTimeout: 10000, | |
| hookTimeout: 10000, | |
| setupFiles: ['./test/setup.ts'] |
🤖 Prompt for AI Agents
In vitest.config.ts around lines 37 to 46, the include glob pattern does not
cover .tsx and .jsx files and uses brace expansion that can misinterpret nested
braces. Update the include array to explicitly list all test file extensions
separately, including .tsx and .jsx, for example by specifying patterns like
'test/**/*.test.ts', 'test/**/*.spec.ts', 'test/**/*.test.tsx',
'test/**/*.spec.tsx', 'test/**/*.test.jsx', and 'test/**/*.spec.jsx' to ensure
all relevant test files are included correctly.
| it('应该正确创建Vue应用实例', () => { | ||
| // 模拟Vue应用创建流程 | ||
| const mockApp = { | ||
| use: vi.fn().mockReturnThis(), | ||
| mount: vi.fn() | ||
| } | ||
|
|
||
| const createApp = vi.fn(() => mockApp) | ||
| const createPinia = vi.fn(() => ({})) | ||
| const createI18n = vi.fn(() => ({ | ||
| global: { t: vi.fn(), locale: 'zh-CN' } | ||
| })) | ||
|
|
||
| // 验证函数被调用 | ||
| expect(createApp).toBeDefined() | ||
| expect(createPinia).toBeDefined() | ||
| expect(createI18n).toBeDefined() | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Tests assert stubs, not production code
createApp, createPinia, and createI18n are locally-defined mocks; the test never touches the real entry file, so a typo in src/renderer/main.ts would pass unnoticed. Import the actual module and spy on the real factories instead.
-const createApp = vi.fn(() => mockApp)
-const createPinia = vi.fn(() => ({}))
-const createI18n = vi.fn(() => ({ … }))
+vi.mock('vue', async (orig) => {
+ const mod = await orig()
+ return { ...mod, createApp: vi.fn(() => mockApp) }
+})
+// idem for pinia / vue-i18n
+await import('@/renderer/main') // or relative pathCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In test/renderer/shell/main.test.ts around lines 19 to 36, the test currently
only asserts on locally defined mock functions instead of the real production
code, which means it won't catch issues in the actual implementation. To fix
this, import the real module from src/renderer/main.ts and use spies on the real
createApp, createPinia, and createI18n functions to verify their behavior. This
ensures the test interacts with the actual code and detects any typos or errors
in the production factories.
| eventBus = new EventBus() | ||
|
|
||
| // Mock WindowPresenter | ||
| mockWindowPresenter = { | ||
| sendToWindow: vi.fn(), | ||
| sendToAllWindows: vi.fn(), | ||
| sendToDefaultTab: vi.fn() | ||
| } as Partial<IWindowPresenter> as IWindowPresenter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Heavy casting hides type drift
as Partial<IWindowPresenter> as IWindowPresenter discards type-safety and will not alert when the interface evolves. Prefer an explicit helper that fills required fields with no-ops to keep TS protection.
const mockWindowPresenter: IWindowPresenter = {
createShellWindow: vi.fn(),
mainWindow: undefined,
previewFile: vi.fn(),
minimize: vi.fn(),
maximize: vi.fn(),
close: vi.fn(),
hide: vi.fn(),
show: vi.fn(),
isMaximized: vi.fn(),
isMainWindowFocused: vi.fn(),
sendToAllWindows: vi.fn(),
sendToWindow: vi.fn(),
sendToDefaultTab: vi.fn(),
closeWindow: vi.fn(),
}🤖 Prompt for AI Agents
In test/main/eventbus/eventbus.test.ts around lines 11 to 18, the
mockWindowPresenter uses heavy casting with 'as Partial<IWindowPresenter> as
IWindowPresenter' which bypasses type safety. Replace this with an explicit mock
object that implements all required IWindowPresenter methods and properties
using no-op functions or appropriate defaults to maintain TypeScript type
checking and catch interface changes.
| afterEach(() => { | ||
| // Stop all active streams after each test | ||
| const activeStreams = (llmProviderPresenter as any).activeStreams as Map<string, any> | ||
| for (const [eventId] of activeStreams) { | ||
| llmProviderPresenter.stopStream(eventId) | ||
| } | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Mark afterEach async and await stream shutdown
stopStream is async; without await the test runner may finish while streams are still tearing down, causing flaky leakage into later tests.
-afterEach(() => {
+afterEach(async () => {
…
- llmProviderPresenter.stopStream(eventId)
+ await llmProviderPresenter.stopStream(eventId)
})📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| afterEach(() => { | |
| // Stop all active streams after each test | |
| const activeStreams = (llmProviderPresenter as any).activeStreams as Map<string, any> | |
| for (const [eventId] of activeStreams) { | |
| llmProviderPresenter.stopStream(eventId) | |
| } | |
| }) | |
| afterEach(async () => { | |
| // Stop all active streams after each test | |
| const activeStreams = (llmProviderPresenter as any).activeStreams as Map<string, any> | |
| for (const [eventId] of activeStreams) { | |
| await llmProviderPresenter.stopStream(eventId) | |
| } | |
| }) |
🤖 Prompt for AI Agents
In test/main/presenter/llmProviderPresenter.test.ts around lines 98 to 104, the
afterEach hook calls the async stopStream method without awaiting it, which can
cause tests to finish before streams are fully stopped. Mark the afterEach
callback as async and await each call to stopStream to ensure all streams are
properly shut down before proceeding to the next test.
开始给项目增加 vitest
目录结构
Summary by CodeRabbit
New Features
Bug Fixes
Chores