mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 20:20:57 +00:00
fix: 修复扩展管理对话框测试和代码质量问题
- 为 ActionSelectionStep.test.tsx 和 ExtensionListStep.test.tsx 添加 KeypressProvider 包裹 - 修复 KeypressContext 导入路径 - 更新测试快照 - 重构 ExtensionsManagerDialog:提取 enable/disable 公共逻辑到 handleToggleExtensionState - 添加错误消息状态和用户友好的错误提示
This commit is contained in:
parent
4d27950a95
commit
0072c47996
5 changed files with 160 additions and 394 deletions
|
|
@ -21,6 +21,7 @@ import { t } from '../../../i18n/index.js';
|
|||
import type { Extension, Config } from '@qwen-code/qwen-code-core';
|
||||
import { SettingScope, createDebugLogger } from '@qwen-code/qwen-code-core';
|
||||
import { ExtensionUpdateState } from '../../state/extensions.js';
|
||||
import { getErrorMessage } from '../../../utils/errors.js';
|
||||
|
||||
interface ExtensionsManagerDialogProps {
|
||||
onClose: () => void;
|
||||
|
|
@ -44,6 +45,7 @@ export function ExtensionsManagerDialog({
|
|||
const [updateInProgress, setUpdateInProgress] = useState(false);
|
||||
const [updateError, setUpdateError] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
// Load extensions
|
||||
const loadExtensions = useCallback(async () => {
|
||||
|
|
@ -94,6 +96,7 @@ export function ExtensionsManagerDialog({
|
|||
const handleSelectExtension = useCallback((extensionIndex: number) => {
|
||||
setSelectedExtensionIndex(extensionIndex);
|
||||
setSuccessMessage(null); // Clear success message when navigating
|
||||
setErrorMessage(null); // Clear error message when navigating
|
||||
setNavigationStack((prev) => [...prev, MANAGEMENT_STEPS.ACTION_SELECTION]);
|
||||
}, []);
|
||||
|
||||
|
|
@ -108,6 +111,8 @@ export function ExtensionsManagerDialog({
|
|||
}
|
||||
return prev.slice(0, -1);
|
||||
});
|
||||
// Clear messages when navigating back
|
||||
setErrorMessage(null);
|
||||
}, []);
|
||||
|
||||
const handleUpdateExtension = useCallback(async () => {
|
||||
|
|
@ -195,8 +200,9 @@ export function ExtensionsManagerDialog({
|
|||
[handleNavigateToStep, handleUpdateExtension],
|
||||
);
|
||||
|
||||
const handleDisableExtension = useCallback(
|
||||
async (scope: 'user' | 'workspace') => {
|
||||
// Unified handler for toggling extension state (enable/disable)
|
||||
const handleToggleExtensionState = useCallback(
|
||||
async (scope: 'user' | 'workspace', newState: boolean) => {
|
||||
if (!config || !selectedExtension) return;
|
||||
|
||||
try {
|
||||
|
|
@ -208,77 +214,68 @@ export function ExtensionsManagerDialog({
|
|||
const settingScope =
|
||||
scope === 'user' ? SettingScope.User : SettingScope.Workspace;
|
||||
|
||||
await extensionManager.disableExtension(
|
||||
selectedExtension.name,
|
||||
settingScope,
|
||||
);
|
||||
if (newState) {
|
||||
await extensionManager.enableExtension(
|
||||
selectedExtension.name,
|
||||
settingScope,
|
||||
);
|
||||
} else {
|
||||
await extensionManager.disableExtension(
|
||||
selectedExtension.name,
|
||||
settingScope,
|
||||
);
|
||||
}
|
||||
|
||||
// Update local state
|
||||
setExtensions((prev) =>
|
||||
prev.map((ext) =>
|
||||
ext.name === selectedExtension.name
|
||||
? { ...ext, isActive: false }
|
||||
? { ...ext, isActive: newState }
|
||||
: ext,
|
||||
),
|
||||
);
|
||||
|
||||
// Show success message
|
||||
const actionKey = newState ? 'enabled' : 'disabled';
|
||||
setSuccessMessage(
|
||||
t('Extension "{{name}}" disabled successfully.', {
|
||||
t(`Extension "{{name}}" ${actionKey} successfully.`, {
|
||||
name: selectedExtension.name,
|
||||
}),
|
||||
);
|
||||
setErrorMessage(null);
|
||||
|
||||
// Go back to extension list to show success message
|
||||
setNavigationStack([MANAGEMENT_STEPS.EXTENSION_LIST]);
|
||||
} catch (error) {
|
||||
debugLogger.error('Failed to disable extension:', error);
|
||||
debugLogger.error(
|
||||
`Failed to ${newState ? 'enable' : 'disable'} extension:`,
|
||||
error,
|
||||
);
|
||||
setErrorMessage(
|
||||
t('Failed to {{action}} extension "{{name}}": {{error}}', {
|
||||
action: newState ? 'enable' : 'disable',
|
||||
name: selectedExtension.name,
|
||||
error: getErrorMessage(error),
|
||||
}),
|
||||
);
|
||||
setSuccessMessage(null);
|
||||
}
|
||||
},
|
||||
[config, selectedExtension],
|
||||
);
|
||||
|
||||
const handleDisableExtension = useCallback(
|
||||
async (scope: 'user' | 'workspace') => {
|
||||
await handleToggleExtensionState(scope, false);
|
||||
},
|
||||
[handleToggleExtensionState],
|
||||
);
|
||||
|
||||
const handleEnableExtension = useCallback(
|
||||
async (scope: 'user' | 'workspace') => {
|
||||
if (!config || !selectedExtension) return;
|
||||
|
||||
try {
|
||||
const extensionManager = config.getExtensionManager();
|
||||
if (!extensionManager) {
|
||||
throw new Error('ExtensionManager not available');
|
||||
}
|
||||
|
||||
const settingScope =
|
||||
scope === 'user' ? SettingScope.User : SettingScope.Workspace;
|
||||
|
||||
await extensionManager.enableExtension(
|
||||
selectedExtension.name,
|
||||
settingScope,
|
||||
);
|
||||
|
||||
// Update local state
|
||||
setExtensions((prev) =>
|
||||
prev.map((ext) =>
|
||||
ext.name === selectedExtension.name
|
||||
? { ...ext, isActive: true }
|
||||
: ext,
|
||||
),
|
||||
);
|
||||
|
||||
// Show success message
|
||||
setSuccessMessage(
|
||||
t('Extension "{{name}}" enabled successfully.', {
|
||||
name: selectedExtension.name,
|
||||
}),
|
||||
);
|
||||
|
||||
// Go back to extension list to show success message
|
||||
setNavigationStack([MANAGEMENT_STEPS.EXTENSION_LIST]);
|
||||
} catch (error) {
|
||||
debugLogger.error('Failed to enable extension:', error);
|
||||
}
|
||||
await handleToggleExtensionState(scope, true);
|
||||
},
|
||||
[config, selectedExtension],
|
||||
[handleToggleExtensionState],
|
||||
);
|
||||
|
||||
const handleUninstallExtension = useCallback(
|
||||
|
|
@ -394,6 +391,15 @@ export function ExtensionsManagerDialog({
|
|||
const renderStepContent = useCallback(() => {
|
||||
const currentStep = getCurrentStep();
|
||||
|
||||
// Show error message if present (only on extension list step)
|
||||
if (errorMessage && currentStep === MANAGEMENT_STEPS.EXTENSION_LIST) {
|
||||
return (
|
||||
<Box flexDirection="column" gap={1}>
|
||||
<Text color={theme.status.error}>{errorMessage}</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// Show success message if present (only on extension list step)
|
||||
if (successMessage && currentStep === MANAGEMENT_STEPS.EXTENSION_LIST) {
|
||||
return (
|
||||
|
|
@ -489,6 +495,7 @@ export function ExtensionsManagerDialog({
|
|||
updateInProgress,
|
||||
updateError,
|
||||
successMessage,
|
||||
errorMessage,
|
||||
handleSelectExtension,
|
||||
handleNavigateToStep,
|
||||
handleNavigateBack,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { render } from 'ink-testing-library';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { ActionSelectionStep } from './ActionSelectionStep.js';
|
||||
import { KeypressProvider } from '../../../contexts/KeypressContext.js';
|
||||
import type { Extension } from '@qwen-code/qwen-code-core';
|
||||
|
||||
const createMockExtension = (name: string, isActive = true): Extension =>
|
||||
|
|
@ -38,11 +39,13 @@ describe('ActionSelectionStep Snapshots', () => {
|
|||
|
||||
it('should render for active extension without update', () => {
|
||||
const { lastFrame } = render(
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('active-ext', true)}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('active-ext', true)}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -50,11 +53,13 @@ describe('ActionSelectionStep Snapshots', () => {
|
|||
|
||||
it('should render for disabled extension', () => {
|
||||
const { lastFrame } = render(
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('disabled-ext', false)}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('disabled-ext', false)}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -62,11 +67,13 @@ describe('ActionSelectionStep Snapshots', () => {
|
|||
|
||||
it('should render for extension with update available', () => {
|
||||
const { lastFrame } = render(
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('update-ext', true)}
|
||||
hasUpdateAvailable={true}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('update-ext', true)}
|
||||
hasUpdateAvailable={true}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -74,11 +81,13 @@ describe('ActionSelectionStep Snapshots', () => {
|
|||
|
||||
it('should render for disabled extension with update', () => {
|
||||
const { lastFrame } = render(
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('disabled-update-ext', false)}
|
||||
hasUpdateAvailable={true}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ActionSelectionStep
|
||||
selectedExtension={createMockExtension('disabled-update-ext', false)}
|
||||
hasUpdateAvailable={true}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -86,11 +95,13 @@ describe('ActionSelectionStep Snapshots', () => {
|
|||
|
||||
it('should render with no extension selected', () => {
|
||||
const { lastFrame } = render(
|
||||
<ActionSelectionStep
|
||||
selectedExtension={null}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ActionSelectionStep
|
||||
selectedExtension={null}
|
||||
hasUpdateAvailable={false}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { render } from 'ink-testing-library';
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { ExtensionListStep } from './ExtensionListStep.js';
|
||||
import { KeypressProvider } from '../../../contexts/KeypressContext.js';
|
||||
import type { Extension } from '@qwen-code/qwen-code-core';
|
||||
import { ExtensionUpdateState } from '../../../state/extensions.js';
|
||||
|
||||
|
|
@ -41,11 +42,13 @@ describe('ExtensionListStep Snapshots', () => {
|
|||
|
||||
it('should render empty state', () => {
|
||||
const { lastFrame } = render(
|
||||
<ExtensionListStep
|
||||
extensions={[]}
|
||||
extensionsUpdateState={new Map()}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ExtensionListStep
|
||||
extensions={[]}
|
||||
extensionsUpdateState={new Map()}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -54,11 +57,13 @@ describe('ExtensionListStep Snapshots', () => {
|
|||
it('should render list with single extension', () => {
|
||||
const extensions = [createMockExtension('test-extension', true)];
|
||||
const { lastFrame } = render(
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={new Map()}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={new Map()}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -77,11 +82,13 @@ describe('ExtensionListStep Snapshots', () => {
|
|||
]);
|
||||
|
||||
const { lastFrame } = render(
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -94,11 +101,13 @@ describe('ExtensionListStep Snapshots', () => {
|
|||
]);
|
||||
|
||||
const { lastFrame } = render(
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
@ -111,11 +120,13 @@ describe('ExtensionListStep Snapshots', () => {
|
|||
]);
|
||||
|
||||
const { lastFrame } = render(
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>,
|
||||
<KeypressProvider kittyProtocolEnabled={false}>
|
||||
<ExtensionListStep
|
||||
extensions={extensions}
|
||||
extensionsUpdateState={updateState}
|
||||
{...baseProps}
|
||||
/>
|
||||
</KeypressProvider>,
|
||||
);
|
||||
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -1,166 +1,38 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`ActionSelectionStep Snapshots > should render for active extension without update 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- useSelectionList (src/ui/hooks/useSelectionList.ts:287:3)
|
||||
- BaseSelectionList (src/ui/components/shared/BaseSelectionList.tsx:64:27)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
"
|
||||
"● View Details
|
||||
Disable Extension
|
||||
Uninstall Extension
|
||||
Back"
|
||||
`;
|
||||
|
||||
exports[`ActionSelectionStep Snapshots > should render for disabled extension 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- useSelectionList (src/ui/hooks/useSelectionList.ts:287:3)
|
||||
- BaseSelectionList (src/ui/components/shared/BaseSelectionList.tsx:64:27)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
"
|
||||
"● View Details
|
||||
Enable Extension
|
||||
Uninstall Extension
|
||||
Back"
|
||||
`;
|
||||
|
||||
exports[`ActionSelectionStep Snapshots > should render for disabled extension with update 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- useSelectionList (src/ui/hooks/useSelectionList.ts:287:3)
|
||||
- BaseSelectionList (src/ui/components/shared/BaseSelectionList.tsx:64:27)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
"
|
||||
"● View Details
|
||||
Update Extension
|
||||
Enable Extension
|
||||
Uninstall Extension
|
||||
Back"
|
||||
`;
|
||||
|
||||
exports[`ActionSelectionStep Snapshots > should render for extension with update available 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- useSelectionList (src/ui/hooks/useSelectionList.ts:287:3)
|
||||
- BaseSelectionList (src/ui/components/shared/BaseSelectionList.tsx:64:27)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
"
|
||||
"● View Details
|
||||
Update Extension
|
||||
Disable Extension
|
||||
Uninstall Extension
|
||||
Back"
|
||||
`;
|
||||
|
||||
exports[`ActionSelectionStep Snapshots > should render with no extension selected 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- useSelectionList (src/ui/hooks/useSelectionList.ts:287:3)
|
||||
- BaseSelectionList (src/ui/components/shared/BaseSelectionList.tsx:64:27)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
"
|
||||
"● View Details
|
||||
Enable Extension
|
||||
Uninstall Extension
|
||||
Back"
|
||||
`;
|
||||
|
|
|
|||
|
|
@ -1,171 +1,36 @@
|
|||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`ExtensionListStep Snapshots > should render empty state 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- ExtensionListStep (src/ui/components/extensions/steps/ExtensionListStep.tsx:36:3)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
-workLoopSyn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.devel
|
||||
opment.js:12644:41)
|
||||
"
|
||||
"No extensions installed.
|
||||
Use '/extensions install' to install your first extension."
|
||||
`;
|
||||
|
||||
exports[`ExtensionListStep Snapshots > should render list with multiple extensions 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
"● active-extension v1.0.0 (active) [up to date]
|
||||
disabled-extension v1.0.0 (disabled) [not updatable]
|
||||
update-available v1.0.0 (active) [update available]
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- ExtensionListStep (src/ui/components/extensions/steps/ExtensionListStep.tsx:36:3)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
-workLoopSyn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.devel
|
||||
opment.js:12644:41)
|
||||
"
|
||||
3 extensions installed"
|
||||
`;
|
||||
|
||||
exports[`ExtensionListStep Snapshots > should render list with single extension 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
"● test-extension v1.0.0 (active)
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- ExtensionListStep (src/ui/components/extensions/steps/ExtensionListStep.tsx:36:3)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
-workLoopSyn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.devel
|
||||
opment.js:12644:41)
|
||||
"
|
||||
1 extensions installed"
|
||||
`;
|
||||
|
||||
exports[`ExtensionListStep Snapshots > should render with checking status 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
"● checking-extension v1.0.0 (active) [checking for updates]
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- ExtensionListStep (src/ui/components/extensions/steps/ExtensionListStep.tsx:36:3)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
-workLoopSyn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.devel
|
||||
opment.js:12644:41)
|
||||
"
|
||||
1 extensions installed"
|
||||
`;
|
||||
|
||||
exports[`ExtensionListStep Snapshots > should render with error status 1`] = `
|
||||
"
|
||||
ERROR useKeypressContext must be used within a KeypressProvider
|
||||
"● error-extension v1.0.0 (active) [error]
|
||||
|
||||
src/ui/contexts/KeypressContext.tsx:77:11
|
||||
|
||||
74: export function useKeypressContext() {
|
||||
75: const context = useContext(KeypressContext);
|
||||
76: if (!context) {
|
||||
77: throw new Error(
|
||||
78: 'useKeypressContext must be used within a KeypressProvider',
|
||||
79: );
|
||||
80: }
|
||||
|
||||
- useKeypressContext (src/ui/contexts/KeypressContext.tsx:77:11)
|
||||
- useKeypress (src/ui/hooks/useKeypress.ts:24:38)
|
||||
- ExtensionListStep (src/ui/components/extensions/steps/ExtensionListStep.tsx:36:3)
|
||||
-Object.react-stack-bott (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reco
|
||||
m-frame nciler.development.js:15859:20)
|
||||
-renderWithHoo (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.dev
|
||||
s elopment.js:3221:22)
|
||||
-updateFunctionComp (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconcile
|
||||
nent r.development.js:6475:19)
|
||||
-beginWor (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.developm
|
||||
ent.js:8009:18)
|
||||
-runWithFiberIn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
EV velopment.js:1738:13)
|
||||
-performUnitOfW (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.de
|
||||
rk velopment.js:12834:22)
|
||||
-workLoopSyn (/Users/mochi/code/qwen-code/node_modules/react-reconciler/cjs/react-reconciler.devel
|
||||
opment.js:12644:41)
|
||||
"
|
||||
1 extensions installed"
|
||||
`;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue