Loading src/__mocks__/vscode.js +5 −0 Original line number Diff line number Diff line Loading @@ -124,4 +124,9 @@ module.exports = { this.range = range; this.command = command; }, ConfigurationTarget: { Global: 1, Workspace: 2, WorkspaceFolder: 3, }, }; src/common/utils/extension_configuration.test.ts 0 → 100644 +51 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { createFakePartial } from '../test_utils/create_fake_partial'; import { AI_ASSISTED_CODE_SUGGESTIONS_CONFIG, setAiAssistedCodeSuggestionsConfiguration, } from './extension_configuration'; describe('utils/extension_configuration', () => { describe('setAiAssistedCodeSuggestionsConfiguration', () => { let mockAiConfig: vscode.WorkspaceConfiguration; beforeEach(() => { mockAiConfig = createFakePartial<vscode.WorkspaceConfiguration>({ update: jest.fn().mockResolvedValue(undefined), inspect: jest.fn().mockReturnValue(undefined), }); jest.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockAiConfig); }); it('requests AI config', async () => { expect(vscode.workspace.getConfiguration).not.toHaveBeenCalled(); await setAiAssistedCodeSuggestionsConfiguration({ enabled: true, }); expect(vscode.workspace.getConfiguration).toHaveBeenCalledTimes(1); expect(vscode.workspace.getConfiguration).toHaveBeenCalledWith( AI_ASSISTED_CODE_SUGGESTIONS_CONFIG, ); }); it.each` config | mockInspect | expectedUpdate ${{ enabled: true }} | ${undefined} | ${[['enabled', true, vscode.ConfigurationTarget.Global]]} ${{ enabled: false }} | ${{ workspaceValue: false }} | ${[['enabled', false, vscode.ConfigurationTarget.Workspace]]} ${{ enabled: true, preferredAccount: 'lorem' }} | ${{ workspaceValue: false }} | ${[['enabled', true, vscode.ConfigurationTarget.Workspace], ['preferredAccount', 'lorem', vscode.ConfigurationTarget.Workspace]]} `( 'with config=$config and inspect=$mockInspect, should update', async ({ config, mockInspect, expectedUpdate }) => { jest.mocked(mockAiConfig.inspect).mockReturnValue(mockInspect); expect(mockAiConfig.update).not.toHaveBeenCalled(); await setAiAssistedCodeSuggestionsConfiguration(config); expect(jest.mocked(mockAiConfig.update).mock.calls).toEqual(expectedUpdate); }, ); }); }); src/common/utils/extension_configuration.ts +16 −2 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; import { CONFIG_NAMESPACE } from '../constants'; import { AI_ASSISTED_CODE_SUGGESTIONS_CONFIG_NAMESPACE } from '../code_suggestions/constants'; import { CustomQuery } from '../gitlab/custom_query'; import { getConfigurationTargetForKey } from './get_configuration_target_for_key'; // These constants represent `settings.json` keys. Other constants belong to `constants.ts`. export const GITLAB_DEBUG_MODE = 'gitlab.debug'; Loading Loading @@ -43,6 +44,15 @@ export function getAiAssistedCodeSuggestionsConfiguration(): AiAssistedCodeSugge }; } /** * Calls `config.update` but ises `getConfigurationTargetForKey` to make * sure we pick the right ConfigurationTarget */ const updateConfig = <T>(config: vscode.WorkspaceConfiguration, key: string, value: T) => { const target = getConfigurationTargetForKey(config, key); return config.update(key, value, target); }; export async function setAiAssistedCodeSuggestionsConfiguration( config: AiAssistedCodeSuggestionsConfiguration, ) { Loading @@ -50,9 +60,13 @@ export async function setAiAssistedCodeSuggestionsConfiguration( AI_ASSISTED_CODE_SUGGESTIONS_CONFIG_NAMESPACE, ); await aiAssistedCodeSuggestionsConfig.update('enabled', Boolean(config.enabled)); await updateConfig(aiAssistedCodeSuggestionsConfig, 'enabled', Boolean(config.enabled)); if (typeof config.preferredAccount === 'string') { await aiAssistedCodeSuggestionsConfig.update('preferredAccount', config.preferredAccount); await updateConfig( aiAssistedCodeSuggestionsConfig, 'preferredAccount', config.preferredAccount, ); } } src/common/utils/get_configuration_target_for_key.test.ts 0 → 100644 +39 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { createFakePartial } from '../test_utils/create_fake_partial'; import { getConfigurationTargetForKey } from './get_configuration_target_for_key'; type ConfigurationInspection = Omit<ReturnType<vscode.WorkspaceConfiguration['inspect']>, 'key'>; const CONFIG_KEY = 'lorem'; describe('utils/get_configuration_target_for_key', () => { const createFakeConfiguration = (mockKey: string, mockInspection: ConfigurationInspection) => createFakePartial<vscode.WorkspaceConfiguration>({ inspect(key: string) { if (key === mockKey) { return { ...mockInspection, key: mockKey, }; } return undefined; }, }); it.each` mockInspection | expectation ${undefined} | ${vscode.ConfigurationTarget.Global} ${{ workspaceFolderValue: false }} | ${vscode.ConfigurationTarget.WorkspaceFolder} ${{ workspaceFolderLanguageValue: 0 }} | ${vscode.ConfigurationTarget.WorkspaceFolder} ${{ workspaceValue: true }} | ${vscode.ConfigurationTarget.Workspace} ${{ workspaceLanguageValue: false }} | ${vscode.ConfigurationTarget.Workspace} ${{ defaultValue: true }} | ${vscode.ConfigurationTarget.Global} `('with $mockInspection, result is $expectation', ({ mockInspection, expectation }) => { const config = createFakeConfiguration(CONFIG_KEY, mockInspection); const result = getConfigurationTargetForKey(config, CONFIG_KEY); expect(result).toEqual(expectation); }); }); src/common/utils/get_configuration_target_for_key.ts 0 → 100644 +28 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; export const getConfigurationTargetForKey = ( config: vscode.WorkspaceConfiguration, key: string, ) => { const inspection = config.inspect(key); if (!inspection) { return vscode.ConfigurationTarget.Global; } const { workspaceFolderValue, workspaceFolderLanguageValue, workspaceValue, workspaceLanguageValue, } = inspection; if (workspaceFolderValue !== undefined || workspaceFolderLanguageValue !== undefined) { return vscode.ConfigurationTarget.WorkspaceFolder; } if (workspaceValue !== undefined || workspaceLanguageValue !== undefined) { return vscode.ConfigurationTarget.Workspace; } return vscode.ConfigurationTarget.Global; }; Loading
src/__mocks__/vscode.js +5 −0 Original line number Diff line number Diff line Loading @@ -124,4 +124,9 @@ module.exports = { this.range = range; this.command = command; }, ConfigurationTarget: { Global: 1, Workspace: 2, WorkspaceFolder: 3, }, };
src/common/utils/extension_configuration.test.ts 0 → 100644 +51 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { createFakePartial } from '../test_utils/create_fake_partial'; import { AI_ASSISTED_CODE_SUGGESTIONS_CONFIG, setAiAssistedCodeSuggestionsConfiguration, } from './extension_configuration'; describe('utils/extension_configuration', () => { describe('setAiAssistedCodeSuggestionsConfiguration', () => { let mockAiConfig: vscode.WorkspaceConfiguration; beforeEach(() => { mockAiConfig = createFakePartial<vscode.WorkspaceConfiguration>({ update: jest.fn().mockResolvedValue(undefined), inspect: jest.fn().mockReturnValue(undefined), }); jest.mocked(vscode.workspace.getConfiguration).mockReturnValue(mockAiConfig); }); it('requests AI config', async () => { expect(vscode.workspace.getConfiguration).not.toHaveBeenCalled(); await setAiAssistedCodeSuggestionsConfiguration({ enabled: true, }); expect(vscode.workspace.getConfiguration).toHaveBeenCalledTimes(1); expect(vscode.workspace.getConfiguration).toHaveBeenCalledWith( AI_ASSISTED_CODE_SUGGESTIONS_CONFIG, ); }); it.each` config | mockInspect | expectedUpdate ${{ enabled: true }} | ${undefined} | ${[['enabled', true, vscode.ConfigurationTarget.Global]]} ${{ enabled: false }} | ${{ workspaceValue: false }} | ${[['enabled', false, vscode.ConfigurationTarget.Workspace]]} ${{ enabled: true, preferredAccount: 'lorem' }} | ${{ workspaceValue: false }} | ${[['enabled', true, vscode.ConfigurationTarget.Workspace], ['preferredAccount', 'lorem', vscode.ConfigurationTarget.Workspace]]} `( 'with config=$config and inspect=$mockInspect, should update', async ({ config, mockInspect, expectedUpdate }) => { jest.mocked(mockAiConfig.inspect).mockReturnValue(mockInspect); expect(mockAiConfig.update).not.toHaveBeenCalled(); await setAiAssistedCodeSuggestionsConfiguration(config); expect(jest.mocked(mockAiConfig.update).mock.calls).toEqual(expectedUpdate); }, ); }); });
src/common/utils/extension_configuration.ts +16 −2 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; import { CONFIG_NAMESPACE } from '../constants'; import { AI_ASSISTED_CODE_SUGGESTIONS_CONFIG_NAMESPACE } from '../code_suggestions/constants'; import { CustomQuery } from '../gitlab/custom_query'; import { getConfigurationTargetForKey } from './get_configuration_target_for_key'; // These constants represent `settings.json` keys. Other constants belong to `constants.ts`. export const GITLAB_DEBUG_MODE = 'gitlab.debug'; Loading Loading @@ -43,6 +44,15 @@ export function getAiAssistedCodeSuggestionsConfiguration(): AiAssistedCodeSugge }; } /** * Calls `config.update` but ises `getConfigurationTargetForKey` to make * sure we pick the right ConfigurationTarget */ const updateConfig = <T>(config: vscode.WorkspaceConfiguration, key: string, value: T) => { const target = getConfigurationTargetForKey(config, key); return config.update(key, value, target); }; export async function setAiAssistedCodeSuggestionsConfiguration( config: AiAssistedCodeSuggestionsConfiguration, ) { Loading @@ -50,9 +60,13 @@ export async function setAiAssistedCodeSuggestionsConfiguration( AI_ASSISTED_CODE_SUGGESTIONS_CONFIG_NAMESPACE, ); await aiAssistedCodeSuggestionsConfig.update('enabled', Boolean(config.enabled)); await updateConfig(aiAssistedCodeSuggestionsConfig, 'enabled', Boolean(config.enabled)); if (typeof config.preferredAccount === 'string') { await aiAssistedCodeSuggestionsConfig.update('preferredAccount', config.preferredAccount); await updateConfig( aiAssistedCodeSuggestionsConfig, 'preferredAccount', config.preferredAccount, ); } }
src/common/utils/get_configuration_target_for_key.test.ts 0 → 100644 +39 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; import { createFakePartial } from '../test_utils/create_fake_partial'; import { getConfigurationTargetForKey } from './get_configuration_target_for_key'; type ConfigurationInspection = Omit<ReturnType<vscode.WorkspaceConfiguration['inspect']>, 'key'>; const CONFIG_KEY = 'lorem'; describe('utils/get_configuration_target_for_key', () => { const createFakeConfiguration = (mockKey: string, mockInspection: ConfigurationInspection) => createFakePartial<vscode.WorkspaceConfiguration>({ inspect(key: string) { if (key === mockKey) { return { ...mockInspection, key: mockKey, }; } return undefined; }, }); it.each` mockInspection | expectation ${undefined} | ${vscode.ConfigurationTarget.Global} ${{ workspaceFolderValue: false }} | ${vscode.ConfigurationTarget.WorkspaceFolder} ${{ workspaceFolderLanguageValue: 0 }} | ${vscode.ConfigurationTarget.WorkspaceFolder} ${{ workspaceValue: true }} | ${vscode.ConfigurationTarget.Workspace} ${{ workspaceLanguageValue: false }} | ${vscode.ConfigurationTarget.Workspace} ${{ defaultValue: true }} | ${vscode.ConfigurationTarget.Global} `('with $mockInspection, result is $expectation', ({ mockInspection, expectation }) => { const config = createFakeConfiguration(CONFIG_KEY, mockInspection); const result = getConfigurationTargetForKey(config, CONFIG_KEY); expect(result).toEqual(expectation); }); });
src/common/utils/get_configuration_target_for_key.ts 0 → 100644 +28 −0 Original line number Diff line number Diff line import * as vscode from 'vscode'; export const getConfigurationTargetForKey = ( config: vscode.WorkspaceConfiguration, key: string, ) => { const inspection = config.inspect(key); if (!inspection) { return vscode.ConfigurationTarget.Global; } const { workspaceFolderValue, workspaceFolderLanguageValue, workspaceValue, workspaceLanguageValue, } = inspection; if (workspaceFolderValue !== undefined || workspaceFolderLanguageValue !== undefined) { return vscode.ConfigurationTarget.WorkspaceFolder; } if (workspaceValue !== undefined || workspaceLanguageValue !== undefined) { return vscode.ConfigurationTarget.Workspace; } return vscode.ConfigurationTarget.Global; };