mirror of
https://github.com/QwenLM/qwen-code.git
synced 2026-04-29 20:20:57 +00:00
Merge remote-tracking branch 'origin/main' into feat/debug-logging-refactor
This commit is contained in:
commit
4abec5c055
331 changed files with 19546 additions and 7771 deletions
42
packages/cli/src/utils/acpModelUtils.test.ts
Normal file
42
packages/cli/src/utils/acpModelUtils.test.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { AuthType } from '@qwen-code/qwen-code-core';
|
||||
import {
|
||||
formatAcpModelId,
|
||||
parseAcpBaseModelId,
|
||||
parseAcpModelOption,
|
||||
} from './acpModelUtils.js';
|
||||
|
||||
describe('acpModelUtils', () => {
|
||||
it('formats modelId(authType)', () => {
|
||||
expect(formatAcpModelId('qwen3', AuthType.QWEN_OAUTH)).toBe(
|
||||
`qwen3(${AuthType.QWEN_OAUTH})`,
|
||||
);
|
||||
});
|
||||
|
||||
it('extracts base model id when string ends with parentheses', () => {
|
||||
expect(parseAcpBaseModelId(`qwen3(${AuthType.USE_OPENAI})`)).toBe('qwen3');
|
||||
});
|
||||
|
||||
it('does not strip when parentheses are not a trailing suffix', () => {
|
||||
expect(parseAcpBaseModelId('qwen3(x) y')).toBe('qwen3(x) y');
|
||||
});
|
||||
|
||||
it('parses modelId and validates authType', () => {
|
||||
expect(parseAcpModelOption(` qwen3(${AuthType.USE_OPENAI}) `)).toEqual({
|
||||
modelId: 'qwen3',
|
||||
authType: AuthType.USE_OPENAI,
|
||||
});
|
||||
});
|
||||
|
||||
it('returns trimmed input as modelId when authType is invalid', () => {
|
||||
expect(parseAcpModelOption('qwen3(not-a-real-auth)')).toEqual({
|
||||
modelId: 'qwen3(not-a-real-auth)',
|
||||
});
|
||||
});
|
||||
});
|
||||
61
packages/cli/src/utils/acpModelUtils.ts
Normal file
61
packages/cli/src/utils/acpModelUtils.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2025 Qwen Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { AuthType } from '@qwen-code/qwen-code-core';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* ACP model IDs are represented as `${modelId}(${authType})` in the ACP protocol.
|
||||
*/
|
||||
export function formatAcpModelId(modelId: string, authType: AuthType): string {
|
||||
return `${modelId}(${authType})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the base model id from an ACP model id string.
|
||||
*
|
||||
* If the string ends with `(...)`, the suffix is removed; otherwise returns the
|
||||
* trimmed input as-is.
|
||||
*/
|
||||
export function parseAcpBaseModelId(value: string): string {
|
||||
const trimmed = value.trim();
|
||||
const closeIdx = trimmed.lastIndexOf(')');
|
||||
const openIdx = trimmed.lastIndexOf('(');
|
||||
if (openIdx >= 0 && closeIdx === trimmed.length - 1 && openIdx < closeIdx) {
|
||||
return trimmed.slice(0, openIdx);
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an ACP model option string into `{ modelId, authType? }`.
|
||||
*
|
||||
* Supports the following formats:
|
||||
* - `${modelId}(${authType})` - Standard registry model (e.g., "gpt-4(USE_OPENAI)")
|
||||
* - `${snapshotId}(${authType})` - Runtime model snapshot (e.g., "$runtime|USE_OPENAI|gpt-4(USE_OPENAI)")
|
||||
* where snapshotId is in format `$runtime|${authType}|${modelId}`
|
||||
* - Plain model ID - Returns as-is with no authType
|
||||
*
|
||||
* If the string ends with `(...)` and `...` is a valid `AuthType`, returns both;
|
||||
* otherwise returns the trimmed input as `modelId` only.
|
||||
*/
|
||||
export function parseAcpModelOption(input: string): {
|
||||
modelId: string;
|
||||
authType?: AuthType;
|
||||
} {
|
||||
const trimmed = input.trim();
|
||||
const closeIdx = trimmed.lastIndexOf(')');
|
||||
const openIdx = trimmed.lastIndexOf('(');
|
||||
if (openIdx >= 0 && closeIdx === trimmed.length - 1 && openIdx < closeIdx) {
|
||||
const maybeModelId = trimmed.slice(0, openIdx);
|
||||
const maybeAuthType = trimmed.slice(openIdx + 1, closeIdx);
|
||||
const parsedAuthType = z.nativeEnum(AuthType).safeParse(maybeAuthType);
|
||||
if (parsedAuthType.success) {
|
||||
return { modelId: maybeModelId, authType: parsedAuthType.data };
|
||||
}
|
||||
}
|
||||
return { modelId: trimmed };
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ describe('handleAutoUpdate', () => {
|
|||
mockSettings = {
|
||||
merged: {
|
||||
general: {
|
||||
disableAutoUpdate: false,
|
||||
enableAutoUpdate: true,
|
||||
},
|
||||
},
|
||||
} as LoadedSettings;
|
||||
|
|
@ -94,32 +94,29 @@ describe('handleAutoUpdate', () => {
|
|||
expect(mockSpawn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should do nothing if update nag is disabled', () => {
|
||||
mockSettings.merged.general!.disableUpdateNag = true;
|
||||
handleAutoUpdate(mockUpdateInfo, mockSettings, '/root', mockSpawn);
|
||||
expect(mockGetInstallationInfo).not.toHaveBeenCalled();
|
||||
expect(mockUpdateEventEmitter.emit).not.toHaveBeenCalled();
|
||||
expect(mockSpawn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit "update-received" but not update if auto-updates are disabled', () => {
|
||||
mockSettings.merged.general!.disableAutoUpdate = true;
|
||||
it('should show manual update message when enableAutoUpdate is false', () => {
|
||||
// When enableAutoUpdate is false, gemini.tsx won't call checkForUpdates(),
|
||||
// but if handleAutoUpdate is still called, it should show a manual update message.
|
||||
mockSettings.merged.general!.enableAutoUpdate = false;
|
||||
mockGetInstallationInfo.mockReturnValue({
|
||||
updateCommand: 'npm i -g @qwen-code/qwen-code@latest',
|
||||
updateMessage: 'Please update manually.',
|
||||
updateMessage:
|
||||
'Please run npm i -g @qwen-code/qwen-code@latest to update',
|
||||
isGlobal: true,
|
||||
packageManager: PackageManager.NPM,
|
||||
});
|
||||
|
||||
handleAutoUpdate(mockUpdateInfo, mockSettings, '/root', mockSpawn);
|
||||
|
||||
expect(mockUpdateEventEmitter.emit).toHaveBeenCalledTimes(1);
|
||||
// Should still emit update-received with manual update message
|
||||
expect(mockUpdateEventEmitter.emit).toHaveBeenCalledWith(
|
||||
'update-received',
|
||||
{
|
||||
message: 'An update is available!\nPlease update manually.',
|
||||
message:
|
||||
'An update is available!\nPlease run npm i -g @qwen-code/qwen-code@latest to update',
|
||||
},
|
||||
);
|
||||
// Should NOT spawn update when enableAutoUpdate is false
|
||||
expect(mockSpawn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,14 @@ export function handleAutoUpdate(
|
|||
return;
|
||||
}
|
||||
|
||||
if (settings.merged.general?.disableUpdateNag) {
|
||||
return;
|
||||
}
|
||||
// enableAutoUpdate is checked in gemini.tsx before calling this function,
|
||||
// so if we get here, auto-update is enabled (or undefined, which defaults to enabled).
|
||||
const isAutoUpdateEnabled =
|
||||
settings.merged.general?.enableAutoUpdate !== false;
|
||||
|
||||
const installationInfo = getInstallationInfo(
|
||||
projectRoot,
|
||||
settings.merged.general?.disableAutoUpdate ?? false,
|
||||
isAutoUpdateEnabled,
|
||||
);
|
||||
|
||||
let combinedMessage = info.message;
|
||||
|
|
@ -42,10 +43,8 @@ export function handleAutoUpdate(
|
|||
message: combinedMessage,
|
||||
});
|
||||
|
||||
if (
|
||||
!installationInfo.updateCommand ||
|
||||
settings.merged.general?.disableAutoUpdate
|
||||
) {
|
||||
// Don't automatically run the update if auto-update is disabled or no update command
|
||||
if (!installationInfo.updateCommand || !isAutoUpdateEnabled) {
|
||||
return;
|
||||
}
|
||||
const isNightly = info.update.latest.includes('nightly');
|
||||
|
|
|
|||
|
|
@ -180,13 +180,15 @@ describe('getInstallationInfo', () => {
|
|||
throw new Error('Command failed');
|
||||
});
|
||||
|
||||
const info = getInstallationInfo(projectRoot, false);
|
||||
// isAutoUpdateEnabled = true -> "Attempting to automatically update"
|
||||
const info = getInstallationInfo(projectRoot, true);
|
||||
expect(info.packageManager).toBe(PackageManager.PNPM);
|
||||
expect(info.isGlobal).toBe(true);
|
||||
expect(info.updateCommand).toBe('pnpm add -g @qwen-code/qwen-code@latest');
|
||||
expect(info.updateMessage).toContain('Attempting to automatically update');
|
||||
|
||||
const infoDisabled = getInstallationInfo(projectRoot, true);
|
||||
// isAutoUpdateEnabled = false -> "Please run..."
|
||||
const infoDisabled = getInstallationInfo(projectRoot, false);
|
||||
expect(infoDisabled.updateMessage).toContain('Please run pnpm add');
|
||||
});
|
||||
|
||||
|
|
@ -198,7 +200,8 @@ describe('getInstallationInfo', () => {
|
|||
throw new Error('Command failed');
|
||||
});
|
||||
|
||||
const info = getInstallationInfo(projectRoot, false);
|
||||
// isAutoUpdateEnabled = true -> "Attempting to automatically update"
|
||||
const info = getInstallationInfo(projectRoot, true);
|
||||
expect(info.packageManager).toBe(PackageManager.YARN);
|
||||
expect(info.isGlobal).toBe(true);
|
||||
expect(info.updateCommand).toBe(
|
||||
|
|
@ -206,7 +209,8 @@ describe('getInstallationInfo', () => {
|
|||
);
|
||||
expect(info.updateMessage).toContain('Attempting to automatically update');
|
||||
|
||||
const infoDisabled = getInstallationInfo(projectRoot, true);
|
||||
// isAutoUpdateEnabled = false -> "Please run..."
|
||||
const infoDisabled = getInstallationInfo(projectRoot, false);
|
||||
expect(infoDisabled.updateMessage).toContain('Please run yarn global add');
|
||||
});
|
||||
|
||||
|
|
@ -218,13 +222,15 @@ describe('getInstallationInfo', () => {
|
|||
throw new Error('Command failed');
|
||||
});
|
||||
|
||||
const info = getInstallationInfo(projectRoot, false);
|
||||
// isAutoUpdateEnabled = true -> "Attempting to automatically update"
|
||||
const info = getInstallationInfo(projectRoot, true);
|
||||
expect(info.packageManager).toBe(PackageManager.BUN);
|
||||
expect(info.isGlobal).toBe(true);
|
||||
expect(info.updateCommand).toBe('bun add -g @qwen-code/qwen-code@latest');
|
||||
expect(info.updateMessage).toContain('Attempting to automatically update');
|
||||
|
||||
const infoDisabled = getInstallationInfo(projectRoot, true);
|
||||
// isAutoUpdateEnabled = false -> "Please run..."
|
||||
const infoDisabled = getInstallationInfo(projectRoot, false);
|
||||
expect(infoDisabled.updateMessage).toContain('Please run bun add');
|
||||
});
|
||||
|
||||
|
|
@ -303,7 +309,8 @@ describe('getInstallationInfo', () => {
|
|||
throw new Error('Command failed');
|
||||
});
|
||||
|
||||
const info = getInstallationInfo(projectRoot, false);
|
||||
// isAutoUpdateEnabled = true -> "Attempting to automatically update"
|
||||
const info = getInstallationInfo(projectRoot, true);
|
||||
expect(info.packageManager).toBe(PackageManager.NPM);
|
||||
expect(info.isGlobal).toBe(true);
|
||||
expect(info.updateCommand).toBe(
|
||||
|
|
@ -311,7 +318,8 @@ describe('getInstallationInfo', () => {
|
|||
);
|
||||
expect(info.updateMessage).toContain('Attempting to automatically update');
|
||||
|
||||
const infoDisabled = getInstallationInfo(projectRoot, true);
|
||||
// isAutoUpdateEnabled = false -> "Please run..."
|
||||
const infoDisabled = getInstallationInfo(projectRoot, false);
|
||||
expect(infoDisabled.updateMessage).toContain('Please run npm install');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ export interface InstallationInfo {
|
|||
|
||||
export function getInstallationInfo(
|
||||
projectRoot: string,
|
||||
isAutoUpdateDisabled: boolean,
|
||||
isAutoUpdateEnabled: boolean,
|
||||
): InstallationInfo {
|
||||
const cliPath = process.argv[1];
|
||||
if (!cliPath) {
|
||||
|
|
@ -101,9 +101,9 @@ export function getInstallationInfo(
|
|||
packageManager: PackageManager.PNPM,
|
||||
isGlobal: true,
|
||||
updateCommand,
|
||||
updateMessage: isAutoUpdateDisabled
|
||||
? `Please run ${updateCommand} to update`
|
||||
: 'Installed with pnpm. Attempting to automatically update now...',
|
||||
updateMessage: isAutoUpdateEnabled
|
||||
? 'Installed with pnpm. Attempting to automatically update now...'
|
||||
: `Please run ${updateCommand} to update`,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -114,9 +114,9 @@ export function getInstallationInfo(
|
|||
packageManager: PackageManager.YARN,
|
||||
isGlobal: true,
|
||||
updateCommand,
|
||||
updateMessage: isAutoUpdateDisabled
|
||||
? `Please run ${updateCommand} to update`
|
||||
: 'Installed with yarn. Attempting to automatically update now...',
|
||||
updateMessage: isAutoUpdateEnabled
|
||||
? 'Installed with yarn. Attempting to automatically update now...'
|
||||
: `Please run ${updateCommand} to update`,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -134,9 +134,9 @@ export function getInstallationInfo(
|
|||
packageManager: PackageManager.BUN,
|
||||
isGlobal: true,
|
||||
updateCommand,
|
||||
updateMessage: isAutoUpdateDisabled
|
||||
? `Please run ${updateCommand} to update`
|
||||
: 'Installed with bun. Attempting to automatically update now...',
|
||||
updateMessage: isAutoUpdateEnabled
|
||||
? 'Installed with bun. Attempting to automatically update now...'
|
||||
: `Please run ${updateCommand} to update`,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -167,9 +167,9 @@ export function getInstallationInfo(
|
|||
packageManager: PackageManager.NPM,
|
||||
isGlobal: true,
|
||||
updateCommand,
|
||||
updateMessage: isAutoUpdateDisabled
|
||||
? `Please run ${updateCommand} to update`
|
||||
: 'Installed with npm. Attempting to automatically update now...',
|
||||
updateMessage: isAutoUpdateEnabled
|
||||
? 'Installed with npm. Attempting to automatically update now...'
|
||||
: `Please run ${updateCommand} to update`,
|
||||
};
|
||||
} catch (error) {
|
||||
debugLogger.error('Failed to detect installation info:', error);
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ describe('SettingsUtils', () => {
|
|||
description: 'Accessibility settings.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
disableLoadingPhrases: {
|
||||
enableLoadingPhrases: {
|
||||
type: 'boolean',
|
||||
label: 'Disable Loading Phrases',
|
||||
category: 'UI',
|
||||
|
|
@ -285,14 +285,14 @@ describe('SettingsUtils', () => {
|
|||
|
||||
it('should handle nested settings correctly', () => {
|
||||
const settings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
});
|
||||
const mergedSettings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: false } },
|
||||
ui: { accessibility: { enableLoadingPhrases: false } },
|
||||
});
|
||||
|
||||
const value = getEffectiveValue(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
mergedSettings,
|
||||
);
|
||||
|
|
@ -316,7 +316,7 @@ describe('SettingsUtils', () => {
|
|||
it('should return all setting keys', () => {
|
||||
const keys = getAllSettingKeys();
|
||||
expect(keys).toContain('test');
|
||||
expect(keys).toContain('ui.accessibility.disableLoadingPhrases');
|
||||
expect(keys).toContain('ui.accessibility.enableLoadingPhrases');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -343,9 +343,9 @@ describe('SettingsUtils', () => {
|
|||
describe('isValidSettingKey', () => {
|
||||
it('should return true for valid setting keys', () => {
|
||||
expect(isValidSettingKey('ui.requiresRestart')).toBe(true);
|
||||
expect(
|
||||
isValidSettingKey('ui.accessibility.disableLoadingPhrases'),
|
||||
).toBe(true);
|
||||
expect(isValidSettingKey('ui.accessibility.enableLoadingPhrases')).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return false for invalid setting keys', () => {
|
||||
|
|
@ -358,7 +358,7 @@ describe('SettingsUtils', () => {
|
|||
it('should return correct category for valid settings', () => {
|
||||
expect(getSettingCategory('ui.requiresRestart')).toBe('UI');
|
||||
expect(
|
||||
getSettingCategory('ui.accessibility.disableLoadingPhrases'),
|
||||
getSettingCategory('ui.accessibility.enableLoadingPhrases'),
|
||||
).toBe('UI');
|
||||
});
|
||||
|
||||
|
|
@ -392,7 +392,7 @@ describe('SettingsUtils', () => {
|
|||
const uiSettings = categories['UI'];
|
||||
const uiKeys = uiSettings.map((s) => s.key);
|
||||
expect(uiKeys).toContain('ui.requiresRestart');
|
||||
expect(uiKeys).toContain('ui.accessibility.disableLoadingPhrases');
|
||||
expect(uiKeys).toContain('ui.accessibility.enableLoadingPhrases');
|
||||
expect(uiKeys).not.toContain('ui.theme'); // This is now marked false
|
||||
});
|
||||
|
||||
|
|
@ -422,7 +422,7 @@ describe('SettingsUtils', () => {
|
|||
|
||||
const keys = booleanSettings.map((s) => s.key);
|
||||
expect(keys).toContain('ui.requiresRestart');
|
||||
expect(keys).toContain('ui.accessibility.disableLoadingPhrases');
|
||||
expect(keys).toContain('ui.accessibility.enableLoadingPhrases');
|
||||
expect(keys).not.toContain('privacy.usageStatisticsEnabled');
|
||||
expect(keys).not.toContain('security.auth.selectedType'); // Advanced setting
|
||||
expect(keys).not.toContain('security.auth.useExternal'); // Advanced setting
|
||||
|
|
@ -455,7 +455,7 @@ describe('SettingsUtils', () => {
|
|||
expect(dialogKeys).toContain('ui.requiresRestart');
|
||||
|
||||
// Should include nested settings marked for dialog
|
||||
expect(dialogKeys).toContain('ui.accessibility.disableLoadingPhrases');
|
||||
expect(dialogKeys).toContain('ui.accessibility.enableLoadingPhrases');
|
||||
|
||||
// Should NOT include settings marked as hidden
|
||||
expect(dialogKeys).not.toContain('ui.theme'); // Hidden
|
||||
|
|
@ -602,14 +602,14 @@ describe('SettingsUtils', () => {
|
|||
it('should return true when value differs from default', () => {
|
||||
expect(isSettingModified('ui.requiresRestart', true)).toBe(true);
|
||||
expect(
|
||||
isSettingModified('ui.accessibility.disableLoadingPhrases', true),
|
||||
isSettingModified('ui.accessibility.enableLoadingPhrases', true),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when value matches default', () => {
|
||||
expect(isSettingModified('ui.requiresRestart', false)).toBe(false);
|
||||
expect(
|
||||
isSettingModified('ui.accessibility.disableLoadingPhrases', false),
|
||||
isSettingModified('ui.accessibility.enableLoadingPhrases', false),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -629,11 +629,11 @@ describe('SettingsUtils', () => {
|
|||
|
||||
it('should return true for nested settings that exist', () => {
|
||||
const settings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
});
|
||||
expect(
|
||||
settingExistsInScope(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
),
|
||||
).toBe(true);
|
||||
|
|
@ -643,7 +643,7 @@ describe('SettingsUtils', () => {
|
|||
const settings = makeMockSettings({});
|
||||
expect(
|
||||
settingExistsInScope(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
),
|
||||
).toBe(false);
|
||||
|
|
@ -653,7 +653,7 @@ describe('SettingsUtils', () => {
|
|||
const settings = makeMockSettings({ ui: { accessibility: {} } });
|
||||
expect(
|
||||
settingExistsInScope(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
),
|
||||
).toBe(false);
|
||||
|
|
@ -675,25 +675,25 @@ describe('SettingsUtils', () => {
|
|||
it('should set nested setting value', () => {
|
||||
const pendingSettings = makeMockSettings({});
|
||||
const result = setPendingSettingValue(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
true,
|
||||
pendingSettings,
|
||||
);
|
||||
|
||||
expect(result.ui?.accessibility?.disableLoadingPhrases).toBe(true);
|
||||
expect(result.ui?.accessibility?.enableLoadingPhrases).toBe(true);
|
||||
});
|
||||
|
||||
it('should preserve existing nested settings', () => {
|
||||
const pendingSettings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: false } },
|
||||
ui: { accessibility: { enableLoadingPhrases: false } },
|
||||
});
|
||||
const result = setPendingSettingValue(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
true,
|
||||
pendingSettings,
|
||||
);
|
||||
|
||||
expect(result.ui?.accessibility?.disableLoadingPhrases).toBe(true);
|
||||
expect(result.ui?.accessibility?.enableLoadingPhrases).toBe(true);
|
||||
});
|
||||
|
||||
it('should not mutate original settings', () => {
|
||||
|
|
@ -1030,7 +1030,7 @@ describe('SettingsUtils', () => {
|
|||
const settings = makeMockSettings({}); // nested setting doesn't exist
|
||||
|
||||
const result = isDefaultValue(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
);
|
||||
expect(result).toBe(true);
|
||||
|
|
@ -1038,11 +1038,11 @@ describe('SettingsUtils', () => {
|
|||
|
||||
it('should return false when nested setting exists in scope', () => {
|
||||
const settings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
}); // nested setting exists
|
||||
|
||||
const result = isDefaultValue(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
);
|
||||
expect(result).toBe(false);
|
||||
|
|
@ -1080,14 +1080,14 @@ describe('SettingsUtils', () => {
|
|||
|
||||
it('should return false for nested settings that exist in scope', () => {
|
||||
const settings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
});
|
||||
const mergedSettings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
});
|
||||
|
||||
const result = isValueInherited(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
mergedSettings,
|
||||
);
|
||||
|
|
@ -1097,11 +1097,11 @@ describe('SettingsUtils', () => {
|
|||
it('should return true for nested settings that do not exist in scope', () => {
|
||||
const settings = makeMockSettings({});
|
||||
const mergedSettings = makeMockSettings({
|
||||
ui: { accessibility: { disableLoadingPhrases: true } },
|
||||
ui: { accessibility: { enableLoadingPhrases: true } },
|
||||
});
|
||||
|
||||
const result = isValueInherited(
|
||||
'ui.accessibility.disableLoadingPhrases',
|
||||
'ui.accessibility.enableLoadingPhrases',
|
||||
settings,
|
||||
mergedSettings,
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue