@google/gemini-cli 0.12.0-preview.4 → 0.13.0-nightly.20251031.c89bc30d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/google-gemini-cli-0.13.0-nightly.20251029.cca41edc.tgz +0 -0
- package/dist/package.json +2 -2
- package/dist/src/commands/extensions/install.js +2 -2
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +27 -16
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.js +2 -2
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/update.js +3 -2
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/commands/extensions/validate.d.ts +12 -0
- package/dist/src/commands/extensions/validate.js +83 -0
- package/dist/src/commands/extensions/validate.js.map +1 -0
- package/dist/src/commands/extensions/validate.test.d.ts +6 -0
- package/dist/src/commands/extensions/validate.test.js +93 -0
- package/dist/src/commands/extensions/validate.test.js.map +1 -0
- package/dist/src/commands/extensions.js +2 -0
- package/dist/src/commands/extensions.js.map +1 -1
- package/dist/src/config/auth.js +0 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/auth.test.js +1 -3
- package/dist/src/config/auth.test.js.map +1 -1
- package/dist/src/config/config.js +2 -1
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +6 -10
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extensions/update.d.ts +2 -2
- package/dist/src/config/extensions/update.js +28 -22
- package/dist/src/config/extensions/update.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +1 -1
- package/dist/src/config/sandboxConfig.js +6 -3
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.js +2 -2
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settings.test.js +13 -53
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +25 -7
- package/dist/src/config/settingsSchema.js +24 -6
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +2 -0
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/gemini.js +8 -1
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +1 -0
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/nonInteractiveCli.d.ts +9 -1
- package/dist/src/nonInteractiveCli.js +16 -1
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +209 -103
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/test-utils/async.d.ts +9 -0
- package/dist/src/test-utils/async.js +29 -0
- package/dist/src/test-utils/async.js.map +1 -0
- package/dist/src/test-utils/render.d.ts +2 -1
- package/dist/src/test-utils/render.js +23 -1
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/test-utils/render.test.js +29 -4
- package/dist/src/test-utils/render.test.js.map +1 -1
- package/dist/src/ui/App.test.js +1 -1
- package/dist/src/ui/App.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +33 -4
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +205 -99
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
- package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
- package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
- package/dist/src/ui/auth/AuthDialog.js +7 -3
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/useAuth.d.ts +2 -0
- package/dist/src/ui/auth/useAuth.js +31 -2
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/components/AnsiOutput.test.js +1 -1
- package/dist/src/ui/components/AnsiOutput.test.js.map +1 -1
- package/dist/src/ui/components/Composer.test.js +1 -1
- package/dist/src/ui/components/Composer.test.js.map +1 -1
- package/dist/src/ui/components/ConsentPrompt.test.js +18 -8
- package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.test.js +11 -6
- package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +4 -3
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/Footer.js +3 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.test.js +59 -0
- package/dist/src/ui/components/Footer.test.js.map +1 -1
- package/dist/src/ui/components/Header.test.js +9 -5
- package/dist/src/ui/components/Header.test.js.map +1 -1
- package/dist/src/ui/components/Help.test.js +5 -3
- package/dist/src/ui/components/Help.test.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +139 -111
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.test.js +27 -14
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +20 -10
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +11 -10
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/PrepareLabel.test.js +13 -7
- package/dist/src/ui/components/PrepareLabel.test.js.map +1 -1
- package/dist/src/ui/components/ProQuotaDialog.test.js +14 -6
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
- package/dist/src/ui/components/QueuedMessageDisplay.test.js +11 -6
- package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +438 -512
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.test.js +3 -2
- package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/messages/CompressionMessage.test.js +25 -17
- package/dist/src/ui/components/messages/CompressionMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.js +27 -5
- package/dist/src/ui/components/messages/Todo.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.test.js +20 -8
- package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +29 -15
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.js +12 -11
- package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +43 -22
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -1
- package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
- package/dist/src/ui/components/shared/TextInput.js +38 -0
- package/dist/src/ui/components/shared/TextInput.js.map +1 -0
- package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
- package/dist/src/ui/components/shared/TextInput.test.js +242 -0
- package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +8 -2
- package/dist/src/ui/components/shared/text-buffer.js +28 -13
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +137 -0
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/components/views/ChatList.test.js +7 -4
- package/dist/src/ui/components/views/ChatList.test.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.js +1 -0
- package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.test.js +13 -5
- package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
- package/dist/src/ui/components/views/McpStatus.test.js +23 -12
- package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +132 -252
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.test.js +9 -5
- package/dist/src/ui/contexts/SessionContext.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +29 -7
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +163 -64
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +47 -34
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +141 -104
- package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.test.js +23 -21
- package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.js +16 -15
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.test.js +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.js +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.js +9 -3
- package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +10 -9
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
- package/dist/src/ui/hooks/useFocus.test.js +1 -1
- package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.test.js +7 -6
- package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +39 -38
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js +5 -4
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
- package/dist/src/ui/hooks/useIdeTrustListener.test.js +25 -11
- package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.test.js +1 -1
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useMemoryMonitor.test.js +1 -1
- package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.test.js +5 -4
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
- package/dist/src/ui/hooks/useModelCommand.test.js +7 -4
- package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.test.js +46 -16
- package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.js +11 -7
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +28 -14
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.test.js +116 -109
- package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.test.js +25 -17
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.js +18 -7
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +244 -111
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useTimer.test.js +1 -1
- package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +6 -2
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/vim.test.js +6 -21
- package/dist/src/ui/hooks/vim.test.js.map +1 -1
- package/dist/src/ui/state/extensions.d.ts +1 -0
- package/dist/src/ui/state/extensions.js +1 -0
- package/dist/src/ui/state/extensions.js.map +1 -1
- package/dist/src/ui/types.d.ts +1 -0
- package/dist/src/ui/types.js +2 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/clipboardUtils.js +2 -2
- package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.js +6 -3
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +5 -1
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/commentJson.js +2 -2
- package/dist/src/utils/commentJson.js.map +1 -1
- package/dist/src/utils/commentJson.test.js +7 -6
- package/dist/src/utils/commentJson.test.js.map +1 -1
- package/dist/src/utils/version.js +6 -2
- package/dist/src/utils/version.js.map +1 -1
- package/dist/src/zed-integration/acp.js +2 -1
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/google-gemini-cli-0.12.0-preview.3.tgz +0 -0
- package/dist/src/utils/package.d.ts +0 -12
- package/dist/src/utils/package.js +0 -24
- package/dist/src/utils/package.js.map +0 -1
|
@@ -20,7 +20,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
20
20
|
* - Display values for inherited and overridden settings
|
|
21
21
|
*
|
|
22
22
|
*/
|
|
23
|
-
import { render } from '
|
|
23
|
+
import { render } from '../../test-utils/render.js';
|
|
24
|
+
import { waitFor } from '../../test-utils/async.js';
|
|
24
25
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
25
26
|
import { SettingsDialog } from './SettingsDialog.js';
|
|
26
27
|
import { LoadedSettings, SettingScope } from '../../config/settings.js';
|
|
@@ -196,9 +197,9 @@ const TOOLS_SHELL_FAKE_SCHEMA = {
|
|
|
196
197
|
},
|
|
197
198
|
},
|
|
198
199
|
};
|
|
200
|
+
// Helper function to render SettingsDialog with standard wrapper
|
|
201
|
+
const renderDialog = (settings, onSelect, options) => render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect, onRestartRequest: options?.onRestartRequest, availableTerminalHeight: options?.availableTerminalHeight }) }));
|
|
199
202
|
describe('SettingsDialog', () => {
|
|
200
|
-
// Simple delay function for remaining tests that need gradual migration
|
|
201
|
-
const wait = (ms = 50) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
202
203
|
beforeEach(() => {
|
|
203
204
|
mockToggleVimEnabled.mockResolvedValue(true);
|
|
204
205
|
});
|
|
@@ -211,83 +212,80 @@ describe('SettingsDialog', () => {
|
|
|
211
212
|
it('should render the settings dialog with default state', () => {
|
|
212
213
|
const settings = createMockSettings();
|
|
213
214
|
const onSelect = vi.fn();
|
|
214
|
-
const { lastFrame } =
|
|
215
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
215
216
|
const output = lastFrame();
|
|
216
217
|
expect(output).toContain('Settings');
|
|
217
218
|
expect(output).toContain('Apply To');
|
|
218
|
-
|
|
219
|
+
// Use regex for more flexible help text matching
|
|
220
|
+
expect(output).toMatch(/Enter.*select.*Esc.*close/);
|
|
219
221
|
});
|
|
220
222
|
it('should accept availableTerminalHeight prop without errors', () => {
|
|
221
223
|
const settings = createMockSettings();
|
|
222
224
|
const onSelect = vi.fn();
|
|
223
|
-
const { lastFrame } =
|
|
225
|
+
const { lastFrame } = renderDialog(settings, onSelect, {
|
|
226
|
+
availableTerminalHeight: 20,
|
|
227
|
+
});
|
|
224
228
|
const output = lastFrame();
|
|
225
229
|
// Should still render properly with the height prop
|
|
226
230
|
expect(output).toContain('Settings');
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
it('should show settings list with default values', () => {
|
|
230
|
-
const settings = createMockSettings();
|
|
231
|
-
const onSelect = vi.fn();
|
|
232
|
-
const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
233
|
-
const output = lastFrame();
|
|
234
|
-
// Should show some default settings
|
|
235
|
-
expect(output).toContain('●'); // Active indicator
|
|
231
|
+
// Use regex for more flexible help text matching
|
|
232
|
+
expect(output).toMatch(/Enter.*select.*Esc.*close/);
|
|
236
233
|
});
|
|
237
|
-
it('should
|
|
234
|
+
it('should render settings list with visual indicators', () => {
|
|
238
235
|
const settings = createMockSettings();
|
|
239
236
|
const onSelect = vi.fn();
|
|
240
|
-
const { lastFrame } =
|
|
237
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
241
238
|
const output = lastFrame();
|
|
242
|
-
//
|
|
243
|
-
expect(output).
|
|
239
|
+
// Use snapshot to capture visual layout including indicators
|
|
240
|
+
expect(output).toMatchSnapshot();
|
|
244
241
|
});
|
|
245
242
|
});
|
|
246
243
|
describe('Settings Navigation', () => {
|
|
247
|
-
it(
|
|
244
|
+
it.each([
|
|
245
|
+
{
|
|
246
|
+
name: 'arrow keys',
|
|
247
|
+
down: TerminalKeys.DOWN_ARROW,
|
|
248
|
+
up: TerminalKeys.UP_ARROW,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'vim keys (j/k)',
|
|
252
|
+
down: 'j',
|
|
253
|
+
up: 'k',
|
|
254
|
+
},
|
|
255
|
+
])('should navigate with $name', async ({ down, up }) => {
|
|
248
256
|
const settings = createMockSettings();
|
|
249
257
|
const onSelect = vi.fn();
|
|
250
|
-
const { stdin, unmount, lastFrame } =
|
|
251
|
-
|
|
258
|
+
const { stdin, unmount, lastFrame } = renderDialog(settings, onSelect);
|
|
259
|
+
const initialFrame = lastFrame();
|
|
260
|
+
expect(initialFrame).toContain('Vim Mode');
|
|
261
|
+
// Navigate down
|
|
252
262
|
act(() => {
|
|
253
|
-
stdin.write(
|
|
263
|
+
stdin.write(down);
|
|
264
|
+
});
|
|
265
|
+
await waitFor(() => {
|
|
266
|
+
expect(lastFrame()).toContain('Disable Auto Update');
|
|
267
|
+
});
|
|
268
|
+
// Navigate up
|
|
269
|
+
act(() => {
|
|
270
|
+
stdin.write(up);
|
|
271
|
+
});
|
|
272
|
+
await waitFor(() => {
|
|
273
|
+
expect(lastFrame()).toContain('Vim Mode');
|
|
254
274
|
});
|
|
255
|
-
expect(lastFrame()).toContain('● Disable Auto Update');
|
|
256
|
-
// The active index should have changed (tested indirectly through behavior)
|
|
257
|
-
unmount();
|
|
258
|
-
});
|
|
259
|
-
it('should navigate up with arrow key', async () => {
|
|
260
|
-
const settings = createMockSettings();
|
|
261
|
-
const onSelect = vi.fn();
|
|
262
|
-
const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
263
|
-
// First go down, then up
|
|
264
|
-
stdin.write(TerminalKeys.DOWN_ARROW); // Down arrow
|
|
265
|
-
await wait();
|
|
266
|
-
stdin.write(TerminalKeys.UP_ARROW);
|
|
267
|
-
await wait();
|
|
268
|
-
unmount();
|
|
269
|
-
});
|
|
270
|
-
it('should navigate with vim keys (j/k)', async () => {
|
|
271
|
-
const settings = createMockSettings();
|
|
272
|
-
const onSelect = vi.fn();
|
|
273
|
-
const { stdin, unmount } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
274
|
-
// Navigate with vim keys
|
|
275
|
-
stdin.write('j'); // Down
|
|
276
|
-
await wait();
|
|
277
|
-
stdin.write('k'); // Up
|
|
278
|
-
await wait();
|
|
279
275
|
unmount();
|
|
280
276
|
});
|
|
281
277
|
it('wraps around when at the top of the list', async () => {
|
|
282
278
|
const settings = createMockSettings();
|
|
283
279
|
const onSelect = vi.fn();
|
|
284
|
-
const { stdin, unmount, lastFrame } =
|
|
280
|
+
const { stdin, unmount, lastFrame } = renderDialog(settings, onSelect);
|
|
285
281
|
// Try to go up from first item
|
|
286
282
|
act(() => {
|
|
287
283
|
stdin.write(TerminalKeys.UP_ARROW);
|
|
288
284
|
});
|
|
289
|
-
await
|
|
290
|
-
|
|
285
|
+
await waitFor(() => {
|
|
286
|
+
// Should wrap to last setting (without relying on exact bullet character)
|
|
287
|
+
expect(lastFrame()).toContain('Codebase Investigator Max Num Turns');
|
|
288
|
+
});
|
|
291
289
|
unmount();
|
|
292
290
|
});
|
|
293
291
|
});
|
|
@@ -296,29 +294,28 @@ describe('SettingsDialog', () => {
|
|
|
296
294
|
vi.mocked(saveModifiedSettings).mockClear();
|
|
297
295
|
const settings = createMockSettings();
|
|
298
296
|
const onSelect = vi.fn();
|
|
299
|
-
const
|
|
300
|
-
const { stdin, unmount, lastFrame } = render(component);
|
|
297
|
+
const { stdin, unmount, lastFrame } = renderDialog(settings, onSelect);
|
|
301
298
|
// Wait for initial render and verify we're on Vim Mode (first setting)
|
|
302
|
-
await
|
|
303
|
-
expect(lastFrame()).toContain('
|
|
299
|
+
await waitFor(() => {
|
|
300
|
+
expect(lastFrame()).toContain('Vim Mode');
|
|
304
301
|
});
|
|
305
302
|
// Navigate to Disable Auto Update setting and verify we're there
|
|
306
303
|
act(() => {
|
|
307
304
|
stdin.write(TerminalKeys.DOWN_ARROW);
|
|
308
305
|
});
|
|
309
|
-
await
|
|
310
|
-
expect(lastFrame()).toContain('
|
|
306
|
+
await waitFor(() => {
|
|
307
|
+
expect(lastFrame()).toContain('Disable Auto Update');
|
|
311
308
|
});
|
|
312
309
|
// Toggle the setting
|
|
313
310
|
act(() => {
|
|
314
311
|
stdin.write(TerminalKeys.ENTER);
|
|
315
312
|
});
|
|
316
313
|
// Wait for the setting change to be processed
|
|
317
|
-
await
|
|
314
|
+
await waitFor(() => {
|
|
318
315
|
expect(vi.mocked(saveModifiedSettings).mock.calls.length).toBeGreaterThan(0);
|
|
319
316
|
});
|
|
320
317
|
// Wait for the mock to be called
|
|
321
|
-
await
|
|
318
|
+
await waitFor(() => {
|
|
322
319
|
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
|
|
323
320
|
});
|
|
324
321
|
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(new Set(['general.disableAutoUpdate']), expect.objectContaining({
|
|
@@ -329,47 +326,36 @@ describe('SettingsDialog', () => {
|
|
|
329
326
|
unmount();
|
|
330
327
|
});
|
|
331
328
|
describe('enum values', () => {
|
|
332
|
-
it(
|
|
329
|
+
it.each([
|
|
330
|
+
{
|
|
331
|
+
name: 'toggles to next value',
|
|
332
|
+
initialValue: undefined,
|
|
333
|
+
expectedValue: StringEnum.BAZ,
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
name: 'loops back to first value when at end',
|
|
337
|
+
initialValue: StringEnum.BAZ,
|
|
338
|
+
expectedValue: StringEnum.FOO,
|
|
339
|
+
},
|
|
340
|
+
])('$name', async ({ initialValue, expectedValue }) => {
|
|
333
341
|
vi.mocked(saveModifiedSettings).mockClear();
|
|
334
342
|
vi.mocked(getSettingsSchema).mockReturnValue(ENUM_FAKE_SCHEMA);
|
|
335
343
|
const settings = createMockSettings();
|
|
344
|
+
if (initialValue !== undefined) {
|
|
345
|
+
settings.setValue(SettingScope.User, 'ui.theme', initialValue);
|
|
346
|
+
}
|
|
336
347
|
const onSelect = vi.fn();
|
|
337
|
-
const
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
await wait();
|
|
342
|
-
stdin.write(TerminalKeys.ENTER);
|
|
343
|
-
await wait();
|
|
344
|
-
await vi.waitFor(() => {
|
|
345
|
-
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
|
|
348
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
349
|
+
act(() => {
|
|
350
|
+
stdin.write(TerminalKeys.DOWN_ARROW);
|
|
351
|
+
stdin.write(TerminalKeys.ENTER);
|
|
346
352
|
});
|
|
347
|
-
|
|
348
|
-
ui: expect.objectContaining({
|
|
349
|
-
theme: StringEnum.BAZ,
|
|
350
|
-
}),
|
|
351
|
-
}), expect.any(LoadedSettings), SettingScope.User);
|
|
352
|
-
unmount();
|
|
353
|
-
});
|
|
354
|
-
it('loops back when reaching the end of an enum', async () => {
|
|
355
|
-
vi.mocked(saveModifiedSettings).mockClear();
|
|
356
|
-
vi.mocked(getSettingsSchema).mockReturnValue(ENUM_FAKE_SCHEMA);
|
|
357
|
-
const settings = createMockSettings();
|
|
358
|
-
settings.setValue(SettingScope.User, 'ui.theme', StringEnum.BAZ);
|
|
359
|
-
const onSelect = vi.fn();
|
|
360
|
-
const component = (_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
361
|
-
const { stdin, unmount } = render(component);
|
|
362
|
-
// Press Enter to toggle current setting
|
|
363
|
-
stdin.write(TerminalKeys.DOWN_ARROW);
|
|
364
|
-
await wait();
|
|
365
|
-
stdin.write(TerminalKeys.ENTER);
|
|
366
|
-
await wait();
|
|
367
|
-
await vi.waitFor(() => {
|
|
353
|
+
await waitFor(() => {
|
|
368
354
|
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalled();
|
|
369
355
|
});
|
|
370
356
|
expect(vi.mocked(saveModifiedSettings)).toHaveBeenCalledWith(new Set(['ui.theme']), expect.objectContaining({
|
|
371
357
|
ui: expect.objectContaining({
|
|
372
|
-
theme:
|
|
358
|
+
theme: expectedValue,
|
|
373
359
|
}),
|
|
374
360
|
}), expect.any(LoadedSettings), SettingScope.User);
|
|
375
361
|
unmount();
|
|
@@ -378,20 +364,22 @@ describe('SettingsDialog', () => {
|
|
|
378
364
|
it('should toggle setting with Space key', async () => {
|
|
379
365
|
const settings = createMockSettings();
|
|
380
366
|
const onSelect = vi.fn();
|
|
381
|
-
const { stdin, unmount } =
|
|
367
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
382
368
|
// Press Space to toggle current setting
|
|
383
|
-
|
|
384
|
-
|
|
369
|
+
act(() => {
|
|
370
|
+
stdin.write(' '); // Space key
|
|
371
|
+
});
|
|
385
372
|
unmount();
|
|
386
373
|
});
|
|
387
374
|
it('should handle vim mode setting specially', async () => {
|
|
388
375
|
const settings = createMockSettings();
|
|
389
376
|
const onSelect = vi.fn();
|
|
390
|
-
const { stdin, unmount } =
|
|
377
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
391
378
|
// Navigate to vim mode setting and toggle it
|
|
392
379
|
// This would require knowing the exact position, so we'll just test that the mock is called
|
|
393
|
-
|
|
394
|
-
|
|
380
|
+
act(() => {
|
|
381
|
+
stdin.write(TerminalKeys.ENTER); // Enter key
|
|
382
|
+
});
|
|
395
383
|
// The mock should potentially be called if vim mode was toggled
|
|
396
384
|
unmount();
|
|
397
385
|
});
|
|
@@ -400,26 +388,26 @@ describe('SettingsDialog', () => {
|
|
|
400
388
|
it('should switch between scopes', async () => {
|
|
401
389
|
const settings = createMockSettings();
|
|
402
390
|
const onSelect = vi.fn();
|
|
403
|
-
const { stdin, unmount } =
|
|
391
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
404
392
|
// Switch to scope focus
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
393
|
+
act(() => {
|
|
394
|
+
stdin.write(TerminalKeys.TAB); // Tab key
|
|
395
|
+
// Select different scope (numbers 1-3 typically available)
|
|
396
|
+
stdin.write('2'); // Select second scope option
|
|
397
|
+
});
|
|
410
398
|
unmount();
|
|
411
399
|
});
|
|
412
400
|
it('should reset to settings focus when scope is selected', async () => {
|
|
413
401
|
const settings = createMockSettings();
|
|
414
402
|
const onSelect = vi.fn();
|
|
415
|
-
const { lastFrame, unmount } =
|
|
403
|
+
const { lastFrame, unmount } = renderDialog(settings, onSelect);
|
|
416
404
|
// Wait for initial render
|
|
417
|
-
await
|
|
405
|
+
await waitFor(() => {
|
|
418
406
|
expect(lastFrame()).toContain('Vim Mode');
|
|
419
407
|
});
|
|
420
408
|
// The UI should show the settings section is active and scope section is inactive
|
|
421
|
-
expect(lastFrame()).toContain('
|
|
422
|
-
expect(lastFrame()).toContain('
|
|
409
|
+
expect(lastFrame()).toContain('Vim Mode'); // Settings section active
|
|
410
|
+
expect(lastFrame()).toContain('Apply To'); // Scope section (don't rely on exact spacing)
|
|
423
411
|
// This test validates the initial state - scope selection behavior
|
|
424
412
|
// is complex due to keypress handling, so we focus on state validation
|
|
425
413
|
unmount();
|
|
@@ -429,19 +417,23 @@ describe('SettingsDialog', () => {
|
|
|
429
417
|
it('should show restart prompt for restart-required settings', async () => {
|
|
430
418
|
const settings = createMockSettings();
|
|
431
419
|
const onRestartRequest = vi.fn();
|
|
432
|
-
const { unmount } =
|
|
420
|
+
const { unmount } = renderDialog(settings, vi.fn(), {
|
|
421
|
+
onRestartRequest,
|
|
422
|
+
});
|
|
433
423
|
// This test would need to trigger a restart-required setting change
|
|
434
424
|
// The exact steps depend on which settings require restart
|
|
435
|
-
await wait();
|
|
436
425
|
unmount();
|
|
437
426
|
});
|
|
438
427
|
it('should handle restart request when r is pressed', async () => {
|
|
439
428
|
const settings = createMockSettings();
|
|
440
429
|
const onRestartRequest = vi.fn();
|
|
441
|
-
const { stdin, unmount } =
|
|
430
|
+
const { stdin, unmount } = renderDialog(settings, vi.fn(), {
|
|
431
|
+
onRestartRequest,
|
|
432
|
+
});
|
|
442
433
|
// Press 'r' key (this would only work if restart prompt is showing)
|
|
443
|
-
|
|
444
|
-
|
|
434
|
+
act(() => {
|
|
435
|
+
stdin.write('r');
|
|
436
|
+
});
|
|
445
437
|
// If restart prompt was showing, onRestartRequest should be called
|
|
446
438
|
unmount();
|
|
447
439
|
});
|
|
@@ -450,9 +442,9 @@ describe('SettingsDialog', () => {
|
|
|
450
442
|
it('should call onSelect with undefined when Escape is pressed', async () => {
|
|
451
443
|
const settings = createMockSettings();
|
|
452
444
|
const onSelect = vi.fn();
|
|
453
|
-
const { lastFrame, unmount } =
|
|
445
|
+
const { lastFrame, unmount } = renderDialog(settings, onSelect);
|
|
454
446
|
// Wait for initial render
|
|
455
|
-
await
|
|
447
|
+
await waitFor(() => {
|
|
456
448
|
expect(lastFrame()).toContain('Hide Window Title');
|
|
457
449
|
});
|
|
458
450
|
// Verify the dialog is rendered properly
|
|
@@ -467,13 +459,12 @@ describe('SettingsDialog', () => {
|
|
|
467
459
|
it('should persist settings across scope changes', async () => {
|
|
468
460
|
const settings = createMockSettings({ vimMode: true });
|
|
469
461
|
const onSelect = vi.fn();
|
|
470
|
-
const { stdin, unmount } =
|
|
471
|
-
// Switch to scope selector
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
await wait();
|
|
462
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
463
|
+
// Switch to scope selector and change scope
|
|
464
|
+
act(() => {
|
|
465
|
+
stdin.write(TerminalKeys.TAB); // Tab
|
|
466
|
+
stdin.write('2'); // Select workspace scope
|
|
467
|
+
});
|
|
477
468
|
// Settings should be reloaded for new scope
|
|
478
469
|
unmount();
|
|
479
470
|
});
|
|
@@ -482,7 +473,7 @@ describe('SettingsDialog', () => {
|
|
|
482
473
|
{ vimMode: false }, // System settings
|
|
483
474
|
{ autoUpdate: false });
|
|
484
475
|
const onSelect = vi.fn();
|
|
485
|
-
const { lastFrame } =
|
|
476
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
486
477
|
// Should show user scope values initially
|
|
487
478
|
const output = lastFrame();
|
|
488
479
|
expect(output).toContain('Settings');
|
|
@@ -493,10 +484,11 @@ describe('SettingsDialog', () => {
|
|
|
493
484
|
mockToggleVimEnabled.mockRejectedValue(new Error('Toggle failed'));
|
|
494
485
|
const settings = createMockSettings();
|
|
495
486
|
const onSelect = vi.fn();
|
|
496
|
-
const { stdin, unmount } =
|
|
487
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
497
488
|
// Try to toggle a setting (this might trigger vim mode toggle)
|
|
498
|
-
|
|
499
|
-
|
|
489
|
+
act(() => {
|
|
490
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
491
|
+
});
|
|
500
492
|
// Should not crash
|
|
501
493
|
unmount();
|
|
502
494
|
});
|
|
@@ -505,27 +497,26 @@ describe('SettingsDialog', () => {
|
|
|
505
497
|
it('should track modified settings correctly', async () => {
|
|
506
498
|
const settings = createMockSettings();
|
|
507
499
|
const onSelect = vi.fn();
|
|
508
|
-
const { stdin, unmount } =
|
|
509
|
-
// Toggle a setting
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
stdin.write(TerminalKeys.ENTER); // Enter
|
|
516
|
-
await wait();
|
|
500
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
501
|
+
// Toggle a setting, then toggle another setting
|
|
502
|
+
act(() => {
|
|
503
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
504
|
+
stdin.write(TerminalKeys.DOWN_ARROW); // Down
|
|
505
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
506
|
+
});
|
|
517
507
|
// Should track multiple modified settings
|
|
518
508
|
unmount();
|
|
519
509
|
});
|
|
520
510
|
it('should handle scrolling when there are many settings', async () => {
|
|
521
511
|
const settings = createMockSettings();
|
|
522
512
|
const onSelect = vi.fn();
|
|
523
|
-
const { stdin, unmount } =
|
|
513
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
524
514
|
// Navigate down many times to test scrolling
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
515
|
+
act(() => {
|
|
516
|
+
for (let i = 0; i < 10; i++) {
|
|
517
|
+
stdin.write(TerminalKeys.DOWN_ARROW); // Down arrow
|
|
518
|
+
}
|
|
519
|
+
});
|
|
529
520
|
unmount();
|
|
530
521
|
});
|
|
531
522
|
});
|
|
@@ -536,8 +527,9 @@ describe('SettingsDialog', () => {
|
|
|
536
527
|
const { stdin, unmount } = render(_jsx(VimModeProvider, { settings: settings, children: _jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }) }));
|
|
537
528
|
// Navigate to and toggle vim mode setting
|
|
538
529
|
// This would require knowing the exact position of vim mode setting
|
|
539
|
-
|
|
540
|
-
|
|
530
|
+
act(() => {
|
|
531
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
532
|
+
});
|
|
541
533
|
unmount();
|
|
542
534
|
});
|
|
543
535
|
});
|
|
@@ -547,7 +539,7 @@ describe('SettingsDialog', () => {
|
|
|
547
539
|
{ hideWindowTitle: true }, // System settings
|
|
548
540
|
{ ideMode: false });
|
|
549
541
|
const onSelect = vi.fn();
|
|
550
|
-
const { lastFrame } =
|
|
542
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
551
543
|
const output = lastFrame();
|
|
552
544
|
// Should contain settings labels
|
|
553
545
|
expect(output).toContain('Settings');
|
|
@@ -555,28 +547,30 @@ describe('SettingsDialog', () => {
|
|
|
555
547
|
it('should handle immediate settings save for non-restart-required settings', async () => {
|
|
556
548
|
const settings = createMockSettings();
|
|
557
549
|
const onSelect = vi.fn();
|
|
558
|
-
const { stdin, unmount } =
|
|
550
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
559
551
|
// Toggle a non-restart-required setting (like hideTips)
|
|
560
|
-
|
|
561
|
-
|
|
552
|
+
act(() => {
|
|
553
|
+
stdin.write(TerminalKeys.ENTER); // Enter - toggle current setting
|
|
554
|
+
});
|
|
562
555
|
// Should save immediately without showing restart prompt
|
|
563
556
|
unmount();
|
|
564
557
|
});
|
|
565
558
|
it('should show restart prompt for restart-required settings', async () => {
|
|
566
559
|
const settings = createMockSettings();
|
|
567
560
|
const onSelect = vi.fn();
|
|
568
|
-
const { lastFrame, unmount } =
|
|
561
|
+
const { lastFrame, unmount } = renderDialog(settings, onSelect);
|
|
569
562
|
// This test would need to navigate to a specific restart-required setting
|
|
570
563
|
// Since we can't easily target specific settings, we test the general behavior
|
|
571
|
-
await wait();
|
|
572
564
|
// Should not show restart prompt initially
|
|
573
|
-
|
|
565
|
+
await waitFor(() => {
|
|
566
|
+
expect(lastFrame()).not.toContain('To see changes, Gemini CLI must be restarted');
|
|
567
|
+
});
|
|
574
568
|
unmount();
|
|
575
569
|
});
|
|
576
570
|
it('should clear restart prompt when switching scopes', async () => {
|
|
577
571
|
const settings = createMockSettings();
|
|
578
572
|
const onSelect = vi.fn();
|
|
579
|
-
const { unmount } =
|
|
573
|
+
const { unmount } = renderDialog(settings, onSelect);
|
|
580
574
|
// Restart prompt should be cleared when switching scopes
|
|
581
575
|
unmount();
|
|
582
576
|
});
|
|
@@ -586,7 +580,7 @@ describe('SettingsDialog', () => {
|
|
|
586
580
|
const settings = createMockSettings({}, { vimMode: true, hideWindowTitle: false }, // System settings
|
|
587
581
|
{});
|
|
588
582
|
const onSelect = vi.fn();
|
|
589
|
-
const { lastFrame } =
|
|
583
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
590
584
|
const output = lastFrame();
|
|
591
585
|
// Settings should show inherited values
|
|
592
586
|
expect(output).toContain('Settings');
|
|
@@ -596,89 +590,69 @@ describe('SettingsDialog', () => {
|
|
|
596
590
|
{ vimMode: true }, // System default
|
|
597
591
|
{});
|
|
598
592
|
const onSelect = vi.fn();
|
|
599
|
-
const { lastFrame } =
|
|
593
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
600
594
|
const output = lastFrame();
|
|
601
595
|
// Should show settings with override indicators
|
|
602
596
|
expect(output).toContain('Settings');
|
|
603
597
|
});
|
|
604
598
|
});
|
|
605
599
|
describe('Race Condition Regression Tests', () => {
|
|
606
|
-
it(
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
enableInteractiveShell: true,
|
|
614
|
-
},
|
|
600
|
+
it.each([
|
|
601
|
+
{
|
|
602
|
+
name: 'not reset sibling settings when toggling a nested setting multiple times',
|
|
603
|
+
toggleCount: 5,
|
|
604
|
+
shellSettings: {
|
|
605
|
+
showColor: false,
|
|
606
|
+
enableInteractiveShell: true,
|
|
615
607
|
},
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
const [modifiedKeys, pendingSettings] = call;
|
|
635
|
-
if (modifiedKeys.has('tools.shell.showColor')) {
|
|
636
|
-
expect(pendingSettings.tools?.shell?.enableInteractiveShell).toBe(true);
|
|
637
|
-
expect(modifiedKeys.has('tools.shell.enableInteractiveShell')).toBe(false);
|
|
638
|
-
}
|
|
639
|
-
});
|
|
640
|
-
expect(calls.length).toBeGreaterThan(0);
|
|
641
|
-
unmount();
|
|
642
|
-
});
|
|
643
|
-
it('should preserve multiple sibling settings in nested objects during rapid toggles', async () => {
|
|
608
|
+
expectedSiblings: {
|
|
609
|
+
enableInteractiveShell: true,
|
|
610
|
+
},
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
name: 'preserve multiple sibling settings in nested objects during rapid toggles',
|
|
614
|
+
toggleCount: 3,
|
|
615
|
+
shellSettings: {
|
|
616
|
+
showColor: false,
|
|
617
|
+
enableInteractiveShell: true,
|
|
618
|
+
pager: 'less',
|
|
619
|
+
},
|
|
620
|
+
expectedSiblings: {
|
|
621
|
+
enableInteractiveShell: true,
|
|
622
|
+
pager: 'less',
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
])('should $name', async ({ toggleCount, shellSettings, expectedSiblings }) => {
|
|
644
626
|
vi.mocked(saveModifiedSettings).mockClear();
|
|
645
627
|
vi.mocked(getSettingsSchema).mockReturnValue(TOOLS_SHELL_FAKE_SCHEMA);
|
|
646
628
|
const settings = createMockSettings({
|
|
647
629
|
tools: {
|
|
648
|
-
shell:
|
|
649
|
-
showColor: false,
|
|
650
|
-
enableInteractiveShell: true,
|
|
651
|
-
pager: 'less',
|
|
652
|
-
},
|
|
630
|
+
shell: shellSettings,
|
|
653
631
|
},
|
|
654
632
|
});
|
|
655
633
|
const onSelect = vi.fn();
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
await wait();
|
|
659
|
-
// Rapid toggles
|
|
660
|
-
for (let i = 0; i < 3; i++) {
|
|
634
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
635
|
+
for (let i = 0; i < toggleCount; i++) {
|
|
661
636
|
act(() => {
|
|
662
637
|
stdin.write(TerminalKeys.ENTER);
|
|
663
638
|
});
|
|
664
|
-
await wait(30);
|
|
665
639
|
}
|
|
666
|
-
await
|
|
640
|
+
await waitFor(() => {
|
|
667
641
|
expect(vi.mocked(saveModifiedSettings).mock.calls.length).toBeGreaterThan(0);
|
|
668
642
|
});
|
|
669
|
-
// Verify all siblings preserved
|
|
670
643
|
const calls = vi.mocked(saveModifiedSettings).mock.calls;
|
|
671
644
|
calls.forEach((call) => {
|
|
672
645
|
const [modifiedKeys, pendingSettings] = call;
|
|
673
646
|
if (modifiedKeys.has('tools.shell.showColor')) {
|
|
674
647
|
const shellSettings = pendingSettings.tools?.shell;
|
|
675
|
-
|
|
676
|
-
|
|
648
|
+
Object.entries(expectedSiblings).forEach(([key, value]) => {
|
|
649
|
+
expect(shellSettings?.[key]).toBe(value);
|
|
650
|
+
expect(modifiedKeys.has(`tools.shell.${key}`)).toBe(false);
|
|
651
|
+
});
|
|
677
652
|
expect(modifiedKeys.size).toBe(1);
|
|
678
|
-
expect(modifiedKeys.has('tools.shell.enableInteractiveShell')).toBe(false);
|
|
679
|
-
expect(modifiedKeys.has('tools.shell.pager')).toBe(false);
|
|
680
653
|
}
|
|
681
654
|
});
|
|
655
|
+
expect(calls.length).toBeGreaterThan(0);
|
|
682
656
|
unmount();
|
|
683
657
|
});
|
|
684
658
|
});
|
|
@@ -686,58 +660,52 @@ describe('SettingsDialog', () => {
|
|
|
686
660
|
it('should handle rapid key presses gracefully', async () => {
|
|
687
661
|
const settings = createMockSettings();
|
|
688
662
|
const onSelect = vi.fn();
|
|
689
|
-
const { stdin, unmount } =
|
|
663
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
690
664
|
// Rapid navigation
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
665
|
+
act(() => {
|
|
666
|
+
for (let i = 0; i < 5; i++) {
|
|
667
|
+
stdin.write(TerminalKeys.DOWN_ARROW);
|
|
668
|
+
stdin.write(TerminalKeys.UP_ARROW);
|
|
669
|
+
}
|
|
670
|
+
});
|
|
696
671
|
// Should not crash
|
|
697
672
|
unmount();
|
|
698
673
|
});
|
|
699
|
-
it(
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
stdin.write('\u0003'); // Ctrl+C
|
|
705
|
-
await wait();
|
|
706
|
-
// Should reset the current setting to its default value
|
|
707
|
-
unmount();
|
|
708
|
-
});
|
|
709
|
-
it('should handle Ctrl+L to reset current setting to default', async () => {
|
|
710
|
-
const settings = createMockSettings({ vimMode: true }); // Start with vimMode enabled
|
|
674
|
+
it.each([
|
|
675
|
+
{ key: 'Ctrl+C', code: '\u0003' },
|
|
676
|
+
{ key: 'Ctrl+L', code: '\u000C' },
|
|
677
|
+
])('should handle $key to reset current setting to default', async ({ code }) => {
|
|
678
|
+
const settings = createMockSettings({ vimMode: true });
|
|
711
679
|
const onSelect = vi.fn();
|
|
712
|
-
const { stdin, unmount } =
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
680
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
681
|
+
act(() => {
|
|
682
|
+
stdin.write(code);
|
|
683
|
+
});
|
|
716
684
|
// Should reset the current setting to its default value
|
|
717
685
|
unmount();
|
|
718
686
|
});
|
|
719
687
|
it('should handle navigation when only one setting exists', async () => {
|
|
720
688
|
const settings = createMockSettings();
|
|
721
689
|
const onSelect = vi.fn();
|
|
722
|
-
const { stdin, unmount } =
|
|
690
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
723
691
|
// Try to navigate when potentially at bounds
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
692
|
+
act(() => {
|
|
693
|
+
stdin.write(TerminalKeys.DOWN_ARROW);
|
|
694
|
+
stdin.write(TerminalKeys.UP_ARROW);
|
|
695
|
+
});
|
|
728
696
|
unmount();
|
|
729
697
|
});
|
|
730
698
|
it('should properly handle Tab navigation between sections', async () => {
|
|
731
699
|
const settings = createMockSettings();
|
|
732
700
|
const onSelect = vi.fn();
|
|
733
|
-
const { lastFrame, unmount } =
|
|
701
|
+
const { lastFrame, unmount } = renderDialog(settings, onSelect);
|
|
734
702
|
// Wait for initial render
|
|
735
|
-
await
|
|
703
|
+
await waitFor(() => {
|
|
736
704
|
expect(lastFrame()).toContain('Vim Mode');
|
|
737
705
|
});
|
|
738
706
|
// Verify initial state: settings section active, scope section inactive
|
|
739
|
-
expect(lastFrame()).toContain('
|
|
740
|
-
expect(lastFrame()).toContain('
|
|
707
|
+
expect(lastFrame()).toContain('Vim Mode'); // Settings section active
|
|
708
|
+
expect(lastFrame()).toContain('Apply To'); // Scope section (don't rely on exact spacing)
|
|
741
709
|
// This test validates the rendered UI structure for tab navigation
|
|
742
710
|
// Actual tab behavior testing is complex due to keypress handling
|
|
743
711
|
unmount();
|
|
@@ -749,7 +717,7 @@ describe('SettingsDialog', () => {
|
|
|
749
717
|
const settings = createMockSettings({ vimMode: null }, // Invalid value
|
|
750
718
|
{}, {});
|
|
751
719
|
const onSelect = vi.fn();
|
|
752
|
-
const { lastFrame } =
|
|
720
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
753
721
|
// Should still render without crashing
|
|
754
722
|
expect(lastFrame()).toContain('Settings');
|
|
755
723
|
});
|
|
@@ -757,7 +725,7 @@ describe('SettingsDialog', () => {
|
|
|
757
725
|
const settings = createMockSettings();
|
|
758
726
|
const onSelect = vi.fn();
|
|
759
727
|
// Should not crash even if some settings are missing definitions
|
|
760
|
-
const { lastFrame } =
|
|
728
|
+
const { lastFrame } = renderDialog(settings, onSelect);
|
|
761
729
|
expect(lastFrame()).toContain('Settings');
|
|
762
730
|
});
|
|
763
731
|
});
|
|
@@ -765,17 +733,18 @@ describe('SettingsDialog', () => {
|
|
|
765
733
|
it('should handle complete user workflow: navigate, toggle, change scope, exit', async () => {
|
|
766
734
|
const settings = createMockSettings();
|
|
767
735
|
const onSelect = vi.fn();
|
|
768
|
-
const { lastFrame, unmount } =
|
|
736
|
+
const { lastFrame, unmount } = renderDialog(settings, onSelect);
|
|
769
737
|
// Wait for initial render
|
|
770
|
-
await
|
|
738
|
+
await waitFor(() => {
|
|
771
739
|
expect(lastFrame()).toContain('Vim Mode');
|
|
772
740
|
});
|
|
773
741
|
// Verify the complete UI is rendered with all necessary sections
|
|
774
742
|
expect(lastFrame()).toContain('Settings'); // Title
|
|
775
|
-
expect(lastFrame()).toContain('
|
|
743
|
+
expect(lastFrame()).toContain('Vim Mode'); // Active setting
|
|
776
744
|
expect(lastFrame()).toContain('Apply To'); // Scope section
|
|
777
745
|
expect(lastFrame()).toContain('User Settings'); // Scope options (no numbers when settings focused)
|
|
778
|
-
|
|
746
|
+
// Use regex for more flexible help text matching
|
|
747
|
+
expect(lastFrame()).toMatch(/Enter.*select.*Tab.*focus.*Esc.*close/);
|
|
779
748
|
// This test validates the complete UI structure is available for user workflow
|
|
780
749
|
// Individual interactions are tested in focused unit tests
|
|
781
750
|
unmount();
|
|
@@ -783,20 +752,15 @@ describe('SettingsDialog', () => {
|
|
|
783
752
|
it('should allow changing multiple settings without losing pending changes', async () => {
|
|
784
753
|
const settings = createMockSettings();
|
|
785
754
|
const onSelect = vi.fn();
|
|
786
|
-
const { stdin, unmount } =
|
|
787
|
-
// Toggle
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
// Navigate to another setting and toggle it (should also require restart)
|
|
796
|
-
stdin.write(TerminalKeys.DOWN_ARROW); // Down
|
|
797
|
-
await wait();
|
|
798
|
-
stdin.write(TerminalKeys.ENTER); // Enter
|
|
799
|
-
await wait();
|
|
755
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
756
|
+
// Toggle multiple settings
|
|
757
|
+
act(() => {
|
|
758
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
759
|
+
stdin.write(TerminalKeys.DOWN_ARROW); // Down
|
|
760
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
761
|
+
stdin.write(TerminalKeys.DOWN_ARROW); // Down
|
|
762
|
+
stdin.write(TerminalKeys.ENTER); // Enter
|
|
763
|
+
});
|
|
800
764
|
// The test verifies that all changes are preserved and the dialog still works
|
|
801
765
|
// This tests the fix for the bug where changing one setting would reset all pending changes
|
|
802
766
|
unmount();
|
|
@@ -804,28 +768,28 @@ describe('SettingsDialog', () => {
|
|
|
804
768
|
it('should maintain state consistency during complex interactions', async () => {
|
|
805
769
|
const settings = createMockSettings({ vimMode: true });
|
|
806
770
|
const onSelect = vi.fn();
|
|
807
|
-
const { stdin, unmount } =
|
|
771
|
+
const { stdin, unmount } = renderDialog(settings, onSelect);
|
|
808
772
|
// Multiple scope changes
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
await wait();
|
|
817
|
-
stdin.write('1'); // User
|
|
818
|
-
await wait();
|
|
773
|
+
act(() => {
|
|
774
|
+
stdin.write(TerminalKeys.TAB); // Tab to scope
|
|
775
|
+
stdin.write('2'); // Workspace
|
|
776
|
+
stdin.write(TerminalKeys.TAB); // Tab to settings
|
|
777
|
+
stdin.write(TerminalKeys.TAB); // Tab to scope
|
|
778
|
+
stdin.write('1'); // User
|
|
779
|
+
});
|
|
819
780
|
// Should maintain consistent state
|
|
820
781
|
unmount();
|
|
821
782
|
});
|
|
822
783
|
it('should handle restart workflow correctly', async () => {
|
|
823
784
|
const settings = createMockSettings();
|
|
824
785
|
const onRestartRequest = vi.fn();
|
|
825
|
-
const { stdin, unmount } =
|
|
786
|
+
const { stdin, unmount } = renderDialog(settings, vi.fn(), {
|
|
787
|
+
onRestartRequest,
|
|
788
|
+
});
|
|
826
789
|
// This would test the restart workflow if we could trigger it
|
|
827
|
-
|
|
828
|
-
|
|
790
|
+
act(() => {
|
|
791
|
+
stdin.write('r'); // Try restart key
|
|
792
|
+
});
|
|
829
793
|
// Without restart prompt showing, this should have no effect
|
|
830
794
|
expect(onRestartRequest).not.toHaveBeenCalled();
|
|
831
795
|
unmount();
|
|
@@ -836,282 +800,244 @@ describe('SettingsDialog', () => {
|
|
|
836
800
|
let settings = createMockSettings({ 'a.string.setting': 'initial' });
|
|
837
801
|
const onSelect = vi.fn();
|
|
838
802
|
const { stdin, unmount, rerender } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
839
|
-
// Wait for the dialog to render
|
|
840
|
-
await wait();
|
|
841
803
|
// Navigate to the last setting
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
stdin.write('\r');
|
|
854
|
-
await wait();
|
|
804
|
+
act(() => {
|
|
805
|
+
for (let i = 0; i < 20; i++) {
|
|
806
|
+
stdin.write('j'); // Down
|
|
807
|
+
}
|
|
808
|
+
});
|
|
809
|
+
// Press Enter to start editing, type new value, and commit
|
|
810
|
+
act(() => {
|
|
811
|
+
stdin.write('\r'); // Start editing
|
|
812
|
+
stdin.write('new value');
|
|
813
|
+
stdin.write('\r'); // Commit
|
|
814
|
+
});
|
|
855
815
|
settings = createMockSettings({ 'a.string.setting': 'new value' }, {}, {});
|
|
856
816
|
rerender(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
857
|
-
await wait();
|
|
858
817
|
// Press Escape to exit
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
818
|
+
act(() => {
|
|
819
|
+
stdin.write('\u001B');
|
|
820
|
+
});
|
|
821
|
+
await waitFor(() => {
|
|
822
|
+
expect(onSelect).toHaveBeenCalledWith(undefined, 'User');
|
|
823
|
+
});
|
|
862
824
|
unmount();
|
|
863
825
|
});
|
|
864
826
|
});
|
|
865
827
|
describe('Snapshot Tests', () => {
|
|
866
828
|
/**
|
|
867
829
|
* Snapshot tests for SettingsDialog component using ink-testing-library.
|
|
868
|
-
* These tests capture the visual output of the component in various states
|
|
869
|
-
*
|
|
870
|
-
* - Default rendering with no custom settings
|
|
871
|
-
* - Various combinations of boolean settings (enabled/disabled)
|
|
872
|
-
* - Mixed boolean and number settings configurations
|
|
873
|
-
* - Different focus states (settings vs scope selector)
|
|
874
|
-
* - Different scope selections (User, System, Workspace)
|
|
875
|
-
* - Accessibility settings enabled
|
|
876
|
-
* - File filtering configurations
|
|
877
|
-
* - Tools and security settings
|
|
878
|
-
* - All settings disabled state
|
|
879
|
-
*
|
|
830
|
+
* These tests capture the visual output of the component in various states.
|
|
880
831
|
* The snapshots help ensure UI consistency and catch unintended visual changes.
|
|
881
832
|
*/
|
|
882
|
-
it(
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
hideTips: true,
|
|
899
|
-
showMemoryUsage: true,
|
|
900
|
-
showLineNumbers: true,
|
|
901
|
-
showCitations: true,
|
|
902
|
-
accessibility: {
|
|
903
|
-
disableLoadingPhrases: true,
|
|
904
|
-
screenReader: true,
|
|
833
|
+
it.each([
|
|
834
|
+
{
|
|
835
|
+
name: 'default state',
|
|
836
|
+
userSettings: {},
|
|
837
|
+
systemSettings: {},
|
|
838
|
+
workspaceSettings: {},
|
|
839
|
+
stdinActions: undefined,
|
|
840
|
+
},
|
|
841
|
+
{
|
|
842
|
+
name: 'various boolean settings enabled',
|
|
843
|
+
userSettings: {
|
|
844
|
+
general: {
|
|
845
|
+
vimMode: true,
|
|
846
|
+
disableAutoUpdate: true,
|
|
847
|
+
debugKeystrokeLogging: true,
|
|
848
|
+
enablePromptCompletion: true,
|
|
905
849
|
},
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
disableFuzzySearch: false,
|
|
850
|
+
ui: {
|
|
851
|
+
hideWindowTitle: true,
|
|
852
|
+
hideTips: true,
|
|
853
|
+
showMemoryUsage: true,
|
|
854
|
+
showLineNumbers: true,
|
|
855
|
+
showCitations: true,
|
|
856
|
+
accessibility: {
|
|
857
|
+
disableLoadingPhrases: true,
|
|
858
|
+
screenReader: true,
|
|
859
|
+
},
|
|
917
860
|
},
|
|
918
|
-
|
|
919
|
-
tools: {
|
|
920
|
-
enableInteractiveShell: true,
|
|
921
|
-
autoAccept: true,
|
|
922
|
-
useRipgrep: true,
|
|
923
|
-
},
|
|
924
|
-
security: {
|
|
925
|
-
folderTrust: {
|
|
861
|
+
ide: {
|
|
926
862
|
enabled: true,
|
|
927
863
|
},
|
|
864
|
+
context: {
|
|
865
|
+
loadMemoryFromIncludeDirectories: true,
|
|
866
|
+
fileFiltering: {
|
|
867
|
+
respectGitIgnore: true,
|
|
868
|
+
respectGeminiIgnore: true,
|
|
869
|
+
enableRecursiveFileSearch: true,
|
|
870
|
+
disableFuzzySearch: false,
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
tools: {
|
|
874
|
+
enableInteractiveShell: true,
|
|
875
|
+
autoAccept: true,
|
|
876
|
+
useRipgrep: true,
|
|
877
|
+
},
|
|
878
|
+
security: {
|
|
879
|
+
folderTrust: {
|
|
880
|
+
enabled: true,
|
|
881
|
+
},
|
|
882
|
+
},
|
|
928
883
|
},
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
});
|
|
934
|
-
it('should render with mixed boolean and number settings', () => {
|
|
935
|
-
const settings = createMockSettings({
|
|
936
|
-
general: {
|
|
937
|
-
vimMode: false,
|
|
938
|
-
disableAutoUpdate: true,
|
|
939
|
-
},
|
|
940
|
-
ui: {
|
|
941
|
-
showMemoryUsage: true,
|
|
942
|
-
hideWindowTitle: false,
|
|
943
|
-
},
|
|
944
|
-
tools: {
|
|
945
|
-
truncateToolOutputThreshold: 50000,
|
|
946
|
-
truncateToolOutputLines: 1000,
|
|
947
|
-
},
|
|
948
|
-
context: {
|
|
949
|
-
discoveryMaxDirs: 500,
|
|
950
|
-
},
|
|
951
|
-
model: {
|
|
952
|
-
maxSessionTurns: 100,
|
|
953
|
-
skipNextSpeakerCheck: false,
|
|
954
|
-
},
|
|
955
|
-
});
|
|
956
|
-
const onSelect = vi.fn();
|
|
957
|
-
const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
958
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
959
|
-
});
|
|
960
|
-
it('should render focused on scope selector', () => {
|
|
961
|
-
const settings = createMockSettings();
|
|
962
|
-
const onSelect = vi.fn();
|
|
963
|
-
const { lastFrame, stdin } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
964
|
-
// Switch focus to scope selector with Tab
|
|
965
|
-
stdin.write('\t');
|
|
966
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
967
|
-
});
|
|
968
|
-
it('should render with different scope selected (System)', () => {
|
|
969
|
-
const settings = createMockSettings({}, // userSettings
|
|
884
|
+
systemSettings: {},
|
|
885
|
+
workspaceSettings: {},
|
|
886
|
+
stdinActions: undefined,
|
|
887
|
+
},
|
|
970
888
|
{
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
889
|
+
name: 'mixed boolean and number settings',
|
|
890
|
+
userSettings: {
|
|
891
|
+
general: {
|
|
892
|
+
vimMode: false,
|
|
893
|
+
disableAutoUpdate: true,
|
|
894
|
+
},
|
|
895
|
+
ui: {
|
|
896
|
+
showMemoryUsage: true,
|
|
897
|
+
hideWindowTitle: false,
|
|
898
|
+
},
|
|
899
|
+
tools: {
|
|
900
|
+
truncateToolOutputThreshold: 50000,
|
|
901
|
+
truncateToolOutputLines: 1000,
|
|
902
|
+
},
|
|
903
|
+
context: {
|
|
904
|
+
discoveryMaxDirs: 500,
|
|
905
|
+
},
|
|
906
|
+
model: {
|
|
907
|
+
maxSessionTurns: 100,
|
|
908
|
+
skipNextSpeakerCheck: false,
|
|
909
|
+
},
|
|
978
910
|
},
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
stdin.write('\t');
|
|
984
|
-
// Navigate to System scope
|
|
985
|
-
stdin.write('ArrowDown');
|
|
986
|
-
stdin.write('\r'); // Enter to select
|
|
987
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
988
|
-
});
|
|
989
|
-
it('should render with different scope selected (Workspace)', () => {
|
|
990
|
-
const settings = createMockSettings({}, // userSettings
|
|
991
|
-
{}, // systemSettings
|
|
911
|
+
systemSettings: {},
|
|
912
|
+
workspaceSettings: {},
|
|
913
|
+
stdinActions: undefined,
|
|
914
|
+
},
|
|
992
915
|
{
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
916
|
+
name: 'focused on scope selector',
|
|
917
|
+
userSettings: {},
|
|
918
|
+
systemSettings: {},
|
|
919
|
+
workspaceSettings: {},
|
|
920
|
+
stdinActions: (stdin) => {
|
|
921
|
+
act(() => {
|
|
922
|
+
stdin.write('\t');
|
|
923
|
+
});
|
|
997
924
|
},
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
stdin.write('ArrowDown');
|
|
1010
|
-
stdin.write('\r'); // Enter to select
|
|
1011
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
1012
|
-
});
|
|
1013
|
-
it('should render with accessibility settings enabled', () => {
|
|
1014
|
-
const settings = createMockSettings({
|
|
1015
|
-
ui: {
|
|
1016
|
-
accessibility: {
|
|
1017
|
-
disableLoadingPhrases: true,
|
|
1018
|
-
screenReader: true,
|
|
925
|
+
},
|
|
926
|
+
{
|
|
927
|
+
name: 'accessibility settings enabled',
|
|
928
|
+
userSettings: {
|
|
929
|
+
ui: {
|
|
930
|
+
accessibility: {
|
|
931
|
+
disableLoadingPhrases: true,
|
|
932
|
+
screenReader: true,
|
|
933
|
+
},
|
|
934
|
+
showMemoryUsage: true,
|
|
935
|
+
showLineNumbers: true,
|
|
1019
936
|
},
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
},
|
|
1023
|
-
general: {
|
|
1024
|
-
vimMode: true,
|
|
1025
|
-
},
|
|
1026
|
-
});
|
|
1027
|
-
const onSelect = vi.fn();
|
|
1028
|
-
const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
1029
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
1030
|
-
});
|
|
1031
|
-
it('should render with file filtering settings configured', () => {
|
|
1032
|
-
const settings = createMockSettings({
|
|
1033
|
-
context: {
|
|
1034
|
-
fileFiltering: {
|
|
1035
|
-
respectGitIgnore: false,
|
|
1036
|
-
respectGeminiIgnore: true,
|
|
1037
|
-
enableRecursiveFileSearch: false,
|
|
1038
|
-
disableFuzzySearch: true,
|
|
937
|
+
general: {
|
|
938
|
+
vimMode: true,
|
|
1039
939
|
},
|
|
1040
|
-
loadMemoryFromIncludeDirectories: true,
|
|
1041
|
-
discoveryMaxDirs: 100,
|
|
1042
|
-
},
|
|
1043
|
-
});
|
|
1044
|
-
const onSelect = vi.fn();
|
|
1045
|
-
const { lastFrame } = render(_jsx(KeypressProvider, { kittyProtocolEnabled: false, children: _jsx(SettingsDialog, { settings: settings, onSelect: onSelect }) }));
|
|
1046
|
-
expect(lastFrame()).toMatchSnapshot();
|
|
1047
|
-
});
|
|
1048
|
-
it('should render with tools and security settings', () => {
|
|
1049
|
-
const settings = createMockSettings({
|
|
1050
|
-
tools: {
|
|
1051
|
-
enableInteractiveShell: true,
|
|
1052
|
-
autoAccept: false,
|
|
1053
|
-
useRipgrep: true,
|
|
1054
|
-
truncateToolOutputThreshold: 25000,
|
|
1055
|
-
truncateToolOutputLines: 500,
|
|
1056
940
|
},
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
941
|
+
systemSettings: {},
|
|
942
|
+
workspaceSettings: {},
|
|
943
|
+
stdinActions: undefined,
|
|
944
|
+
},
|
|
945
|
+
{
|
|
946
|
+
name: 'file filtering settings configured',
|
|
947
|
+
userSettings: {
|
|
948
|
+
context: {
|
|
949
|
+
fileFiltering: {
|
|
950
|
+
respectGitIgnore: false,
|
|
951
|
+
respectGeminiIgnore: true,
|
|
952
|
+
enableRecursiveFileSearch: false,
|
|
953
|
+
disableFuzzySearch: true,
|
|
954
|
+
},
|
|
955
|
+
loadMemoryFromIncludeDirectories: true,
|
|
956
|
+
discoveryMaxDirs: 100,
|
|
1060
957
|
},
|
|
1061
958
|
},
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
disableAutoUpdate: false,
|
|
1076
|
-
debugKeystrokeLogging: false,
|
|
1077
|
-
enablePromptCompletion: false,
|
|
1078
|
-
},
|
|
1079
|
-
ui: {
|
|
1080
|
-
hideWindowTitle: false,
|
|
1081
|
-
hideTips: false,
|
|
1082
|
-
showMemoryUsage: false,
|
|
1083
|
-
showLineNumbers: false,
|
|
1084
|
-
showCitations: false,
|
|
1085
|
-
accessibility: {
|
|
1086
|
-
disableLoadingPhrases: false,
|
|
1087
|
-
screenReader: false,
|
|
959
|
+
systemSettings: {},
|
|
960
|
+
workspaceSettings: {},
|
|
961
|
+
stdinActions: undefined,
|
|
962
|
+
},
|
|
963
|
+
{
|
|
964
|
+
name: 'tools and security settings',
|
|
965
|
+
userSettings: {
|
|
966
|
+
tools: {
|
|
967
|
+
enableInteractiveShell: true,
|
|
968
|
+
autoAccept: false,
|
|
969
|
+
useRipgrep: true,
|
|
970
|
+
truncateToolOutputThreshold: 25000,
|
|
971
|
+
truncateToolOutputLines: 500,
|
|
1088
972
|
},
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
respectGeminiIgnore: false,
|
|
1098
|
-
enableRecursiveFileSearch: false,
|
|
1099
|
-
disableFuzzySearch: false,
|
|
973
|
+
security: {
|
|
974
|
+
folderTrust: {
|
|
975
|
+
enabled: true,
|
|
976
|
+
},
|
|
977
|
+
},
|
|
978
|
+
model: {
|
|
979
|
+
maxSessionTurns: 50,
|
|
980
|
+
skipNextSpeakerCheck: true,
|
|
1100
981
|
},
|
|
1101
982
|
},
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
983
|
+
systemSettings: {},
|
|
984
|
+
workspaceSettings: {},
|
|
985
|
+
stdinActions: undefined,
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
name: 'all boolean settings disabled',
|
|
989
|
+
userSettings: {
|
|
990
|
+
general: {
|
|
991
|
+
vimMode: false,
|
|
992
|
+
disableAutoUpdate: false,
|
|
993
|
+
debugKeystrokeLogging: false,
|
|
994
|
+
enablePromptCompletion: false,
|
|
995
|
+
},
|
|
996
|
+
ui: {
|
|
997
|
+
hideWindowTitle: false,
|
|
998
|
+
hideTips: false,
|
|
999
|
+
showMemoryUsage: false,
|
|
1000
|
+
showLineNumbers: false,
|
|
1001
|
+
showCitations: false,
|
|
1002
|
+
accessibility: {
|
|
1003
|
+
disableLoadingPhrases: false,
|
|
1004
|
+
screenReader: false,
|
|
1005
|
+
},
|
|
1006
|
+
},
|
|
1007
|
+
ide: {
|
|
1109
1008
|
enabled: false,
|
|
1110
1009
|
},
|
|
1010
|
+
context: {
|
|
1011
|
+
loadMemoryFromIncludeDirectories: false,
|
|
1012
|
+
fileFiltering: {
|
|
1013
|
+
respectGitIgnore: false,
|
|
1014
|
+
respectGeminiIgnore: false,
|
|
1015
|
+
enableRecursiveFileSearch: false,
|
|
1016
|
+
disableFuzzySearch: false,
|
|
1017
|
+
},
|
|
1018
|
+
},
|
|
1019
|
+
tools: {
|
|
1020
|
+
enableInteractiveShell: false,
|
|
1021
|
+
autoAccept: false,
|
|
1022
|
+
useRipgrep: false,
|
|
1023
|
+
},
|
|
1024
|
+
security: {
|
|
1025
|
+
folderTrust: {
|
|
1026
|
+
enabled: false,
|
|
1027
|
+
},
|
|
1028
|
+
},
|
|
1111
1029
|
},
|
|
1112
|
-
|
|
1030
|
+
systemSettings: {},
|
|
1031
|
+
workspaceSettings: {},
|
|
1032
|
+
stdinActions: undefined,
|
|
1033
|
+
},
|
|
1034
|
+
])('should render $name correctly', ({ userSettings, systemSettings, workspaceSettings, stdinActions }) => {
|
|
1035
|
+
const settings = createMockSettings(userSettings, systemSettings, workspaceSettings);
|
|
1113
1036
|
const onSelect = vi.fn();
|
|
1114
|
-
const { lastFrame } =
|
|
1037
|
+
const { lastFrame, stdin } = renderDialog(settings, onSelect);
|
|
1038
|
+
if (stdinActions) {
|
|
1039
|
+
stdinActions(stdin);
|
|
1040
|
+
}
|
|
1115
1041
|
expect(lastFrame()).toMatchSnapshot();
|
|
1116
1042
|
});
|
|
1117
1043
|
});
|